tcmodules.pas 884 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2018 by Michael Van Canneyt
  4. Unit tests for Pascal-to-Javascript converter class.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************
  11. Examples:
  12. ./testpas2js --suite=TTestModule.TestEmptyProgram
  13. ./testpas2js --suite=TTestModule.TestEmptyUnit
  14. }
  15. unit TCModules;
  16. {$mode objfpc}{$H+}
  17. interface
  18. uses
  19. Classes, SysUtils, fpcunit, testregistry, contnrs,
  20. jstree, jswriter, jsbase,
  21. PasTree, PScanner, PasResolver, PParser, PasResolveEval,
  22. FPPas2Js;
  23. const
  24. // default parser+scanner options
  25. po_tcmodules = po_Pas2js+[po_KeepScannerError];
  26. co_tcmodules = [];
  27. type
  28. TSrcMarkerKind = (
  29. mkLabel,
  30. mkResolverReference,
  31. mkDirectReference
  32. );
  33. PSrcMarker = ^TSrcMarker;
  34. TSrcMarker = record
  35. Kind: TSrcMarkerKind;
  36. Filename: string;
  37. Row: integer;
  38. StartCol, EndCol: integer; // token start, end column
  39. Identifier: string;
  40. Next: PSrcMarker;
  41. end;
  42. TSystemUnitPart = (
  43. supTObject,
  44. supTVarRec,
  45. supTypeInfo,
  46. supTInterfacedObject,
  47. supWriteln
  48. );
  49. TSystemUnitParts = set of TSystemUnitPart;
  50. { TTestHintMessage }
  51. TTestHintMessage = class
  52. public
  53. Id: int64;
  54. MsgType: TMessageType;
  55. MsgNumber: integer;
  56. Msg: string;
  57. SourcePos: TPasSourcePos;
  58. end;
  59. { TTestPasParser }
  60. TTestPasParser = Class(TPasParser)
  61. end;
  62. TOnFindUnit = function(const aUnitName: String): TPasModule of object;
  63. { TTestEnginePasResolver }
  64. TTestEnginePasResolver = class(TPas2JsResolver)
  65. private
  66. FFilename: string;
  67. FModule: TPasModule;
  68. FOnFindUnit: TOnFindUnit;
  69. FParser: TTestPasParser;
  70. FStreamResolver: TStreamResolver;
  71. FScanner: TPas2jsPasScanner;
  72. FSource: string;
  73. public
  74. destructor Destroy; override;
  75. function FindUnit(const AName, InFilename: String; NameExpr,
  76. InFileExpr: TPasExpr): TPasModule; override;
  77. procedure UsedInterfacesFinished(Section: TPasSection); override;
  78. property OnFindUnit: TOnFindUnit read FOnFindUnit write FOnFindUnit;
  79. property Filename: string read FFilename write FFilename;
  80. property StreamResolver: TStreamResolver read FStreamResolver write FStreamResolver;
  81. property Scanner: TPas2jsPasScanner read FScanner write FScanner;
  82. property Parser: TTestPasParser read FParser write FParser;
  83. property Source: string read FSource write FSource;
  84. property Module: TPasModule read FModule;
  85. end;
  86. { TCustomTestModule }
  87. TCustomTestModule = Class(TTestCase)
  88. private
  89. FConverter: TPasToJSConverter;
  90. FEngine: TTestEnginePasResolver;
  91. FExpectedErrorClass: ExceptClass;
  92. FExpectedErrorMsg: string;
  93. FExpectedErrorNumber: integer;
  94. FFilename: string;
  95. FFileResolver: TStreamResolver;
  96. FHub: TPas2JSResolverHub;
  97. FJSImplementationUses: TJSArrayLiteral;
  98. FJSInitBody: TJSFunctionBody;
  99. FJSImplentationUses: TJSArrayLiteral;
  100. FJSInterfaceUses: TJSArrayLiteral;
  101. FJSModule: TJSSourceElements;
  102. FJSModuleSrc: TJSSourceElements;
  103. FJSSource: TStringList;
  104. FModule: TPasModule;
  105. FJSModuleCallArgs: TJSArguments;
  106. FModules: TObjectList;// list of TTestEnginePasResolver
  107. FParser: TTestPasParser;
  108. FPasProgram: TPasProgram;
  109. FPasLibrary: TPasLibrary;
  110. FHintMsgs: TObjectList; // list of TTestHintMessage
  111. FHintMsgsGood: TFPList; // list of TTestHintMessage marked as expected
  112. FJSRegModuleCall: TJSCallExpression;
  113. FScanner: TPas2jsPasScanner;
  114. FSkipTests: boolean;
  115. FSource: TStringList;
  116. FFirstPasStatement: TPasImplBlock;
  117. FWithTypeInfo: boolean;
  118. {$IFDEF EnablePasTreeGlobalRefCount}
  119. FElementRefCountAtSetup: int64;
  120. {$ENDIF}
  121. function GetMsgCount: integer;
  122. function GetMsgs(Index: integer): TTestHintMessage;
  123. function GetResolverCount: integer;
  124. function GetResolvers(Index: integer): TTestEnginePasResolver;
  125. function OnPasResolverFindUnit(const aUnitName: String): TPasModule;
  126. procedure OnParserLog(Sender: TObject; const Msg: String);
  127. procedure OnPasResolverLog(Sender: TObject; const Msg: String);
  128. procedure OnScannerLog(Sender: TObject; const Msg: String);
  129. procedure SetWithTypeInfo(const AValue: boolean);
  130. protected
  131. procedure SetUp; override;
  132. function CreateConverter: TPasToJSConverter; virtual;
  133. function LoadUnit(const aUnitName: String): TPasModule;
  134. procedure InitScanner(aScanner: TPas2jsPasScanner); virtual;
  135. procedure TearDown; override;
  136. Procedure Add(Line: string); virtual;
  137. Procedure Add(const Lines: array of string);
  138. Procedure StartParsing; virtual;
  139. procedure ParseModuleQueue; virtual;
  140. procedure ParseModule; virtual;
  141. procedure ParseProgram; virtual;
  142. procedure ParseLibrary; virtual;
  143. procedure ParseUnit; virtual;
  144. protected
  145. function FindModuleWithFilename(aFilename: string): TTestEnginePasResolver; virtual;
  146. function AddModule(aFilename: string): TTestEnginePasResolver; virtual;
  147. function AddModuleWithSrc(aFilename, Src: string): TTestEnginePasResolver; virtual;
  148. function AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  149. ImplementationSrc: string): TTestEnginePasResolver; virtual;
  150. procedure AddSystemUnit(Parts: TSystemUnitParts = []); virtual;
  151. procedure StartProgram(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []); virtual;
  152. procedure StartLibrary(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []); virtual;
  153. procedure StartUnit(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []); virtual;
  154. procedure ConvertModule; virtual;
  155. procedure ConvertProgram; virtual;
  156. procedure ConvertLibrary; virtual;
  157. procedure ConvertUnit; virtual;
  158. function ConvertJSModuleToString(El: TJSElement): string; virtual;
  159. procedure CheckDottedIdentifier(Msg: string; El: TJSElement; DottedName: string);
  160. function GetDottedIdentifier(El: TJSElement): string;
  161. procedure CheckSource(Msg,Statements: String; InitStatements: string = '';
  162. ImplStatements: string = ''); virtual;
  163. procedure CheckDiff(Msg, Expected, Actual: string); virtual;
  164. procedure CheckUnit(Filename, ExpectedSrc: string); virtual;
  165. procedure CheckHint(MsgType: TMessageType; MsgNumber: integer;
  166. Msg: string; Marker: PSrcMarker = nil); virtual;
  167. procedure CheckResolverUnexpectedHints(WithSourcePos: boolean = false); virtual;
  168. procedure SetExpectedScannerError(Msg: string; MsgNumber: integer);
  169. procedure SetExpectedParserError(Msg: string; MsgNumber: integer);
  170. procedure SetExpectedPasResolverError(Msg: string; MsgNumber: integer);
  171. procedure SetExpectedConverterError(Msg: string; MsgNumber: integer);
  172. function IsErrorExpected(E: Exception): boolean;
  173. procedure HandleScannerError(E: EScannerError);
  174. procedure HandleParserError(E: EParserError);
  175. procedure HandlePasResolveError(E: EPasResolve);
  176. procedure HandlePas2JSError(E: EPas2JS);
  177. procedure HandleException(E: Exception);
  178. procedure FailException(E: Exception);
  179. procedure WriteSources(const aFilename: string; aRow, aCol: integer);
  180. function IndexOfResolver(const Filename: string): integer;
  181. function GetResolver(const Filename: string): TTestEnginePasResolver;
  182. function GetDefaultNamespace: string;
  183. property PasProgram: TPasProgram Read FPasProgram;
  184. property PasLibrary: TPasLibrary Read FPasLibrary;
  185. property Resolvers[Index: integer]: TTestEnginePasResolver read GetResolvers;
  186. property ResolverCount: integer read GetResolverCount;
  187. property Engine: TTestEnginePasResolver read FEngine;
  188. property Filename: string read FFilename;
  189. Property Module: TPasModule Read FModule;
  190. property FirstPasStatement: TPasImplBlock read FFirstPasStatement;
  191. property Converter: TPasToJSConverter read FConverter;
  192. property JSSource: TStringList read FJSSource;
  193. property JSModule: TJSSourceElements read FJSModule;
  194. property JSRegModuleCall: TJSCallExpression read FJSRegModuleCall;
  195. property JSModuleCallArgs: TJSArguments read FJSModuleCallArgs;
  196. property JSImplementationUses: TJSArrayLiteral read FJSImplementationUses;
  197. property JSInterfaceUses: TJSArrayLiteral read FJSInterfaceUses;
  198. property JSModuleSrc: TJSSourceElements read FJSModuleSrc;
  199. property JSInitBody: TJSFunctionBody read FJSInitBody;
  200. property ExpectedErrorClass: ExceptClass read FExpectedErrorClass write FExpectedErrorClass;
  201. property ExpectedErrorMsg: string read FExpectedErrorMsg write FExpectedErrorMsg;
  202. property ExpectedErrorNumber: integer read FExpectedErrorNumber write FExpectedErrorNumber;
  203. property SkipTests: boolean read FSkipTests write FSkipTests;
  204. public
  205. constructor Create; override;
  206. destructor Destroy; override;
  207. property Hub: TPas2JSResolverHub read FHub;
  208. property Source: TStringList read FSource;
  209. property FileResolver: TStreamResolver read FFileResolver;
  210. property Scanner: TPas2jsPasScanner read FScanner;
  211. property Parser: TTestPasParser read FParser;
  212. property MsgCount: integer read GetMsgCount;
  213. property Msgs[Index: integer]: TTestHintMessage read GetMsgs;
  214. property WithTypeInfo: boolean read FWithTypeInfo write SetWithTypeInfo;
  215. end;
  216. { TTestModule }
  217. TTestModule = class(TCustomTestModule)
  218. Published
  219. Procedure TestReservedWords;
  220. // program, units, includes
  221. Procedure TestEmptyProgram;
  222. Procedure TestEmptyProgramUseStrict;
  223. Procedure TestEmptyUnit;
  224. Procedure TestEmptyUnitUseStrict;
  225. Procedure TestDottedUnitNames;
  226. Procedure TestDottedUnitNameImpl;
  227. Procedure TestDottedUnitExpr;
  228. Procedure Test_ModeFPCFail;
  229. Procedure Test_ModeSwitchCBlocksFail;
  230. Procedure TestUnit_UseSystem;
  231. Procedure TestUnit_Intf1Impl2Intf1;
  232. Procedure TestIncludeVersion;
  233. // vars/const
  234. Procedure TestVarInt;
  235. Procedure TestVarBaseTypes;
  236. Procedure TestBaseTypeSingleFail;
  237. Procedure TestBaseTypeExtendedFail;
  238. Procedure TestConstBaseTypes;
  239. Procedure TestUnitImplVars;
  240. Procedure TestUnitImplConsts;
  241. Procedure TestUnitImplRecord;
  242. Procedure TestRenameJSNameConflict;
  243. Procedure TestLocalConst;
  244. Procedure TestVarExternal;
  245. Procedure TestVarExternalOtherUnit;
  246. Procedure TestVarAbsoluteFail;
  247. Procedure TestConstExternal;
  248. // numbers
  249. Procedure TestDouble;
  250. Procedure TestInteger;
  251. Procedure TestIntegerRange;
  252. Procedure TestIntegerTypecasts;
  253. Procedure TestInteger_BitwiseShrNativeInt;
  254. Procedure TestInteger_BitwiseShlNativeInt;
  255. Procedure TestInteger_SystemFunc;
  256. Procedure TestInteger_AssignOutsideConst;
  257. Procedure TestCurrency;
  258. Procedure TestForBoolDo;
  259. Procedure TestForIntDo;
  260. Procedure TestForIntInDo;
  261. // strings
  262. Procedure TestCharConst;
  263. Procedure TestChar_Compare;
  264. Procedure TestChar_BuiltInProcs;
  265. Procedure TestStringConst;
  266. Procedure TestStringConst_InvalidUTF16;
  267. Procedure TestStringConstSurrogate;
  268. Procedure TestString_Length;
  269. Procedure TestString_Compare;
  270. Procedure TestString_SetLength;
  271. Procedure TestString_CharAt;
  272. Procedure TestStringHMinusFail;
  273. Procedure TestStr;
  274. Procedure TestBaseType_AnsiStringFail;
  275. Procedure TestBaseType_WideStringFail;
  276. Procedure TestBaseType_ShortStringFail;
  277. Procedure TestBaseType_RawByteStringFail;
  278. Procedure TestTypeShortstring_Fail;
  279. Procedure TestCharSet_Custom;
  280. Procedure TestWideChar;
  281. Procedure TestForCharDo;
  282. Procedure TestForCharInDo;
  283. // alias types
  284. Procedure TestAliasTypeRef;
  285. Procedure TestTypeCast_BaseTypes;
  286. Procedure TestTypeCast_AliasBaseTypes;
  287. // functions
  288. Procedure TestEmptyProc;
  289. Procedure TestProcOneParam;
  290. Procedure TestFunctionWithoutParams;
  291. Procedure TestProcedureWithoutParams;
  292. Procedure TestPrgProcVar;
  293. Procedure TestProcTwoArgs;
  294. Procedure TestProc_DefaultValue;
  295. Procedure TestUnitProcVar;
  296. Procedure TestImplProc;
  297. Procedure TestFunctionResult;
  298. Procedure TestNestedProc;
  299. Procedure TestNestedProc_ResultString;
  300. Procedure TestForwardProc;
  301. Procedure TestNestedForwardProc;
  302. Procedure TestAssignFunctionResult;
  303. Procedure TestFunctionResultInCondition;
  304. Procedure TestFunctionResultInForLoop;
  305. Procedure TestFunctionResultInTypeCast;
  306. Procedure TestExit;
  307. Procedure TestExit_ResultInFinally;
  308. Procedure TestBreak;
  309. Procedure TestBreakAsVar;
  310. Procedure TestContinue;
  311. Procedure TestProc_External;
  312. Procedure TestProc_ExternalOtherUnit;
  313. Procedure TestProc_Asm;
  314. Procedure TestProc_AsmSubBlock;
  315. Procedure TestProc_Assembler;
  316. Procedure TestProc_VarParam;
  317. Procedure TestProc_VarParamString;
  318. Procedure TestProc_VarParamV;
  319. Procedure TestProc_Overload;
  320. Procedure TestProc_OverloadForward;
  321. Procedure TestProc_OverloadIntfImpl;
  322. Procedure TestProc_OverloadNested;
  323. Procedure TestProc_OverloadNestedForward;
  324. Procedure TestProc_OverloadUnitCycle;
  325. Procedure TestProc_Varargs;
  326. Procedure TestProc_ConstOrder;
  327. Procedure TestProc_DuplicateConst;
  328. Procedure TestProc_LocalVarAbsolute;
  329. Procedure TestProc_LocalVarInit;
  330. Procedure TestProc_ReservedWords;
  331. Procedure TestProc_ConstRefWord;
  332. // anonymous functions
  333. Procedure TestAnonymousProc_Assign_ObjFPC;
  334. Procedure TestAnonymousProc_Assign_Delphi;
  335. Procedure TestAnonymousProc_Arg;
  336. Procedure TestAnonymousProc_Typecast;
  337. Procedure TestAnonymousProc_With;
  338. Procedure TestAnonymousProc_ExceptOn;
  339. Procedure TestAnonymousProc_Nested;
  340. Procedure TestAnonymousProc_NestedAssignResult;
  341. Procedure TestAnonymousProc_Class;
  342. Procedure TestAnonymousProc_ForLoop;
  343. Procedure TestAnonymousProc_AsmDelphi;
  344. // enums, sets
  345. Procedure TestEnum_Name;
  346. Procedure TestEnum_Number;
  347. Procedure TestEnum_ConstFail;
  348. Procedure TestEnum_Functions;
  349. Procedure TestEnumRg_Functions;
  350. Procedure TestEnum_AsParams;
  351. Procedure TestEnumRange_Array;
  352. Procedure TestEnum_ForIn;
  353. Procedure TestEnum_ScopedNumber;
  354. Procedure TestEnum_InFunction;
  355. Procedure TestEnum_Name_Anonymous_Unit;
  356. Procedure TestSet_Enum;
  357. Procedure TestSet_Operators;
  358. Procedure TestSet_Operator_In;
  359. Procedure TestSet_Functions;
  360. Procedure TestSet_PassAsArgClone;
  361. Procedure TestSet_AsParams;
  362. Procedure TestSet_Property;
  363. Procedure TestSet_EnumConst;
  364. Procedure TestSet_IntConst;
  365. Procedure TestSet_IntRange;
  366. Procedure TestSet_AnonymousEnumType;
  367. Procedure TestSet_AnonymousEnumTypeChar; // ToDo
  368. Procedure TestSet_ConstEnum;
  369. Procedure TestSet_ConstChar;
  370. Procedure TestSet_ConstInt;
  371. Procedure TestSet_InFunction;
  372. Procedure TestSet_ForIn;
  373. // statements
  374. Procedure TestNestBegin;
  375. Procedure TestIncDec;
  376. Procedure TestLoHiFpcMode;
  377. Procedure TestLoHiDelphiMode;
  378. Procedure TestAssignments;
  379. Procedure TestArithmeticOperators1;
  380. Procedure TestMultiAdd;
  381. Procedure TestLogicalOperators;
  382. Procedure TestBitwiseOperators;
  383. Procedure TestBitwiseOperatorsLongword;
  384. Procedure TestFunctionInt;
  385. Procedure TestFunctionString;
  386. Procedure TestIfThen;
  387. Procedure TestForLoop;
  388. Procedure TestForLoopInsideFunction;
  389. Procedure TestForLoop_ReadVarAfter;
  390. Procedure TestForLoop_Nested;
  391. Procedure TestRepeatUntil;
  392. Procedure TestAsmBlock;
  393. Procedure TestAsmPas_Impl; // ToDo
  394. Procedure TestTryFinally;
  395. Procedure TestTryExcept;
  396. Procedure TestTryExcept_ReservedWords;
  397. Procedure TestIfThenRaiseElse;
  398. Procedure TestCaseOf;
  399. Procedure TestCaseOf_UseSwitch;
  400. Procedure TestCaseOfNoElse;
  401. Procedure TestCaseOfNoElse_UseSwitch;
  402. Procedure TestCaseOfRange;
  403. Procedure TestCaseOfString;
  404. Procedure TestCaseOfChar;
  405. Procedure TestCaseOfExternalClassConst;
  406. Procedure TestDebugger;
  407. // arrays
  408. Procedure TestArray_Dynamic;
  409. Procedure TestArray_Dynamic_Nil;
  410. Procedure TestArray_DynMultiDimensional;
  411. Procedure TestArray_DynamicAssign;
  412. Procedure TestArray_StaticInt;
  413. Procedure TestArray_StaticBool;
  414. Procedure TestArray_StaticChar;
  415. Procedure TestArray_StaticMultiDim;
  416. Procedure TestArray_StaticInFunction;
  417. Procedure TestArray_StaticMultiDimEqualNotImplemented;
  418. Procedure TestArrayOfRecord;
  419. Procedure TestArray_StaticRecord;
  420. Procedure TestArrayOfSet;
  421. Procedure TestArray_DynAsParam;
  422. Procedure TestArray_StaticAsParam;
  423. Procedure TestArrayElement_AsParams;
  424. Procedure TestArrayElementFromFuncResult_AsParams;
  425. Procedure TestArrayEnumTypeRange;
  426. Procedure TestArray_SetLengthOutArg;
  427. Procedure TestArray_SetLengthProperty;
  428. Procedure TestArray_SetLengthMultiDim;
  429. Procedure TestArray_SetLengthDynOfStatic;
  430. Procedure TestArray_OpenArrayOfString;
  431. Procedure TestArray_ArrayOfCharAssignString; // ToDo
  432. Procedure TestArray_ConstRef;
  433. Procedure TestArray_Concat;
  434. Procedure TestArray_Copy;
  435. Procedure TestArray_InsertDelete;
  436. Procedure TestArray_DynArrayConstObjFPC;
  437. Procedure TestArray_DynArrayConstDelphi;
  438. Procedure TestArray_ArrayLitAsParam;
  439. Procedure TestArray_ArrayLitMultiDimAsParam;
  440. Procedure TestArray_ArrayLitStaticAsParam;
  441. Procedure TestArray_ForInArrOfString;
  442. Procedure TestExternalClass_TypeCastArrayToExternalClass;
  443. Procedure TestExternalClass_TypeCastArrayFromExternalClass;
  444. Procedure TestArrayOfConst_TVarRec;
  445. Procedure TestArrayOfConst_PassBaseTypes;
  446. Procedure TestArrayOfConst_PassObj;
  447. // record
  448. Procedure TestRecord_Empty;
  449. Procedure TestRecord_Var;
  450. Procedure TestRecord_VarExternal;
  451. Procedure TestRecord_WithDo;
  452. Procedure TestRecord_Assign;
  453. Procedure TestRecord_AsParams;
  454. Procedure TestRecord_ConstRef;
  455. Procedure TestRecordElement_AsParams;
  456. Procedure TestRecordElementFromFuncResult_AsParams;
  457. Procedure TestRecordElementFromWith_AsParams;
  458. Procedure TestRecord_Equal;
  459. Procedure TestRecord_JSValue;
  460. Procedure TestRecord_VariantFail;
  461. Procedure TestRecord_FieldArray;
  462. Procedure TestRecord_Const;
  463. Procedure TestRecord_TypecastFail;
  464. Procedure TestRecord_InFunction;
  465. Procedure TestRecord_AnonymousFail;
  466. // advanced record
  467. Procedure TestAdvRecord_Function;
  468. Procedure TestAdvRecord_Property;
  469. Procedure TestAdvRecord_PropertyDefault;
  470. Procedure TestAdvRecord_Property_ClassMethod;
  471. Procedure TestAdvRecord_Const;
  472. Procedure TestAdvRecord_ExternalField;
  473. Procedure TestAdvRecord_SubRecord;
  474. Procedure TestAdvRecord_SubClass;
  475. Procedure TestAdvRecord_SubInterfaceFail;
  476. Procedure TestAdvRecord_Constructor;
  477. Procedure TestAdvRecord_ClassConstructor_Program;
  478. Procedure TestAdvRecord_ClassConstructor_Unit;
  479. // classes
  480. Procedure TestClass_TObjectDefaultConstructor;
  481. Procedure TestClass_TObjectConstructorWithParams;
  482. Procedure TestClass_TObjectConstructorWithDefaultParam;
  483. Procedure TestClass_Var;
  484. Procedure TestClass_Method;
  485. Procedure TestClass_Implementation;
  486. Procedure TestClass_Inheritance;
  487. Procedure TestClass_TypeAlias;
  488. Procedure TestClass_AbstractMethod;
  489. Procedure TestClass_CallInherited_ProcNoParams;
  490. Procedure TestClass_CallInherited_WithParams;
  491. Procedure TestClasS_CallInheritedConstructor;
  492. Procedure TestClass_ClassVar_Assign;
  493. Procedure TestClass_CallClassMethod;
  494. Procedure TestClass_CallClassMethodStatic; // ToDo
  495. Procedure TestClass_Property;
  496. Procedure TestClass_Property_ClassMethod;
  497. Procedure TestClass_Property_Indexed;
  498. Procedure TestClass_Property_IndexSpec;
  499. Procedure TestClass_PropertyOfTypeArray;
  500. Procedure TestClass_PropertyDefault;
  501. Procedure TestClass_PropertyDefault_TypecastToOtherDefault;
  502. //Procedure TestClass_PropertyDefault;
  503. Procedure TestClass_PropertyOverride;
  504. Procedure TestClass_PropertyIncVisibility;
  505. Procedure TestClass_Assigned;
  506. Procedure TestClass_WithClassDoCreate;
  507. Procedure TestClass_WithClassInstDoProperty;
  508. Procedure TestClass_WithClassInstDoPropertyWithParams;
  509. Procedure TestClass_WithClassInstDoFunc;
  510. Procedure TestClass_TypeCast;
  511. Procedure TestClass_TypeCastUntypedParam;
  512. Procedure TestClass_Overloads;
  513. Procedure TestClass_OverloadsAncestor;
  514. Procedure TestClass_OverloadConstructor;
  515. Procedure TestClass_OverloadDelphiOverride;
  516. Procedure TestClass_ReintroduceVarDelphi;
  517. Procedure TestClass_ReintroducedVar;
  518. Procedure TestClass_RaiseDescendant;
  519. Procedure TestClass_ExternalMethod;
  520. Procedure TestClass_ExternalVirtualNameMismatchFail;
  521. Procedure TestClass_ExternalOverrideFail;
  522. Procedure TestClass_ExternalVar;
  523. Procedure TestClass_Const;
  524. Procedure TestClass_ConstEnum;
  525. Procedure TestClass_LocalConstDuplicate_Prg;
  526. Procedure TestClass_LocalConstDuplicate_Unit;
  527. // ToDo: Procedure TestAdvRecord_LocalConstDuplicate;
  528. Procedure TestClass_LocalVarSelfFail;
  529. Procedure TestClass_ArgSelfFail;
  530. Procedure TestClass_NestedProcSelf;
  531. Procedure TestClass_NestedProcSelf2;
  532. Procedure TestClass_NestedProcClassSelf;
  533. Procedure TestClass_NestedProcCallInherited;
  534. Procedure TestClass_TObjectFree;
  535. Procedure TestClass_TObjectFree_VarArg;
  536. Procedure TestClass_TObjectFreeNewInstance;
  537. Procedure TestClass_TObjectFreeLowerCase;
  538. Procedure TestClass_TObjectFreeFunctionFail;
  539. Procedure TestClass_TObjectFreePropertyFail;
  540. Procedure TestClass_ForIn;
  541. Procedure TestClass_DispatchMessage;
  542. Procedure TestClass_Message_DuplicateIntFail;
  543. Procedure TestClass_DispatchMessage_WrongFieldNameFail;
  544. // class of
  545. Procedure TestClassOf_Create;
  546. Procedure TestClassOf_Call;
  547. Procedure TestClassOf_Assign;
  548. Procedure TestClassOf_Is;
  549. Procedure TestClassOf_Compare;
  550. Procedure TestClassOf_ClassVar;
  551. Procedure TestClassOf_ClassMethod;
  552. Procedure TestClassOf_ClassProperty;
  553. Procedure TestClassOf_ClassMethodSelf;
  554. Procedure TestClassOf_TypeCast;
  555. Procedure TestClassOf_ImplicitFunctionCall;
  556. Procedure TestClassOf_Const;
  557. // nested class
  558. Procedure TestNestedClass_Alias;
  559. Procedure TestNestedClass_Record;
  560. Procedure TestNestedClass_Class;
  561. // external class
  562. Procedure TestExternalClass_Var;
  563. Procedure TestExternalClass_Const;
  564. Procedure TestExternalClass_Dollar;
  565. Procedure TestExternalClass_DuplicateVarFail;
  566. Procedure TestExternalClass_Method;
  567. Procedure TestExternalClass_ClassMethod;
  568. Procedure TestExternalClass_ClassMethodStatic;
  569. Procedure TestExternalClass_FunctionResultInTypeCast;
  570. Procedure TestExternalClass_NonExternalOverride;
  571. Procedure TestExternalClass_OverloadHint;
  572. Procedure TestExternalClass_SameNamePublishedProperty;
  573. Procedure TestExternalClass_Property;
  574. Procedure TestExternalClass_PropertyDate;
  575. Procedure TestExternalClass_ClassProperty;
  576. Procedure TestExternalClass_ClassOf;
  577. Procedure TestExternalClass_ClassOtherUnit;
  578. Procedure TestExternalClass_Is;
  579. Procedure TestExternalClass_As;
  580. Procedure TestExternalClass_DestructorFail;
  581. Procedure TestExternalClass_New;
  582. Procedure TestExternalClass_ClassOf_New;
  583. Procedure TestExternalClass_FuncClassOf_New;
  584. Procedure TestExternalClass_New_PasClassFail;
  585. Procedure TestExternalClass_New_PasClassBracketsFail;
  586. Procedure TestExternalClass_NewExtName;
  587. Procedure TestExternalClass_Constructor;
  588. Procedure TestExternalClass_ConstructorBrackets;
  589. Procedure TestExternalClass_LocalConstSameName;
  590. Procedure TestExternalClass_ReintroduceOverload;
  591. Procedure TestExternalClass_Inherited;
  592. Procedure TestExternalClass_PascalAncestorFail;
  593. Procedure TestExternalClass_NewInstance;
  594. Procedure TestExternalClass_NewInstance_NonVirtualFail;
  595. Procedure TestExternalClass_NewInstance_FirstParamNotString_Fail;
  596. Procedure TestExternalClass_NewInstance_SecondParamTyped_Fail;
  597. Procedure TestExternalClass_JSFunctionPasDescendant;
  598. Procedure TestExternalClass_PascalProperty;
  599. Procedure TestExternalClass_TypeCastToRootClass;
  600. Procedure TestExternalClass_TypeCastToJSObject;
  601. Procedure TestExternalClass_TypeCastStringToExternalString;
  602. Procedure TestExternalClass_TypeCastToJSFunction;
  603. Procedure TestExternalClass_TypeCastDelphiUnrelated;
  604. Procedure TestExternalClass_CallClassFunctionOfInstanceFail;
  605. Procedure TestExternalClass_BracketAccessor;
  606. Procedure TestExternalClass_BracketAccessor_Call;
  607. Procedure TestExternalClass_BracketAccessor_2ParamsFail;
  608. Procedure TestExternalClass_BracketAccessor_ReadOnly;
  609. Procedure TestExternalClass_BracketAccessor_WriteOnly;
  610. Procedure TestExternalClass_BracketAccessor_MultiType;
  611. Procedure TestExternalClass_BracketAccessor_Index;
  612. Procedure TestExternalClass_ForInJSObject;
  613. Procedure TestExternalClass_ForInJSArray;
  614. Procedure TestExternalClass_IncompatibleArgDuplicateIdentifier;
  615. // class interfaces
  616. Procedure TestClassInterface_Corba;
  617. Procedure TestClassInterface_ProcExternalFail;
  618. Procedure TestClassInterface_Overloads;
  619. Procedure TestClassInterface_DuplicateGUIInIntfListFail;
  620. Procedure TestClassInterface_DuplicateGUIInAncestorFail;
  621. Procedure TestClassInterface_AncestorImpl;
  622. Procedure TestClassInterface_ImplReintroduce;
  623. Procedure TestClassInterface_MethodResolution;
  624. Procedure TestClassInterface_AncestorMoreInterfaces;
  625. Procedure TestClassInterface_MethodOverride;
  626. Procedure TestClassInterface_Corba_Delegation;
  627. Procedure TestClassInterface_Corba_DelegationStatic;
  628. Procedure TestClassInterface_Corba_Operators;
  629. Procedure TestClassInterface_Corba_Args;
  630. Procedure TestClassInterface_Corba_ForIn;
  631. Procedure TestClassInterface_COM_AssignVar;
  632. Procedure TestClassInterface_COM_AssignArg;
  633. Procedure TestClassInterface_COM_FunctionResult;
  634. Procedure TestClassInterface_COM_InheritedFuncResult;
  635. Procedure TestClassInterface_COM_IsAsTypeCasts;
  636. Procedure TestClassInterface_COM_PassAsArg;
  637. Procedure TestClassInterface_COM_PassToUntypedParam;
  638. Procedure TestClassInterface_COM_FunctionInExpr;
  639. Procedure TestClassInterface_COM_Property;
  640. Procedure TestClassInterface_COM_IntfProperty;
  641. Procedure TestClassInterface_COM_Delegation;
  642. Procedure TestClassInterface_COM_With;
  643. Procedure TestClassInterface_COM_ForIn;
  644. Procedure TestClassInterface_COM_ArrayOfIntfFail;
  645. Procedure TestClassInterface_COM_RecordIntfFail;
  646. Procedure TestClassInterface_COM_UnitInitialization;
  647. Procedure TestClassInterface_GUID;
  648. Procedure TestClassInterface_GUIDProperty;
  649. // helpers
  650. Procedure TestClassHelper_ClassVar;
  651. Procedure TestClassHelper_Method_AccessInstanceFields;
  652. Procedure TestClassHelper_Method_Call;
  653. Procedure TestClassHelper_Method_Nested_Call;
  654. Procedure TestClassHelper_ClassMethod_Call;
  655. Procedure TestClassHelper_ClassOf;
  656. Procedure TestClassHelper_MethodRefObjFPC;
  657. Procedure TestClassHelper_Constructor;
  658. Procedure TestClassHelper_InheritedObjFPC;
  659. Procedure TestClassHelper_Property;
  660. Procedure TestClassHelper_Property_Array;
  661. Procedure TestClassHelper_Property_Array_Default;
  662. Procedure TestClassHelper_Property_Array_DefaultDefault;
  663. Procedure TestClassHelper_ClassProperty;
  664. Procedure TestClassHelper_ClassPropertyStatic;
  665. Procedure TestClassHelper_ClassProperty_Array;
  666. Procedure TestClassHelper_ForIn;
  667. Procedure TestClassHelper_PassProperty;
  668. Procedure TestExtClassHelper_ClassVar;
  669. Procedure TestExtClassHelper_Method_Call;
  670. Procedure TestExtClassHelper_ClassMethod_MissingStatic;
  671. Procedure TestRecordHelper_ClassVar;
  672. Procedure TestRecordHelper_Method_Call;
  673. Procedure TestRecordHelper_Constructor;
  674. Procedure TestTypeHelper_ClassVar;
  675. Procedure TestTypeHelper_PassResultElement;
  676. Procedure TestTypeHelper_PassArgs;
  677. Procedure TestTypeHelper_PassVarConst;
  678. Procedure TestTypeHelper_PassFuncResult;
  679. Procedure TestTypeHelper_PassPropertyField;
  680. Procedure TestTypeHelper_PassPropertyGetter;
  681. Procedure TestTypeHelper_PassClassPropertyField;
  682. Procedure TestTypeHelper_PassClassPropertyGetterStatic;
  683. Procedure TestTypeHelper_PassClassPropertyGetterNonStatic;
  684. Procedure TestTypeHelper_Property;
  685. Procedure TestTypeHelper_Property_Array;
  686. Procedure TestTypeHelper_ClassProperty;
  687. Procedure TestTypeHelper_ClassProperty_Array;
  688. Procedure TestTypeHelper_ClassMethod;
  689. Procedure TestTypeHelper_ExtClassMethodFail;
  690. Procedure TestTypeHelper_Constructor;
  691. Procedure TestTypeHelper_Word;
  692. Procedure TestTypeHelper_Boolean;
  693. Procedure TestTypeHelper_WordBool;
  694. Procedure TestTypeHelper_Double;
  695. Procedure TestTypeHelper_NativeInt;
  696. Procedure TestTypeHelper_StringChar;
  697. Procedure TestTypeHelper_JSValue;
  698. Procedure TestTypeHelper_Array;
  699. Procedure TestTypeHelper_EnumType;
  700. Procedure TestTypeHelper_SetType;
  701. Procedure TestTypeHelper_InterfaceType;
  702. Procedure TestTypeHelper_NestedSelf;
  703. // proc types
  704. Procedure TestProcType;
  705. Procedure TestProcType_Arg;
  706. Procedure TestProcType_FunctionFPC;
  707. Procedure TestProcType_FunctionDelphi;
  708. Procedure TestProcType_ProcedureDelphi;
  709. Procedure TestProcType_AsParam;
  710. Procedure TestProcType_MethodFPC;
  711. Procedure TestProcType_MethodDelphi;
  712. Procedure TestProcType_PropertyFPC;
  713. Procedure TestProcType_PropertyDelphi;
  714. Procedure TestProcType_WithClassInstDoPropertyFPC;
  715. Procedure TestProcType_Nested;
  716. Procedure TestProcType_NestedOfObject;
  717. Procedure TestProcType_ReferenceToProc;
  718. Procedure TestProcType_ReferenceToMethod;
  719. Procedure TestProcType_Typecast;
  720. Procedure TestProcType_PassProcToUntyped;
  721. Procedure TestProcType_PassProcToArray;
  722. Procedure TestProcType_SafeCallObjFPC;
  723. Procedure TestProcType_SafeCallDelphi;
  724. // pointer
  725. Procedure TestPointer;
  726. Procedure TestPointer_Proc;
  727. Procedure TestPointer_AssignRecordFail;
  728. Procedure TestPointer_AssignStaticArrayFail;
  729. Procedure TestPointer_TypeCastJSValueToPointer;
  730. Procedure TestPointer_NonRecordFail;
  731. Procedure TestPointer_AnonymousArgTypeFail;
  732. Procedure TestPointer_AnonymousVarTypeFail;
  733. Procedure TestPointer_AnonymousResultTypeFail;
  734. Procedure TestPointer_AddrOperatorFail;
  735. Procedure TestPointer_ArrayParamsFail;
  736. Procedure TestPointer_PointerAddFail;
  737. Procedure TestPointer_IncPointerFail;
  738. Procedure TestPointer_Record;
  739. Procedure TestPointer_RecordArg;
  740. // jsvalue
  741. Procedure TestJSValue_AssignToJSValue;
  742. Procedure TestJSValue_TypeCastToBaseType;
  743. Procedure TestJSValue_TypecastToJSValue;
  744. Procedure TestJSValue_Equal;
  745. Procedure TestJSValue_If;
  746. Procedure TestJSValue_Not;
  747. Procedure TestJSValue_Enum;
  748. Procedure TestJSValue_ClassInstance;
  749. Procedure TestJSValue_ClassOf;
  750. Procedure TestJSValue_ArrayOfJSValue;
  751. Procedure TestJSValue_ArrayLit;
  752. Procedure TestJSValue_Params;
  753. Procedure TestJSValue_UntypedParam;
  754. Procedure TestJSValue_FuncResultType;
  755. Procedure TestJSValue_ProcType_Assign;
  756. Procedure TestJSValue_ProcType_Equal;
  757. Procedure TestJSValue_ProcType_Param;
  758. Procedure TestJSValue_AssignToPointerFail;
  759. Procedure TestJSValue_OverloadDouble;
  760. Procedure TestJSValue_OverloadNativeInt;
  761. Procedure TestJSValue_OverloadWord;
  762. Procedure TestJSValue_OverloadString;
  763. Procedure TestJSValue_OverloadChar;
  764. Procedure TestJSValue_OverloadPointer;
  765. Procedure TestJSValue_ForIn;
  766. // RTTI
  767. Procedure TestRTTI_IntRange;
  768. Procedure TestRTTI_Double;
  769. Procedure TestRTTI_ProcType;
  770. Procedure TestRTTI_ProcType_ArgFromOtherUnit;
  771. Procedure TestRTTI_EnumAndSetType;
  772. Procedure TestRTTI_EnumRange;
  773. Procedure TestRTTI_AnonymousEnumType;
  774. Procedure TestRTTI_StaticArray;
  775. Procedure TestRTTI_DynArray;
  776. Procedure TestRTTI_ArrayNestedAnonymous;
  777. Procedure TestRTTI_PublishedMethodOverloadFail;
  778. Procedure TestRTTI_PublishedMethodHideNoHint;
  779. Procedure TestRTTI_PublishedMethodExternalFail;
  780. Procedure TestRTTI_PublishedClassPropertyFail;
  781. Procedure TestRTTI_PublishedClassFieldFail;
  782. Procedure TestRTTI_PublishedFieldExternalFail;
  783. Procedure TestRTTI_Class_Field;
  784. Procedure TestRTTI_Class_Method;
  785. Procedure TestRTTI_Class_MethodArgFlags;
  786. Procedure TestRTTI_Class_Property;
  787. Procedure TestRTTI_Class_PropertyParams;
  788. Procedure TestRTTI_Class_OtherUnit_TypeAlias;
  789. Procedure TestRTTI_Class_OmitRTTI;
  790. Procedure TestRTTI_Class_Field_AnonymousArrayOfSelfClass;
  791. Procedure TestRTTI_IndexModifier;
  792. Procedure TestRTTI_StoredModifier;
  793. Procedure TestRTTI_DefaultValue;
  794. Procedure TestRTTI_DefaultValueSet;
  795. Procedure TestRTTI_DefaultValueRangeType;
  796. Procedure TestRTTI_DefaultValueInherit;
  797. Procedure TestRTTI_OverrideMethod;
  798. Procedure TestRTTI_ReintroduceMethod;
  799. Procedure TestRTTI_OverloadProperty;
  800. // ToDo: array argument
  801. Procedure TestRTTI_ClassForward;
  802. Procedure TestRTTI_ClassOf;
  803. Procedure TestRTTI_Record;
  804. Procedure TestRTTI_RecordAnonymousArray;
  805. Procedure TestRTTI_Record_ClassVarType;
  806. Procedure TestRTTI_LocalTypes;
  807. Procedure TestRTTI_TypeInfo_BaseTypes;
  808. Procedure TestRTTI_TypeInfo_Type_BaseTypes;
  809. Procedure TestRTTI_TypeInfo_LocalFail;
  810. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses1;
  811. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses2;
  812. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses3;
  813. Procedure TestRTTI_TypeInfo_FunctionClassType;
  814. Procedure TestRTTI_TypeInfo_MixedUnits_PointerAndClass;
  815. Procedure TestRTTI_Interface_Corba;
  816. Procedure TestRTTI_Interface_COM;
  817. Procedure TestRTTI_ClassHelper;
  818. Procedure TestRTTI_ExternalClass;
  819. Procedure TestRTTI_Unit;
  820. // Resourcestring
  821. Procedure TestResourcestringProgram;
  822. Procedure TestResourcestringUnit;
  823. Procedure TestResourcestringImplementation;
  824. // Attributes
  825. Procedure TestAttributes_Members;
  826. Procedure TestAttributes_Types;
  827. Procedure TestAttributes_HelperConstructor_Fail;
  828. // Assertions, checks
  829. procedure TestAssert;
  830. procedure TestAssert_SysUtils;
  831. procedure TestObjectChecks;
  832. procedure TestOverflowChecks_Int;
  833. procedure TestRangeChecks_AssignInt;
  834. procedure TestRangeChecks_AssignIntRange;
  835. procedure TestRangeChecks_AssignEnum;
  836. procedure TestRangeChecks_AssignEnumRange;
  837. procedure TestRangeChecks_AssignChar;
  838. procedure TestRangeChecks_AssignCharRange;
  839. procedure TestRangeChecks_ArrayIndex;
  840. procedure TestRangeChecks_ArrayOfRecIndex;
  841. procedure TestRangeChecks_StringIndex;
  842. procedure TestRangeChecks_TypecastInt;
  843. procedure TestRangeChecks_TypeHelperInt;
  844. // Async/AWait
  845. Procedure TestAsync_Proc;
  846. Procedure TestAsync_CallResultIsPromise;
  847. Procedure TestAsync_ConstructorFail;
  848. Procedure TestAsync_PropertyGetterFail;
  849. Procedure TestAwait_NonPromiseWithTypeFail;
  850. Procedure TestAwait_AsyncCallTypeMismatch;
  851. Procedure TestAWait_OutsideAsyncFail;
  852. Procedure TestAWait_IntegerFail;
  853. Procedure TestAWait_ExternalClassPromise;
  854. Procedure TestAWait_JSValue;
  855. Procedure TestAWait_Result;
  856. Procedure TestAWait_ResultPromiseMissingTypeFail; // await(AsyncCallResultPromise) needs T
  857. Procedure TestAsync_AnonymousProc;
  858. Procedure TestAsync_ProcType;
  859. Procedure TestAsync_ProcTypeAsyncModMismatchFail;
  860. Procedure TestAsync_Inherited;
  861. Procedure TestAsync_ClassInterface;
  862. Procedure TestAsync_ClassInterface_AsyncMissmatchFail;
  863. // Library
  864. Procedure TestLibrary_Empty;
  865. Procedure TestLibrary_ExportFunc; // ToDo
  866. // ToDo: test delayed specialization init
  867. // ToDO: analyzer
  868. end;
  869. function LinesToStr(Args: array of const): string;
  870. function ExtractFileUnitName(aFilename: string): string;
  871. function JSToStr(El: TJSElement): string;
  872. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  873. implementation
  874. function LinesToStr(Args: array of const): string;
  875. var
  876. s: String;
  877. i: Integer;
  878. begin
  879. s:='';
  880. for i:=Low(Args) to High(Args) do
  881. case Args[i].VType of
  882. vtChar: s += Args[i].VChar+LineEnding;
  883. vtString: s += Args[i].VString^+LineEnding;
  884. vtPChar: s += Args[i].VPChar+LineEnding;
  885. vtWideChar: s += AnsiString(Args[i].VWideChar)+LineEnding;
  886. vtPWideChar: s += AnsiString(Args[i].VPWideChar)+LineEnding;
  887. vtAnsiString: s += AnsiString(Args[i].VAnsiString)+LineEnding;
  888. vtWidestring: s += AnsiString(WideString(Args[i].VWideString))+LineEnding;
  889. vtUnicodeString:s += AnsiString(UnicodeString(Args[i].VUnicodeString))+LineEnding;
  890. end;
  891. Result:=s;
  892. end;
  893. function ExtractFileUnitName(aFilename: string): string;
  894. var
  895. p: Integer;
  896. begin
  897. Result:=ExtractFileName(aFilename);
  898. if Result='' then exit;
  899. for p:=length(Result) downto 1 do
  900. case Result[p] of
  901. '/','\': exit;
  902. '.':
  903. begin
  904. Delete(Result,p,length(Result));
  905. exit;
  906. end;
  907. end;
  908. end;
  909. function JSToStr(El: TJSElement): string;
  910. var
  911. aWriter: TBufferWriter;
  912. aJSWriter: TJSWriter;
  913. begin
  914. aJSWriter:=nil;
  915. aWriter:=TBufferWriter.Create(1000);
  916. try
  917. aJSWriter:=TJSWriter.Create(aWriter);
  918. aJSWriter.IndentSize:=2;
  919. aJSWriter.WriteJS(El);
  920. Result:=aWriter.AsString;
  921. finally
  922. aJSWriter.Free;
  923. aWriter.Free;
  924. end;
  925. end;
  926. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  927. // search diff, ignore changes in spaces
  928. const
  929. SpaceChars = [#9,#10,#13,' '];
  930. var
  931. ExpectedP, ActualP: PChar;
  932. function FindLineEnd(p: PChar): PChar;
  933. begin
  934. Result:=p;
  935. while not (Result^ in [#0,#10,#13]) do inc(Result);
  936. end;
  937. function FindLineStart(p, MinP: PChar): PChar;
  938. begin
  939. while (p>MinP) and not (p[-1] in [#10,#13]) do dec(p);
  940. Result:=p;
  941. end;
  942. procedure SkipLineEnd(var p: PChar);
  943. begin
  944. if p^ in [#10,#13] then
  945. begin
  946. if (p[1] in [#10,#13]) and (p^<>p[1]) then
  947. inc(p,2)
  948. else
  949. inc(p);
  950. end;
  951. end;
  952. function HasSpecialChar(s: string): boolean;
  953. var
  954. i: Integer;
  955. begin
  956. for i:=1 to length(s) do
  957. if s[i] in [#0..#31,#127..#255] then
  958. exit(true);
  959. Result:=false;
  960. end;
  961. function HashSpecialChars(s: string): string;
  962. var
  963. i: Integer;
  964. begin
  965. Result:='';
  966. for i:=1 to length(s) do
  967. if s[i] in [#0..#31,#127..#255] then
  968. Result:=Result+'#'+hexstr(ord(s[i]),2)
  969. else
  970. Result:=Result+s[i];
  971. end;
  972. procedure DiffFound;
  973. var
  974. ActLineStartP, ActLineEndP, p, StartPos: PChar;
  975. ExpLine, ActLine: String;
  976. i, LineNo, DiffLineNo: Integer;
  977. begin
  978. writeln('Diff found "',Msg,'". Lines:');
  979. // write correct lines
  980. p:=PChar(Expected);
  981. LineNo:=0;
  982. DiffLineNo:=0;
  983. repeat
  984. StartPos:=p;
  985. while not (p^ in [#0,#10,#13]) do inc(p);
  986. ExpLine:=copy(Expected,StartPos-PChar(Expected)+1,p-StartPos);
  987. SkipLineEnd(p);
  988. inc(LineNo);
  989. if (p<=ExpectedP) and (p^<>#0) then
  990. begin
  991. writeln('= ',ExpLine);
  992. end else begin
  993. // diff line
  994. if DiffLineNo=0 then DiffLineNo:=LineNo;
  995. // write actual line
  996. ActLineStartP:=FindLineStart(ActualP,PChar(Actual));
  997. ActLineEndP:=FindLineEnd(ActualP);
  998. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  999. writeln('- ',ActLine);
  1000. if HasSpecialChar(ActLine) then
  1001. writeln('- ',HashSpecialChars(ActLine));
  1002. // write expected line
  1003. writeln('+ ',ExpLine);
  1004. if HasSpecialChar(ExpLine) then
  1005. writeln('- ',HashSpecialChars(ExpLine));
  1006. // write empty line with pointer ^
  1007. for i:=1 to 2+ExpectedP-StartPos do write(' ');
  1008. writeln('^');
  1009. Msg:='expected "'+ExpLine+'", but got "'+ActLine+'".';
  1010. CheckSrcDiff:=false;
  1011. // write up to three following actual lines to get some context
  1012. for i:=1 to 3 do begin
  1013. ActLineStartP:=ActLineEndP;
  1014. SkipLineEnd(ActLineStartP);
  1015. if ActLineStartP^=#0 then break;
  1016. ActLineEndP:=FindLineEnd(ActLineStartP);
  1017. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  1018. writeln('~ ',ActLine);
  1019. end;
  1020. exit;
  1021. end;
  1022. until p^=#0;
  1023. writeln('DiffFound Actual:-----------------------');
  1024. writeln(Actual);
  1025. writeln('DiffFound Expected:---------------------');
  1026. writeln(Expected);
  1027. writeln('DiffFound ------------------------------');
  1028. Msg:='diff found, but lines are the same, internal error';
  1029. CheckSrcDiff:=false;
  1030. end;
  1031. var
  1032. IsSpaceNeeded: Boolean;
  1033. LastChar, Quote: Char;
  1034. begin
  1035. Result:=true;
  1036. Msg:='';
  1037. if Expected='' then Expected:=' ';
  1038. if Actual='' then Actual:=' ';
  1039. ExpectedP:=PChar(Expected);
  1040. ActualP:=PChar(Actual);
  1041. repeat
  1042. //writeln('TTestModule.CheckDiff Exp="',ExpectedP^,'" Act="',ActualP^,'"');
  1043. case ExpectedP^ of
  1044. #0:
  1045. begin
  1046. // check that rest of Actual has only spaces
  1047. while ActualP^ in SpaceChars do inc(ActualP);
  1048. if ActualP^<>#0 then
  1049. begin
  1050. DiffFound;
  1051. exit;
  1052. end;
  1053. exit(true);
  1054. end;
  1055. ' ',#9,#10,#13:
  1056. begin
  1057. // skip space in Expected
  1058. IsSpaceNeeded:=false;
  1059. if ExpectedP>PChar(Expected) then
  1060. LastChar:=ExpectedP[-1]
  1061. else
  1062. LastChar:=#0;
  1063. while ExpectedP^ in SpaceChars do inc(ExpectedP);
  1064. if (LastChar in ['a'..'z','A'..'Z','0'..'9','_','$'])
  1065. and (ExpectedP^ in ['a'..'z','A'..'Z','0'..'9','_','$']) then
  1066. IsSpaceNeeded:=true;
  1067. if IsSpaceNeeded and (not (ActualP^ in SpaceChars)) then
  1068. begin
  1069. DiffFound;
  1070. exit;
  1071. end;
  1072. while ActualP^ in SpaceChars do inc(ActualP);
  1073. end;
  1074. '''','"':
  1075. begin
  1076. while ActualP^ in SpaceChars do inc(ActualP);
  1077. if ExpectedP^<>ActualP^ then
  1078. begin
  1079. DiffFound;
  1080. exit;
  1081. end;
  1082. Quote:=ExpectedP^;
  1083. repeat
  1084. inc(ExpectedP);
  1085. inc(ActualP);
  1086. if ExpectedP^<>ActualP^ then
  1087. begin
  1088. DiffFound;
  1089. exit;
  1090. end;
  1091. if (ExpectedP^ in [#0,#10,#13]) then
  1092. break
  1093. else if (ExpectedP^=Quote) then
  1094. begin
  1095. inc(ExpectedP);
  1096. inc(ActualP);
  1097. break;
  1098. end;
  1099. until false;
  1100. end;
  1101. else
  1102. while ActualP^ in SpaceChars do inc(ActualP);
  1103. if ExpectedP^<>ActualP^ then
  1104. begin
  1105. DiffFound;
  1106. exit;
  1107. end;
  1108. inc(ExpectedP);
  1109. inc(ActualP);
  1110. end;
  1111. until false;
  1112. end;
  1113. { TTestEnginePasResolver }
  1114. destructor TTestEnginePasResolver.Destroy;
  1115. begin
  1116. FreeAndNil(FStreamResolver);
  1117. FreeAndNil(FParser);
  1118. FreeAndNil(FScanner);
  1119. FreeAndNil(FStreamResolver);
  1120. if Module<>nil then
  1121. begin
  1122. Module.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
  1123. FModule:=nil;
  1124. end;
  1125. inherited Destroy;
  1126. end;
  1127. function TTestEnginePasResolver.FindUnit(const AName, InFilename: String;
  1128. NameExpr, InFileExpr: TPasExpr): TPasModule;
  1129. begin
  1130. Result:=nil;
  1131. if InFilename<>'' then
  1132. RaiseNotYetImplemented(20180224101926,InFileExpr,'Use testcase tcunitsearch instead');
  1133. if Assigned(OnFindUnit) then
  1134. Result:=OnFindUnit(AName);
  1135. if NameExpr=nil then ;
  1136. end;
  1137. procedure TTestEnginePasResolver.UsedInterfacesFinished(Section: TPasSection);
  1138. begin
  1139. // do not parse recursively
  1140. // parse via the queue
  1141. if Section=nil then ;
  1142. end;
  1143. { TCustomTestModule }
  1144. function TCustomTestModule.GetMsgCount: integer;
  1145. begin
  1146. Result:=FHintMsgs.Count;
  1147. end;
  1148. function TCustomTestModule.GetMsgs(Index: integer): TTestHintMessage;
  1149. begin
  1150. Result:=TTestHintMessage(FHintMsgs[Index]);
  1151. end;
  1152. function TCustomTestModule.GetResolverCount: integer;
  1153. begin
  1154. Result:=FModules.Count;
  1155. end;
  1156. function TCustomTestModule.GetResolvers(Index: integer
  1157. ): TTestEnginePasResolver;
  1158. begin
  1159. Result:=TTestEnginePasResolver(FModules[Index]);
  1160. end;
  1161. function TCustomTestModule.OnPasResolverFindUnit(const aUnitName: String
  1162. ): TPasModule;
  1163. var
  1164. DefNamespace: String;
  1165. begin
  1166. //writeln('TTestModule.OnPasResolverFindUnit START Unit="',aUnitName,'"');
  1167. if (Pos('.',aUnitName)<1) then
  1168. begin
  1169. DefNamespace:=GetDefaultNamespace;
  1170. if DefNamespace<>'' then
  1171. begin
  1172. Result:=LoadUnit(DefNamespace+'.'+aUnitName);
  1173. if Result<>nil then exit;
  1174. end;
  1175. end;
  1176. Result:=LoadUnit(aUnitName);
  1177. if Result<>nil then exit;
  1178. {$IFDEF VerbosePas2JS}
  1179. writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"');
  1180. {$ENDIF}
  1181. Fail('can''t find unit "'+aUnitName+'"');
  1182. end;
  1183. procedure TCustomTestModule.OnParserLog(Sender: TObject; const Msg: String);
  1184. var
  1185. aParser: TPasParser;
  1186. Item: TTestHintMessage;
  1187. begin
  1188. aParser:=Sender as TPasParser;
  1189. Item:=TTestHintMessage.Create;
  1190. Item.Id:=aParser.LastMsgNumber;
  1191. Item.MsgType:=aParser.LastMsgType;
  1192. Item.MsgNumber:=aParser.LastMsgNumber;
  1193. Item.Msg:=Msg;
  1194. Item.SourcePos:=aParser.Scanner.CurSourcePos;
  1195. {$IFDEF VerbosePas2JS}
  1196. writeln('TCustomTestModule.OnParserLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1197. {$ENDIF}
  1198. FHintMsgs.Add(Item);
  1199. end;
  1200. procedure TCustomTestModule.OnPasResolverLog(Sender: TObject; const Msg: String
  1201. );
  1202. var
  1203. aResolver: TTestEnginePasResolver;
  1204. Item: TTestHintMessage;
  1205. begin
  1206. aResolver:=Sender as TTestEnginePasResolver;
  1207. Item:=TTestHintMessage.Create;
  1208. Item.Id:=aResolver.LastMsgId;
  1209. Item.MsgType:=aResolver.LastMsgType;
  1210. Item.MsgNumber:=aResolver.LastMsgNumber;
  1211. Item.Msg:=Msg;
  1212. Item.SourcePos:=aResolver.LastSourcePos;
  1213. {$IFDEF VerbosePas2JS}
  1214. writeln('TCustomTestModule.OnPasResolverLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1215. {$ENDIF}
  1216. FHintMsgs.Add(Item);
  1217. end;
  1218. procedure TCustomTestModule.OnScannerLog(Sender: TObject; const Msg: String);
  1219. var
  1220. Item: TTestHintMessage;
  1221. aScanner: TPas2jsPasScanner;
  1222. begin
  1223. aScanner:=Sender as TPas2jsPasScanner;
  1224. Item:=TTestHintMessage.Create;
  1225. Item.Id:=aScanner.LastMsgNumber;
  1226. Item.MsgType:=aScanner.LastMsgType;
  1227. Item.MsgNumber:=aScanner.LastMsgNumber;
  1228. Item.Msg:=Msg;
  1229. Item.SourcePos:=aScanner.CurSourcePos;
  1230. {$IFDEF VerbosePas2JS}
  1231. writeln('TCustomTestModule.OnScannerLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1232. {$ENDIF}
  1233. FHintMsgs.Add(Item);
  1234. end;
  1235. procedure TCustomTestModule.SetWithTypeInfo(const AValue: boolean);
  1236. begin
  1237. if FWithTypeInfo=AValue then Exit;
  1238. FWithTypeInfo:=AValue;
  1239. if AValue then
  1240. Converter.Options:=Converter.Options-[coNoTypeInfo]
  1241. else
  1242. Converter.Options:=Converter.Options+[coNoTypeInfo];
  1243. end;
  1244. function TCustomTestModule.LoadUnit(const aUnitName: String): TPasModule;
  1245. var
  1246. i: Integer;
  1247. CurEngine: TTestEnginePasResolver;
  1248. CurUnitName: String;
  1249. begin
  1250. //writeln('TTestModule.FindUnit START Unit="',aUnitName,'"');
  1251. Result:=nil;
  1252. if (Module.ClassType=TPasModule)
  1253. and (CompareText(Module.Name,aUnitName)=0) then
  1254. exit(Module);
  1255. for i:=0 to ResolverCount-1 do
  1256. begin
  1257. CurEngine:=Resolvers[i];
  1258. CurUnitName:=ExtractFileUnitName(CurEngine.Filename);
  1259. //writeln('TTestModule.FindUnit Checking ',i,'/',ResolverCount,' ',CurEngine.Filename,' ',CurUnitName);
  1260. if CompareText(aUnitName,CurUnitName)=0 then
  1261. begin
  1262. Result:=CurEngine.Module;
  1263. if Result<>nil then exit;
  1264. //writeln('TTestModule.FindUnit PARSING unit "',CurEngine.Filename,'"');
  1265. FileResolver.FindSourceFile(aUnitName);
  1266. CurEngine.StreamResolver:=TStreamResolver.Create;
  1267. CurEngine.StreamResolver.OwnsStreams:=True;
  1268. //writeln('TTestModule.FindUnit SOURCE=',CurEngine.Source);
  1269. CurEngine.StreamResolver.AddStream(CurEngine.FileName,TStringStream.Create(CurEngine.Source));
  1270. CurEngine.Scanner:=TPas2jsPasScanner.Create(CurEngine.StreamResolver);
  1271. InitScanner(CurEngine.Scanner);
  1272. CurEngine.Parser:=TTestPasParser.Create(CurEngine.Scanner,CurEngine.StreamResolver,CurEngine);
  1273. CurEngine.Parser.Options:=po_tcmodules;
  1274. if CompareText(CurUnitName,'System')=0 then
  1275. CurEngine.Parser.ImplicitUses.Clear;
  1276. CurEngine.Scanner.OpenFile(CurEngine.Filename);
  1277. try
  1278. CurEngine.Parser.NextToken;
  1279. CurEngine.Parser.ParseUnit(CurEngine.FModule);
  1280. except
  1281. on E: Exception do
  1282. HandleException(E);
  1283. end;
  1284. //writeln('TTestModule.FindUnit END ',CurUnitName);
  1285. Result:=CurEngine.Module;
  1286. exit;
  1287. end;
  1288. end;
  1289. end;
  1290. procedure TCustomTestModule.SetUp;
  1291. begin
  1292. {$IFDEF EnablePasTreeGlobalRefCount}
  1293. FElementRefCountAtSetup:=TPasElement.GlobalRefCount;
  1294. {$ENDIF}
  1295. if FModules<>nil then
  1296. begin
  1297. writeln('TCustomTestModule.SetUp FModules<>nil');
  1298. Halt;
  1299. end;
  1300. inherited SetUp;
  1301. FSkipTests:=false;
  1302. FWithTypeInfo:=false;
  1303. FSource:=TStringList.Create;
  1304. FHub:=TPas2JSResolverHub.Create(Self);
  1305. FModules:=TObjectList.Create(true);
  1306. FFilename:='test1.pp';
  1307. FFileResolver:=TStreamResolver.Create;
  1308. FFileResolver.OwnsStreams:=True;
  1309. FScanner:=TPas2jsPasScanner.Create(FFileResolver);
  1310. InitScanner(FScanner);
  1311. FEngine:=AddModule(Filename);
  1312. FEngine.Scanner:=FScanner;
  1313. FScanner.Resolver:=FEngine;
  1314. FParser:=TTestPasParser.Create(FScanner,FFileResolver,FEngine);
  1315. FParser.OnLog:=@OnParserLog;
  1316. FEngine.Parser:=FParser;
  1317. Parser.Options:=po_tcmodules;
  1318. FModule:=Nil;
  1319. FConverter:=CreateConverter;
  1320. FExpectedErrorClass:=nil;
  1321. end;
  1322. function TCustomTestModule.CreateConverter: TPasToJSConverter;
  1323. var
  1324. Options: TPasToJsConverterOptions;
  1325. begin
  1326. Result:=TPasToJSConverter.Create;
  1327. Options:=co_tcmodules;
  1328. if WithTypeInfo then
  1329. Exclude(Options,coNoTypeInfo)
  1330. else
  1331. Include(Options,coNoTypeInfo);
  1332. Result.Options:=Options;
  1333. Result.Globals:=TPasToJSConverterGlobals.Create(Result);
  1334. end;
  1335. procedure TCustomTestModule.InitScanner(aScanner: TPas2jsPasScanner);
  1336. begin
  1337. aScanner.AllowedModeSwitches:=msAllPas2jsModeSwitches;
  1338. aScanner.ReadOnlyModeSwitches:=msAllPas2jsModeSwitchesReadOnly;
  1339. aScanner.CurrentModeSwitches:=OBJFPCModeSwitches*msAllPas2jsModeSwitches+msAllPas2jsModeSwitchesReadOnly;
  1340. aScanner.AllowedBoolSwitches:=bsAllPas2jsBoolSwitches;
  1341. aScanner.ReadOnlyBoolSwitches:=bsAllPas2jsBoolSwitchesReadOnly;
  1342. aScanner.CurrentBoolSwitches:=bsAllPas2jsBoolSwitchesReadOnly+[bsHints,bsNotes,bsWarnings,bsWriteableConst];
  1343. aScanner.AllowedValueSwitches:=vsAllPas2jsValueSwitches;
  1344. aScanner.ReadOnlyValueSwitches:=vsAllPas2jsValueSwitchesReadOnly;
  1345. aScanner.OnLog:=@OnScannerLog;
  1346. aScanner.CompilerVersion:='Comp.Ver.tcmodules';
  1347. end;
  1348. procedure TCustomTestModule.TearDown;
  1349. {$IFDEF CheckPasTreeRefCount}
  1350. var
  1351. El: TPasElement;
  1352. {$ENDIF}
  1353. var
  1354. i: Integer;
  1355. CurModule: TPasModule;
  1356. begin
  1357. FHintMsgs.Clear;
  1358. FHintMsgsGood.Clear;
  1359. FSkipTests:=false;
  1360. FWithTypeInfo:=false;
  1361. FJSRegModuleCall:=nil;
  1362. FJSModuleCallArgs:=nil;
  1363. FJSImplentationUses:=nil;
  1364. FJSInterfaceUses:=nil;
  1365. FJSModuleSrc:=nil;
  1366. FJSInitBody:=nil;
  1367. FreeAndNil(FJSSource);
  1368. FreeAndNil(FJSModule);
  1369. FreeAndNil(FConverter);
  1370. Engine.Clear;
  1371. FreeAndNil(FSource);
  1372. FreeAndNil(FFileResolver);
  1373. if FModules<>nil then
  1374. begin
  1375. for i:=0 to FModules.Count-1 do
  1376. begin
  1377. CurModule:=TTestEnginePasResolver(FModules[i]).Module;
  1378. if CurModule=nil then continue;
  1379. //writeln('TCustomTestModule.TearDown ReleaseUsedUnits ',CurModule.Name,' ',CurModule.RefCount,' ',CurModule.RefIds.Text);
  1380. CurModule.ReleaseUsedUnits;
  1381. end;
  1382. if FModule<>nil then
  1383. FModule.ReleaseUsedUnits;
  1384. for i:=0 to FModules.Count-1 do
  1385. begin
  1386. CurModule:=TTestEnginePasResolver(FModules[i]).Module;
  1387. if CurModule=nil then continue;
  1388. //writeln('TCustomTestModule.TearDown UsesReleased ',CurModule.Name,' ',CurModule.RefCount,' ',CurModule.RefIds.Text);
  1389. end;
  1390. FreeAndNil(FModules);
  1391. ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
  1392. FEngine:=nil;
  1393. end;
  1394. FreeAndNil(FHub);
  1395. inherited TearDown;
  1396. {$IFDEF EnablePasTreeGlobalRefCount}
  1397. if FElementRefCountAtSetup<>TPasElement.GlobalRefCount then
  1398. begin
  1399. writeln('TCustomTestModule.TearDown GlobalRefCount Was='+IntToStr(FElementRefCountAtSetup)+' Now='+IntToStr(TPasElement.GlobalRefCount));
  1400. {$IFDEF CheckPasTreeRefCount}
  1401. El:=TPasElement.FirstRefEl;
  1402. while El<>nil do
  1403. begin
  1404. writeln(' ',GetObjName(El),' RefIds.Count=',El.RefIds.Count,':');
  1405. for i:=0 to El.RefIds.Count-1 do
  1406. writeln(' ',El.RefIds[i]);
  1407. El:=El.NextRefEl;
  1408. end;
  1409. {$ENDIF}
  1410. Halt;
  1411. Fail('TCustomTestModule.TearDown Was='+IntToStr(FElementRefCountAtSetup)+' Now='+IntToStr(TPasElement.GlobalRefCount));
  1412. end;
  1413. {$ENDIF}
  1414. end;
  1415. procedure TCustomTestModule.Add(Line: string);
  1416. begin
  1417. Source.Add(Line);
  1418. end;
  1419. procedure TCustomTestModule.Add(const Lines: array of string);
  1420. var
  1421. i: Integer;
  1422. begin
  1423. for i:=low(Lines) to high(Lines) do
  1424. Add(Lines[i]);
  1425. end;
  1426. procedure TCustomTestModule.StartParsing;
  1427. var
  1428. Src: String;
  1429. begin
  1430. Src:=Source.Text;
  1431. FEngine.Source:=Src;
  1432. FileResolver.AddStream(FileName,TStringStream.Create(Src));
  1433. Scanner.OpenFile(FileName);
  1434. Writeln('// Test : ',Self.TestName);
  1435. Writeln(Src);
  1436. end;
  1437. procedure TCustomTestModule.ParseModuleQueue;
  1438. var
  1439. i: Integer;
  1440. CurResolver: TTestEnginePasResolver;
  1441. Found: Boolean;
  1442. Section: TPasSection;
  1443. begin
  1444. // parse til exception or all modules finished
  1445. while not SkipTests do
  1446. begin
  1447. Found:=false;
  1448. for i:=0 to ResolverCount-1 do
  1449. begin
  1450. CurResolver:=Resolvers[i];
  1451. if CurResolver.CurrentParser=nil then continue;
  1452. if not CurResolver.CurrentParser.CanParseContinue(Section) then
  1453. continue;
  1454. CurResolver.Parser.ParseContinue;
  1455. Found:=true;
  1456. break;
  1457. end;
  1458. if not Found then break;
  1459. end;
  1460. for i:=0 to ResolverCount-1 do
  1461. begin
  1462. CurResolver:=Resolvers[i];
  1463. if CurResolver.Parser=nil then
  1464. begin
  1465. if CurResolver.CurrentParser<>nil then
  1466. Fail('TCustomTestModule.ParseModuleQueue '+CurResolver.Filename+' '+GetObjName(CurResolver.Parser)+'=Parser<>CurrentParser='+GetObjName(CurResolver.CurrentParser));
  1467. continue;
  1468. end;
  1469. if CurResolver.Parser.CurModule<>nil then
  1470. Fail('TCustomTestModule.ParseModuleQueue '+CurResolver.Filename+' NOT FINISHED CurModule='+GetObjName(CurResolver.Parser.CurModule));
  1471. end;
  1472. end;
  1473. procedure TCustomTestModule.ParseModule;
  1474. begin
  1475. if SkipTests then exit;
  1476. FFirstPasStatement:=nil;
  1477. try
  1478. StartParsing;
  1479. Parser.ParseMain(FModule);
  1480. ParseModuleQueue;
  1481. except
  1482. on E: Exception do
  1483. HandleException(E);
  1484. end;
  1485. if SkipTests then exit;
  1486. AssertNotNull('Module resulted in Module',Module);
  1487. AssertEquals('modulename',lowercase(ChangeFileExt(FFileName,'')),lowercase(Module.Name));
  1488. TAssert.AssertSame('Has resolver',Engine,Parser.Engine);
  1489. end;
  1490. procedure TCustomTestModule.ParseProgram;
  1491. begin
  1492. if SkipTests then exit;
  1493. ParseModule;
  1494. if SkipTests then exit;
  1495. AssertEquals('Has program',TPasProgram,Module.ClassType);
  1496. FPasProgram:=TPasProgram(Module);
  1497. AssertNotNull('Has program section',PasProgram.ProgramSection);
  1498. AssertNotNull('Has initialization section',PasProgram.InitializationSection);
  1499. if (PasProgram.InitializationSection.Elements.Count>0) then
  1500. if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
  1501. FFirstPasStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
  1502. end;
  1503. procedure TCustomTestModule.ParseLibrary;
  1504. var
  1505. Init: TInitializationSection;
  1506. begin
  1507. if SkipTests then exit;
  1508. ParseModule;
  1509. if SkipTests then exit;
  1510. AssertEquals('Has library',TPasLibrary,Module.ClassType);
  1511. FPasLibrary:=TPasLibrary(Module);
  1512. AssertNotNull('Has library section',PasLibrary.LibrarySection);
  1513. Init:=PasLibrary.InitializationSection;
  1514. if (Init<>nil) and (Init.Elements.Count>0) then
  1515. if TObject(Init.Elements[0]) is TPasImplBlock then
  1516. FFirstPasStatement:=TPasImplBlock(PasLibrary.InitializationSection.Elements[0]);
  1517. end;
  1518. procedure TCustomTestModule.ParseUnit;
  1519. begin
  1520. if SkipTests then exit;
  1521. ParseModule;
  1522. if SkipTests then exit;
  1523. AssertEquals('Has unit (TPasModule)',TPasModule,Module.ClassType);
  1524. AssertNotNull('Has interface section',Module.InterfaceSection);
  1525. AssertNotNull('Has implementation section',Module.ImplementationSection);
  1526. if (Module.InitializationSection<>nil)
  1527. and (Module.InitializationSection.Elements.Count>0)
  1528. and (TObject(Module.InitializationSection.Elements[0]) is TPasImplBlock) then
  1529. FFirstPasStatement:=TPasImplBlock(Module.InitializationSection.Elements[0]);
  1530. end;
  1531. function TCustomTestModule.FindModuleWithFilename(aFilename: string
  1532. ): TTestEnginePasResolver;
  1533. var
  1534. i: Integer;
  1535. begin
  1536. for i:=0 to ResolverCount-1 do
  1537. if CompareText(Resolvers[i].Filename,aFilename)=0 then
  1538. exit(Resolvers[i]);
  1539. Result:=nil;
  1540. end;
  1541. function TCustomTestModule.AddModule(aFilename: string
  1542. ): TTestEnginePasResolver;
  1543. begin
  1544. //writeln('TTestModuleConverter.AddModule ',aFilename);
  1545. if FindModuleWithFilename(aFilename)<>nil then
  1546. Fail('TTestModuleConverter.AddModule: file "'+aFilename+'" already exists');
  1547. Result:=TTestEnginePasResolver.Create;
  1548. Result.Filename:=aFilename;
  1549. Result.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs);
  1550. Result.OnFindUnit:=@OnPasResolverFindUnit;
  1551. Result.OnLog:=@OnPasResolverLog;
  1552. Result.Hub:=Hub;
  1553. FModules.Add(Result);
  1554. end;
  1555. function TCustomTestModule.AddModuleWithSrc(aFilename, Src: string
  1556. ): TTestEnginePasResolver;
  1557. begin
  1558. Result:=AddModule(aFilename);
  1559. Result.Source:=Src;
  1560. end;
  1561. function TCustomTestModule.AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  1562. ImplementationSrc: string): TTestEnginePasResolver;
  1563. var
  1564. Src: String;
  1565. begin
  1566. Src:='unit '+ExtractFileUnitName(aFilename)+';'+LineEnding;
  1567. Src+=LineEnding;
  1568. Src+='interface'+LineEnding;
  1569. Src+=LineEnding;
  1570. Src+=InterfaceSrc;
  1571. Src+='implementation'+LineEnding;
  1572. Src+=LineEnding;
  1573. Src+=ImplementationSrc;
  1574. Src+='end.'+LineEnding;
  1575. Result:=AddModuleWithSrc(aFilename,Src);
  1576. end;
  1577. procedure TCustomTestModule.AddSystemUnit(Parts: TSystemUnitParts);
  1578. var
  1579. Intf, Impl: TStringList;
  1580. begin
  1581. Intf:=TStringList.Create;
  1582. if supTInterfacedObject in Parts then Include(Parts,supTObject);
  1583. // unit interface
  1584. if [supTVarRec,supTypeInfo]*Parts<>[] then
  1585. Intf.Add('{$modeswitch externalclass}');
  1586. Intf.Add('type');
  1587. Intf.Add(' integer=longint;');
  1588. Intf.Add(' sizeint=nativeint;');
  1589. //'const',
  1590. //' LineEnding = #10;',
  1591. //' DirectorySeparator = ''/'';',
  1592. //' DriveSeparator = '''';',
  1593. //' AllowDirectorySeparators : set of char = [''\'',''/''];',
  1594. //' AllowDriveSeparators : set of char = [];',
  1595. if supTObject in Parts then
  1596. Intf.AddStrings([
  1597. 'type',
  1598. ' TClass = class of TObject;',
  1599. ' TObject = class',
  1600. ' constructor Create;',
  1601. ' destructor Destroy; virtual;',
  1602. ' class function ClassType: TClass; assembler;',
  1603. ' class function ClassName: String; assembler;',
  1604. ' class function ClassNameIs(const Name: string): boolean;',
  1605. ' class function ClassParent: TClass; assembler;',
  1606. ' class function InheritsFrom(aClass: TClass): boolean; assembler;',
  1607. ' class function UnitName: String; assembler;',
  1608. ' procedure AfterConstruction; virtual;',
  1609. ' procedure BeforeDestruction;virtual;',
  1610. ' function Equals(Obj: TObject): boolean; virtual;',
  1611. ' function ToString: String; virtual;',
  1612. ' end;']);
  1613. if supTInterfacedObject in Parts then
  1614. Intf.AddStrings([
  1615. ' {$Interfaces COM}',
  1616. ' IUnknown = interface',
  1617. ' [''{00000000-0000-0000-C000-000000000046}'']',
  1618. //' function QueryInterface(const iid: TGuid; out obj): Integer;',
  1619. ' function _AddRef: Integer;',
  1620. ' function _Release: Integer;',
  1621. ' end;',
  1622. ' IInterface = IUnknown;',
  1623. ' TInterfacedObject = class(TObject,IUnknown)',
  1624. ' protected',
  1625. ' fRefCount: Integer;',
  1626. ' { implement methods of IUnknown }',
  1627. //' function QueryInterface(const iid: TGuid; out obj): Integer; virtual;',
  1628. ' function _AddRef: Integer; virtual;',
  1629. ' function _Release: Integer; virtual;',
  1630. ' end;',
  1631. ' TInterfacedClass = class of TInterfacedObject;',
  1632. '',
  1633. '']);
  1634. if supTVarRec in Parts then
  1635. Intf.AddStrings([
  1636. 'const',
  1637. ' vtInteger = 0;',
  1638. ' vtBoolean = 1;',
  1639. ' vtJSValue = 19;',
  1640. 'type',
  1641. ' PVarRec = ^TVarRec;',
  1642. ' TVarRec = record',
  1643. ' VType : byte;',
  1644. ' VJSValue: JSValue;',
  1645. ' vInteger: longint external name ''VJSValue'';',
  1646. ' vBoolean: boolean external name ''VJSValue'';',
  1647. ' end;',
  1648. ' TVarRecArray = array of TVarRec;',
  1649. 'function VarRecs: TVarRecArray; varargs;',
  1650. '']);
  1651. if supTypeInfo in Parts then
  1652. begin
  1653. Intf.AddStrings([
  1654. 'type',
  1655. ' TTypeKind = (',
  1656. ' tkUnknown, // 0',
  1657. ' tkInteger, // 1',
  1658. ' tkChar, // 2 in Delphi/FPC tkWChar, tkUChar',
  1659. ' tkString, // 3 in Delphi/FPC tkSString, tkWString or tkUString',
  1660. ' tkEnumeration, // 4',
  1661. ' tkSet, // 5',
  1662. ' tkDouble, // 6',
  1663. ' tkBool, // 7',
  1664. ' tkProcVar, // 8 function or procedure',
  1665. ' tkMethod, // 9 proc var of object',
  1666. ' tkArray, // 10 static array',
  1667. ' tkDynArray, // 11',
  1668. ' tkRecord, // 12',
  1669. ' tkClass, // 13',
  1670. ' tkClassRef, // 14',
  1671. ' tkPointer, // 15',
  1672. ' tkJSValue, // 16',
  1673. ' tkRefToProcVar, // 17 variable of procedure type',
  1674. ' tkInterface, // 18',
  1675. ' //tkObject,',
  1676. ' //tkSString,tkLString,tkAString,tkWString,',
  1677. ' //tkVariant,',
  1678. ' //tkWChar,',
  1679. ' //tkInt64,',
  1680. ' //tkQWord,',
  1681. ' //tkInterfaceRaw,',
  1682. ' //tkUString,tkUChar,',
  1683. ' tkHelper, // 19',
  1684. ' //tkFile,',
  1685. ' tkExtClass // 20',
  1686. ' );',
  1687. ' TTypeKinds = set of TTypeKind;',
  1688. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  1689. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
  1690. ' end;',
  1691. ' TTypeInfoEnum = class external name ''rtl.tTypeInfoEnum''(TTypeInfoInteger) end;',
  1692. ' TTypeInfoSet = class external name ''rtl.tTypeInfoSet''(TTypeInfo) end;',
  1693. ' TTypeInfoStaticArray = class external name ''rtl.tTypeInfoStaticArray''(TTypeInfo) end;',
  1694. ' TTypeInfoDynArray = class external name ''rtl.tTypeInfoDynArray''(TTypeInfo) end;',
  1695. ' TTypeInfoProcVar = class external name ''rtl.tTypeInfoProcVar''(TTypeInfo) end;',
  1696. ' TTypeInfoMethodVar = class external name ''rtl.tTypeInfoMethodVar''(TTypeInfoProcVar) end;',
  1697. ' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;',
  1698. ' TTypeInfoClassRef = class external name ''rtl.tTypeInfoClassRef''(TTypeInfo) end;',
  1699. ' TTypeInfoExtClass = class external name ''rtl.tTypeInfoExtClass''(TTypeInfo) end;',
  1700. ' TTypeInfoRecord = class external name ''rtl.tTypeInfoRecord''(TTypeInfo) end;',
  1701. ' TTypeInfoPointer = class external name ''rtl.tTypeInfoPointer''(TTypeInfo) end;',
  1702. ' TTypeInfoHelper = class external name ''rtl.tTypeInfoHelper''(TTypeInfo) end;',
  1703. ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
  1704. '']);
  1705. end;
  1706. if supWriteln in Parts then
  1707. Intf.Add('procedure writeln; varargs; external name ''console.log'';');
  1708. Intf.Add('var');
  1709. Intf.Add(' ExitCode: Longint = 0;');
  1710. // unit implementation
  1711. Impl:=TStringList.Create;
  1712. if supTObject in Parts then
  1713. Impl.AddStrings([
  1714. '// needed by ClassNameIs, the real SameText is in SysUtils',
  1715. 'function SameText(const s1, s2: String): Boolean; assembler;',
  1716. 'asm',
  1717. 'end;',
  1718. 'constructor TObject.Create; begin end;',
  1719. 'destructor TObject.Destroy; begin end;',
  1720. 'class function TObject.ClassType: TClass; assembler;',
  1721. 'asm',
  1722. 'end;',
  1723. 'class function TObject.ClassName: String; assembler;',
  1724. 'asm',
  1725. 'end;',
  1726. 'class function TObject.ClassNameIs(const Name: string): boolean;',
  1727. 'begin',
  1728. ' Result:=SameText(Name,ClassName);',
  1729. 'end;',
  1730. 'class function TObject.ClassParent: TClass; assembler;',
  1731. 'asm',
  1732. 'end;',
  1733. 'class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;',
  1734. 'asm',
  1735. 'end;',
  1736. 'class function TObject.UnitName: String; assembler;',
  1737. 'asm',
  1738. 'end;',
  1739. 'procedure TObject.AfterConstruction; begin end;',
  1740. 'procedure TObject.BeforeDestruction; begin end;',
  1741. 'function TObject.Equals(Obj: TObject): boolean;',
  1742. 'begin',
  1743. ' Result:=Obj=Self;',
  1744. 'end;',
  1745. 'function TObject.ToString: String;',
  1746. 'begin',
  1747. ' Result:=ClassName;',
  1748. 'end;'
  1749. ]);
  1750. if supTInterfacedObject in Parts then
  1751. Impl.AddStrings([
  1752. //'function TInterfacedObject.QueryInterface(const iid: TGuid; out obj): Integer;',
  1753. //'begin',
  1754. //'end;',
  1755. 'function TInterfacedObject._AddRef: Integer;',
  1756. 'begin',
  1757. 'end;',
  1758. 'function TInterfacedObject._Release: Integer;',
  1759. 'begin',
  1760. 'end;',
  1761. '']);
  1762. if supTVarRec in Parts then
  1763. Impl.AddStrings([
  1764. 'function VarRecs: TVarRecArray; varargs;',
  1765. 'var',
  1766. ' v: PVarRec;',
  1767. 'begin',
  1768. ' v^.VType:=1;',
  1769. ' v^.VJSValue:=2;',
  1770. 'end;',
  1771. '']);
  1772. try
  1773. AddModuleWithIntfImplSrc('system.pp',Intf.Text,Impl.Text);
  1774. finally
  1775. Intf.Free;
  1776. Impl.Free;
  1777. end;
  1778. end;
  1779. procedure TCustomTestModule.StartProgram(NeedSystemUnit: boolean;
  1780. SystemUnitParts: TSystemUnitParts);
  1781. begin
  1782. if NeedSystemUnit then
  1783. AddSystemUnit(SystemUnitParts)
  1784. else
  1785. Parser.ImplicitUses.Clear;
  1786. Add('program '+ExtractFileUnitName(Filename)+';');
  1787. Add('');
  1788. end;
  1789. procedure TCustomTestModule.StartLibrary(NeedSystemUnit: boolean;
  1790. SystemUnitParts: TSystemUnitParts);
  1791. begin
  1792. if NeedSystemUnit then
  1793. AddSystemUnit(SystemUnitParts)
  1794. else
  1795. Parser.ImplicitUses.Clear;
  1796. Add('library '+ExtractFileUnitName(Filename)+';');
  1797. Add('');
  1798. end;
  1799. procedure TCustomTestModule.StartUnit(NeedSystemUnit: boolean;
  1800. SystemUnitParts: TSystemUnitParts);
  1801. begin
  1802. if NeedSystemUnit then
  1803. AddSystemUnit(SystemUnitParts)
  1804. else
  1805. Parser.ImplicitUses.Clear;
  1806. Add('unit Test1;');
  1807. Add('');
  1808. end;
  1809. procedure TCustomTestModule.ConvertModule;
  1810. procedure CheckUsesList(UsesName: String; Arg: TJSArrayLiteralElement;
  1811. out UsesLit: TJSArrayLiteral);
  1812. var
  1813. i: Integer;
  1814. Item: TJSElement;
  1815. Lit: TJSLiteral;
  1816. begin
  1817. UsesLit:=nil;
  1818. AssertNotNull(UsesName+' uses section',Arg.Expr);
  1819. if (Arg.Expr.ClassType=TJSLiteral) and TJSLiteral(Arg.Expr).Value.IsNull then
  1820. exit; // null is ok
  1821. AssertEquals(UsesName+' uses section param is array',TJSArrayLiteral,Arg.Expr.ClassType);
  1822. FJSInterfaceUses:=TJSArrayLiteral(Arg.Expr);
  1823. for i:=0 to FJSInterfaceUses.Elements.Count-1 do
  1824. begin
  1825. Item:=FJSInterfaceUses.Elements.Elements[i].Expr;
  1826. AssertNotNull(UsesName+' uses section item['+IntToStr(i)+'].Expr',Item);
  1827. AssertEquals(UsesName+' uses section item['+IntToStr(i)+'] is lit',TJSLiteral,Item.ClassType);
  1828. Lit:=TJSLiteral(Item);
  1829. AssertEquals(UsesName+' uses section item['+IntToStr(i)+'] is string lit',
  1830. ord(jsbase.jstString),ord(Lit.Value.ValueType));
  1831. end;
  1832. end;
  1833. procedure CheckFunctionParam(ParamName: string; Arg: TJSArrayLiteralElement;
  1834. out Src: TJSSourceElements);
  1835. var
  1836. FunDecl: TJSFunctionDeclarationStatement;
  1837. FunDef: TJSFuncDef;
  1838. FunBody: TJSFunctionBody;
  1839. begin
  1840. Src:=nil;
  1841. AssertNotNull(ParamName,Arg.Expr);
  1842. AssertEquals(ParamName+' Arg.Expr type',TJSFunctionDeclarationStatement,Arg.Expr.ClassType);
  1843. FunDecl:=Arg.Expr as TJSFunctionDeclarationStatement;
  1844. AssertNotNull(ParamName+' FunDecl.AFunction',FunDecl.AFunction);
  1845. AssertEquals(ParamName+' FunDecl.AFunction type',TJSFuncDef,FunDecl.AFunction.ClassType);
  1846. FunDef:=FunDecl.AFunction as TJSFuncDef;
  1847. AssertEquals(ParamName+' name empty','',String(FunDef.Name));
  1848. AssertNotNull(ParamName+' body',FunDef.Body);
  1849. AssertEquals(ParamName+' body type',TJSFunctionBody,FunDef.Body.ClassType);
  1850. FunBody:=FunDef.Body as TJSFunctionBody;
  1851. AssertNotNull(ParamName+' body.A',FunBody.A);
  1852. AssertEquals(ParamName+' body.A type',TJSSourceElements,FunBody.A.ClassType);
  1853. Src:=FunBody.A as TJSSourceElements;
  1854. end;
  1855. var
  1856. ModuleNameExpr: TJSLiteral;
  1857. InitFunction: TJSFunctionDeclarationStatement;
  1858. InitAssign: TJSSimpleAssignStatement;
  1859. InitName: String;
  1860. LastNode: TJSElement;
  1861. Arg: TJSArrayLiteralElement;
  1862. begin
  1863. if SkipTests then exit;
  1864. try
  1865. FJSModule:=FConverter.ConvertPasElement(Module,Engine) as TJSSourceElements;
  1866. except
  1867. on E: Exception do
  1868. HandleException(E);
  1869. end;
  1870. if SkipTests then exit;
  1871. if ExpectedErrorClass<>nil then
  1872. Fail('Missing '+ExpectedErrorClass.ClassName+' error {'+ExpectedErrorMsg+'} ('+IntToStr(ExpectedErrorNumber)+')');
  1873. FJSSource:=TStringList.Create;
  1874. FJSSource.Text:=ConvertJSModuleToString(JSModule);
  1875. {$IFDEF VerbosePas2JS}
  1876. writeln('TTestModule.ConvertModule JS:');
  1877. write(FJSSource.Text);
  1878. {$ENDIF}
  1879. // rtl.module(...
  1880. AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
  1881. AssertNotNull('register module call',JSModule.Statements.Nodes[0].Node);
  1882. AssertEquals('register module call',TJSCallExpression,JSModule.Statements.Nodes[0].Node.ClassType);
  1883. FJSRegModuleCall:=JSModule.Statements.Nodes[0].Node as TJSCallExpression;
  1884. AssertNotNull('register module rtl.module expr',JSRegModuleCall.Expr);
  1885. AssertNotNull('register module rtl.module args',JSRegModuleCall.Args);
  1886. AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
  1887. FJSModuleCallArgs:=JSRegModuleCall.Args as TJSArguments;
  1888. // parameter 'unitname'
  1889. if JSModuleCallArgs.Elements.Count<1 then
  1890. Fail('rtl.module first param unit missing');
  1891. Arg:=JSModuleCallArgs.Elements.Elements[0];
  1892. AssertNotNull('module name param',Arg.Expr);
  1893. ModuleNameExpr:=Arg.Expr as TJSLiteral;
  1894. AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
  1895. if Module is TPasProgram then
  1896. AssertEquals('module name','program',String(ModuleNameExpr.Value.AsString))
  1897. else if Module is TPasLibrary then
  1898. AssertEquals('module name','library',String(ModuleNameExpr.Value.AsString))
  1899. else
  1900. AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
  1901. // main uses section
  1902. if JSModuleCallArgs.Elements.Count<2 then
  1903. Fail('rtl.module second param main uses missing');
  1904. Arg:=JSModuleCallArgs.Elements.Elements[1];
  1905. CheckUsesList('interface',Arg,FJSInterfaceUses);
  1906. // program/library/interface function()
  1907. if JSModuleCallArgs.Elements.Count<3 then
  1908. Fail('rtl.module third param intf-function missing');
  1909. Arg:=JSModuleCallArgs.Elements.Elements[2];
  1910. CheckFunctionParam('module intf-function',Arg,FJSModuleSrc);
  1911. // search for $mod.$init or $mod.$main - the last statement
  1912. if (Module is TPasProgram) or (Module is TPasLibrary) then
  1913. begin
  1914. InitName:='$main';
  1915. AssertEquals('$mod.'+InitName+' function 1',true,JSModuleSrc.Statements.Count>0);
  1916. end
  1917. else
  1918. InitName:='$init';
  1919. FJSInitBody:=nil;
  1920. if JSModuleSrc.Statements.Count>0 then
  1921. begin
  1922. LastNode:=JSModuleSrc.Statements.Nodes[JSModuleSrc.Statements.Count-1].Node;
  1923. if LastNode is TJSSimpleAssignStatement then
  1924. begin
  1925. InitAssign:=LastNode as TJSSimpleAssignStatement;
  1926. if GetDottedIdentifier(InitAssign.LHS)='$mod.'+InitName then
  1927. begin
  1928. InitFunction:=InitAssign.Expr as TJSFunctionDeclarationStatement;
  1929. FJSInitBody:=InitFunction.AFunction.Body as TJSFunctionBody;
  1930. end
  1931. else if (Module is TPasProgram) or (Module is TPasLibrary) then
  1932. CheckDottedIdentifier('init function',InitAssign.LHS,'$mod.'+InitName);
  1933. end;
  1934. end;
  1935. // optional: implementation uses section
  1936. if JSModuleCallArgs.Elements.Count<4 then
  1937. exit;
  1938. Arg:=JSModuleCallArgs.Elements.Elements[3];
  1939. CheckUsesList('implementation',Arg,FJSImplentationUses);
  1940. end;
  1941. procedure TCustomTestModule.ConvertProgram;
  1942. begin
  1943. Add('end.');
  1944. ParseProgram;
  1945. ConvertModule;
  1946. end;
  1947. procedure TCustomTestModule.ConvertLibrary;
  1948. begin
  1949. Add('end.');
  1950. ParseLibrary;
  1951. ConvertModule;
  1952. end;
  1953. procedure TCustomTestModule.ConvertUnit;
  1954. begin
  1955. Add('end.');
  1956. ParseUnit;
  1957. ConvertModule;
  1958. end;
  1959. function TCustomTestModule.ConvertJSModuleToString(El: TJSElement): string;
  1960. begin
  1961. Result:=tcmodules.JSToStr(El);
  1962. end;
  1963. procedure TCustomTestModule.CheckDottedIdentifier(Msg: string; El: TJSElement;
  1964. DottedName: string);
  1965. begin
  1966. if DottedName='' then
  1967. begin
  1968. AssertNull(Msg,El);
  1969. end
  1970. else
  1971. begin
  1972. AssertNotNull(Msg,El);
  1973. AssertEquals(Msg,DottedName,GetDottedIdentifier(El));
  1974. end;
  1975. end;
  1976. function TCustomTestModule.GetDottedIdentifier(El: TJSElement): string;
  1977. begin
  1978. if El=nil then
  1979. Result:=''
  1980. else if El is TJSPrimaryExpressionIdent then
  1981. Result:=String(TJSPrimaryExpressionIdent(El).Name)
  1982. else if El is TJSDotMemberExpression then
  1983. Result:=GetDottedIdentifier(TJSDotMemberExpression(El).MExpr)+'.'+String(TJSDotMemberExpression(El).Name)
  1984. else
  1985. AssertEquals('GetDottedIdentifier',TJSPrimaryExpressionIdent,El.ClassType);
  1986. end;
  1987. procedure TCustomTestModule.CheckSource(Msg, Statements: String;
  1988. InitStatements: string; ImplStatements: string);
  1989. var
  1990. ActualSrc, ExpectedSrc, InitName: String;
  1991. begin
  1992. ActualSrc:=JSToStr(JSModuleSrc);
  1993. if coUseStrict in Converter.Options then
  1994. ExpectedSrc:='"use strict";'+LineEnding
  1995. else
  1996. ExpectedSrc:='';
  1997. ExpectedSrc:=ExpectedSrc+'var $mod = this;'+LineEnding;
  1998. ExpectedSrc:=ExpectedSrc+Statements;
  1999. // unit implementation
  2000. if (Trim(ImplStatements)<>'') then
  2001. ExpectedSrc:=ExpectedSrc+LineEnding
  2002. +'$mod.$implcode = function () {'+LineEnding
  2003. +ImplStatements
  2004. +'};'+LineEnding;
  2005. // program main or unit initialization
  2006. if (Module is TPasProgram) or (Trim(InitStatements)<>'') then
  2007. begin
  2008. if (Module is TPasProgram) or (Module is TPasLibrary) then
  2009. InitName:='$main'
  2010. else
  2011. InitName:='$init';
  2012. ExpectedSrc:=ExpectedSrc+LineEnding
  2013. +'$mod.'+InitName+' = function () {'+LineEnding
  2014. +InitStatements
  2015. +'};'+LineEnding;
  2016. end;
  2017. //writeln('TCustomTestModule.CheckSource ExpectedIntf="',ExpectedSrc,'"');
  2018. //writeln('TTestModule.CheckSource InitStatements="',Trim(InitStatements),'"');
  2019. CheckDiff(Msg,ExpectedSrc,ActualSrc);
  2020. end;
  2021. procedure TCustomTestModule.CheckDiff(Msg, Expected, Actual: string);
  2022. // search diff, ignore changes in spaces
  2023. var
  2024. s: string;
  2025. begin
  2026. if CheckSrcDiff(Expected,Actual,s) then exit;
  2027. Fail(Msg+': '+s);
  2028. end;
  2029. procedure TCustomTestModule.CheckUnit(Filename, ExpectedSrc: string);
  2030. var
  2031. aResolver: TTestEnginePasResolver;
  2032. aConverter: TPasToJSConverter;
  2033. aJSModule: TJSSourceElements;
  2034. ActualSrc: String;
  2035. begin
  2036. aResolver:=GetResolver(Filename);
  2037. AssertNotNull('missing resolver of unit '+Filename,aResolver);
  2038. AssertNotNull('missing resolver.module of unit '+Filename,aResolver.Module);
  2039. {$IFDEF VerbosePas2JS}
  2040. writeln('CheckUnit '+Filename+' converting ...');
  2041. {$ENDIF}
  2042. aConverter:=CreateConverter;
  2043. aJSModule:=nil;
  2044. try
  2045. try
  2046. aJSModule:=aConverter.ConvertPasElement(aResolver.Module,aResolver) as TJSSourceElements;
  2047. except
  2048. on E: Exception do
  2049. HandleException(E);
  2050. end;
  2051. ActualSrc:=ConvertJSModuleToString(aJSModule);
  2052. {$IFDEF VerbosePas2JS}
  2053. writeln('TTestModule.CheckUnit ',Filename,' Pas:');
  2054. write(aResolver.Source);
  2055. writeln('TTestModule.CheckUnit ',Filename,' JS:');
  2056. write(ActualSrc);
  2057. {$ENDIF}
  2058. CheckDiff('Converted unit: "'+ChangeFileExt(Filename,'.js')+'"',ExpectedSrc,ActualSrc);
  2059. finally
  2060. aJSModule.Free;
  2061. aConverter.Free;
  2062. end;
  2063. end;
  2064. procedure TCustomTestModule.CheckHint(MsgType: TMessageType;
  2065. MsgNumber: integer; Msg: string; Marker: PSrcMarker);
  2066. var
  2067. i: Integer;
  2068. Item: TTestHintMessage;
  2069. Expected,Actual: string;
  2070. begin
  2071. //writeln('TCustomTestModule.CheckHint MsgCount=',MsgCount);
  2072. for i:=0 to MsgCount-1 do
  2073. begin
  2074. Item:=Msgs[i];
  2075. if (Item.MsgNumber<>MsgNumber) or (Item.Msg<>Msg) then continue;
  2076. if (Marker<>nil) then
  2077. begin
  2078. if Item.SourcePos.Row<>cardinal(Marker^.Row) then continue;
  2079. if (Item.SourcePos.Column<cardinal(Marker^.StartCol))
  2080. or (Item.SourcePos.Column>cardinal(Marker^.EndCol)) then continue;
  2081. end;
  2082. // found
  2083. FHintMsgsGood.Add(Item);
  2084. str(Item.MsgType,Actual);
  2085. str(MsgType,Expected);
  2086. AssertEquals('MsgType',Expected,Actual);
  2087. exit;
  2088. end;
  2089. // needed message missing -> show emitted messages
  2090. WriteSources('',0,0);
  2091. for i:=0 to MsgCount-1 do
  2092. begin
  2093. Item:=Msgs[i];
  2094. write('TCustomTestModule.CheckHint ',i,'/',MsgCount,' ',Item.MsgType,
  2095. ' ('+IntToStr(Item.MsgNumber),')');
  2096. if Marker<>nil then
  2097. write(' '+ExtractFileName(Item.SourcePos.FileName),'(',Item.SourcePos.Row,',',Item.SourcePos.Column,')');
  2098. writeln(' {',Item.Msg,'}');
  2099. end;
  2100. str(MsgType,Expected);
  2101. Actual:='Missing '+Expected+' ('+IntToStr(MsgNumber)+')';
  2102. if Marker<>nil then
  2103. Actual:=Actual+' '+ExtractFileName(Marker^.Filename)+'('+IntToStr(Marker^.Row)+','+IntToStr(Marker^.StartCol)+'..'+IntToStr(Marker^.EndCol)+')';
  2104. Actual:=Actual+' '+Msg;
  2105. Fail(Actual);
  2106. end;
  2107. procedure TCustomTestModule.CheckResolverUnexpectedHints(WithSourcePos: boolean
  2108. );
  2109. var
  2110. i: Integer;
  2111. s, Txt: String;
  2112. Msg: TTestHintMessage;
  2113. begin
  2114. for i:=0 to MsgCount-1 do
  2115. begin
  2116. Msg:=Msgs[i];
  2117. if FHintMsgsGood.IndexOf(Msg)>=0 then continue;
  2118. s:='';
  2119. str(Msg.MsgType,s);
  2120. Txt:='Unexpected resolver message found ['+IntToStr(Msg.Id)+'] '
  2121. +s+': ('+IntToStr(Msg.MsgNumber)+')';
  2122. if WithSourcePos then
  2123. Txt:=Txt+' '+ExtractFileName(Msg.SourcePos.FileName)+'('+IntToStr(Msg.SourcePos.Row)+','+IntToStr(Msg.SourcePos.Column)+')';
  2124. Txt:=Txt+' {'+Msg.Msg+'}';
  2125. Fail(Txt);
  2126. end;
  2127. end;
  2128. procedure TCustomTestModule.SetExpectedScannerError(Msg: string;
  2129. MsgNumber: integer);
  2130. begin
  2131. ExpectedErrorClass:=EScannerError;
  2132. ExpectedErrorMsg:=Msg;
  2133. ExpectedErrorNumber:=MsgNumber;
  2134. end;
  2135. procedure TCustomTestModule.SetExpectedParserError(Msg: string;
  2136. MsgNumber: integer);
  2137. begin
  2138. ExpectedErrorClass:=EParserError;
  2139. ExpectedErrorMsg:=Msg;
  2140. ExpectedErrorNumber:=MsgNumber;
  2141. end;
  2142. procedure TCustomTestModule.SetExpectedPasResolverError(Msg: string;
  2143. MsgNumber: integer);
  2144. begin
  2145. ExpectedErrorClass:=EPasResolve;
  2146. ExpectedErrorMsg:=Msg;
  2147. ExpectedErrorNumber:=MsgNumber;
  2148. end;
  2149. procedure TCustomTestModule.SetExpectedConverterError(Msg: string;
  2150. MsgNumber: integer);
  2151. begin
  2152. ExpectedErrorClass:=EPas2JS;
  2153. ExpectedErrorMsg:=Msg;
  2154. ExpectedErrorNumber:=MsgNumber;
  2155. end;
  2156. function TCustomTestModule.IsErrorExpected(E: Exception): boolean;
  2157. var
  2158. MsgNumber: Integer;
  2159. Msg: String;
  2160. begin
  2161. Result:=false;
  2162. if (ExpectedErrorClass=nil) or (ExpectedErrorClass<>E.ClassType) then exit;
  2163. Msg:=E.Message;
  2164. if E is EPas2JS then
  2165. MsgNumber:=EPas2JS(E).MsgNumber
  2166. else if E is EPasResolve then
  2167. MsgNumber:=EPasResolve(E).MsgNumber
  2168. else if E is EParserError then
  2169. MsgNumber:=Parser.LastMsgNumber
  2170. else if E is EScannerError then
  2171. begin
  2172. MsgNumber:=Scanner.LastMsgNumber;
  2173. Msg:=Scanner.LastMsg;
  2174. end
  2175. else
  2176. MsgNumber:=0;
  2177. Result:=(MsgNumber=ExpectedErrorNumber) and (Msg=ExpectedErrorMsg);
  2178. if Result then
  2179. SkipTests:=true;
  2180. end;
  2181. procedure TCustomTestModule.HandleScannerError(E: EScannerError);
  2182. begin
  2183. if IsErrorExpected(E) then exit;
  2184. WriteSources(Scanner.CurFilename,Scanner.CurRow,Scanner.CurColumn);
  2185. writeln('ERROR: TCustomTestModule.HandleScannerError '+E.ClassName+':'+E.Message
  2186. +' '+Scanner.CurFilename
  2187. +'('+IntToStr(Scanner.CurRow)+','+IntToStr(Scanner.CurColumn)+')');
  2188. FailException(E);
  2189. end;
  2190. procedure TCustomTestModule.HandleParserError(E: EParserError);
  2191. begin
  2192. if IsErrorExpected(E) then exit;
  2193. WriteSources(E.Filename,E.Row,E.Column);
  2194. writeln('ERROR: TCustomTestModule.HandleParserError '+E.ClassName+':'+E.Message
  2195. +' '+E.Filename+'('+IntToStr(E.Row)+','+IntToStr(E.Column)+')'
  2196. +' MainModuleScannerLine="'+Scanner.CurLine+'"'
  2197. );
  2198. FailException(E);
  2199. end;
  2200. procedure TCustomTestModule.HandlePasResolveError(E: EPasResolve);
  2201. var
  2202. P: TPasSourcePos;
  2203. begin
  2204. if IsErrorExpected(E) then exit;
  2205. P:=E.SourcePos;
  2206. WriteSources(P.FileName,P.Row,P.Column);
  2207. writeln('ERROR: TCustomTestModule.HandlePasResolveError '+E.ClassName+':'+E.Message
  2208. +' '+P.FileName+'('+IntToStr(P.Row)+','+IntToStr(P.Column)+')');
  2209. FailException(E);
  2210. end;
  2211. procedure TCustomTestModule.HandlePas2JSError(E: EPas2JS);
  2212. var
  2213. Row, Col: integer;
  2214. begin
  2215. if IsErrorExpected(E) then exit;
  2216. Engine.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,Row,Col);
  2217. WriteSources(E.PasElement.SourceFilename,Row,Col);
  2218. writeln('ERROR: TCustomTestModule.HandlePas2JSError '+E.ClassName+':'+E.Message
  2219. +' '+E.PasElement.SourceFilename
  2220. +'('+IntToStr(Row)+','+IntToStr(Col)+')');
  2221. FailException(E);
  2222. end;
  2223. procedure TCustomTestModule.HandleException(E: Exception);
  2224. begin
  2225. if E is EScannerError then
  2226. HandleScannerError(EScannerError(E))
  2227. else if E is EParserError then
  2228. HandleParserError(EParserError(E))
  2229. else if E is EPasResolve then
  2230. HandlePasResolveError(EPasResolve(E))
  2231. else if E is EPas2JS then
  2232. HandlePas2JSError(EPas2JS(E))
  2233. else
  2234. begin
  2235. if IsErrorExpected(E) then exit;
  2236. if not (E is EAssertionFailedError) then
  2237. begin
  2238. WriteSources('',0,0);
  2239. writeln('ERROR: TCustomTestModule.HandleException '+E.ClassName+':'+E.Message);
  2240. end;
  2241. FailException(E);
  2242. end;
  2243. end;
  2244. procedure TCustomTestModule.FailException(E: Exception);
  2245. var
  2246. MsgNumber: Integer;
  2247. begin
  2248. if ExpectedErrorClass<>nil then
  2249. begin
  2250. if FExpectedErrorClass=E.ClassType then
  2251. begin
  2252. if E is EPas2JS then
  2253. MsgNumber:=EPas2JS(E).MsgNumber
  2254. else if E is EPasResolve then
  2255. MsgNumber:=EPasResolve(E).MsgNumber
  2256. else if E is EParserError then
  2257. MsgNumber:=Parser.LastMsgNumber
  2258. else if E is EScannerError then
  2259. MsgNumber:=Scanner.LastMsgNumber
  2260. else
  2261. MsgNumber:=0;
  2262. AssertEquals('Expected error message ('+IntToStr(ExpectedErrorNumber)+')','{'+ExpectedErrorMsg+'}','{'+E.Message+'}');
  2263. AssertEquals('Expected {'+ExpectedErrorMsg+'}, but got msg {'+E.Message+'} number',
  2264. ExpectedErrorNumber,MsgNumber);
  2265. end else begin
  2266. AssertEquals('Wrong exception class',ExpectedErrorClass.ClassName,E.ClassName);
  2267. end;
  2268. end;
  2269. Fail(E.Message);
  2270. end;
  2271. procedure TCustomTestModule.WriteSources(const aFilename: string; aRow,
  2272. aCol: integer);
  2273. var
  2274. IsSrc: Boolean;
  2275. i, j: Integer;
  2276. SrcLines: TStringList;
  2277. Line: string;
  2278. aModule: TTestEnginePasResolver;
  2279. begin
  2280. writeln('TCustomTestModule.WriteSources File="',aFilename,'" Row=',aRow,' Col=',aCol);
  2281. for i:=0 to ResolverCount-1 do
  2282. begin
  2283. aModule:=Resolvers[i];
  2284. SrcLines:=TStringList.Create;
  2285. try
  2286. SrcLines.Text:=aModule.Source;
  2287. IsSrc:=ExtractFilename(aModule.Filename)=ExtractFileName(aFilename);
  2288. writeln('Testcode:-File="',aModule.Filename,'"----------------------------------:');
  2289. for j:=1 to SrcLines.Count do
  2290. begin
  2291. Line:=SrcLines[j-1];
  2292. if IsSrc and (j=aRow) then
  2293. begin
  2294. write('*');
  2295. Line:=LeftStr(Line,aCol-1)+'|'+copy(Line,aCol,length(Line));
  2296. end;
  2297. writeln(Format('%:4d: ',[j]),Line);
  2298. end;
  2299. finally
  2300. SrcLines.Free;
  2301. end;
  2302. end;
  2303. end;
  2304. function TCustomTestModule.IndexOfResolver(const Filename: string): integer;
  2305. var
  2306. i: Integer;
  2307. begin
  2308. for i:=0 to ResolverCount-1 do
  2309. if Filename=Resolvers[i].Filename then exit(i);
  2310. Result:=-1;
  2311. end;
  2312. function TCustomTestModule.GetResolver(const Filename: string
  2313. ): TTestEnginePasResolver;
  2314. var
  2315. i: Integer;
  2316. begin
  2317. i:=IndexOfResolver(Filename);
  2318. if i<0 then exit(nil);
  2319. Result:=Resolvers[i];
  2320. end;
  2321. function TCustomTestModule.GetDefaultNamespace: string;
  2322. var
  2323. C: TClass;
  2324. begin
  2325. Result:='';
  2326. if FModule=nil then exit;
  2327. C:=FModule.ClassType;
  2328. if (C=TPasProgram) or (C=TPasLibrary) or (C=TPasPackage) then
  2329. Result:=Engine.DefaultNameSpace;
  2330. end;
  2331. constructor TCustomTestModule.Create;
  2332. begin
  2333. inherited Create;
  2334. FHintMsgs:=TObjectList.Create(true);
  2335. FHintMsgsGood:=TFPList.Create;
  2336. end;
  2337. destructor TCustomTestModule.Destroy;
  2338. begin
  2339. FreeAndNil(FHintMsgs);
  2340. FreeAndNil(FHintMsgsGood);
  2341. inherited Destroy;
  2342. end;
  2343. { TTestModule }
  2344. procedure TTestModule.TestReservedWords;
  2345. var
  2346. i: integer;
  2347. begin
  2348. for i:=low(JSReservedWords) to High(JSReservedWords)-1 do
  2349. if CompareStr(JSReservedWords[i],JSReservedWords[i+1])>=0 then
  2350. Fail('20170203135442 '+JSReservedWords[i]+' >= '+JSReservedWords[i+1]);
  2351. for i:=low(JSReservedGlobalWords) to High(JSReservedGlobalWords)-1 do
  2352. if CompareStr(JSReservedGlobalWords[i],JSReservedGlobalWords[i+1])>=0 then
  2353. Fail('20170203135443 '+JSReservedGlobalWords[i]+' >= '+JSReservedGlobalWords[i+1]);
  2354. end;
  2355. procedure TTestModule.TestEmptyProgram;
  2356. begin
  2357. StartProgram(false);
  2358. Add('begin');
  2359. ConvertProgram;
  2360. CheckSource('TestEmptyProgram','','');
  2361. end;
  2362. procedure TTestModule.TestEmptyProgramUseStrict;
  2363. begin
  2364. Converter.Options:=Converter.Options+[coUseStrict];
  2365. StartProgram(false);
  2366. Add('begin');
  2367. ConvertProgram;
  2368. CheckSource('TestEmptyProgramUseStrict','','');
  2369. end;
  2370. procedure TTestModule.TestEmptyUnit;
  2371. begin
  2372. StartUnit(false);
  2373. Add('interface');
  2374. Add('implementation');
  2375. ConvertUnit;
  2376. CheckSource('TestEmptyUnit',
  2377. LinesToStr([
  2378. ]),
  2379. '');
  2380. end;
  2381. procedure TTestModule.TestEmptyUnitUseStrict;
  2382. begin
  2383. Converter.Options:=Converter.Options+[coUseStrict];
  2384. StartUnit(false);
  2385. Add('interface');
  2386. Add('implementation');
  2387. ConvertUnit;
  2388. CheckSource('TestEmptyUnitUseStrict',
  2389. LinesToStr([
  2390. ''
  2391. ]),
  2392. '');
  2393. end;
  2394. procedure TTestModule.TestDottedUnitNames;
  2395. begin
  2396. AddModuleWithIntfImplSrc('NS1.Unit2.pas',
  2397. LinesToStr([
  2398. 'var iV: longint;'
  2399. ]),
  2400. '');
  2401. FFilename:='ns1.test1.pp';
  2402. StartProgram(true);
  2403. Add('uses unIt2;');
  2404. Add('var');
  2405. Add(' i: longint;');
  2406. Add('begin');
  2407. Add(' i:=iv;');
  2408. Add(' i:=uNit2.iv;');
  2409. Add(' i:=Ns1.TEst1.i;');
  2410. ConvertProgram;
  2411. CheckSource('TestDottedUnitNames',
  2412. LinesToStr([
  2413. 'this.i = 0;',
  2414. '']),
  2415. LinesToStr([ // this.$init
  2416. '$mod.i = pas["NS1.Unit2"].iV;',
  2417. '$mod.i = pas["NS1.Unit2"].iV;',
  2418. '$mod.i = $mod.i;',
  2419. '']) );
  2420. end;
  2421. procedure TTestModule.TestDottedUnitNameImpl;
  2422. begin
  2423. AddModuleWithIntfImplSrc('TEST.UnitA.pas',
  2424. LinesToStr([
  2425. 'type',
  2426. ' TObject = class end;',
  2427. ' TTestA = class',
  2428. ' end;'
  2429. ]),
  2430. LinesToStr(['uses TEST.UnitB;'])
  2431. );
  2432. AddModuleWithIntfImplSrc('TEST.UnitB.pas',
  2433. LinesToStr([
  2434. 'uses TEST.UnitA;',
  2435. 'type TTestB = class(TTestA);'
  2436. ]),
  2437. ''
  2438. );
  2439. StartProgram(true);
  2440. Add('uses TEST.UnitA;');
  2441. Add('begin');
  2442. ConvertProgram;
  2443. CheckSource('TestDottedUnitNameImpl',
  2444. LinesToStr([
  2445. '']),
  2446. LinesToStr([ // this.$init
  2447. '']) );
  2448. CheckUnit('TEST.UnitA.pas',
  2449. LinesToStr([
  2450. 'rtl.module("TEST.UnitA", ["system"], function () {',
  2451. ' var $mod = this;',
  2452. ' rtl.createClass(this, "TObject", null, function () {',
  2453. ' this.$init = function () {',
  2454. ' };',
  2455. ' this.$final = function () {',
  2456. ' };',
  2457. ' });',
  2458. ' rtl.createClass(this, "TTestA", this.TObject, function () {',
  2459. ' });',
  2460. '}, ["TEST.UnitB"]);'
  2461. ]));
  2462. CheckUnit('TEST.UnitB.pas',
  2463. LinesToStr([
  2464. 'rtl.module("TEST.UnitB", ["system","TEST.UnitA"], function () {',
  2465. ' var $mod = this;',
  2466. ' rtl.createClass(this, "TTestB", pas["TEST.UnitA"].TTestA, function () {',
  2467. ' });',
  2468. '});'
  2469. ]));
  2470. end;
  2471. procedure TTestModule.TestDottedUnitExpr;
  2472. begin
  2473. AddModuleWithIntfImplSrc('NS2.SubNs2.Unit2.pas',
  2474. LinesToStr([
  2475. 'procedure DoIt;'
  2476. ]),
  2477. 'procedure DoIt; begin end;');
  2478. FFilename:='Ns1.SubNs1.Test1.pp';
  2479. StartProgram(true);
  2480. Add('uses Ns2.sUbnS2.unIt2;');
  2481. Add('var');
  2482. Add(' i: longint;');
  2483. Add('begin');
  2484. Add(' ns2.subns2.unit2.doit;');
  2485. Add(' i:=Ns1.SubNS1.TEst1.i;');
  2486. ConvertProgram;
  2487. CheckSource('TestDottedUnitExpr',
  2488. LinesToStr([
  2489. 'this.i = 0;',
  2490. '']),
  2491. LinesToStr([ // this.$init
  2492. 'pas["NS2.SubNs2.Unit2"].DoIt();',
  2493. '$mod.i = $mod.i;',
  2494. '']) );
  2495. end;
  2496. procedure TTestModule.Test_ModeFPCFail;
  2497. begin
  2498. StartProgram(false);
  2499. Add('{$mode FPC}');
  2500. Add('begin');
  2501. SetExpectedScannerError('Invalid mode: "FPC"',nErrInvalidMode);
  2502. ConvertProgram;
  2503. end;
  2504. procedure TTestModule.Test_ModeSwitchCBlocksFail;
  2505. begin
  2506. StartProgram(false);
  2507. Add('{$modeswitch cblocks-}');
  2508. Add('begin');
  2509. ConvertProgram;
  2510. CheckHint(mtWarning,nErrInvalidModeSwitch,'Warning: test1.pp(3,23) : Invalid mode switch: "cblocks"');
  2511. CheckResolverUnexpectedHints();
  2512. end;
  2513. procedure TTestModule.TestUnit_UseSystem;
  2514. begin
  2515. StartUnit(true);
  2516. Add([
  2517. 'interface',
  2518. 'var i: integer;',
  2519. 'implementation']);
  2520. ConvertUnit;
  2521. CheckSource('TestUnit_UseSystem',
  2522. LinesToStr([
  2523. 'this.i = 0;',
  2524. '']),
  2525. LinesToStr([
  2526. '']) );
  2527. end;
  2528. procedure TTestModule.TestUnit_Intf1Impl2Intf1;
  2529. begin
  2530. AddModuleWithIntfImplSrc('unit1.pp',
  2531. LinesToStr([
  2532. 'type number = longint;']),
  2533. LinesToStr([
  2534. 'uses test1;',
  2535. 'procedure DoIt;',
  2536. 'begin',
  2537. ' i:=3;',
  2538. 'end;']));
  2539. StartUnit(true);
  2540. Add([
  2541. 'interface',
  2542. 'uses unit1;',
  2543. 'var i: number;',
  2544. 'implementation']);
  2545. ConvertUnit;
  2546. CheckSource('TestUnit_Intf1Impl2Intf1',
  2547. LinesToStr([
  2548. 'this.i = 0;',
  2549. '']),
  2550. LinesToStr([
  2551. '']) );
  2552. end;
  2553. procedure TTestModule.TestIncludeVersion;
  2554. begin
  2555. StartProgram(false);
  2556. Add([
  2557. 'var',
  2558. ' s: string;',
  2559. ' i: word;',
  2560. 'begin',
  2561. ' s:={$I %line%};',
  2562. ' i:={$I %linenum%};',
  2563. ' s:={$I %currentroutine%};',
  2564. ' s:={$I %pas2jsversion%};',
  2565. ' s:={$I %pas2jstarget%};',
  2566. ' s:={$I %pas2jstargetos%};',
  2567. ' s:={$I %pas2jstargetcpu%};',
  2568. ' s:={$I %file%};',
  2569. '']);
  2570. ConvertProgram;
  2571. CheckSource('TestIncludeVersion',
  2572. LinesToStr([
  2573. 'this.s="";',
  2574. 'this.i = 0;']),
  2575. LinesToStr([
  2576. '$mod.s = "7";',
  2577. '$mod.i = 8;',
  2578. '$mod.s = "<anonymous>";',
  2579. '$mod.s = "Comp.Ver.tcmodules";',
  2580. '$mod.s = "Browser";',
  2581. '$mod.s = "Browser";',
  2582. '$mod.s = "ECMAScript5";',
  2583. '$mod.s = "test1.pp";',
  2584. '']));
  2585. end;
  2586. procedure TTestModule.TestVarInt;
  2587. begin
  2588. StartProgram(false);
  2589. Add('var MyI: longint;');
  2590. Add('begin');
  2591. ConvertProgram;
  2592. CheckSource('TestVarInt','this.MyI=0;','');
  2593. end;
  2594. procedure TTestModule.TestVarBaseTypes;
  2595. begin
  2596. StartProgram(false);
  2597. Add('var');
  2598. Add(' i: longint;');
  2599. Add(' s: string;');
  2600. Add(' c: char;');
  2601. Add(' b: boolean;');
  2602. Add(' d: double;');
  2603. Add(' i2: longint = 3;');
  2604. Add(' s2: string = ''foo'';');
  2605. Add(' c2: char = ''4'';');
  2606. Add(' b2: boolean = true;');
  2607. Add(' d2: double = 5.6;');
  2608. Add(' i3: longint = $707;');
  2609. Add(' i4: nativeint = 9007199254740991;');
  2610. Add(' i5: nativeint = -9007199254740991-1;');
  2611. Add(' i6: nativeint = $fffffffffffff;');
  2612. Add(' i7: nativeint = -$fffffffffffff-1;');
  2613. Add(' i8: byte = 00;');
  2614. Add(' u8: nativeuint = $fffffffffffff;');
  2615. Add(' u9: nativeuint = $0000000000000;');
  2616. Add(' u10: nativeuint = $00ff00;');
  2617. Add('begin');
  2618. ConvertProgram;
  2619. CheckSource('TestVarBaseTypes',
  2620. LinesToStr([
  2621. 'this.i = 0;',
  2622. 'this.s = "";',
  2623. 'this.c = "";',
  2624. 'this.b = false;',
  2625. 'this.d = 0.0;',
  2626. 'this.i2 = 3;',
  2627. 'this.s2 = "foo";',
  2628. 'this.c2 = "4";',
  2629. 'this.b2 = true;',
  2630. 'this.d2 = 5.6;',
  2631. 'this.i3 = 0x707;',
  2632. 'this.i4 = 9007199254740991;',
  2633. 'this.i5 = -9007199254740991-1;',
  2634. 'this.i6 = 0xfffffffffffff;',
  2635. 'this.i7 =-0xfffffffffffff-1;',
  2636. 'this.i8 = 0;',
  2637. 'this.u8 = 0xfffffffffffff;',
  2638. 'this.u9 = 0x0;',
  2639. 'this.u10 = 0xff00;'
  2640. ]),
  2641. '');
  2642. end;
  2643. procedure TTestModule.TestBaseTypeSingleFail;
  2644. begin
  2645. StartProgram(false);
  2646. Add('var s: single;');
  2647. SetExpectedPasResolverError('identifier not found "single"',PasResolveEval.nIdentifierNotFound);
  2648. ConvertProgram;
  2649. end;
  2650. procedure TTestModule.TestBaseTypeExtendedFail;
  2651. begin
  2652. StartProgram(false);
  2653. Add('var e: extended;');
  2654. SetExpectedPasResolverError('identifier not found "extended"',PasResolveEval.nIdentifierNotFound);
  2655. ConvertProgram;
  2656. end;
  2657. procedure TTestModule.TestConstBaseTypes;
  2658. begin
  2659. StartProgram(false);
  2660. Add('const');
  2661. Add(' i: longint = 3;');
  2662. Add(' s: string = ''foo'';');
  2663. Add(' c: char = ''4'';');
  2664. Add(' b: boolean = true;');
  2665. Add(' d: double = 5.6;');
  2666. Add(' e = low(word);');
  2667. Add(' f = high(word);');
  2668. Add('begin');
  2669. ConvertProgram;
  2670. CheckSource('TestVarBaseTypes',
  2671. LinesToStr([
  2672. 'this.i=3;',
  2673. 'this.s="foo";',
  2674. 'this.c="4";',
  2675. 'this.b=true;',
  2676. 'this.d=5.6;',
  2677. 'this.e = 0;',
  2678. 'this.f = 65535;'
  2679. ]),
  2680. '');
  2681. end;
  2682. procedure TTestModule.TestAliasTypeRef;
  2683. begin
  2684. StartProgram(false);
  2685. Add('type');
  2686. Add(' a=longint;');
  2687. Add(' b=a;');
  2688. Add('var');
  2689. Add(' c: A;');
  2690. Add(' d: B;');
  2691. Add('begin');
  2692. ConvertProgram;
  2693. CheckSource('TestAliasTypeRef',
  2694. LinesToStr([ // statements
  2695. 'this.c = 0;',
  2696. 'this.d = 0;'
  2697. ]),
  2698. LinesToStr([ // this.$main
  2699. ''
  2700. ]));
  2701. end;
  2702. procedure TTestModule.TestTypeCast_BaseTypes;
  2703. begin
  2704. StartProgram(false);
  2705. Add([
  2706. 'var',
  2707. ' i: longint;',
  2708. ' b: boolean;',
  2709. ' d: double;',
  2710. ' s: string;',
  2711. ' c: char;',
  2712. 'begin',
  2713. ' i:=longint(i);',
  2714. ' i:=longint(b);',
  2715. ' b:=boolean(b);',
  2716. ' b:=boolean(i);',
  2717. ' d:=double(d);',
  2718. ' d:=double(i);',
  2719. ' s:=string(s);',
  2720. ' s:=string(c);',
  2721. ' c:=char(c);',
  2722. ' c:=char(i);',
  2723. ' c:=char(65);',
  2724. ' c:=char(#10);',
  2725. ' c:=char(#$E000);',
  2726. '']);
  2727. ConvertProgram;
  2728. CheckSource('TestAliasTypeRef',
  2729. LinesToStr([ // statements
  2730. 'this.i = 0;',
  2731. 'this.b = false;',
  2732. 'this.d = 0.0;',
  2733. 'this.s = "";',
  2734. 'this.c = "";',
  2735. '']),
  2736. LinesToStr([ // this.$main
  2737. '$mod.i = $mod.i;',
  2738. '$mod.i = ($mod.b ? 1 : 0);',
  2739. '$mod.b = $mod.b;',
  2740. '$mod.b = $mod.i != 0;',
  2741. '$mod.d = $mod.d;',
  2742. '$mod.d = $mod.i;',
  2743. '$mod.s = $mod.s;',
  2744. '$mod.s = $mod.c;',
  2745. '$mod.c = $mod.c;',
  2746. '$mod.c = String.fromCharCode($mod.i);',
  2747. '$mod.c = "A";',
  2748. '$mod.c = "\n";',
  2749. '$mod.c = "";',
  2750. '']));
  2751. end;
  2752. procedure TTestModule.TestTypeCast_AliasBaseTypes;
  2753. begin
  2754. StartProgram(false);
  2755. Add('type');
  2756. Add(' integer = longint;');
  2757. Add(' TYesNo = boolean;');
  2758. Add(' TFloat = double;');
  2759. Add(' TCaption = string;');
  2760. Add(' TChar = char;');
  2761. Add('var');
  2762. Add(' i: integer;');
  2763. Add(' b: TYesNo;');
  2764. Add(' d: TFloat;');
  2765. Add(' s: TCaption;');
  2766. Add(' c: TChar;');
  2767. Add('begin');
  2768. Add(' i:=integer(i);');
  2769. Add(' i:=integer(b);');
  2770. Add(' b:=TYesNo(b);');
  2771. Add(' b:=TYesNo(i);');
  2772. Add(' d:=TFloat(d);');
  2773. Add(' d:=TFloat(i);');
  2774. Add(' s:=TCaption(s);');
  2775. Add(' s:=TCaption(c);');
  2776. Add(' c:=TChar(c);');
  2777. ConvertProgram;
  2778. CheckSource('TestAliasTypeRef',
  2779. LinesToStr([ // statements
  2780. 'this.i = 0;',
  2781. 'this.b = false;',
  2782. 'this.d = 0.0;',
  2783. 'this.s = "";',
  2784. 'this.c = "";',
  2785. '']),
  2786. LinesToStr([ // this.$main
  2787. '$mod.i = $mod.i;',
  2788. '$mod.i = ($mod.b ? 1 : 0);',
  2789. '$mod.b = $mod.b;',
  2790. '$mod.b = $mod.i != 0;',
  2791. '$mod.d = $mod.d;',
  2792. '$mod.d = $mod.i;',
  2793. '$mod.s = $mod.s;',
  2794. '$mod.s = $mod.c;',
  2795. '$mod.c = $mod.c;',
  2796. '']));
  2797. end;
  2798. procedure TTestModule.TestEmptyProc;
  2799. begin
  2800. StartProgram(false);
  2801. Add('procedure Test;');
  2802. Add('begin');
  2803. Add('end;');
  2804. Add('begin');
  2805. ConvertProgram;
  2806. CheckSource('TestEmptyProc',
  2807. LinesToStr([ // statements
  2808. 'this.Test = function () {',
  2809. '};'
  2810. ]),
  2811. LinesToStr([ // this.$main
  2812. ''
  2813. ]));
  2814. end;
  2815. procedure TTestModule.TestProcOneParam;
  2816. begin
  2817. StartProgram(false);
  2818. Add('procedure ProcA(i: longint);');
  2819. Add('begin');
  2820. Add('end;');
  2821. Add('begin');
  2822. Add(' PROCA(3);');
  2823. ConvertProgram;
  2824. CheckSource('TestProcOneParam',
  2825. LinesToStr([ // statements
  2826. 'this.ProcA = function (i) {',
  2827. '};'
  2828. ]),
  2829. LinesToStr([ // this.$main
  2830. '$mod.ProcA(3);'
  2831. ]));
  2832. end;
  2833. procedure TTestModule.TestFunctionWithoutParams;
  2834. begin
  2835. StartProgram(false);
  2836. Add('function FuncA: longint;');
  2837. Add('begin');
  2838. Add('end;');
  2839. Add('var i: longint;');
  2840. Add('begin');
  2841. Add(' I:=FUNCA();');
  2842. Add(' I:=FUNCA;');
  2843. Add(' FUNCA();');
  2844. Add(' FUNCA;');
  2845. ConvertProgram;
  2846. CheckSource('TestProcWithoutParams',
  2847. LinesToStr([ // statements
  2848. 'this.FuncA = function () {',
  2849. ' var Result = 0;',
  2850. ' return Result;',
  2851. '};',
  2852. 'this.i=0;'
  2853. ]),
  2854. LinesToStr([ // this.$main
  2855. '$mod.i=$mod.FuncA();',
  2856. '$mod.i=$mod.FuncA();',
  2857. '$mod.FuncA();',
  2858. '$mod.FuncA();'
  2859. ]));
  2860. end;
  2861. procedure TTestModule.TestProcedureWithoutParams;
  2862. begin
  2863. StartProgram(false);
  2864. Add('procedure ProcA;');
  2865. Add('begin');
  2866. Add('end;');
  2867. Add('begin');
  2868. Add(' PROCA();');
  2869. Add(' PROCA;');
  2870. ConvertProgram;
  2871. CheckSource('TestProcWithoutParams',
  2872. LinesToStr([ // statements
  2873. 'this.ProcA = function () {',
  2874. '};'
  2875. ]),
  2876. LinesToStr([ // this.$main
  2877. '$mod.ProcA();',
  2878. '$mod.ProcA();'
  2879. ]));
  2880. end;
  2881. procedure TTestModule.TestIncDec;
  2882. begin
  2883. StartProgram(false);
  2884. Add([
  2885. 'procedure DoIt(var i: longint);',
  2886. 'begin',
  2887. ' inc(i);',
  2888. ' inc(i,2);',
  2889. 'end;',
  2890. 'var',
  2891. ' Bar: longint;',
  2892. 'begin',
  2893. ' inc(bar);',
  2894. ' inc(bar,2);',
  2895. ' dec(bar);',
  2896. ' dec(bar,3);',
  2897. '']);
  2898. ConvertProgram;
  2899. CheckSource('TestIncDec',
  2900. LinesToStr([ // statements
  2901. 'this.DoIt = function (i) {',
  2902. ' i.set(i.get()+1);',
  2903. ' i.set(i.get()+2);',
  2904. '};',
  2905. 'this.Bar = 0;'
  2906. ]),
  2907. LinesToStr([ // this.$main
  2908. '$mod.Bar+=1;',
  2909. '$mod.Bar+=2;',
  2910. '$mod.Bar-=1;',
  2911. '$mod.Bar-=3;'
  2912. ]));
  2913. end;
  2914. procedure TTestModule.TestLoHiFpcMode;
  2915. begin
  2916. StartProgram(false);
  2917. Add([
  2918. '{$mode objfpc}',
  2919. 'const',
  2920. ' LoByte1 = Lo(Word($1234));',
  2921. ' HiByte1 = Hi(Word($1234));',
  2922. ' LoByte2 = Lo(SmallInt($1234));',
  2923. ' HiByte2 = Hi(SmallInt($1234));',
  2924. ' LoWord1 = Lo($1234CDEF);',
  2925. ' HiWord1 = Hi($1234CDEF);',
  2926. ' LoWord2 = Lo(-$1234CDEF);',
  2927. ' HiWord2 = Hi(-$1234CDEF);',
  2928. ' lo4:byte=lo(byte($34));',
  2929. ' hi4:byte=hi(byte($34));',
  2930. ' lo5:byte=lo(shortint(-$34));',
  2931. ' hi5:byte=hi(shortint(-$34));',
  2932. ' lo6:longword=lo($123456789ABCD);',
  2933. ' hi6:longword=hi($123456789ABCD);',
  2934. ' lo7:longword=lo(-$123456789ABCD);',
  2935. ' hi7:longword=hi(-$123456789ABCD);',
  2936. 'var',
  2937. ' b: Byte;',
  2938. ' ss: shortint;',
  2939. ' w: Word;',
  2940. ' si: SmallInt;',
  2941. ' lw: LongWord;',
  2942. ' li: LongInt;',
  2943. ' b2: Byte;',
  2944. ' ni: nativeint;',
  2945. 'begin',
  2946. ' w := $1234;',
  2947. ' ss := -$12;',
  2948. ' b := lo(ss);',
  2949. ' b := HI(ss);',
  2950. ' b := lo(w);',
  2951. ' b := HI(w);',
  2952. ' b2 := lo(b);',
  2953. ' b2 := hi(b);',
  2954. ' lw := $1234CDEF;',
  2955. ' w := lo(lw);',
  2956. ' w := hi(lw);',
  2957. ' ni := $123456789ABCD;',
  2958. ' lw := lo(ni);',
  2959. ' lw := hi(ni);',
  2960. '']);
  2961. ConvertProgram;
  2962. CheckSource('TestLoHiFpcMode',
  2963. LinesToStr([ // statements
  2964. 'this.LoByte1 = 0x1234 & 0xFF;',
  2965. 'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
  2966. 'this.LoByte2 = 0x1234 & 0xFF;',
  2967. 'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
  2968. 'this.LoWord1 = 0x1234CDEF & 0xFFFF;',
  2969. 'this.HiWord1 = (0x1234CDEF >> 16) & 0xFFFF;',
  2970. 'this.LoWord2 = -0x1234CDEF >>> 0;',
  2971. 'this.HiWord2 = Math.floor(-0x1234CDEF / 4294967296) >>> 0;',
  2972. 'this.lo4 = 0x34 & 0xF;',
  2973. 'this.hi4 = (0x34 >> 4) & 0xF;',
  2974. 'this.lo5 = (((-0x34 & 255) << 24) >> 24) & 0xFF;',
  2975. 'this.hi5 = ((((-0x34 & 255) << 24) >> 24) >> 8) & 0xFF;',
  2976. 'this.lo6 = 0x123456789ABCD >>> 0;',
  2977. 'this.hi6 = 74565 >>> 0;',
  2978. 'this.lo7 = -0x123456789ABCD >>> 0;',
  2979. 'this.hi7 = Math.floor(-0x123456789ABCD / 4294967296) >>> 0;',
  2980. 'this.b = 0;',
  2981. 'this.ss = 0;',
  2982. 'this.w = 0;',
  2983. 'this.si = 0;',
  2984. 'this.lw = 0;',
  2985. 'this.li = 0;',
  2986. 'this.b2 = 0;',
  2987. 'this.ni = 0;',
  2988. '']),
  2989. LinesToStr([ // this.$main
  2990. '$mod.w = 0x1234;',
  2991. '$mod.ss = -0x12;',
  2992. '$mod.b = $mod.ss & 0xFF;',
  2993. '$mod.b = ($mod.ss >> 8) & 0xFF;',
  2994. '$mod.b = $mod.w & 0xFF;',
  2995. '$mod.b = ($mod.w >> 8) & 0xFF;',
  2996. '$mod.b2 = $mod.b & 0xF;',
  2997. '$mod.b2 = ($mod.b >> 4) & 0xF;',
  2998. '$mod.lw = 0x1234CDEF;',
  2999. '$mod.w = $mod.lw & 0xFFFF;',
  3000. '$mod.w = ($mod.lw >> 16) & 0xFFFF;',
  3001. '$mod.ni = 0x123456789ABCD;',
  3002. '$mod.lw = $mod.ni >>> 0;',
  3003. '$mod.lw = Math.floor($mod.ni / 4294967296) >>> 0;',
  3004. '']));
  3005. end;
  3006. procedure TTestModule.TestLoHiDelphiMode;
  3007. begin
  3008. StartProgram(false);
  3009. Add([
  3010. '{$mode delphi}',
  3011. 'const',
  3012. ' LoByte1 = Lo(Word($1234));',
  3013. ' HiByte1 = Hi(Word($1234));',
  3014. ' LoByte2 = Lo(SmallInt($1234));',
  3015. ' HiByte2 = Hi(SmallInt($1234));',
  3016. ' LoByte3 = Lo($1234CDEF);',
  3017. ' HiByte3 = Hi($1234CDEF);',
  3018. ' LoByte4 = Lo(-$1234CDEF);',
  3019. ' HiByte4 = Hi(-$1234CDEF);',
  3020. 'var',
  3021. ' b: Byte;',
  3022. ' w: Word;',
  3023. ' si: SmallInt;',
  3024. ' lw: LongWord;',
  3025. ' li: LongInt;',
  3026. 'begin',
  3027. ' w := $1234;',
  3028. ' b := lo(w);',
  3029. ' b := HI(w);',
  3030. ' lw := $1234CDEF;',
  3031. ' b := lo(lw);',
  3032. ' b := hi(lw);',
  3033. '']);
  3034. ConvertProgram;
  3035. CheckSource('TestLoHiDelphiMode',
  3036. LinesToStr([ // statements
  3037. 'this.LoByte1 = 0x1234 & 0xFF;',
  3038. 'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
  3039. 'this.LoByte2 = 0x1234 & 0xFF;',
  3040. 'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
  3041. 'this.LoByte3 = 0x1234CDEF & 0xFF;',
  3042. 'this.HiByte3 = (0x1234CDEF >> 8) & 0xFF;',
  3043. 'this.LoByte4 = -0x1234CDEF & 0xFF;',
  3044. 'this.HiByte4 = (-0x1234CDEF >> 8) & 0xFF;',
  3045. 'this.b = 0;',
  3046. 'this.w = 0;',
  3047. 'this.si = 0;',
  3048. 'this.lw = 0;',
  3049. 'this.li = 0;'
  3050. ]),
  3051. LinesToStr([ // this.$main
  3052. '$mod.w = 0x1234;',
  3053. '$mod.b = $mod.w & 0xFF;',
  3054. '$mod.b = ($mod.w >> 8) & 0xFF;',
  3055. '$mod.lw = 0x1234CDEF;',
  3056. '$mod.b = $mod.lw & 0xFF;',
  3057. '$mod.b = ($mod.lw >> 8) & 0xFF;'
  3058. ]));
  3059. end;
  3060. procedure TTestModule.TestAssignments;
  3061. begin
  3062. StartProgram(false);
  3063. Parser.Options:=Parser.Options+[po_cassignments];
  3064. Add('var');
  3065. Add(' Bar:longint;');
  3066. Add('begin');
  3067. Add(' bar:=3;');
  3068. Add(' bar+=4;');
  3069. Add(' bar-=5;');
  3070. Add(' bar*=6;');
  3071. ConvertProgram;
  3072. CheckSource('TestAssignments',
  3073. LinesToStr([ // statements
  3074. 'this.Bar = 0;'
  3075. ]),
  3076. LinesToStr([ // this.$main
  3077. '$mod.Bar=3;',
  3078. '$mod.Bar+=4;',
  3079. '$mod.Bar-=5;',
  3080. '$mod.Bar*=6;'
  3081. ]));
  3082. end;
  3083. procedure TTestModule.TestArithmeticOperators1;
  3084. begin
  3085. StartProgram(false);
  3086. Add('var');
  3087. Add(' vA,vB,vC:longint;');
  3088. Add('begin');
  3089. Add(' va:=1;');
  3090. Add(' vb:=va+va;');
  3091. Add(' vb:=va div vb;');
  3092. Add(' vb:=va mod vb;');
  3093. Add(' vb:=va+va*vb+va div vb;');
  3094. Add(' vc:=-va;');
  3095. Add(' va:=va-vb;');
  3096. Add(' vb:=va;');
  3097. Add(' if va<vb then vc:=va else vc:=vb;');
  3098. ConvertProgram;
  3099. CheckSource('TestArithmeticOperators1',
  3100. LinesToStr([ // statements
  3101. 'this.vA = 0;',
  3102. 'this.vB = 0;',
  3103. 'this.vC = 0;'
  3104. ]),
  3105. LinesToStr([ // this.$main
  3106. '$mod.vA = 1;',
  3107. '$mod.vB = $mod.vA + $mod.vA;',
  3108. '$mod.vB = rtl.trunc($mod.vA / $mod.vB);',
  3109. '$mod.vB = $mod.vA % $mod.vB;',
  3110. '$mod.vB = $mod.vA + ($mod.vA * $mod.vB) + rtl.trunc($mod.vA / $mod.vB);',
  3111. '$mod.vC = -$mod.vA;',
  3112. '$mod.vA = $mod.vA - $mod.vB;',
  3113. '$mod.vB = $mod.vA;',
  3114. 'if ($mod.vA < $mod.vB){ $mod.vC = $mod.vA } else $mod.vC = $mod.vB;'
  3115. ]));
  3116. end;
  3117. procedure TTestModule.TestMultiAdd;
  3118. begin
  3119. StartProgram(false);
  3120. Add([
  3121. 'function Fly: string; external name ''fly'';',
  3122. 'function TryEncodeDate(Year, Month, Day: Word): Boolean;',
  3123. 'var',
  3124. ' Date: double;',
  3125. 'begin',
  3126. ' Result:=(Year>0) and (Year<10000) and',
  3127. ' (Month >= 1) and (Month<=12) and',
  3128. ' (Day>0) and (Day<=31);',
  3129. ' Date := (146097*Year) SHR 2 + (1461*Year) SHR 2 + (153*LongWord(Month)+2) DIV 5 + LongWord(Day);',
  3130. 'end;',
  3131. 'var s: string;',
  3132. 'begin',
  3133. ' s:=''a''+''b''+''c''+''d'';',
  3134. ' s:=s+Fly+''e'';',
  3135. ' s:=Fly+Fly+Fly;',
  3136. '']);
  3137. ConvertProgram;
  3138. CheckSource('TestMultiAdd',
  3139. LinesToStr([ // statements
  3140. 'this.TryEncodeDate = function (Year, Month, Day) {',
  3141. ' var Result = false;',
  3142. ' var date = 0.0;',
  3143. ' Result = (Year > 0) && (Year < 10000) && (Month >= 1) && (Month <= 12) && (Day > 0) && (Day <= 31);',
  3144. ' date = ((146097 * Year) >>> 2) + ((1461 * Year) >>> 2) + rtl.trunc(((153 * Month) + 2) / 5) + Day;',
  3145. ' return Result;',
  3146. '};',
  3147. 'this.s = "";',
  3148. '']),
  3149. LinesToStr([ // this.$main
  3150. '$mod.s = "a" + "b" + "c" + "d";',
  3151. '$mod.s = $mod.s + fly() + "e";',
  3152. '$mod.s = fly() + fly() + fly();',
  3153. '']));
  3154. end;
  3155. procedure TTestModule.TestLogicalOperators;
  3156. begin
  3157. StartProgram(false);
  3158. Add('var');
  3159. Add(' vA,vB,vC:boolean;');
  3160. Add('begin');
  3161. Add(' va:=vb and vc;');
  3162. Add(' va:=vb or vc;');
  3163. Add(' va:=vb xor vc;');
  3164. Add(' va:=true and vc;');
  3165. Add(' va:=(vb and vc) or (va and vb);');
  3166. Add(' va:=not vb;');
  3167. ConvertProgram;
  3168. CheckSource('TestLogicalOperators',
  3169. LinesToStr([ // statements
  3170. 'this.vA = false;',
  3171. 'this.vB = false;',
  3172. 'this.vC = false;'
  3173. ]),
  3174. LinesToStr([ // this.$main
  3175. '$mod.vA = $mod.vB && $mod.vC;',
  3176. '$mod.vA = $mod.vB || $mod.vC;',
  3177. '$mod.vA = $mod.vB ^ $mod.vC;',
  3178. '$mod.vA = true && $mod.vC;',
  3179. '$mod.vA = ($mod.vB && $mod.vC) || ($mod.vA && $mod.vB);',
  3180. '$mod.vA = !$mod.vB;'
  3181. ]));
  3182. end;
  3183. procedure TTestModule.TestBitwiseOperators;
  3184. begin
  3185. StartProgram(false);
  3186. Add([
  3187. 'var',
  3188. ' vA,vB,vC:longint;',
  3189. ' X,Y,Z: nativeint;',
  3190. 'begin',
  3191. ' va:=vb and vc;',
  3192. ' va:=vb or vc;',
  3193. ' va:=vb xor vc;',
  3194. ' va:=vb shl vc;',
  3195. ' va:=vb shr vc;',
  3196. ' va:=3 and vc;',
  3197. ' va:=(vb and vc) or (va and vb);',
  3198. ' va:=not vb;',
  3199. ' X:=Y and Z;',
  3200. ' X:=Y and va;',
  3201. ' X:=Y or Z;',
  3202. ' X:=Y or va;',
  3203. ' X:=Y xor Z;',
  3204. ' X:=Y xor va;',
  3205. '']);
  3206. ConvertProgram;
  3207. CheckSource('TestBitwiseOperators',
  3208. LinesToStr([ // statements
  3209. 'this.vA = 0;',
  3210. 'this.vB = 0;',
  3211. 'this.vC = 0;',
  3212. 'this.X = 0;',
  3213. 'this.Y = 0;',
  3214. 'this.Z = 0;',
  3215. '']),
  3216. LinesToStr([ // this.$main
  3217. '$mod.vA = $mod.vB & $mod.vC;',
  3218. '$mod.vA = $mod.vB | $mod.vC;',
  3219. '$mod.vA = $mod.vB ^ $mod.vC;',
  3220. '$mod.vA = $mod.vB << $mod.vC;',
  3221. '$mod.vA = $mod.vB >>> $mod.vC;',
  3222. '$mod.vA = 3 & $mod.vC;',
  3223. '$mod.vA = ($mod.vB & $mod.vC) | ($mod.vA & $mod.vB);',
  3224. '$mod.vA = ~$mod.vB;',
  3225. '$mod.X = rtl.and($mod.Y, $mod.Z);',
  3226. '$mod.X = $mod.Y & $mod.vA;',
  3227. '$mod.X = rtl.or($mod.Y, $mod.Z);',
  3228. '$mod.X = rtl.or($mod.Y, $mod.vA);',
  3229. '$mod.X = rtl.xor($mod.Y, $mod.Z);',
  3230. '$mod.X = rtl.xor($mod.Y, $mod.vA);',
  3231. '']));
  3232. end;
  3233. procedure TTestModule.TestBitwiseOperatorsLongword;
  3234. begin
  3235. StartProgram(false);
  3236. Add([
  3237. 'var',
  3238. ' a,b,c:longword;',
  3239. ' i: longint;',
  3240. 'begin',
  3241. ' a:=$12345678;',
  3242. ' b:=$EDCBA987;',
  3243. ' c:=not a;',
  3244. ' c:=a and b;',
  3245. ' c:=a and $ffff0000;',
  3246. ' c:=a or b;',
  3247. ' c:=a or $ff00ff00;',
  3248. ' c:=a xor b;',
  3249. ' c:=a xor $f0f0f0f0;',
  3250. ' c:=a shl 1;',
  3251. ' c:=a shl 16;',
  3252. ' c:=a shl 24;',
  3253. ' c:=a shl b;',
  3254. ' c:=a shr 1;',
  3255. ' c:=a shr 16;',
  3256. ' c:=a shr 24;',
  3257. ' c:=a shr b;',
  3258. ' c:=(b and c) or (a and b);',
  3259. ' c:=i and a;',
  3260. ' c:=i or a;',
  3261. ' c:=i xor a;',
  3262. '']);
  3263. ConvertProgram;
  3264. CheckSource('TestBitwiseOperatorsLongword',
  3265. LinesToStr([ // statements
  3266. 'this.a = 0;',
  3267. 'this.b = 0;',
  3268. 'this.c = 0;',
  3269. 'this.i = 0;',
  3270. '']),
  3271. LinesToStr([ // this.$main
  3272. '$mod.a = 0x12345678;',
  3273. '$mod.b = 0xEDCBA987;',
  3274. '$mod.c = rtl.lw(~$mod.a);',
  3275. '$mod.c = rtl.lw($mod.a & $mod.b);',
  3276. '$mod.c = rtl.lw($mod.a & 0xffff0000);',
  3277. '$mod.c = rtl.lw($mod.a | $mod.b);',
  3278. '$mod.c = rtl.lw($mod.a | 0xff00ff00);',
  3279. '$mod.c = rtl.lw($mod.a ^ $mod.b);',
  3280. '$mod.c = rtl.lw($mod.a ^ 0xf0f0f0f0);',
  3281. '$mod.c = rtl.lw($mod.a << 1);',
  3282. '$mod.c = rtl.lw($mod.a << 16);',
  3283. '$mod.c = rtl.lw($mod.a << 24);',
  3284. '$mod.c = rtl.lw($mod.a << $mod.b);',
  3285. '$mod.c = rtl.lw($mod.a >>> 1);',
  3286. '$mod.c = rtl.lw($mod.a >>> 16);',
  3287. '$mod.c = rtl.lw($mod.a >>> 24);',
  3288. '$mod.c = rtl.lw($mod.a >>> $mod.b);',
  3289. '$mod.c = rtl.lw(rtl.lw($mod.b & $mod.c) | rtl.lw($mod.a & $mod.b));',
  3290. '$mod.c = $mod.i & $mod.a;',
  3291. '$mod.c = $mod.i | $mod.a;',
  3292. '$mod.c = $mod.i ^ $mod.a;',
  3293. '']));
  3294. end;
  3295. procedure TTestModule.TestPrgProcVar;
  3296. begin
  3297. StartProgram(false);
  3298. Add('procedure Proc1;');
  3299. Add('type');
  3300. Add(' t1=longint;');
  3301. Add('var');
  3302. Add(' vA:t1;');
  3303. Add('begin');
  3304. Add('end;');
  3305. Add('begin');
  3306. ConvertProgram;
  3307. CheckSource('TestPrgProcVar',
  3308. LinesToStr([ // statements
  3309. 'this.Proc1 = function () {',
  3310. ' var vA=0;',
  3311. '};'
  3312. ]),
  3313. LinesToStr([ // this.$main
  3314. ''
  3315. ]));
  3316. end;
  3317. procedure TTestModule.TestUnitProcVar;
  3318. begin
  3319. StartUnit(false);
  3320. Add('interface');
  3321. Add('');
  3322. Add('type tA=string; // unit scope');
  3323. Add('procedure Proc1;');
  3324. Add('');
  3325. Add('implementation');
  3326. Add('');
  3327. Add('procedure Proc1;');
  3328. Add('type tA=longint; // local proc scope');
  3329. Add('var v1:tA; // using local tA');
  3330. Add('begin');
  3331. Add('end;');
  3332. Add('var v2:tA; // using interface tA');
  3333. ConvertUnit;
  3334. CheckSource('TestUnitProcVar',
  3335. LinesToStr([ // statements
  3336. 'var $impl = $mod.$impl;',
  3337. 'this.Proc1 = function () {',
  3338. ' var v1 = 0;',
  3339. '};',
  3340. '']),
  3341. // this.$init
  3342. '',
  3343. // implementation
  3344. LinesToStr([
  3345. '$impl.v2 = "";',
  3346. '']));
  3347. end;
  3348. procedure TTestModule.TestImplProc;
  3349. begin
  3350. StartUnit(false);
  3351. Add('interface');
  3352. Add('');
  3353. Add('procedure Proc1;');
  3354. Add('');
  3355. Add('implementation');
  3356. Add('');
  3357. Add('procedure Proc1; begin end;');
  3358. Add('procedure Proc2; begin end;');
  3359. Add('initialization');
  3360. Add(' Proc1;');
  3361. Add(' Proc2;');
  3362. ConvertUnit;
  3363. CheckSource('TestImplProc',
  3364. LinesToStr([ // statements
  3365. 'var $impl = $mod.$impl;',
  3366. 'this.Proc1 = function () {',
  3367. '};',
  3368. '']),
  3369. LinesToStr([ // this.$init
  3370. '$mod.Proc1();',
  3371. '$impl.Proc2();',
  3372. '']),
  3373. LinesToStr([ // implementation
  3374. '$impl.Proc2 = function () {',
  3375. '};',
  3376. ''])
  3377. );
  3378. end;
  3379. procedure TTestModule.TestFunctionResult;
  3380. begin
  3381. StartProgram(false);
  3382. Add('function Func1: longint;');
  3383. Add('begin');
  3384. Add(' Result:=3;');
  3385. Add(' Func1:=4;');
  3386. Add('end;');
  3387. Add('begin');
  3388. ConvertProgram;
  3389. CheckSource('TestFunctionResult',
  3390. LinesToStr([ // statements
  3391. 'this.Func1 = function () {',
  3392. ' var Result = 0;',
  3393. ' Result = 3;',
  3394. ' Result = 4;',
  3395. ' return Result;',
  3396. '};'
  3397. ]),
  3398. '');
  3399. end;
  3400. procedure TTestModule.TestNestedProc;
  3401. begin
  3402. StartProgram(false);
  3403. Add([
  3404. 'var vInUnit: longint;',
  3405. 'function DoIt(pA,pD: longint): longint;',
  3406. 'var',
  3407. ' vB: longint;',
  3408. ' vC: longint;',
  3409. ' function Nesty(pA: longint): longint; ',
  3410. ' var vB: longint;',
  3411. ' begin',
  3412. ' Result:=pa+vb+vc+pd+vInUnit;',
  3413. ' nesty:=3;',
  3414. ' doit:=4;',
  3415. ' exit;',
  3416. ' end;',
  3417. 'begin',
  3418. ' Result:=pa+vb+vc;',
  3419. ' doit:=6;',
  3420. ' exit;',
  3421. 'end;',
  3422. 'begin']);
  3423. ConvertProgram;
  3424. CheckSource('TestNestedProc',
  3425. LinesToStr([ // statements
  3426. 'this.vInUnit = 0;',
  3427. 'this.DoIt = function (pA, pD) {',
  3428. ' var Result = 0;',
  3429. ' var vB = 0;',
  3430. ' var vC = 0;',
  3431. ' function Nesty(pA) {',
  3432. ' var Result$1 = 0;',
  3433. ' var vB = 0;',
  3434. ' Result$1 = pA + vB + vC + pD + $mod.vInUnit;',
  3435. ' Result$1 = 3;',
  3436. ' Result = 4;',
  3437. ' return Result$1;',
  3438. ' return Result$1;',
  3439. ' };',
  3440. ' Result = pA + vB + vC;',
  3441. ' Result = 6;',
  3442. ' return Result;',
  3443. ' return Result;',
  3444. '};'
  3445. ]),
  3446. '');
  3447. end;
  3448. procedure TTestModule.TestNestedProc_ResultString;
  3449. begin
  3450. StartProgram(false);
  3451. Add([
  3452. 'function DoIt: string;',
  3453. ' function Nesty: string; ',
  3454. ' begin',
  3455. ' nesty:=#65#66;',
  3456. ' nesty[1]:=#67;',
  3457. ' doit:=#68;',
  3458. ' doit[2]:=#69;',
  3459. ' end;',
  3460. 'begin',
  3461. ' doit:=#70;',
  3462. ' doit[3]:=#71;',
  3463. 'end;',
  3464. 'begin']);
  3465. ConvertProgram;
  3466. CheckSource('TestNestedProc_ResultString',
  3467. LinesToStr([ // statements
  3468. 'this.DoIt = function () {',
  3469. ' var Result = "";',
  3470. ' function Nesty() {',
  3471. ' var Result$1 = "";',
  3472. ' Result$1 = "AB";',
  3473. ' Result$1 = rtl.setCharAt(Result$1, 0, "C");',
  3474. ' Result = "D";',
  3475. ' Result = rtl.setCharAt(Result, 1, "E");',
  3476. ' return Result$1;',
  3477. ' };',
  3478. ' Result = "F";',
  3479. ' Result = rtl.setCharAt(Result, 2, "G");',
  3480. ' return Result;',
  3481. '};'
  3482. ]),
  3483. '');
  3484. end;
  3485. procedure TTestModule.TestForwardProc;
  3486. begin
  3487. StartProgram(false);
  3488. Add('procedure FuncA(Bar: longint); forward;');
  3489. Add('procedure FuncB(Bar: longint);');
  3490. Add('begin');
  3491. Add(' funca(bar);');
  3492. Add('end;');
  3493. Add('procedure funca(bar: longint);');
  3494. Add('begin');
  3495. Add(' if bar=3 then ;');
  3496. Add('end;');
  3497. Add('begin');
  3498. Add(' funca(4);');
  3499. Add(' funcb(5);');
  3500. ConvertProgram;
  3501. CheckSource('TestForwardProc',
  3502. LinesToStr([ // statements'
  3503. 'this.FuncB = function (Bar) {',
  3504. ' $mod.FuncA(Bar);',
  3505. '};',
  3506. 'this.FuncA = function (Bar) {',
  3507. ' if (Bar === 3);',
  3508. '};'
  3509. ]),
  3510. LinesToStr([
  3511. '$mod.FuncA(4);',
  3512. '$mod.FuncB(5);'
  3513. ])
  3514. );
  3515. end;
  3516. procedure TTestModule.TestNestedForwardProc;
  3517. begin
  3518. StartProgram(false);
  3519. Add('procedure FuncA;');
  3520. Add(' procedure FuncB(i: longint); forward;');
  3521. Add(' procedure FuncC(i: longint);');
  3522. Add(' begin');
  3523. Add(' funcb(i);');
  3524. Add(' end;');
  3525. Add(' procedure FuncB(i: longint);');
  3526. Add(' begin');
  3527. Add(' if i=3 then ;');
  3528. Add(' end;');
  3529. Add('begin');
  3530. Add(' funcc(4)');
  3531. Add('end;');
  3532. Add('begin');
  3533. Add(' funca;');
  3534. ConvertProgram;
  3535. CheckSource('TestNestedForwardProc',
  3536. LinesToStr([ // statements'
  3537. 'this.FuncA = function () {',
  3538. ' function FuncC(i) {',
  3539. ' FuncB(i);',
  3540. ' };',
  3541. ' function FuncB(i) {',
  3542. ' if (i === 3);',
  3543. ' };',
  3544. ' FuncC(4);',
  3545. '};'
  3546. ]),
  3547. LinesToStr([
  3548. '$mod.FuncA();'
  3549. ])
  3550. );
  3551. end;
  3552. procedure TTestModule.TestAssignFunctionResult;
  3553. begin
  3554. StartProgram(false);
  3555. Add('function Func1: longint;');
  3556. Add('begin');
  3557. Add('end;');
  3558. Add('var i: longint;');
  3559. Add('begin');
  3560. Add(' i:=func1();');
  3561. Add(' i:=func1()+func1();');
  3562. ConvertProgram;
  3563. CheckSource('TestAssignFunctionResult',
  3564. LinesToStr([ // statements
  3565. 'this.Func1 = function () {',
  3566. ' var Result = 0;',
  3567. ' return Result;',
  3568. '};',
  3569. 'this.i = 0;'
  3570. ]),
  3571. LinesToStr([
  3572. '$mod.i = $mod.Func1();',
  3573. '$mod.i = $mod.Func1() + $mod.Func1();'
  3574. ]));
  3575. end;
  3576. procedure TTestModule.TestFunctionResultInCondition;
  3577. begin
  3578. StartProgram(false);
  3579. Add('function Func1: longint;');
  3580. Add('begin');
  3581. Add('end;');
  3582. Add('function Func2: boolean;');
  3583. Add('begin');
  3584. Add('end;');
  3585. Add('var i: longint;');
  3586. Add('begin');
  3587. Add(' if func2 then ;');
  3588. Add(' if i=func1() then ;');
  3589. Add(' if i=func1 then ;');
  3590. ConvertProgram;
  3591. CheckSource('TestFunctionResultInCondition',
  3592. LinesToStr([ // statements
  3593. 'this.Func1 = function () {',
  3594. ' var Result = 0;',
  3595. ' return Result;',
  3596. '};',
  3597. 'this.Func2 = function () {',
  3598. ' var Result = false;',
  3599. ' return Result;',
  3600. '};',
  3601. 'this.i = 0;'
  3602. ]),
  3603. LinesToStr([
  3604. 'if ($mod.Func2());',
  3605. 'if ($mod.i === $mod.Func1());',
  3606. 'if ($mod.i === $mod.Func1());'
  3607. ]));
  3608. end;
  3609. procedure TTestModule.TestFunctionResultInForLoop;
  3610. begin
  3611. StartProgram(false);
  3612. Add([
  3613. 'function Func1(a: array of longint): longint;',
  3614. 'begin',
  3615. ' for Result:=High(a) downto Low(a) do if a[Result]=0 then exit;',
  3616. ' for Result in a do if a[Result]=0 then exit;',
  3617. 'end;',
  3618. 'begin',
  3619. ' Func1([1,2,3])']);
  3620. ConvertProgram;
  3621. CheckSource('TestFunctionResultInForLoop',
  3622. LinesToStr([ // statements
  3623. 'this.Func1 = function (a) {',
  3624. ' var Result = 0;',
  3625. ' for (var $l = rtl.length(a) - 1; $l >= 0; $l--) {',
  3626. ' Result = $l;',
  3627. ' if (a[Result] === 0) return Result;',
  3628. ' };',
  3629. ' for (var $in = a, $l1 = 0, $end = rtl.length($in) - 1; $l1 <= $end; $l1++) {',
  3630. ' Result = $in[$l1];',
  3631. ' if (a[Result] === 0) return Result;',
  3632. ' };',
  3633. ' return Result;',
  3634. '};',
  3635. '']),
  3636. LinesToStr([
  3637. '$mod.Func1([1, 2, 3]);'
  3638. ]));
  3639. end;
  3640. procedure TTestModule.TestFunctionResultInTypeCast;
  3641. begin
  3642. StartProgram(false);
  3643. Add([
  3644. 'function GetInt: longint;',
  3645. 'begin',
  3646. 'end;',
  3647. 'begin',
  3648. ' if Byte(GetInt)=0 then ;',
  3649. '']);
  3650. ConvertProgram;
  3651. CheckSource('TestFunctionResultInTypeCast',
  3652. LinesToStr([ // statements
  3653. 'this.GetInt = function () {',
  3654. ' var Result = 0;',
  3655. ' return Result;',
  3656. '};',
  3657. '']),
  3658. LinesToStr([
  3659. 'if (($mod.GetInt() & 255) === 0) ;'
  3660. ]));
  3661. end;
  3662. procedure TTestModule.TestExit;
  3663. begin
  3664. StartProgram(false);
  3665. Add('procedure ProcA;');
  3666. Add('begin');
  3667. Add(' exit;');
  3668. Add('end;');
  3669. Add('function FuncB: longint;');
  3670. Add('begin');
  3671. Add(' exit;');
  3672. Add(' exit(3);');
  3673. Add('end;');
  3674. Add('function FuncC: string;');
  3675. Add('begin');
  3676. Add(' exit;');
  3677. Add(' exit(''a'');');
  3678. Add(' exit(''abc'');');
  3679. Add('end;');
  3680. Add('begin');
  3681. Add(' exit;');
  3682. Add(' exit(1);');
  3683. ConvertProgram;
  3684. CheckSource('TestExit',
  3685. LinesToStr([ // statements
  3686. 'this.ProcA = function () {',
  3687. ' return;',
  3688. '};',
  3689. 'this.FuncB = function () {',
  3690. ' var Result = 0;',
  3691. ' return Result;',
  3692. ' return 3;',
  3693. ' return Result;',
  3694. '};',
  3695. 'this.FuncC = function () {',
  3696. ' var Result = "";',
  3697. ' return Result;',
  3698. ' return "a";',
  3699. ' return "abc";',
  3700. ' return Result;',
  3701. '};'
  3702. ]),
  3703. LinesToStr([
  3704. 'return;',
  3705. 'return 1;',
  3706. '']));
  3707. end;
  3708. procedure TTestModule.TestExit_ResultInFinally;
  3709. begin
  3710. StartProgram(false);
  3711. Add([
  3712. 'function Run: word;',
  3713. 'begin',
  3714. ' try',
  3715. ' exit(3);', // no Result in finally -> use return 3
  3716. ' finally',
  3717. ' end;',
  3718. 'end;',
  3719. 'function Fly: word;',
  3720. 'begin',
  3721. ' try',
  3722. ' exit(3);',
  3723. ' finally',
  3724. ' if Result>0 then ;',
  3725. ' end;',
  3726. 'end;',
  3727. 'function Jump: word;',
  3728. 'begin',
  3729. ' try',
  3730. ' try',
  3731. ' exit(4);',
  3732. ' finally',
  3733. ' end;',
  3734. ' finally',
  3735. ' if Result>0 then ;',
  3736. ' end;',
  3737. 'end;',
  3738. 'begin',
  3739. '']);
  3740. ConvertProgram;
  3741. CheckSource('TestExit_ResultInFinally',
  3742. LinesToStr([ // statements
  3743. 'this.Run = function () {',
  3744. ' var Result = 0;',
  3745. ' try {',
  3746. ' return 3;',
  3747. ' } finally {',
  3748. ' };',
  3749. ' return Result;',
  3750. '};',
  3751. 'this.Fly = function () {',
  3752. ' var Result = 0;',
  3753. ' try {',
  3754. ' Result = 3;',
  3755. ' return Result;',
  3756. ' } finally {',
  3757. ' if (Result > 0) ;',
  3758. ' };',
  3759. ' return Result;',
  3760. '};',
  3761. 'this.Jump = function () {',
  3762. ' var Result = 0;',
  3763. ' try {',
  3764. ' try {',
  3765. ' Result = 4;',
  3766. ' return Result;',
  3767. ' } finally {',
  3768. ' };',
  3769. ' } finally {',
  3770. ' if (Result > 0) ;',
  3771. ' };',
  3772. ' return Result;',
  3773. '};',
  3774. '']),
  3775. LinesToStr([
  3776. '']));
  3777. end;
  3778. procedure TTestModule.TestBreak;
  3779. begin
  3780. StartProgram(false);
  3781. Add([
  3782. 'var',
  3783. ' i: longint;',
  3784. 'begin',
  3785. ' repeat',
  3786. ' break;',
  3787. ' until true;',
  3788. ' while true do',
  3789. ' break;',
  3790. ' for i:=1 to 2 do',
  3791. ' break;']);
  3792. ConvertProgram;
  3793. CheckSource('TestBreak',
  3794. LinesToStr([ // statements
  3795. 'this.i = 0;'
  3796. ]),
  3797. LinesToStr([
  3798. 'do {',
  3799. ' break;',
  3800. '} while (!true);',
  3801. 'while (true) break;',
  3802. 'for ($mod.i = 1; $mod.i <= 2; $mod.i++) break;',
  3803. '']));
  3804. end;
  3805. procedure TTestModule.TestBreakAsVar;
  3806. begin
  3807. StartProgram(false);
  3808. Add([
  3809. 'procedure DoIt(break: boolean);',
  3810. 'begin',
  3811. ' if break then ;',
  3812. 'end;',
  3813. 'var',
  3814. ' break: boolean;',
  3815. 'begin',
  3816. ' if break then ;']);
  3817. ConvertProgram;
  3818. CheckSource('TestBreakAsVar',
  3819. LinesToStr([ // statements
  3820. 'this.DoIt = function (Break) {',
  3821. ' if (Break) ;',
  3822. '};',
  3823. 'this.Break = false;',
  3824. '']),
  3825. LinesToStr([
  3826. 'if($mod.Break) ;',
  3827. '']));
  3828. end;
  3829. procedure TTestModule.TestContinue;
  3830. begin
  3831. StartProgram(false);
  3832. Add('var i: longint;');
  3833. Add('begin');
  3834. Add(' repeat');
  3835. Add(' continue;');
  3836. Add(' until true;');
  3837. Add(' while true do');
  3838. Add(' continue;');
  3839. Add(' for i:=1 to 2 do');
  3840. Add(' continue;');
  3841. ConvertProgram;
  3842. CheckSource('TestContinue',
  3843. LinesToStr([ // statements
  3844. 'this.i = 0;'
  3845. ]),
  3846. LinesToStr([
  3847. 'do {',
  3848. ' continue;',
  3849. '} while (!true);',
  3850. 'while (true) continue;',
  3851. 'for ($mod.i = 1; $mod.i <= 2; $mod.i++) continue;',
  3852. '']));
  3853. end;
  3854. procedure TTestModule.TestProc_External;
  3855. begin
  3856. StartProgram(false);
  3857. Add('procedure Foo; external name ''console.log'';');
  3858. Add('function Bar: longint; external name ''get.item'';');
  3859. Add('function Bla(s: string): longint; external name ''apply.something'';');
  3860. Add('var');
  3861. Add(' i: longint;');
  3862. Add('begin');
  3863. Add(' Foo;');
  3864. Add(' i:=Bar;');
  3865. Add(' i:=Bla(''abc'');');
  3866. ConvertProgram;
  3867. CheckSource('TestProc_External',
  3868. LinesToStr([ // statements
  3869. 'this.i = 0;'
  3870. ]),
  3871. LinesToStr([
  3872. 'console.log();',
  3873. '$mod.i = get.item();',
  3874. '$mod.i = apply.something("abc");'
  3875. ]));
  3876. end;
  3877. procedure TTestModule.TestProc_ExternalOtherUnit;
  3878. begin
  3879. AddModuleWithIntfImplSrc('unit2.pas',
  3880. LinesToStr([
  3881. 'procedure Now; external name ''Date.now'';',
  3882. 'procedure DoIt;'
  3883. ]),
  3884. 'procedure doit; begin end;');
  3885. StartUnit(true);
  3886. Add('interface');
  3887. Add('uses unit2;');
  3888. Add('implementation');
  3889. Add('begin');
  3890. Add(' now;');
  3891. Add(' now();');
  3892. Add(' uNit2.now;');
  3893. Add(' uNit2.now();');
  3894. Add(' doit;');
  3895. Add(' uNit2.doit;');
  3896. ConvertUnit;
  3897. CheckSource('TestProc_ExternalOtherUnit',
  3898. LinesToStr([
  3899. '']),
  3900. LinesToStr([
  3901. 'Date.now();',
  3902. 'Date.now();',
  3903. 'Date.now();',
  3904. 'Date.now();',
  3905. 'pas.unit2.DoIt();',
  3906. 'pas.unit2.DoIt();',
  3907. '']));
  3908. end;
  3909. procedure TTestModule.TestProc_Asm;
  3910. begin
  3911. StartProgram(false);
  3912. Add([
  3913. '{$mode delphi}',
  3914. 'function DoIt: longint;',
  3915. 'begin;',
  3916. ' asm',
  3917. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3918. ' end;',
  3919. ' asm console.log(); end;',
  3920. ' asm',
  3921. ' s = "'' ";',
  3922. ' s = ''" '';',
  3923. ' s = s + "world" + "''";',
  3924. ' // end',
  3925. ' s = ''end'';',
  3926. ' s = "end";',
  3927. ' s = "foo\"bar";',
  3928. ' s = ''a\''b'';',
  3929. ' s = `${expr}\`-"-''-`;',
  3930. ' s = `multi',
  3931. 'line`;',
  3932. ' end;',
  3933. 'end;',
  3934. 'procedure Fly;',
  3935. 'asm',
  3936. ' return;',
  3937. 'end;',
  3938. 'begin']);
  3939. ConvertProgram;
  3940. CheckSource('TestProc_Asm',
  3941. LinesToStr([ // statements
  3942. 'this.DoIt = function () {',
  3943. ' var Result = 0;',
  3944. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3945. ' console.log();',
  3946. ' s = "'' ";',
  3947. ' s = ''" '';',
  3948. ' s = s + "world" + "''";',
  3949. ' // end',
  3950. ' s = ''end'';',
  3951. ' s = "end";',
  3952. ' s = "foo\"bar";',
  3953. ' s = ''a\''b'';',
  3954. ' s = `${expr}\`-"-''-`;',
  3955. ' s = `multi',
  3956. 'line`;',
  3957. ' return Result;',
  3958. '};',
  3959. 'this.Fly = function () {',
  3960. ' return;',
  3961. '};',
  3962. '']),
  3963. LinesToStr([
  3964. ''
  3965. ]));
  3966. end;
  3967. procedure TTestModule.TestProc_AsmSubBlock;
  3968. begin
  3969. StartProgram(true,[supTObject]);
  3970. Add([
  3971. '{$mode delphi}',
  3972. 'type',
  3973. ' TBird = class end;',
  3974. 'procedure Run(w: word);',
  3975. 'begin;',
  3976. ' if true then asm console.log(); end;',
  3977. ' if w>3 then asm',
  3978. ' var a = w+1;',
  3979. ' w = a+3;',
  3980. ' end;',
  3981. ' while (w>7) do asm',
  3982. ' w+=3; w*=2;',
  3983. ' end;',
  3984. ' try',
  3985. ' except',
  3986. ' on E: TBird do',
  3987. ' asm console.log(E); end;',
  3988. ' on E: TObject do',
  3989. ' asm var i=3; i--; end;',
  3990. ' else asm Fly; High; end;',
  3991. ' end;',
  3992. 'end;',
  3993. 'begin']);
  3994. ConvertProgram;
  3995. CheckSource('TestProc_AsmSubBlock',
  3996. LinesToStr([ // statements
  3997. 'rtl.createClass(this, "TBird", pas.system.TObject, function () {',
  3998. '});',
  3999. 'this.Run = function (w) {',
  4000. ' if (true) console.log();',
  4001. ' if (w > 3) {',
  4002. ' var a = w+1;',
  4003. ' w = a+3;',
  4004. ' };',
  4005. ' while (w > 7) {',
  4006. ' w+=3; w*=2;',
  4007. ' };',
  4008. ' try {} catch ($e) {',
  4009. ' if ($mod.TBird.isPrototypeOf($e)) {',
  4010. ' var E = $e;',
  4011. ' console.log(E);',
  4012. ' } else if (pas.system.TObject.isPrototypeOf($e)) {',
  4013. ' var E = $e;',
  4014. ' var i=3; i--;',
  4015. ' } else {',
  4016. ' Fly; High;',
  4017. ' }',
  4018. ' };',
  4019. '};',
  4020. '']),
  4021. LinesToStr([
  4022. ''
  4023. ]));
  4024. end;
  4025. procedure TTestModule.TestProc_Assembler;
  4026. begin
  4027. StartProgram(false);
  4028. Add('function DoIt: longint; assembler;');
  4029. Add('asm');
  4030. Add('{ a:{ b:{}, c:[]}, d:''1'' };');
  4031. Add('end;');
  4032. Add('begin');
  4033. ConvertProgram;
  4034. CheckSource('TestProc_Assembler',
  4035. LinesToStr([ // statements
  4036. 'this.DoIt = function () {',
  4037. ' { a:{ b:{}, c:[]}, d:''1'' };',
  4038. '};'
  4039. ]),
  4040. LinesToStr([
  4041. ''
  4042. ]));
  4043. end;
  4044. procedure TTestModule.TestProc_VarParam;
  4045. begin
  4046. StartProgram(false);
  4047. Add('type integer = longint;');
  4048. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  4049. Add('var vJ: integer;');
  4050. Add('begin');
  4051. Add(' vg:=vg+1;');
  4052. Add(' vj:=vh+2;');
  4053. Add(' vi:=vi+3;');
  4054. Add(' doit(vg,vg,vg);');
  4055. Add(' doit(vh,vh,vj);');
  4056. Add(' doit(vi,vi,vi);');
  4057. Add(' doit(vj,vj,vj);');
  4058. Add('end;');
  4059. Add('var i: integer;');
  4060. Add('begin');
  4061. Add(' doit(i,i,i);');
  4062. ConvertProgram;
  4063. CheckSource('TestProc_VarParam',
  4064. LinesToStr([ // statements
  4065. 'this.DoIt = function (vG,vH,vI) {',
  4066. ' var vJ = 0;',
  4067. ' vG = vG + 1;',
  4068. ' vJ = vH + 2;',
  4069. ' vI.set(vI.get()+3);',
  4070. ' $mod.DoIt(vG, vG, {',
  4071. ' get: function () {',
  4072. ' return vG;',
  4073. ' },',
  4074. ' set: function (v) {',
  4075. ' vG = v;',
  4076. ' }',
  4077. ' });',
  4078. ' $mod.DoIt(vH, vH, {',
  4079. ' get: function () {',
  4080. ' return vJ;',
  4081. ' },',
  4082. ' set: function (v) {',
  4083. ' vJ = v;',
  4084. ' }',
  4085. ' });',
  4086. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  4087. ' $mod.DoIt(vJ, vJ, {',
  4088. ' get: function () {',
  4089. ' return vJ;',
  4090. ' },',
  4091. ' set: function (v) {',
  4092. ' vJ = v;',
  4093. ' }',
  4094. ' });',
  4095. '};',
  4096. 'this.i = 0;'
  4097. ]),
  4098. LinesToStr([
  4099. '$mod.DoIt($mod.i,$mod.i,{',
  4100. ' p: $mod,',
  4101. ' get: function () {',
  4102. ' return this.p.i;',
  4103. ' },',
  4104. ' set: function (v) {',
  4105. ' this.p.i = v;',
  4106. ' }',
  4107. '});'
  4108. ]));
  4109. end;
  4110. procedure TTestModule.TestProc_VarParamString;
  4111. begin
  4112. StartProgram(false);
  4113. Add(['type TCaption = string;',
  4114. 'procedure DoIt(vA: TCaption; var vB: TCaption; out vC: TCaption);',
  4115. 'var c: char;',
  4116. 'begin',
  4117. ' va[1]:=c;',
  4118. ' vb[2]:=c;',
  4119. ' vc[3]:=c;',
  4120. 'end;',
  4121. 'begin']);
  4122. ConvertProgram;
  4123. CheckSource('TestProc_VarParamString',
  4124. LinesToStr([ // statements
  4125. 'this.DoIt = function (vA,vB,vC) {',
  4126. ' var c = "";',
  4127. ' vA = rtl.setCharAt(vA, 0, c);',
  4128. ' vB.set(rtl.setCharAt(vB.get(), 1, c));',
  4129. ' vC.set(rtl.setCharAt(vC.get(), 2, c));',
  4130. '};',
  4131. '']),
  4132. LinesToStr([
  4133. ]));
  4134. end;
  4135. procedure TTestModule.TestProc_VarParamV;
  4136. begin
  4137. StartProgram(false);
  4138. Add([
  4139. 'procedure Inc2(var i: longint);',
  4140. 'begin',
  4141. ' i:=i+2;',
  4142. 'end;',
  4143. 'procedure DoIt(v: longint);',
  4144. 'var p: array of longint;',
  4145. 'begin',
  4146. ' Inc2(v);',
  4147. ' Inc2(p[v]);',
  4148. 'end;',
  4149. 'begin']);
  4150. ConvertProgram;
  4151. CheckSource('TestProc_VarParamV',
  4152. LinesToStr([ // statements
  4153. 'this.Inc2 = function (i) {',
  4154. ' i.set(i.get()+2);',
  4155. '};',
  4156. 'this.DoIt = function (v) {',
  4157. ' var p = [];',
  4158. ' $mod.Inc2({get: function () {',
  4159. ' return v;',
  4160. ' }, set: function (w) {',
  4161. ' v = w;',
  4162. ' }});',
  4163. ' $mod.Inc2({',
  4164. ' a: v,',
  4165. ' p: p,',
  4166. ' get: function () {',
  4167. ' return this.p[this.a];',
  4168. ' },',
  4169. ' set: function (v) {',
  4170. ' this.p[this.a] = v;',
  4171. ' }',
  4172. ' });',
  4173. '};',
  4174. '']),
  4175. LinesToStr([
  4176. '']));
  4177. end;
  4178. procedure TTestModule.TestProc_Overload;
  4179. begin
  4180. StartProgram(false);
  4181. Add('procedure DoIt(vI: longint); begin end;');
  4182. Add('procedure DoIt(vI, vJ: longint); begin end;');
  4183. Add('procedure DoIt(vD: double); begin end;');
  4184. Add('begin');
  4185. Add(' DoIt(1);');
  4186. Add(' DoIt(2,3);');
  4187. Add(' DoIt(4.5);');
  4188. ConvertProgram;
  4189. CheckSource('TestProcedureOverload',
  4190. LinesToStr([ // statements
  4191. 'this.DoIt = function (vI) {',
  4192. '};',
  4193. 'this.DoIt$1 = function (vI, vJ) {',
  4194. '};',
  4195. 'this.DoIt$2 = function (vD) {',
  4196. '};',
  4197. '']),
  4198. LinesToStr([
  4199. '$mod.DoIt(1);',
  4200. '$mod.DoIt$1(2, 3);',
  4201. '$mod.DoIt$2(4.5);',
  4202. '']));
  4203. end;
  4204. procedure TTestModule.TestProc_OverloadForward;
  4205. begin
  4206. StartProgram(false);
  4207. Add('procedure DoIt(vI: longint); forward;');
  4208. Add('procedure DoIt(vI, vJ: longint); begin end;');
  4209. Add('procedure doit(vi: longint); begin end;');
  4210. Add('begin');
  4211. Add(' doit(1);');
  4212. Add(' doit(2,3);');
  4213. ConvertProgram;
  4214. CheckSource('TestProcedureOverloadForward',
  4215. LinesToStr([ // statements
  4216. 'this.DoIt$1 = function (vI, vJ) {',
  4217. '};',
  4218. 'this.DoIt = function (vI) {',
  4219. '};',
  4220. '']),
  4221. LinesToStr([
  4222. '$mod.DoIt(1);',
  4223. '$mod.DoIt$1(2, 3);',
  4224. '']));
  4225. end;
  4226. procedure TTestModule.TestProc_OverloadIntfImpl;
  4227. begin
  4228. StartUnit(false);
  4229. Add('interface');
  4230. Add('procedure DoIt(vI: longint);');
  4231. Add('procedure DoIt(vI, vJ: longint);');
  4232. Add('implementation');
  4233. Add('procedure DoIt(vI, vJ, vK, vL, vM: longint); forward;');
  4234. Add('procedure DoIt(vI, vJ, vK: longint); begin end;');
  4235. Add('procedure DoIt(vi: longint); begin end;');
  4236. Add('procedure DoIt(vI, vJ, vK, vL: longint); begin end;');
  4237. Add('procedure DoIt(vi, vj: longint); begin end;');
  4238. Add('procedure DoIt(vi, vj, vk, vl, vm: longint); begin end;');
  4239. Add('begin');
  4240. Add(' doit(1);');
  4241. Add(' doit(2,3);');
  4242. Add(' doit(4,5,6);');
  4243. Add(' doit(7,8,9,10);');
  4244. Add(' doit(11,12,13,14,15);');
  4245. ConvertUnit;
  4246. CheckSource('TestProcedureOverloadUnit',
  4247. LinesToStr([ // statements
  4248. 'var $impl = $mod.$impl;',
  4249. 'this.DoIt = function (vI) {',
  4250. '};',
  4251. 'this.DoIt$1 = function (vI, vJ) {',
  4252. '};',
  4253. '']),
  4254. LinesToStr([ // this.$init
  4255. '$mod.DoIt(1);',
  4256. '$mod.DoIt$1(2, 3);',
  4257. '$impl.DoIt$3(4,5,6);',
  4258. '$impl.DoIt$4(7,8,9,10);',
  4259. '$impl.DoIt$2(11,12,13,14,15);',
  4260. '']),
  4261. LinesToStr([ // implementation
  4262. '$impl.DoIt$3 = function (vI, vJ, vK) {',
  4263. '};',
  4264. '$impl.DoIt$4 = function (vI, vJ, vK, vL) {',
  4265. '};',
  4266. '$impl.DoIt$2 = function (vI, vJ, vK, vL, vM) {',
  4267. '};',
  4268. '']));
  4269. end;
  4270. procedure TTestModule.TestProc_OverloadNested;
  4271. begin
  4272. StartProgram(false);
  4273. Add([
  4274. 'procedure doit(vA: longint);',
  4275. ' procedure DoIt(vA, vB: longint); overload;',
  4276. ' begin',
  4277. ' doit(1);',
  4278. ' doit(1,2);',
  4279. ' end;',
  4280. ' procedure doit(vA, vB, vC: longint);',
  4281. ' begin',
  4282. ' doit(1);',
  4283. ' doit(1,2);',
  4284. ' doit(1,2,3);',
  4285. ' end;',
  4286. 'begin',
  4287. ' doit(1);',
  4288. ' doit(1,2);',
  4289. ' doit(1,2,3);',
  4290. 'end;',
  4291. 'begin // main',
  4292. ' doit(1);']);
  4293. ConvertProgram;
  4294. CheckSource('TestProcedureOverloadNested',
  4295. LinesToStr([ // statements
  4296. 'this.doit = function (vA) {',
  4297. ' function DoIt$1(vA, vB) {',
  4298. ' $mod.doit(1);',
  4299. ' DoIt$1(1, 2);',
  4300. ' };',
  4301. ' function doit$2(vA, vB, vC) {',
  4302. ' $mod.doit(1);',
  4303. ' DoIt$1(1, 2);',
  4304. ' doit$2(1, 2, 3);',
  4305. ' };',
  4306. ' $mod.doit(1);',
  4307. ' DoIt$1(1, 2);',
  4308. ' doit$2(1, 2, 3);',
  4309. '};',
  4310. '']),
  4311. LinesToStr([
  4312. '$mod.doit(1);',
  4313. '']));
  4314. end;
  4315. procedure TTestModule.TestProc_OverloadNestedForward;
  4316. begin
  4317. StartProgram(false);
  4318. Add([
  4319. 'procedure DoIt(vA: longint); overload; forward;',
  4320. 'procedure DoIt(vB, vC: longint); overload;',
  4321. 'begin // 2 param overload',
  4322. ' doit(1);',
  4323. ' doit(1,2);',
  4324. 'end;',
  4325. 'procedure doit(vA: longint);',
  4326. ' procedure DoIt(vA, vB, vC: longint); overload; forward;',
  4327. ' procedure DoIt(vA, vB, vC, vD: longint); overload;',
  4328. ' begin // 4 param overload',
  4329. ' doit(1);',
  4330. ' doit(1,2);',
  4331. ' doit(1,2,3);',
  4332. ' doit(1,2,3,4);',
  4333. ' end;',
  4334. ' procedure doit(vA, vB, vC: longint);',
  4335. ' procedure DoIt(vA, vB, vC, vD, vE: longint); overload; forward;',
  4336. ' procedure DoIt(vA, vB, vC, vD, vE, vF: longint); overload;',
  4337. ' begin // 6 param overload',
  4338. ' doit(1);',
  4339. ' doit(1,2);',
  4340. ' doit(1,2,3);',
  4341. ' doit(1,2,3,4);',
  4342. ' doit(1,2,3,4,5);',
  4343. ' doit(1,2,3,4,5,6);',
  4344. ' end;',
  4345. ' procedure doit(vA, vB, vC, vD, vE: longint);',
  4346. ' begin // 5 param overload',
  4347. ' doit(1);',
  4348. ' doit(1,2);',
  4349. ' doit(1,2,3);',
  4350. ' doit(1,2,3,4);',
  4351. ' doit(1,2,3,4,5);',
  4352. ' doit(1,2,3,4,5,6);',
  4353. ' end;',
  4354. ' begin // 3 param overload',
  4355. ' doit(1);',
  4356. ' doit(1,2);',
  4357. ' doit(1,2,3);',
  4358. ' doit(1,2,3,4);',
  4359. ' doit(1,2,3,4,5);',
  4360. ' doit(1,2,3,4,5,6);',
  4361. ' end;',
  4362. 'begin // 1 param overload',
  4363. ' doit(1);',
  4364. ' doit(1,2);',
  4365. ' doit(1,2,3);',
  4366. ' doit(1,2,3,4);',
  4367. 'end;',
  4368. 'begin // main',
  4369. ' doit(1);',
  4370. ' doit(1,2);']);
  4371. ConvertProgram;
  4372. CheckSource('TestProc_OverloadNestedForward',
  4373. LinesToStr([ // statements
  4374. 'this.DoIt$1 = function (vB, vC) {',
  4375. ' $mod.DoIt(1);',
  4376. ' $mod.DoIt$1(1, 2);',
  4377. '};',
  4378. 'this.DoIt = function (vA) {',
  4379. ' function DoIt$3(vA, vB, vC, vD) {',
  4380. ' $mod.DoIt(1);',
  4381. ' $mod.DoIt$1(1, 2);',
  4382. ' DoIt$2(1, 2, 3);',
  4383. ' DoIt$3(1, 2, 3, 4);',
  4384. ' };',
  4385. ' function DoIt$2(vA, vB, vC) {',
  4386. ' function DoIt$5(vA, vB, vC, vD, vE, vF) {',
  4387. ' $mod.DoIt(1);',
  4388. ' $mod.DoIt$1(1, 2);',
  4389. ' DoIt$2(1, 2, 3);',
  4390. ' DoIt$3(1, 2, 3, 4);',
  4391. ' DoIt$4(1, 2, 3, 4, 5);',
  4392. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  4393. ' };',
  4394. ' function DoIt$4(vA, vB, vC, vD, vE) {',
  4395. ' $mod.DoIt(1);',
  4396. ' $mod.DoIt$1(1, 2);',
  4397. ' DoIt$2(1, 2, 3);',
  4398. ' DoIt$3(1, 2, 3, 4);',
  4399. ' DoIt$4(1, 2, 3, 4, 5);',
  4400. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  4401. ' };',
  4402. ' $mod.DoIt(1);',
  4403. ' $mod.DoIt$1(1, 2);',
  4404. ' DoIt$2(1, 2, 3);',
  4405. ' DoIt$3(1, 2, 3, 4);',
  4406. ' DoIt$4(1, 2, 3, 4, 5);',
  4407. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  4408. ' };',
  4409. ' $mod.DoIt(1);',
  4410. ' $mod.DoIt$1(1, 2);',
  4411. ' DoIt$2(1, 2, 3);',
  4412. ' DoIt$3(1, 2, 3, 4);',
  4413. '};',
  4414. '']),
  4415. LinesToStr([
  4416. '$mod.DoIt(1);',
  4417. '$mod.DoIt$1(1, 2);',
  4418. '']));
  4419. end;
  4420. procedure TTestModule.TestProc_OverloadUnitCycle;
  4421. begin
  4422. AddModuleWithIntfImplSrc('Unit2.pas',
  4423. LinesToStr([
  4424. 'type',
  4425. ' TObject = class',
  4426. ' procedure DoIt(b: boolean); virtual; abstract;',
  4427. ' procedure DoIt(i: longint); virtual; abstract;',
  4428. ' end;',
  4429. '']),
  4430. 'uses test1;');
  4431. StartUnit(true);
  4432. Add([
  4433. 'interface',
  4434. 'uses unit2;',
  4435. 'type',
  4436. ' TEagle = class(TObject)',
  4437. ' procedure DoIt(b: boolean); override;',
  4438. ' procedure DoIt(i: longint); override;',
  4439. ' end;',
  4440. 'implementation',
  4441. 'procedure TEagle.DoIt(b: boolean); begin end;',
  4442. 'procedure TEagle.DoIt(i: longint); begin end;',
  4443. '']);
  4444. ConvertUnit;
  4445. CheckSource('TestProc_OverloadUnitCycle',
  4446. LinesToStr([ // statements
  4447. 'rtl.createClass(this, "TEagle", pas.Unit2.TObject, function () {',
  4448. ' this.DoIt = function (b) {',
  4449. ' };',
  4450. ' this.DoIt$1 = function (i) {',
  4451. ' };',
  4452. '});',
  4453. '']),
  4454. '',
  4455. LinesToStr([
  4456. '']));
  4457. end;
  4458. procedure TTestModule.TestProc_Varargs;
  4459. begin
  4460. StartProgram(false);
  4461. Add([
  4462. 'procedure ProcA(i:longint); varargs; external name ''ProcA'';',
  4463. 'procedure ProcB; varargs; external name ''ProcB'';',
  4464. 'procedure ProcC(i: longint = 17); varargs; external name ''ProcC'';',
  4465. 'function GetIt: longint; begin end;',
  4466. 'begin',
  4467. ' ProcA(1);',
  4468. ' ProcA(1,2);',
  4469. ' ProcA(1,2.0);',
  4470. ' ProcA(1,2,3);',
  4471. ' ProcA(1,''2'');',
  4472. ' ProcA(2,'''');',
  4473. ' ProcA(3,false);',
  4474. ' ProcB;',
  4475. ' ProcB();',
  4476. ' ProcB(4);',
  4477. ' ProcB(''foo'');',
  4478. ' ProcC;',
  4479. ' ProcC();',
  4480. ' ProcC(4);',
  4481. ' ProcC(5,''foo'');',
  4482. ' ProcB(GetIt);',
  4483. ' ProcB(GetIt());',
  4484. ' ProcB(GetIt,GetIt());']);
  4485. ConvertProgram;
  4486. CheckSource('TestProc_Varargs',
  4487. LinesToStr([ // statements
  4488. 'this.GetIt = function () {',
  4489. ' var Result = 0;',
  4490. ' return Result;',
  4491. '};',
  4492. '']),
  4493. LinesToStr([
  4494. 'ProcA(1);',
  4495. 'ProcA(1, 2);',
  4496. 'ProcA(1, 2.0);',
  4497. 'ProcA(1, 2, 3);',
  4498. 'ProcA(1, "2");',
  4499. 'ProcA(2, "");',
  4500. 'ProcA(3, false);',
  4501. 'ProcB();',
  4502. 'ProcB();',
  4503. 'ProcB(4);',
  4504. 'ProcB("foo");',
  4505. 'ProcC(17);',
  4506. 'ProcC(17);',
  4507. 'ProcC(4);',
  4508. 'ProcC(5, "foo");',
  4509. 'ProcB($mod.GetIt());',
  4510. 'ProcB($mod.GetIt());',
  4511. 'ProcB($mod.GetIt(), $mod.GetIt());',
  4512. '']));
  4513. end;
  4514. procedure TTestModule.TestProc_ConstOrder;
  4515. begin
  4516. StartProgram(false);
  4517. Add([
  4518. 'const A = 3;',
  4519. 'const B = A+1;',
  4520. 'procedure DoIt;',
  4521. 'const C = A+1;',
  4522. 'const D = B+1;',
  4523. 'const E = D+C+B+A;',
  4524. 'begin',
  4525. 'end;',
  4526. 'begin'
  4527. ]);
  4528. ConvertProgram;
  4529. CheckSource('TestProc_ConstOrder',
  4530. LinesToStr([ // statements
  4531. 'this.A = 3;',
  4532. 'this.B = 3 + 1;',
  4533. 'var C = 3 + 1;',
  4534. 'var D = 4 + 1;',
  4535. 'var E = 5 + 4 + 4 + 3;',
  4536. 'this.DoIt = function () {',
  4537. '};',
  4538. '']),
  4539. LinesToStr([
  4540. ''
  4541. ]));
  4542. end;
  4543. procedure TTestModule.TestProc_DuplicateConst;
  4544. begin
  4545. StartProgram(false);
  4546. Add([
  4547. 'const A = 1;',
  4548. 'procedure DoIt;',
  4549. 'const A = 2;',
  4550. ' procedure SubIt;',
  4551. ' const A = 21;',
  4552. ' begin',
  4553. ' end;',
  4554. 'begin',
  4555. 'end;',
  4556. 'procedure DoSome;',
  4557. 'const A = 3;',
  4558. 'begin',
  4559. 'end;',
  4560. 'begin'
  4561. ]);
  4562. ConvertProgram;
  4563. CheckSource('TestProc_DuplicateConst',
  4564. LinesToStr([ // statements
  4565. 'this.A = 1;',
  4566. 'var A$1 = 2;',
  4567. 'var A$2 = 21;',
  4568. 'this.DoIt = function () {',
  4569. ' function SubIt() {',
  4570. ' };',
  4571. '};',
  4572. 'var A$3 = 3;',
  4573. 'this.DoSome = function () {',
  4574. '};',
  4575. '']),
  4576. LinesToStr([
  4577. ''
  4578. ]));
  4579. end;
  4580. procedure TTestModule.TestProc_LocalVarAbsolute;
  4581. begin
  4582. StartProgram(false);
  4583. Add([
  4584. 'type',
  4585. ' TObject = class',
  4586. ' Index: longint;',
  4587. ' procedure DoAbs(Item: pointer);',
  4588. ' end;',
  4589. 'procedure TObject.DoAbs(Item: pointer);',
  4590. 'var',
  4591. ' o: TObject absolute Item;',
  4592. 'begin',
  4593. ' if o.Index<o.Index then o.Index:=o.Index;',
  4594. 'end;',
  4595. 'procedure DoIt(i: longint; p: pointer);',
  4596. 'var',
  4597. ' d: double absolute i;',
  4598. ' s: string absolute d;',
  4599. ' oi: TObject absolute i;',
  4600. ' op: TObject absolute p;',
  4601. 'begin',
  4602. ' if d=d then d:=d;',
  4603. ' if s=s then s:=s;',
  4604. ' if oi.Index<oi.Index then oi.Index:=oi.Index;',
  4605. ' if op.Index=op.Index then op.Index:=op.Index;',
  4606. 'end;',
  4607. 'begin']);
  4608. ConvertProgram;
  4609. CheckSource('TestProc_LocalVarAbsolute',
  4610. LinesToStr([ // statements
  4611. 'rtl.createClass(this, "TObject", null, function () {',
  4612. ' this.$init = function () {',
  4613. ' this.Index = 0;',
  4614. ' };',
  4615. ' this.$final = function () {',
  4616. ' };',
  4617. ' this.DoAbs = function (Item) {',
  4618. ' if (Item.Index < Item.Index) Item.Index = Item.Index;',
  4619. ' };',
  4620. '});',
  4621. 'this.DoIt = function (i, p) {',
  4622. ' if (i === i) i = i;',
  4623. ' if (i === i) i = i;',
  4624. ' if (i.Index < i.Index) i.Index = i.Index;',
  4625. ' if (p.Index === p.Index) p.Index = p.Index;',
  4626. '};'
  4627. ]),
  4628. LinesToStr([
  4629. ]));
  4630. end;
  4631. procedure TTestModule.TestProc_LocalVarInit;
  4632. begin
  4633. StartProgram(false);
  4634. Add([
  4635. 'type TBytes = array of byte;',
  4636. 'procedure DoIt;',
  4637. 'const c = 4;',
  4638. 'var',
  4639. ' b: byte = 1;',
  4640. ' w: word = 2+c;',
  4641. ' p: pointer = nil;',
  4642. ' Buffer: TBytes = nil;',
  4643. 'begin',
  4644. 'end;',
  4645. 'begin']);
  4646. ConvertProgram;
  4647. CheckSource('TestProc_LocalVarInit',
  4648. LinesToStr([ // statements
  4649. 'var c = 4;',
  4650. 'this.DoIt = function () {',
  4651. ' var b = 1;',
  4652. ' var w = 2 + 4;',
  4653. ' var p = null;',
  4654. ' var Buffer = [];',
  4655. '};',
  4656. '']),
  4657. LinesToStr([
  4658. ]));
  4659. end;
  4660. procedure TTestModule.TestProc_ReservedWords;
  4661. begin
  4662. StartProgram(false);
  4663. Add([
  4664. 'procedure Date(ArrayBuffer: longint);',
  4665. 'const',
  4666. ' NaN: longint = 3;',
  4667. 'var',
  4668. ' &Boolean: longint;',
  4669. ' procedure Error(ArrayBuffer: longint);',
  4670. ' begin',
  4671. ' end;',
  4672. 'begin',
  4673. ' Nan:=&bOolean;',
  4674. 'end;',
  4675. 'begin',
  4676. ' Date(1);']);
  4677. ConvertProgram;
  4678. CheckSource('TestProc_ReservedWords',
  4679. LinesToStr([ // statements
  4680. 'var naN = 3;',
  4681. 'this.Date = function (arrayBuffer) {',
  4682. ' var boolean = 0;',
  4683. ' function error(arrayBuffer) {',
  4684. ' };',
  4685. ' naN = boolean;',
  4686. '};',
  4687. '']),
  4688. LinesToStr([
  4689. ' $mod.Date(1);'
  4690. ]));
  4691. end;
  4692. procedure TTestModule.TestProc_ConstRefWord;
  4693. begin
  4694. StartProgram(false);
  4695. Add([
  4696. 'procedure Run(constref w: word);',
  4697. 'var l: word;',
  4698. 'begin',
  4699. ' l:=w;',
  4700. ' Run(w);',
  4701. ' Run(l);',
  4702. 'end;',
  4703. 'procedure Fly(a: word; var b: word; out c: word; const d: word; constref e: word);',
  4704. 'begin',
  4705. ' Run(a);',
  4706. ' Run(b);',
  4707. ' Run(c);',
  4708. ' Run(d);',
  4709. ' Run(e);',
  4710. 'end;',
  4711. 'begin',
  4712. ' Run(1);']);
  4713. ConvertProgram;
  4714. CheckHint(mtWarning,nConstRefNotForXAsConst,'ConstRef not yet implemented for Word. Treating as Const');
  4715. CheckSource('TestProc_ConstRefWord',
  4716. LinesToStr([ // statements
  4717. 'this.Run = function (w) {',
  4718. ' var l = 0;',
  4719. ' l = w;',
  4720. ' $mod.Run(w);',
  4721. ' $mod.Run(l);',
  4722. '};',
  4723. 'this.Fly = function (a, b, c, d, e) {',
  4724. ' $mod.Run(a);',
  4725. ' $mod.Run(b.get());',
  4726. ' $mod.Run(c.get());',
  4727. ' $mod.Run(d);',
  4728. ' $mod.Run(e);',
  4729. '};',
  4730. '']),
  4731. LinesToStr([
  4732. '$mod.Run(1);'
  4733. ]));
  4734. end;
  4735. procedure TTestModule.TestAnonymousProc_Assign_ObjFPC;
  4736. begin
  4737. StartProgram(false);
  4738. Add([
  4739. '{$mode objfpc}',
  4740. 'type',
  4741. ' TFunc = reference to function(x: word): word;',
  4742. 'var Func: TFunc;',
  4743. 'procedure DoIt(a: word);',
  4744. 'begin',
  4745. ' Func:=function(b:word): word',
  4746. ' begin',
  4747. ' Result:=a+b;',
  4748. ' exit(b);',
  4749. ' exit(Result);',
  4750. ' end;',// test semicolon
  4751. ' a:=3;',
  4752. 'end;',
  4753. 'begin',
  4754. ' Func:=function(c:word):word begin',
  4755. ' Result:=3+c;',
  4756. ' exit(c);',
  4757. ' exit(Result);',
  4758. ' end;']);
  4759. ConvertProgram;
  4760. CheckSource('TestAnonymousProc_Assign_ObjFPC',
  4761. LinesToStr([ // statements
  4762. 'this.Func = null;',
  4763. 'this.DoIt = function (a) {',
  4764. ' $mod.Func = function (b) {',
  4765. ' var Result = 0;',
  4766. ' Result = a + b;',
  4767. ' return b;',
  4768. ' return Result;',
  4769. ' return Result;',
  4770. ' };',
  4771. ' a = 3;',
  4772. '};',
  4773. '']),
  4774. LinesToStr([
  4775. '$mod.Func = function (c) {',
  4776. ' var Result = 0;',
  4777. ' Result = 3 + c;',
  4778. ' return c;',
  4779. ' return Result;',
  4780. ' return Result;',
  4781. '};',
  4782. '']));
  4783. end;
  4784. procedure TTestModule.TestAnonymousProc_Assign_Delphi;
  4785. begin
  4786. StartProgram(false);
  4787. Add([
  4788. '{$mode delphi}',
  4789. 'type',
  4790. ' TProc = reference to procedure(x: word);',
  4791. 'procedure DoIt(a: word);',
  4792. 'var Proc: TProc;',
  4793. 'begin',
  4794. ' Proc:=procedure(b:word) begin end;',
  4795. 'end;',
  4796. 'var Proc: TProc;',
  4797. 'begin',
  4798. ' Proc:=procedure(c:word) begin end;',
  4799. '']);
  4800. ConvertProgram;
  4801. CheckSource('TestAnonymousProc_Assign_Delphi',
  4802. LinesToStr([ // statements
  4803. 'this.DoIt = function (a) {',
  4804. ' var Proc = null;',
  4805. ' Proc = function (b) {',
  4806. ' };',
  4807. '};',
  4808. 'this.Proc = null;',
  4809. '']),
  4810. LinesToStr([
  4811. '$mod.Proc = function (c) {',
  4812. '};',
  4813. '']));
  4814. end;
  4815. procedure TTestModule.TestAnonymousProc_Arg;
  4816. begin
  4817. StartProgram(false);
  4818. Add([
  4819. 'type',
  4820. ' TProc = reference to procedure;',
  4821. ' TFunc = reference to function(x: word): word;',
  4822. 'procedure DoMore(f,g: TProc);',
  4823. 'begin',
  4824. 'end;',
  4825. 'procedure DoOdd(v: jsvalue);',
  4826. 'begin',
  4827. 'end;',
  4828. 'procedure DoIt(f: TFunc);',
  4829. 'begin',
  4830. ' DoIt(function(b:word): word',
  4831. ' begin',
  4832. ' Result:=1+b;',
  4833. ' end);',
  4834. ' DoMore(procedure begin end, procedure begin end);',
  4835. ' DoOdd(procedure begin end);',
  4836. 'end;',
  4837. 'begin',
  4838. ' DoMore(procedure begin end,',
  4839. ' procedure assembler asm',
  4840. ' console.log("c");',
  4841. ' end);',
  4842. '']);
  4843. ConvertProgram;
  4844. CheckSource('TestAnonymousProc_Arg',
  4845. LinesToStr([ // statements
  4846. 'this.DoMore = function (f, g) {',
  4847. '};',
  4848. 'this.DoOdd = function (v) {',
  4849. '};',
  4850. 'this.DoIt = function (f) {',
  4851. ' $mod.DoIt(function (b) {',
  4852. ' var Result = 0;',
  4853. ' Result = 1 + b;',
  4854. ' return Result;',
  4855. ' });',
  4856. ' $mod.DoMore(function () {',
  4857. ' }, function () {',
  4858. ' });',
  4859. ' $mod.DoOdd(function () {',
  4860. ' });',
  4861. '};',
  4862. '']),
  4863. LinesToStr([
  4864. '$mod.DoMore(function () {',
  4865. '}, function () {',
  4866. ' console.log("c");',
  4867. '});',
  4868. '']));
  4869. end;
  4870. procedure TTestModule.TestAnonymousProc_Typecast;
  4871. begin
  4872. StartProgram(false);
  4873. Add([
  4874. 'type',
  4875. ' TProc = reference to procedure(w: word);',
  4876. ' TArr = array of word;',
  4877. ' TFuncArr = reference to function: TArr;',
  4878. 'procedure DoIt(p: TProc);',
  4879. 'var',
  4880. ' w: word;',
  4881. ' a: TArr;',
  4882. 'begin',
  4883. ' p:=TProc(procedure(b: smallint) begin end);',
  4884. ' a:=TFuncArr(function: TArr begin end)();',
  4885. ' w:=TFuncArr(function: TArr begin end)()[3];',
  4886. 'end;',
  4887. 'begin']);
  4888. ConvertProgram;
  4889. CheckSource('TestAnonymousProc_Typecast',
  4890. LinesToStr([ // statements
  4891. 'this.DoIt = function (p) {',
  4892. ' var w = 0;',
  4893. ' var a = [];',
  4894. ' p = function (b) {',
  4895. ' };',
  4896. ' a = function () {',
  4897. ' var Result = [];',
  4898. ' return Result;',
  4899. ' }();',
  4900. ' w = function () {',
  4901. ' var Result = [];',
  4902. ' return Result;',
  4903. ' }()[3];',
  4904. '};',
  4905. '']),
  4906. LinesToStr([
  4907. '']));
  4908. end;
  4909. procedure TTestModule.TestAnonymousProc_With;
  4910. begin
  4911. StartProgram(false);
  4912. Add([
  4913. 'type',
  4914. ' TProc = reference to procedure(w: word);',
  4915. ' TObject = class',
  4916. ' b: boolean;',
  4917. ' end;',
  4918. 'var',
  4919. ' p: TProc;',
  4920. ' bird: TObject;',
  4921. 'begin',
  4922. ' with bird do',
  4923. ' p:=procedure(w: word)',
  4924. ' begin',
  4925. ' b:=w>2;',
  4926. ' end;',
  4927. '']);
  4928. ConvertProgram;
  4929. CheckSource('TestAnonymousProc_With',
  4930. LinesToStr([ // statements
  4931. 'rtl.createClass(this, "TObject", null, function () {',
  4932. ' this.$init = function () {',
  4933. ' this.b = false;',
  4934. ' };',
  4935. ' this.$final = function () {',
  4936. ' };',
  4937. '});',
  4938. 'this.p = null;',
  4939. 'this.bird = null;',
  4940. '']),
  4941. LinesToStr([
  4942. 'var $with = $mod.bird;',
  4943. '$mod.p = function (w) {',
  4944. ' $with.b = w > 2;',
  4945. '};',
  4946. '']));
  4947. end;
  4948. procedure TTestModule.TestAnonymousProc_ExceptOn;
  4949. begin
  4950. StartProgram(false);
  4951. Add([
  4952. 'type',
  4953. ' TProc = reference to procedure;',
  4954. ' TObject = class',
  4955. ' b: boolean;',
  4956. ' end;',
  4957. 'procedure DoIt;',
  4958. 'var',
  4959. ' p: TProc;',
  4960. 'begin',
  4961. ' try',
  4962. ' except',
  4963. ' on E: TObject do',
  4964. ' p:=procedure',
  4965. ' begin',
  4966. ' E.b:=true;',
  4967. ' end;',
  4968. ' end;',
  4969. 'end;',
  4970. 'begin']);
  4971. ConvertProgram;
  4972. CheckSource('TestAnonymousProc_ExceptOn',
  4973. LinesToStr([ // statements
  4974. 'rtl.createClass(this, "TObject", null, function () {',
  4975. ' this.$init = function () {',
  4976. ' this.b = false;',
  4977. ' };',
  4978. ' this.$final = function () {',
  4979. ' };',
  4980. '});',
  4981. 'this.DoIt = function () {',
  4982. ' var p = null;',
  4983. ' try {} catch ($e) {',
  4984. ' if ($mod.TObject.isPrototypeOf($e)) {',
  4985. ' var E = $e;',
  4986. ' p = function () {',
  4987. ' E.b = true;',
  4988. ' };',
  4989. ' } else throw $e',
  4990. ' };',
  4991. '};',
  4992. '']),
  4993. LinesToStr([
  4994. '']));
  4995. end;
  4996. procedure TTestModule.TestAnonymousProc_Nested;
  4997. begin
  4998. StartProgram(false);
  4999. Add([
  5000. 'type',
  5001. ' TProc = reference to procedure;',
  5002. ' TObject = class',
  5003. ' i: byte;',
  5004. ' procedure DoIt;',
  5005. ' end;',
  5006. 'procedure TObject.DoIt;',
  5007. 'var',
  5008. ' p: TProc;',
  5009. ' procedure Sub;',
  5010. ' begin',
  5011. ' p:=procedure',
  5012. ' begin',
  5013. ' i:=3;',
  5014. ' Self.i:=4;',
  5015. ' p:=procedure',
  5016. ' procedure SubSub;',
  5017. ' begin',
  5018. ' i:=13;',
  5019. ' Self.i:=14;',
  5020. ' end;',
  5021. ' begin',
  5022. ' i:=13;',
  5023. ' Self.i:=14;',
  5024. ' end;',
  5025. ' end;',
  5026. ' end;',
  5027. 'begin',
  5028. 'end;',
  5029. 'begin']);
  5030. ConvertProgram;
  5031. CheckSource('TestAnonymousProc_Nested',
  5032. LinesToStr([ // statements
  5033. 'rtl.createClass(this, "TObject", null, function () {',
  5034. ' this.$init = function () {',
  5035. ' this.i = 0;',
  5036. ' };',
  5037. ' this.$final = function () {',
  5038. ' };',
  5039. ' this.DoIt = function () {',
  5040. ' var $Self = this;',
  5041. ' var p = null;',
  5042. ' function Sub() {',
  5043. ' p = function () {',
  5044. ' $Self.i = 3;',
  5045. ' $Self.i = 4;',
  5046. ' p = function () {',
  5047. ' function SubSub() {',
  5048. ' $Self.i = 13;',
  5049. ' $Self.i = 14;',
  5050. ' };',
  5051. ' $Self.i = 13;',
  5052. ' $Self.i = 14;',
  5053. ' };',
  5054. ' };',
  5055. ' };',
  5056. ' };',
  5057. '});',
  5058. '']),
  5059. LinesToStr([
  5060. '']));
  5061. end;
  5062. procedure TTestModule.TestAnonymousProc_NestedAssignResult;
  5063. begin
  5064. StartProgram(false);
  5065. Add([
  5066. 'type',
  5067. ' TProc = reference to procedure;',
  5068. 'function DoIt: TProc;',
  5069. ' function Sub: TProc;',
  5070. ' begin',
  5071. ' Result:=procedure',
  5072. ' begin',
  5073. ' Sub:=procedure',
  5074. ' procedure SubSub;',
  5075. ' begin',
  5076. ' Result:=nil;',
  5077. ' Sub:=nil;',
  5078. ' DoIt:=nil;',
  5079. ' end;',
  5080. ' begin',
  5081. ' Result:=nil;',
  5082. ' Sub:=nil;',
  5083. ' DoIt:=nil;',
  5084. ' end;',
  5085. ' end;',
  5086. ' end;',
  5087. 'begin',
  5088. 'end;',
  5089. 'begin']);
  5090. ConvertProgram;
  5091. CheckSource('TestAnonymousProc_NestedAssignResult',
  5092. LinesToStr([ // statements
  5093. 'this.DoIt = function () {',
  5094. ' var Result = null;',
  5095. ' function Sub() {',
  5096. ' var Result$1 = null;',
  5097. ' Result$1 = function () {',
  5098. ' Result$1 = function () {',
  5099. ' function SubSub() {',
  5100. ' Result$1 = null;',
  5101. ' Result$1 = null;',
  5102. ' Result = null;',
  5103. ' };',
  5104. ' Result$1 = null;',
  5105. ' Result$1 = null;',
  5106. ' Result = null;',
  5107. ' };',
  5108. ' };',
  5109. ' return Result$1;',
  5110. ' };',
  5111. ' return Result;',
  5112. '};',
  5113. '']),
  5114. LinesToStr([
  5115. '']));
  5116. end;
  5117. procedure TTestModule.TestAnonymousProc_Class;
  5118. begin
  5119. StartProgram(false);
  5120. Add([
  5121. 'type',
  5122. ' TProc = reference to procedure;',
  5123. ' TEvent = procedure of object;',
  5124. ' TObject = class',
  5125. ' Size: word;',
  5126. ' function GetIt: TProc;',
  5127. ' procedure DoIt; virtual; abstract;',
  5128. ' end;',
  5129. 'function TObject.GetIt: TProc;',
  5130. 'begin',
  5131. ' Result:=procedure',
  5132. ' var p: TEvent;',
  5133. ' begin',
  5134. ' Size:=Size;',
  5135. ' Size:=Self.Size;',
  5136. ' p:=@DoIt;',
  5137. ' p:[email protected];',
  5138. ' end;',
  5139. 'end;',
  5140. 'begin']);
  5141. ConvertProgram;
  5142. CheckSource('TestAnonymousProc_Class',
  5143. LinesToStr([ // statements
  5144. 'rtl.createClass(this, "TObject", null, function () {',
  5145. ' this.$init = function () {',
  5146. ' this.Size = 0;',
  5147. ' };',
  5148. ' this.$final = function () {',
  5149. ' };',
  5150. ' this.GetIt = function () {',
  5151. ' var $Self = this;',
  5152. ' var Result = null;',
  5153. ' Result = function () {',
  5154. ' var p = null;',
  5155. ' $Self.Size = $Self.Size;',
  5156. ' $Self.Size = $Self.Size;',
  5157. ' p = rtl.createCallback($Self, "DoIt");',
  5158. ' p = rtl.createCallback($Self, "DoIt");',
  5159. ' };',
  5160. ' return Result;',
  5161. ' };',
  5162. '});',
  5163. '']),
  5164. LinesToStr([
  5165. '']));
  5166. end;
  5167. procedure TTestModule.TestAnonymousProc_ForLoop;
  5168. begin
  5169. StartProgram(false);
  5170. Add([
  5171. 'type TProc = reference to procedure;',
  5172. 'procedure Foo(p: TProc);',
  5173. 'begin',
  5174. 'end;',
  5175. 'procedure DoIt;',
  5176. 'var i: word;',
  5177. ' a: word;',
  5178. 'begin',
  5179. ' for i:=1 to 10 do begin',
  5180. ' Foo(procedure begin a:=3; end);',
  5181. ' end;',
  5182. 'end;',
  5183. 'begin',
  5184. ' DoIt;']);
  5185. ConvertProgram;
  5186. CheckSource('TestAnonymousProc_ForLoop',
  5187. LinesToStr([ // statements
  5188. 'this.Foo = function (p) {',
  5189. '};',
  5190. 'this.DoIt = function () {',
  5191. ' var i = 0;',
  5192. ' var a = 0;',
  5193. ' for (i = 1; i <= 10; i++) {',
  5194. ' $mod.Foo(function () {',
  5195. ' a = 3;',
  5196. ' });',
  5197. ' };',
  5198. '};',
  5199. '']),
  5200. LinesToStr([
  5201. '$mod.DoIt();'
  5202. ]));
  5203. end;
  5204. procedure TTestModule.TestAnonymousProc_AsmDelphi;
  5205. begin
  5206. StartProgram(false);
  5207. Add([
  5208. '{$mode delphi}',
  5209. 'type',
  5210. ' TProc = reference to procedure;',
  5211. ' TFunc = reference to function(x: word): word;',
  5212. 'procedure Run;',
  5213. 'asm',
  5214. 'end;',
  5215. 'procedure Walk(p: TProc; f: TFunc);',
  5216. 'begin',
  5217. ' Walk(procedure asm end, function(b:word): word asm return 1+b; end);',
  5218. 'end;',
  5219. 'begin',
  5220. ' Walk(procedure',
  5221. ' asm',
  5222. ' console.log("a");',
  5223. ' end,',
  5224. ' function(x: word): word asm',
  5225. ' console.log("c");',
  5226. ' end);',
  5227. '']);
  5228. ConvertProgram;
  5229. CheckSource('TestAnonymousProc_AsmDelphi',
  5230. LinesToStr([ // statements
  5231. 'this.Run = function () {',
  5232. '};',
  5233. 'this.Walk = function (p, f) {',
  5234. ' $mod.Walk(function () {',
  5235. ' }, function (b) {',
  5236. ' return 1+b;',
  5237. ' });',
  5238. '};',
  5239. '']),
  5240. LinesToStr([
  5241. '$mod.Walk(function () {',
  5242. ' console.log("a");',
  5243. '}, function (x) {',
  5244. ' console.log("c");',
  5245. '});',
  5246. '']));
  5247. end;
  5248. procedure TTestModule.TestEnum_Name;
  5249. begin
  5250. StartProgram(false);
  5251. Add('type TMyEnum = (Red, Green, Blue);');
  5252. Add('var e: TMyEnum;');
  5253. Add('var f: TMyEnum = Blue;');
  5254. Add('begin');
  5255. Add(' e:=green;');
  5256. Add(' e:=default(TMyEnum);');
  5257. ConvertProgram;
  5258. CheckSource('TestEnum_Name',
  5259. LinesToStr([ // statements
  5260. 'this.TMyEnum = {',
  5261. ' "0":"Red",',
  5262. ' Red:0,',
  5263. ' "1":"Green",',
  5264. ' Green:1,',
  5265. ' "2":"Blue",',
  5266. ' Blue:2',
  5267. ' };',
  5268. 'this.e = 0;',
  5269. 'this.f = this.TMyEnum.Blue;'
  5270. ]),
  5271. LinesToStr([
  5272. '$mod.e=$mod.TMyEnum.Green;',
  5273. '$mod.e=$mod.TMyEnum.Red;'
  5274. ]));
  5275. end;
  5276. procedure TTestModule.TestEnum_Number;
  5277. begin
  5278. Converter.Options:=Converter.Options+[coEnumNumbers];
  5279. StartProgram(false);
  5280. Add('type TMyEnum = (Red, Green);');
  5281. Add('var');
  5282. Add(' e: TMyEnum;');
  5283. Add(' f: TMyEnum = Green;');
  5284. Add(' i: longint;');
  5285. Add('begin');
  5286. Add(' e:=green;');
  5287. Add(' i:=longint(e);');
  5288. ConvertProgram;
  5289. CheckSource('TestEnumNumber',
  5290. LinesToStr([ // statements
  5291. 'this.TMyEnum = {',
  5292. ' "0":"Red",',
  5293. ' Red:0,',
  5294. ' "1":"Green",',
  5295. ' Green:1',
  5296. ' };',
  5297. 'this.e = 0;',
  5298. 'this.f = 1;',
  5299. 'this.i = 0;'
  5300. ]),
  5301. LinesToStr([
  5302. '$mod.e=1;',
  5303. '$mod.i=$mod.e;'
  5304. ]));
  5305. end;
  5306. procedure TTestModule.TestEnum_ConstFail;
  5307. begin
  5308. StartProgram(false);
  5309. Add([
  5310. 'type TMyEnum = (Red = 100, Green = 101);',
  5311. 'var',
  5312. ' e: TMyEnum;',
  5313. ' f: TMyEnum = Green;',
  5314. 'begin',
  5315. ' e:=green;']);
  5316. SetExpectedPasResolverError('not yet implemented: Red:TPasEnumValue [20180126202434] "enum const"',3002);
  5317. ConvertProgram;
  5318. end;
  5319. procedure TTestModule.TestEnum_Functions;
  5320. begin
  5321. StartProgram(false);
  5322. Add([
  5323. 'type TMyEnum = (Red, Green);',
  5324. 'procedure DoIt(var e: TMyEnum; var i: word);',
  5325. 'var',
  5326. ' v: longint;',
  5327. ' s: string;',
  5328. 'begin',
  5329. ' val(s,e,v);',
  5330. ' val(s,e,i);',
  5331. 'end;',
  5332. 'var',
  5333. ' e: TMyEnum;',
  5334. ' i: longint;',
  5335. ' s: string;',
  5336. ' b: boolean;',
  5337. 'begin',
  5338. ' i:=ord(red);',
  5339. ' i:=ord(green);',
  5340. ' i:=ord(e);',
  5341. ' i:=ord(b);',
  5342. ' e:=low(tmyenum);',
  5343. ' e:=low(e);',
  5344. ' b:=low(boolean);',
  5345. ' e:=high(tmyenum);',
  5346. ' e:=high(e);',
  5347. ' b:=high(boolean);',
  5348. ' e:=pred(green);',
  5349. ' e:=pred(e);',
  5350. ' b:=pred(b);',
  5351. ' e:=succ(red);',
  5352. ' e:=succ(e);',
  5353. ' b:=succ(b);',
  5354. ' e:=tmyenum(1);',
  5355. ' e:=tmyenum(i);',
  5356. ' s:=str(e);',
  5357. ' str(e,s);',
  5358. ' str(red,s);',
  5359. ' s:=str(e:3);',
  5360. ' writestr(s,e:3,red);',
  5361. ' val(s,e,i);',
  5362. ' i:=longint(e);']);
  5363. ConvertProgram;
  5364. CheckSource('TestEnum_Functions',
  5365. LinesToStr([ // statements
  5366. 'this.TMyEnum = {',
  5367. ' "0":"Red",',
  5368. ' Red:0,',
  5369. ' "1":"Green",',
  5370. ' Green:1',
  5371. ' };',
  5372. 'this.DoIt = function (e, i) {',
  5373. ' var v = 0;',
  5374. ' var s = "";',
  5375. ' e.set(rtl.valEnum(s, $mod.TMyEnum, function (w) {',
  5376. ' v = w;',
  5377. ' }));',
  5378. ' e.set(rtl.valEnum(s, $mod.TMyEnum, i.set));',
  5379. '};',
  5380. 'this.e = 0;',
  5381. 'this.i = 0;',
  5382. 'this.s = "";',
  5383. 'this.b = false;',
  5384. '']),
  5385. LinesToStr([
  5386. '$mod.i=$mod.TMyEnum.Red;',
  5387. '$mod.i=$mod.TMyEnum.Green;',
  5388. '$mod.i=$mod.e;',
  5389. '$mod.i=$mod.b+0;',
  5390. '$mod.e=$mod.TMyEnum.Red;',
  5391. '$mod.e=$mod.TMyEnum.Red;',
  5392. '$mod.b=false;',
  5393. '$mod.e=$mod.TMyEnum.Green;',
  5394. '$mod.e=$mod.TMyEnum.Green;',
  5395. '$mod.b=true;',
  5396. '$mod.e=$mod.TMyEnum.Green-1;',
  5397. '$mod.e=$mod.e-1;',
  5398. '$mod.b=false;',
  5399. '$mod.e=$mod.TMyEnum.Red+1;',
  5400. '$mod.e=$mod.e+1;',
  5401. '$mod.b=true;',
  5402. '$mod.e=1;',
  5403. '$mod.e=$mod.i;',
  5404. '$mod.s = $mod.TMyEnum[$mod.e];',
  5405. '$mod.s = $mod.TMyEnum[$mod.e];',
  5406. '$mod.s = $mod.TMyEnum[$mod.TMyEnum.Red];',
  5407. '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3);',
  5408. '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3)+$mod.TMyEnum[$mod.TMyEnum.Red];',
  5409. '$mod.e = rtl.valEnum($mod.s, $mod.TMyEnum, function (v) {',
  5410. ' $mod.i = v;',
  5411. '});',
  5412. '$mod.i=$mod.e;',
  5413. '']));
  5414. end;
  5415. procedure TTestModule.TestEnumRg_Functions;
  5416. begin
  5417. StartProgram(false);
  5418. Add([
  5419. 'type',
  5420. ' TEnum = (Red, Green, Blue);',
  5421. ' TEnumRg = Green..Blue;',
  5422. 'procedure DoIt(var e: TEnumRg; var i: word);',
  5423. 'var',
  5424. ' v: longint;',
  5425. ' s: string;',
  5426. 'begin',
  5427. ' val(s,e,v);',
  5428. ' val(s,e,i);',
  5429. 'end;',
  5430. 'var',
  5431. ' e: TEnumRg;',
  5432. ' i: longint;',
  5433. ' s: string;',
  5434. 'begin',
  5435. ' i:=ord(green);',
  5436. ' i:=ord(e);',
  5437. ' e:=low(tenumrg);',
  5438. ' e:=low(e);',
  5439. ' e:=high(tenumrg);',
  5440. ' e:=high(e);',
  5441. ' e:=pred(blue);',
  5442. ' e:=pred(e);',
  5443. ' e:=succ(green);',
  5444. ' e:=succ(e);',
  5445. ' e:=tenumrg(1);',
  5446. ' e:=tenumrg(i);',
  5447. ' s:=str(e);',
  5448. ' str(e,s);',
  5449. ' str(red,s);',
  5450. ' s:=str(e:3);',
  5451. ' writestr(s,e:3,blue);',
  5452. ' val(s,e,i);',
  5453. ' i:=longint(e);']);
  5454. ConvertProgram;
  5455. CheckSource('TestEnumRg_Functions',
  5456. LinesToStr([ // statements
  5457. 'this.TEnum = {',
  5458. ' "0":"Red",',
  5459. ' Red:0,',
  5460. ' "1":"Green",',
  5461. ' Green:1,',
  5462. ' "2":"Blue",',
  5463. ' Blue:2',
  5464. ' };',
  5465. 'this.DoIt = function (e, i) {',
  5466. ' var v = 0;',
  5467. ' var s = "";',
  5468. ' e.set(rtl.valEnum(s, $mod.TEnum, function (w) {',
  5469. ' v = w;',
  5470. ' }));',
  5471. ' e.set(rtl.valEnum(s, $mod.TEnum, i.set));',
  5472. '};',
  5473. 'this.e = this.TEnum.Green;',
  5474. 'this.i = 0;',
  5475. 'this.s = "";',
  5476. '']),
  5477. LinesToStr([
  5478. '$mod.i=$mod.TEnum.Green;',
  5479. '$mod.i=$mod.e;',
  5480. '$mod.e=$mod.TEnum.Green;',
  5481. '$mod.e=$mod.TEnum.Green;',
  5482. '$mod.e=$mod.TEnum.Blue;',
  5483. '$mod.e=$mod.TEnum.Blue;',
  5484. '$mod.e=$mod.TEnum.Blue-1;',
  5485. '$mod.e=$mod.e-1;',
  5486. '$mod.e=$mod.TEnum.Green+1;',
  5487. '$mod.e=$mod.e+1;',
  5488. '$mod.e=1;',
  5489. '$mod.e=$mod.i;',
  5490. '$mod.s = $mod.TEnum[$mod.e];',
  5491. '$mod.s = $mod.TEnum[$mod.e];',
  5492. '$mod.s = $mod.TEnum[$mod.TEnum.Red];',
  5493. '$mod.s = rtl.spaceLeft($mod.TEnum[$mod.e], 3);',
  5494. '$mod.s = rtl.spaceLeft($mod.TEnum[$mod.e], 3)+$mod.TEnum[$mod.TEnum.Blue];',
  5495. '$mod.e = rtl.valEnum($mod.s, $mod.TEnum, function (v) {',
  5496. ' $mod.i = v;',
  5497. '});',
  5498. '$mod.i=$mod.e;',
  5499. '']));
  5500. end;
  5501. procedure TTestModule.TestEnum_AsParams;
  5502. begin
  5503. StartProgram(false);
  5504. Add('type TEnum = (Red,Blue);');
  5505. Add('procedure DoIt(vG: TEnum; const vH: TEnum; var vI: TEnum);');
  5506. Add('var vJ: TEnum;');
  5507. Add('begin');
  5508. Add(' vg:=vg;');
  5509. Add(' vj:=vh;');
  5510. Add(' vi:=vi;');
  5511. Add(' doit(vg,vg,vg);');
  5512. Add(' doit(vh,vh,vj);');
  5513. Add(' doit(vi,vi,vi);');
  5514. Add(' doit(vj,vj,vj);');
  5515. Add('end;');
  5516. Add('var i: TEnum;');
  5517. Add('begin');
  5518. Add(' doit(i,i,i);');
  5519. ConvertProgram;
  5520. CheckSource('TestEnum_AsParams',
  5521. LinesToStr([ // statements
  5522. 'this.TEnum = {',
  5523. ' "0": "Red",',
  5524. ' Red: 0,',
  5525. ' "1": "Blue",',
  5526. ' Blue: 1',
  5527. '};',
  5528. 'this.DoIt = function (vG,vH,vI) {',
  5529. ' var vJ = 0;',
  5530. ' vG = vG;',
  5531. ' vJ = vH;',
  5532. ' vI.set(vI.get());',
  5533. ' $mod.DoIt(vG, vG, {',
  5534. ' get: function () {',
  5535. ' return vG;',
  5536. ' },',
  5537. ' set: function (v) {',
  5538. ' vG = v;',
  5539. ' }',
  5540. ' });',
  5541. ' $mod.DoIt(vH, vH, {',
  5542. ' get: function () {',
  5543. ' return vJ;',
  5544. ' },',
  5545. ' set: function (v) {',
  5546. ' vJ = v;',
  5547. ' }',
  5548. ' });',
  5549. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  5550. ' $mod.DoIt(vJ, vJ, {',
  5551. ' get: function () {',
  5552. ' return vJ;',
  5553. ' },',
  5554. ' set: function (v) {',
  5555. ' vJ = v;',
  5556. ' }',
  5557. ' });',
  5558. '};',
  5559. 'this.i = 0;'
  5560. ]),
  5561. LinesToStr([
  5562. '$mod.DoIt($mod.i,$mod.i,{',
  5563. ' p: $mod,',
  5564. ' get: function () {',
  5565. ' return this.p.i;',
  5566. ' },',
  5567. ' set: function (v) {',
  5568. ' this.p.i = v;',
  5569. ' }',
  5570. '});'
  5571. ]));
  5572. end;
  5573. procedure TTestModule.TestEnumRange_Array;
  5574. begin
  5575. StartProgram(false);
  5576. Add([
  5577. 'type',
  5578. ' TEnum = (Red, Green, Blue);',
  5579. ' TEnumRg = green..blue;',
  5580. ' TArr = array[TEnumRg] of byte;',
  5581. ' TArr2 = array[green..blue] of byte;',
  5582. 'var',
  5583. ' a: TArr;',
  5584. ' b: TArr = (3,4);',
  5585. ' c: TArr2 = (5,6);',
  5586. 'begin',
  5587. ' a[green] := b[blue];',
  5588. ' c[green] := c[blue];',
  5589. '']);
  5590. ConvertProgram;
  5591. CheckSource('TestEnumRange_Array',
  5592. LinesToStr([ // statements
  5593. 'this.TEnum = {',
  5594. ' "0": "Red",',
  5595. ' Red: 0,',
  5596. ' "1": "Green",',
  5597. ' Green: 1,',
  5598. ' "2": "Blue",',
  5599. ' Blue: 2',
  5600. '};',
  5601. 'this.a = rtl.arraySetLength(null, 0, 2);',
  5602. 'this.b = [3, 4];',
  5603. 'this.c = [5, 6];',
  5604. '']),
  5605. LinesToStr([
  5606. ' $mod.a[$mod.TEnum.Green - 1] = $mod.b[$mod.TEnum.Blue - 1];',
  5607. ' $mod.c[$mod.TEnum.Green - 1] = $mod.c[$mod.TEnum.Blue - 1];',
  5608. '']));
  5609. end;
  5610. procedure TTestModule.TestEnum_ForIn;
  5611. begin
  5612. StartProgram(false);
  5613. Add([
  5614. 'type',
  5615. ' TEnum = (Red, Green, Blue);',
  5616. ' TEnumRg = green..blue;',
  5617. ' TArr = array[TEnum] of byte;',
  5618. ' TArrRg = array[TEnumRg] of byte;',
  5619. 'var',
  5620. ' e: TEnum;',
  5621. ' a1: TArr = (3,4,5);',
  5622. ' a2: TArrRg = (11,12);',
  5623. ' b: byte;',
  5624. 'begin',
  5625. ' for e in TEnum do ;',
  5626. ' for e in TEnumRg do ;',
  5627. ' for e in TArr do ;',
  5628. ' for e in TArrRg do ;',
  5629. ' for b in a1 do ;',
  5630. ' for b in a2 do ;',
  5631. '']);
  5632. ConvertProgram;
  5633. CheckSource('TestEnum_ForIn',
  5634. LinesToStr([ // statements
  5635. 'this.TEnum = {',
  5636. ' "0": "Red",',
  5637. ' Red: 0,',
  5638. ' "1": "Green",',
  5639. ' Green: 1,',
  5640. ' "2": "Blue",',
  5641. ' Blue: 2',
  5642. '};',
  5643. 'this.e = 0;',
  5644. 'this.a1 = [3, 4, 5];',
  5645. 'this.a2 = [11, 12];',
  5646. 'this.b = 0;',
  5647. '']),
  5648. LinesToStr([
  5649. ' for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  5650. ' for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  5651. ' for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  5652. ' for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  5653. ' for (var $in = $mod.a1, $l = 0, $end = rtl.length($in) - 1; $l <= $end; $l++) $mod.b = $in[$l];',
  5654. ' for (var $in1 = $mod.a2, $l1 = 0, $end1 = rtl.length($in1) - 1; $l1 <= $end1; $l1++) $mod.b = $in1[$l1];',
  5655. '']));
  5656. end;
  5657. procedure TTestModule.TestEnum_ScopedNumber;
  5658. begin
  5659. Converter.Options:=Converter.Options+[coEnumNumbers];
  5660. StartProgram(false);
  5661. Add([
  5662. 'type',
  5663. ' TEnum = (Red, Green);',
  5664. 'var',
  5665. ' e: TEnum;',
  5666. 'begin',
  5667. ' e:=TEnum.Green;',
  5668. '']);
  5669. ConvertProgram;
  5670. CheckSource('TestEnum_ScopedNumber',
  5671. LinesToStr([ // statements
  5672. 'this.TEnum = {',
  5673. ' "0": "Red",',
  5674. ' Red: 0,',
  5675. ' "1": "Green",',
  5676. ' Green: 1',
  5677. '};',
  5678. 'this.e = 0;',
  5679. '']),
  5680. LinesToStr([
  5681. '$mod.e = 1;']));
  5682. end;
  5683. procedure TTestModule.TestEnum_InFunction;
  5684. begin
  5685. StartProgram(false);
  5686. Add([
  5687. 'const TEnum = 3;',
  5688. 'procedure DoIt;',
  5689. 'type',
  5690. ' TEnum = (Red, Green, Blue);',
  5691. ' procedure Sub;',
  5692. ' type',
  5693. ' TEnumSub = (Left, Right);',
  5694. ' var',
  5695. ' es: TEnumSub;',
  5696. ' begin',
  5697. ' es:=Left;',
  5698. ' end;',
  5699. 'var',
  5700. ' e, e2: TEnum;',
  5701. 'begin',
  5702. ' if e in [red,blue] then e2:=e;',
  5703. 'end;',
  5704. 'begin']);
  5705. ConvertProgram;
  5706. CheckSource('TestEnum_InFunction',
  5707. LinesToStr([ // statements
  5708. 'this.TEnum = 3;',
  5709. 'var TEnum$1 = {',
  5710. ' "0":"Red",',
  5711. ' Red:0,',
  5712. ' "1":"Green",',
  5713. ' Green:1,',
  5714. ' "2":"Blue",',
  5715. ' Blue:2',
  5716. ' };',
  5717. 'var TEnumSub = {',
  5718. ' "0": "Left",',
  5719. ' Left: 0,',
  5720. ' "1": "Right",',
  5721. ' Right: 1',
  5722. '};',
  5723. 'this.DoIt = function () {',
  5724. ' function Sub() {',
  5725. ' var es = 0;',
  5726. ' es = TEnumSub.Left;',
  5727. ' };',
  5728. ' var e = 0;',
  5729. ' var e2 = 0;',
  5730. ' if (e in rtl.createSet(TEnum$1.Red, TEnum$1.Blue)) e2 = e;',
  5731. '};',
  5732. '']),
  5733. LinesToStr([
  5734. '']));
  5735. end;
  5736. procedure TTestModule.TestEnum_Name_Anonymous_Unit;
  5737. begin
  5738. StartUnit(true);
  5739. Add([
  5740. 'interface',
  5741. 'var color: (red, green);',
  5742. 'implementation',
  5743. 'initialization',
  5744. ' color:=green;',
  5745. '']);
  5746. ConvertUnit;
  5747. CheckSource('TestEnum_Name_Anonymous_Unit',
  5748. LinesToStr([
  5749. 'this.color$a = {',
  5750. ' "0": "red",',
  5751. ' red: 0,',
  5752. ' "1": "green",',
  5753. ' green: 1',
  5754. '};',
  5755. 'this.color = 0;',
  5756. '']),
  5757. LinesToStr([ // this.$init
  5758. '$mod.color = $mod.color$a.green;',
  5759. '']),
  5760. LinesToStr([ // implementation
  5761. '']) );
  5762. end;
  5763. procedure TTestModule.TestSet_Enum;
  5764. begin
  5765. StartProgram(false);
  5766. Add([
  5767. 'type',
  5768. ' TColor = (Red, Green, Blue);',
  5769. ' TColors = set of TColor;',
  5770. 'var',
  5771. ' c: TColor;',
  5772. ' s: TColors;',
  5773. ' t: TColors = [];',
  5774. ' u: TColors = [Red];',
  5775. 'begin',
  5776. ' s:=[];',
  5777. ' s:=[Green];',
  5778. ' s:=[Green,Blue];',
  5779. ' s:=[Red..Blue];',
  5780. ' s:=[Red,Green..Blue];',
  5781. ' s:=[Red,c];',
  5782. ' s:=t;',
  5783. ' s:=default(TColors);',
  5784. '']);
  5785. ConvertProgram;
  5786. CheckSource('TestSet',
  5787. LinesToStr([ // statements
  5788. 'this.TColor = {',
  5789. ' "0":"Red",',
  5790. ' Red:0,',
  5791. ' "1":"Green",',
  5792. ' Green:1,',
  5793. ' "2":"Blue",',
  5794. ' Blue:2',
  5795. ' };',
  5796. 'this.c = 0;',
  5797. 'this.s = {};',
  5798. 'this.t = {};',
  5799. 'this.u = rtl.createSet(this.TColor.Red);'
  5800. ]),
  5801. LinesToStr([
  5802. '$mod.s={};',
  5803. '$mod.s=rtl.createSet($mod.TColor.Green);',
  5804. '$mod.s=rtl.createSet($mod.TColor.Green,$mod.TColor.Blue);',
  5805. '$mod.s=rtl.createSet(null,$mod.TColor.Red,$mod.TColor.Blue);',
  5806. '$mod.s=rtl.createSet($mod.TColor.Red,null,$mod.TColor.Green,$mod.TColor.Blue);',
  5807. '$mod.s=rtl.createSet($mod.TColor.Red,$mod.c);',
  5808. '$mod.s=rtl.refSet($mod.t);',
  5809. '$mod.s={};',
  5810. '']));
  5811. end;
  5812. procedure TTestModule.TestSet_Operators;
  5813. begin
  5814. StartProgram(false);
  5815. Add('type');
  5816. Add(' TColor = (Red, Green, Blue);');
  5817. Add(' TColors = set of tcolor;');
  5818. Add('var');
  5819. Add(' vC: TColor;');
  5820. Add(' vS: TColors;');
  5821. Add(' vT: TColors;');
  5822. Add(' vU: TColors;');
  5823. Add(' B: boolean;');
  5824. Add('begin');
  5825. Add(' include(vs,green);');
  5826. Add(' exclude(vs,vc);');
  5827. Add(' vs:=vt+vu;');
  5828. Add(' vs:=vt+[red];');
  5829. Add(' vs:=[red]+vt;');
  5830. Add(' vs:=[red]+[green];');
  5831. Add(' vs:=vt-vu;');
  5832. Add(' vs:=vt-[red];');
  5833. Add(' vs:=[red]-vt;');
  5834. Add(' vs:=[red]-[green];');
  5835. Add(' vs:=vt*vu;');
  5836. Add(' vs:=vt*[red];');
  5837. Add(' vs:=[red]*vt;');
  5838. Add(' vs:=[red]*[green];');
  5839. Add(' vs:=vt><vu;');
  5840. Add(' vs:=vt><[red];');
  5841. Add(' vs:=[red]><vt;');
  5842. Add(' vs:=[red]><[green];');
  5843. Add(' b:=vt=vu;');
  5844. Add(' b:=vt=[red];');
  5845. Add(' b:=[red]=vt;');
  5846. Add(' b:=[red]=[green];');
  5847. Add(' b:=vt<>vu;');
  5848. Add(' b:=vt<>[red];');
  5849. Add(' b:=[red]<>vt;');
  5850. Add(' b:=[red]<>[green];');
  5851. Add(' b:=vt<=vu;');
  5852. Add(' b:=vt<=[red];');
  5853. Add(' b:=[red]<=vt;');
  5854. Add(' b:=[red]<=[green];');
  5855. Add(' b:=vt>=vu;');
  5856. Add(' b:=vt>=[red];');
  5857. Add(' b:=[red]>=vt;');
  5858. Add(' b:=[red]>=[green];');
  5859. ConvertProgram;
  5860. CheckSource('TestSet_Operators',
  5861. LinesToStr([ // statements
  5862. 'this.TColor = {',
  5863. ' "0":"Red",',
  5864. ' Red:0,',
  5865. ' "1":"Green",',
  5866. ' Green:1,',
  5867. ' "2":"Blue",',
  5868. ' Blue:2',
  5869. ' };',
  5870. 'this.vC = 0;',
  5871. 'this.vS = {};',
  5872. 'this.vT = {};',
  5873. 'this.vU = {};',
  5874. 'this.B = false;'
  5875. ]),
  5876. LinesToStr([
  5877. '$mod.vS = rtl.includeSet($mod.vS,$mod.TColor.Green);',
  5878. '$mod.vS = rtl.excludeSet($mod.vS,$mod.vC);',
  5879. '$mod.vS = rtl.unionSet($mod.vT, $mod.vU);',
  5880. '$mod.vS = rtl.unionSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5881. '$mod.vS = rtl.unionSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5882. '$mod.vS = rtl.unionSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5883. '$mod.vS = rtl.diffSet($mod.vT, $mod.vU);',
  5884. '$mod.vS = rtl.diffSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5885. '$mod.vS = rtl.diffSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5886. '$mod.vS = rtl.diffSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5887. '$mod.vS = rtl.intersectSet($mod.vT, $mod.vU);',
  5888. '$mod.vS = rtl.intersectSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5889. '$mod.vS = rtl.intersectSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5890. '$mod.vS = rtl.intersectSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5891. '$mod.vS = rtl.symDiffSet($mod.vT, $mod.vU);',
  5892. '$mod.vS = rtl.symDiffSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5893. '$mod.vS = rtl.symDiffSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5894. '$mod.vS = rtl.symDiffSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5895. '$mod.B = rtl.eqSet($mod.vT, $mod.vU);',
  5896. '$mod.B = rtl.eqSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5897. '$mod.B = rtl.eqSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5898. '$mod.B = rtl.eqSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5899. '$mod.B = rtl.neSet($mod.vT, $mod.vU);',
  5900. '$mod.B = rtl.neSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5901. '$mod.B = rtl.neSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5902. '$mod.B = rtl.neSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5903. '$mod.B = rtl.leSet($mod.vT, $mod.vU);',
  5904. '$mod.B = rtl.leSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5905. '$mod.B = rtl.leSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5906. '$mod.B = rtl.leSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5907. '$mod.B = rtl.geSet($mod.vT, $mod.vU);',
  5908. '$mod.B = rtl.geSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5909. '$mod.B = rtl.geSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5910. '$mod.B = rtl.geSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5911. '']));
  5912. end;
  5913. procedure TTestModule.TestSet_Operator_In;
  5914. begin
  5915. StartProgram(false);
  5916. Add([
  5917. 'type',
  5918. ' TColor = (Red, Green, Blue);',
  5919. ' TColors = set of tcolor;',
  5920. ' TColorRg = green..blue;',
  5921. 'var',
  5922. ' vC: tcolor;',
  5923. ' vT: tcolors;',
  5924. ' B: boolean;',
  5925. ' rg: TColorRg;',
  5926. 'begin',
  5927. ' b:=red in vt;',
  5928. ' b:=vc in vt;',
  5929. ' b:=green in [red..blue];',
  5930. ' b:=vc in [red..blue];',
  5931. ' ',
  5932. ' if red in vt then ;',
  5933. ' while vC in vt do ;',
  5934. ' repeat',
  5935. ' until vC in vt;',
  5936. ' if rg in [green..blue] then ;',
  5937. '']);
  5938. ConvertProgram;
  5939. CheckSource('TestSet_Operator_In',
  5940. LinesToStr([ // statements
  5941. 'this.TColor = {',
  5942. ' "0":"Red",',
  5943. ' Red:0,',
  5944. ' "1":"Green",',
  5945. ' Green:1,',
  5946. ' "2":"Blue",',
  5947. ' Blue:2',
  5948. ' };',
  5949. 'this.vC = 0;',
  5950. 'this.vT = {};',
  5951. 'this.B = false;',
  5952. 'this.rg = this.TColor.Green;',
  5953. '']),
  5954. LinesToStr([
  5955. '$mod.B = $mod.TColor.Red in $mod.vT;',
  5956. '$mod.B = $mod.vC in $mod.vT;',
  5957. '$mod.B = $mod.TColor.Green in rtl.createSet(null, $mod.TColor.Red, $mod.TColor.Blue);',
  5958. '$mod.B = $mod.vC in rtl.createSet(null, $mod.TColor.Red, $mod.TColor.Blue);',
  5959. 'if ($mod.TColor.Red in $mod.vT) ;',
  5960. 'while ($mod.vC in $mod.vT) {',
  5961. '};',
  5962. 'do {',
  5963. '} while (!($mod.vC in $mod.vT));',
  5964. 'if ($mod.rg in rtl.createSet(null, $mod.TColor.Green, $mod.TColor.Blue)) ;',
  5965. '']));
  5966. end;
  5967. procedure TTestModule.TestSet_Functions;
  5968. begin
  5969. StartProgram(false);
  5970. Add('type');
  5971. Add(' TMyEnum = (Red, Green);');
  5972. Add(' TMyEnums = set of TMyEnum;');
  5973. Add('var');
  5974. Add(' e: TMyEnum;');
  5975. Add(' s: TMyEnums;');
  5976. Add('begin');
  5977. Add(' e:=Low(TMyEnums);');
  5978. Add(' e:=Low(s);');
  5979. Add(' e:=High(TMyEnums);');
  5980. Add(' e:=High(s);');
  5981. ConvertProgram;
  5982. CheckSource('TestSetFunctions',
  5983. LinesToStr([ // statements
  5984. 'this.TMyEnum = {',
  5985. ' "0":"Red",',
  5986. ' Red:0,',
  5987. ' "1":"Green",',
  5988. ' Green:1',
  5989. ' };',
  5990. 'this.e = 0;',
  5991. 'this.s = {};'
  5992. ]),
  5993. LinesToStr([
  5994. '$mod.e=$mod.TMyEnum.Red;',
  5995. '$mod.e=$mod.TMyEnum.Red;',
  5996. '$mod.e=$mod.TMyEnum.Green;',
  5997. '$mod.e=$mod.TMyEnum.Green;',
  5998. '']));
  5999. end;
  6000. procedure TTestModule.TestSet_PassAsArgClone;
  6001. begin
  6002. StartProgram(false);
  6003. Add('type');
  6004. Add(' TMyEnum = (Red, Green);');
  6005. Add(' TMyEnums = set of TMyEnum;');
  6006. Add('procedure DoDefault(s: tmyenums); begin end;');
  6007. Add('procedure DoConst(const s: tmyenums); begin end;');
  6008. Add('var');
  6009. Add(' aSet: tmyenums;');
  6010. Add('begin');
  6011. Add(' dodefault(aset);');
  6012. Add(' doconst(aset);');
  6013. ConvertProgram;
  6014. CheckSource('TestSetFunctions',
  6015. LinesToStr([ // statements
  6016. 'this.TMyEnum = {',
  6017. ' "0":"Red",',
  6018. ' Red:0,',
  6019. ' "1":"Green",',
  6020. ' Green:1',
  6021. ' };',
  6022. 'this.DoDefault = function (s) {',
  6023. '};',
  6024. 'this.DoConst = function (s) {',
  6025. '};',
  6026. 'this.aSet = {};'
  6027. ]),
  6028. LinesToStr([
  6029. '$mod.DoDefault(rtl.refSet($mod.aSet));',
  6030. '$mod.DoConst($mod.aSet);',
  6031. '']));
  6032. end;
  6033. procedure TTestModule.TestSet_AsParams;
  6034. begin
  6035. StartProgram(false);
  6036. Add([
  6037. 'type TEnum = (Red,Blue);',
  6038. 'type TEnums = set of TEnum;',
  6039. 'function DoIt(vG: TEnums; const vH: TEnums; var vI: TEnums): TEnums;',
  6040. 'var vJ: TEnums;',
  6041. 'begin',
  6042. ' Include(vg,red);',
  6043. ' Include(result,blue);',
  6044. ' vg:=vg;',
  6045. ' vj:=vh;',
  6046. ' vi:=vi;',
  6047. ' doit(vg,vg,vg);',
  6048. ' doit(vh,vh,vj);',
  6049. ' doit(vi,vi,vi);',
  6050. ' doit(vj,vj,vj);',
  6051. 'end;',
  6052. 'var i: TEnums;',
  6053. 'begin',
  6054. ' doit(i,i,i);']);
  6055. ConvertProgram;
  6056. CheckSource('TestSet_AsParams',
  6057. LinesToStr([ // statements
  6058. 'this.TEnum = {',
  6059. ' "0": "Red",',
  6060. ' Red: 0,',
  6061. ' "1": "Blue",',
  6062. ' Blue: 1',
  6063. '};',
  6064. 'this.DoIt = function (vG,vH,vI) {',
  6065. ' var Result = {};',
  6066. ' var vJ = {};',
  6067. ' vG = rtl.includeSet(vG, $mod.TEnum.Red);',
  6068. ' Result = rtl.includeSet(Result, $mod.TEnum.Blue);',
  6069. ' vG = rtl.refSet(vG);',
  6070. ' vJ = rtl.refSet(vH);',
  6071. ' vI.set(rtl.refSet(vI.get()));',
  6072. ' $mod.DoIt(rtl.refSet(vG), vG, {',
  6073. ' get: function () {',
  6074. ' return vG;',
  6075. ' },',
  6076. ' set: function (v) {',
  6077. ' vG = v;',
  6078. ' }',
  6079. ' });',
  6080. ' $mod.DoIt(rtl.refSet(vH), vH, {',
  6081. ' get: function () {',
  6082. ' return vJ;',
  6083. ' },',
  6084. ' set: function (v) {',
  6085. ' vJ = v;',
  6086. ' }',
  6087. ' });',
  6088. ' $mod.DoIt(rtl.refSet(vI.get()), vI.get(), vI);',
  6089. ' $mod.DoIt(rtl.refSet(vJ), vJ, {',
  6090. ' get: function () {',
  6091. ' return vJ;',
  6092. ' },',
  6093. ' set: function (v) {',
  6094. ' vJ = v;',
  6095. ' }',
  6096. ' });',
  6097. ' return Result;',
  6098. '};',
  6099. 'this.i = {};'
  6100. ]),
  6101. LinesToStr([
  6102. '$mod.DoIt(rtl.refSet($mod.i),$mod.i,{',
  6103. ' p: $mod,',
  6104. ' get: function () {',
  6105. ' return this.p.i;',
  6106. ' },',
  6107. ' set: function (v) {',
  6108. ' this.p.i = v;',
  6109. ' }',
  6110. '});'
  6111. ]));
  6112. end;
  6113. procedure TTestModule.TestSet_Property;
  6114. begin
  6115. StartProgram(false);
  6116. Add('type');
  6117. Add(' TEnum = (Red,Blue);');
  6118. Add(' TEnums = set of TEnum;');
  6119. Add(' TObject = class');
  6120. Add(' function GetColors: TEnums; external name ''GetColors'';');
  6121. Add(' procedure SetColors(const Value: TEnums); external name ''SetColors'';');
  6122. Add(' property Colors: TEnums read GetColors write SetColors;');
  6123. Add(' end;');
  6124. Add('procedure DoIt(i: TEnums; const j: TEnums; var k: TEnums; out l: TEnums);');
  6125. Add('begin end;');
  6126. Add('var Obj: TObject;');
  6127. Add('begin');
  6128. Add(' Include(Obj.Colors,Red);');
  6129. Add(' Exclude(Obj.Colors,Red);');
  6130. //Add(' DoIt(Obj.Colors,Obj.Colors,Obj.Colors,Obj.Colors);');
  6131. ConvertProgram;
  6132. CheckSource('TestSet_Property',
  6133. LinesToStr([ // statements
  6134. 'this.TEnum = {',
  6135. ' "0": "Red",',
  6136. ' Red: 0,',
  6137. ' "1": "Blue",',
  6138. ' Blue: 1',
  6139. '};',
  6140. 'rtl.createClass(this, "TObject", null, function () {',
  6141. ' this.$init = function () {',
  6142. ' };',
  6143. ' this.$final = function () {',
  6144. ' };',
  6145. '});',
  6146. 'this.DoIt = function (i, j, k, l) {',
  6147. '};',
  6148. 'this.Obj = null;',
  6149. '']),
  6150. LinesToStr([
  6151. '$mod.Obj.SetColors(rtl.includeSet($mod.Obj.GetColors(), $mod.TEnum.Red));',
  6152. '$mod.Obj.SetColors(rtl.excludeSet($mod.Obj.GetColors(), $mod.TEnum.Red));',
  6153. '']));
  6154. end;
  6155. procedure TTestModule.TestSet_EnumConst;
  6156. begin
  6157. StartProgram(false);
  6158. Add([
  6159. 'type',
  6160. ' TEnum = (Red,Blue);',
  6161. ' TEnums = set of TEnum;',
  6162. 'const',
  6163. ' Orange = red;',
  6164. 'var',
  6165. ' Enum: tenum;',
  6166. ' Enums: tenums;',
  6167. 'begin',
  6168. ' Include(enums,orange);',
  6169. ' Exclude(enums,orange);',
  6170. ' if orange in enums then;',
  6171. ' if orange in [orange,red] then;']);
  6172. ConvertProgram;
  6173. CheckSource('TestSet_EnumConst',
  6174. LinesToStr([ // statements
  6175. 'this.TEnum = {',
  6176. ' "0": "Red",',
  6177. ' Red: 0,',
  6178. ' "1": "Blue",',
  6179. ' Blue: 1',
  6180. '};',
  6181. 'this.Orange = this.TEnum.Red;',
  6182. 'this.Enum = 0;',
  6183. 'this.Enums = {};',
  6184. '']),
  6185. LinesToStr([
  6186. '$mod.Enums = rtl.includeSet($mod.Enums, $mod.TEnum.Red);',
  6187. '$mod.Enums = rtl.excludeSet($mod.Enums, $mod.TEnum.Red);',
  6188. 'if ($mod.TEnum.Red in $mod.Enums) ;',
  6189. 'if ($mod.TEnum.Red in rtl.createSet($mod.TEnum.Red, $mod.TEnum.Red)) ;',
  6190. '']));
  6191. end;
  6192. procedure TTestModule.TestSet_IntConst;
  6193. begin
  6194. StartProgram(false);
  6195. Add([
  6196. 'type',
  6197. ' TEnums = set of Byte;',
  6198. 'const',
  6199. ' Orange = 0;',
  6200. 'var',
  6201. ' Enum: byte;',
  6202. ' Enums: tenums;',
  6203. 'begin',
  6204. ' Enums:=[];',
  6205. ' Enums:=[0];',
  6206. ' Enums:=[1..2];',
  6207. //' Include(enums,orange);',
  6208. //' Exclude(enums,orange);',
  6209. ' if orange in enums then;',
  6210. ' if orange in [orange,1] then;']);
  6211. ConvertProgram;
  6212. CheckSource('TestSet_IntConst',
  6213. LinesToStr([ // statements
  6214. 'this.Orange = 0;',
  6215. 'this.Enum = 0;',
  6216. 'this.Enums = {};',
  6217. '']),
  6218. LinesToStr([
  6219. '$mod.Enums = {};',
  6220. '$mod.Enums = rtl.createSet(0);',
  6221. '$mod.Enums = rtl.createSet(null, 1, 2);',
  6222. 'if (0 in $mod.Enums) ;',
  6223. 'if (0 in rtl.createSet(0, 1)) ;',
  6224. '']));
  6225. end;
  6226. procedure TTestModule.TestSet_IntRange;
  6227. begin
  6228. StartProgram(false);
  6229. Add([
  6230. 'type',
  6231. ' TRange = 1..3;',
  6232. ' TEnums = set of TRange;',
  6233. 'const',
  6234. ' Orange = 2;',
  6235. 'var',
  6236. ' Enum: byte;',
  6237. ' Enums: TEnums;',
  6238. 'begin',
  6239. ' Enums:=[];',
  6240. ' Enums:=[1];',
  6241. ' Enums:=[2..3];',
  6242. ' Include(enums,orange);',
  6243. ' Exclude(enums,orange);',
  6244. ' if orange in enums then;',
  6245. ' if orange in [orange,1] then;']);
  6246. ConvertProgram;
  6247. CheckSource('TestSet_IntRange',
  6248. LinesToStr([ // statements
  6249. 'this.Orange = 2;',
  6250. 'this.Enum = 0;',
  6251. 'this.Enums = {};',
  6252. '']),
  6253. LinesToStr([
  6254. '$mod.Enums = {};',
  6255. '$mod.Enums = rtl.createSet(1);',
  6256. '$mod.Enums = rtl.createSet(null, 2, 3);',
  6257. '$mod.Enums = rtl.includeSet($mod.Enums, 2);',
  6258. '$mod.Enums = rtl.excludeSet($mod.Enums, 2);',
  6259. 'if (2 in $mod.Enums) ;',
  6260. 'if (2 in rtl.createSet(2, 1)) ;',
  6261. '']));
  6262. end;
  6263. procedure TTestModule.TestSet_AnonymousEnumType;
  6264. begin
  6265. StartProgram(false);
  6266. Add('type');
  6267. Add(' TFlags = set of (red, green);');
  6268. Add('const');
  6269. Add(' favorite = red;');
  6270. Add('var');
  6271. Add(' f: TFlags;');
  6272. Add(' i: longint;');
  6273. Add('begin');
  6274. Add(' Include(f,red);');
  6275. Add(' Include(f,favorite);');
  6276. Add(' i:=ord(red);');
  6277. Add(' i:=ord(favorite);');
  6278. Add(' i:=ord(low(TFlags));');
  6279. Add(' i:=ord(low(f));');
  6280. Add(' i:=ord(low(favorite));');
  6281. Add(' i:=ord(high(TFlags));');
  6282. Add(' i:=ord(high(f));');
  6283. Add(' i:=ord(high(favorite));');
  6284. Add(' f:=[green,favorite];');
  6285. ConvertProgram;
  6286. CheckSource('TestSet_AnonymousEnumType',
  6287. LinesToStr([ // statements
  6288. 'this.TFlags$a = {',
  6289. ' "0": "red",',
  6290. ' red: 0,',
  6291. ' "1": "green",',
  6292. ' green: 1',
  6293. '};',
  6294. 'this.favorite = this.TFlags$a.red;',
  6295. 'this.f = {};',
  6296. 'this.i = 0;',
  6297. '']),
  6298. LinesToStr([
  6299. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  6300. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  6301. '$mod.i = $mod.TFlags$a.red;',
  6302. '$mod.i = $mod.TFlags$a.red;',
  6303. '$mod.i = $mod.TFlags$a.red;',
  6304. '$mod.i = $mod.TFlags$a.red;',
  6305. '$mod.i = $mod.TFlags$a.red;',
  6306. '$mod.i = $mod.TFlags$a.green;',
  6307. '$mod.i = $mod.TFlags$a.green;',
  6308. '$mod.i = $mod.TFlags$a.green;',
  6309. '$mod.f = rtl.createSet($mod.TFlags$a.green, $mod.TFlags$a.red);',
  6310. '']));
  6311. end;
  6312. procedure TTestModule.TestSet_AnonymousEnumTypeChar;
  6313. begin
  6314. exit;
  6315. StartProgram(false);
  6316. Add([
  6317. 'type',
  6318. ' TAtoZ = ''A''..''Z'';',
  6319. ' TSetOfAZ = set of TAtoZ;',
  6320. 'var',
  6321. ' c: char;',
  6322. ' a: TAtoZ;',
  6323. ' s: TSetOfAZ = [''P'',''A''];',
  6324. ' i: longint;',
  6325. 'begin',
  6326. ' Include(s,''S'');',
  6327. ' Include(s,c);',
  6328. ' Include(s,a);',
  6329. ' c:=low(TAtoZ);',
  6330. ' i:=ord(low(TAtoZ));',
  6331. ' a:=high(TAtoZ);',
  6332. ' a:=high(TSetOfAtoZ);',
  6333. ' s:=[a,c,''M''];',
  6334. '']);
  6335. ConvertProgram;
  6336. CheckSource('TestSet_AnonymousEnumTypeChar',
  6337. LinesToStr([ // statements
  6338. '']),
  6339. LinesToStr([
  6340. '']));
  6341. end;
  6342. procedure TTestModule.TestSet_ConstEnum;
  6343. begin
  6344. StartProgram(false);
  6345. Add([
  6346. 'type',
  6347. ' TEnum = (red,blue,green);',
  6348. ' TEnums = set of TEnum;',
  6349. 'const',
  6350. ' teAny = [low(TEnum)..high(TEnum)];',
  6351. ' teRedBlue = [low(TEnum)..pred(high(TEnum))];',
  6352. 'var',
  6353. ' e: TEnum;',
  6354. ' s: TEnums;',
  6355. 'begin',
  6356. ' if blue in teAny then;',
  6357. ' if blue in teAny+[e] then;',
  6358. ' if blue in teAny+teRedBlue then;',
  6359. ' if e in [red,blue] then;',
  6360. ' s:=teAny;',
  6361. ' s:=teAny+[e];',
  6362. ' s:=[e]+teAny;',
  6363. ' s:=teAny+teRedBlue;',
  6364. ' s:=teAny+teRedBlue+[e];',
  6365. '']);
  6366. ConvertProgram;
  6367. CheckSource('TestSet_ConstEnum',
  6368. LinesToStr([ // statements
  6369. 'this.TEnum = {',
  6370. ' "0": "red",',
  6371. ' red: 0,',
  6372. ' "1": "blue",',
  6373. ' blue: 1,',
  6374. ' "2": "green",',
  6375. ' green: 2',
  6376. '};',
  6377. 'this.teAny = rtl.createSet(null, this.TEnum.red, this.TEnum.green);',
  6378. 'this.teRedBlue = rtl.createSet(null, this.TEnum.red, this.TEnum.green - 1);',
  6379. 'this.e = 0;',
  6380. 'this.s = {};',
  6381. '']),
  6382. LinesToStr([
  6383. 'if ($mod.TEnum.blue in $mod.teAny) ;',
  6384. 'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, rtl.createSet($mod.e))) ;',
  6385. 'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, $mod.teRedBlue)) ;',
  6386. 'if ($mod.e in rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)) ;',
  6387. '$mod.s = rtl.refSet($mod.teAny);',
  6388. '$mod.s = rtl.unionSet($mod.teAny, rtl.createSet($mod.e));',
  6389. '$mod.s = rtl.unionSet(rtl.createSet($mod.e), $mod.teAny);',
  6390. '$mod.s = rtl.unionSet($mod.teAny, $mod.teRedBlue);',
  6391. '$mod.s = rtl.unionSet(rtl.unionSet($mod.teAny, $mod.teRedBlue), rtl.createSet($mod.e));',
  6392. '']));
  6393. end;
  6394. procedure TTestModule.TestSet_ConstChar;
  6395. begin
  6396. StartProgram(false);
  6397. Add([
  6398. 'const',
  6399. ' LowChars = [''a''..''z''];',
  6400. ' Chars = LowChars+[''A''..''Z''];',
  6401. ' sc = [''А'', ''Я''];',
  6402. 'var',
  6403. ' c: char;',
  6404. ' s: string;',
  6405. 'begin',
  6406. ' if c in lowchars then ;',
  6407. ' if ''a'' in lowchars then ;',
  6408. ' if s[1] in lowchars then ;',
  6409. ' if c in chars then ;',
  6410. ' if c in [''a''..''z'',''_''] then ;',
  6411. ' if ''b'' in [''a''..''z'',''_''] then ;',
  6412. ' if ''Я'' in sc then ;',
  6413. ' if 3=ord('' '') then ;',
  6414. '']);
  6415. ConvertProgram;
  6416. CheckSource('TestSet_ConstChar',
  6417. LinesToStr([ // statements
  6418. 'this.LowChars = rtl.createSet(null, 97, 122);',
  6419. 'this.Chars = rtl.unionSet(this.LowChars, rtl.createSet(null, 65, 90));',
  6420. 'this.sc = rtl.createSet(1040, 1071);',
  6421. 'this.c = "";',
  6422. 'this.s = "";',
  6423. '']),
  6424. LinesToStr([
  6425. 'if ($mod.c.charCodeAt() in $mod.LowChars) ;',
  6426. 'if (97 in $mod.LowChars) ;',
  6427. 'if ($mod.s.charCodeAt(0) in $mod.LowChars) ;',
  6428. 'if ($mod.c.charCodeAt() in $mod.Chars) ;',
  6429. 'if ($mod.c.charCodeAt() in rtl.createSet(null, 97, 122, 95)) ;',
  6430. 'if (98 in rtl.createSet(null, 97, 122, 95)) ;',
  6431. 'if (1071 in $mod.sc) ;',
  6432. 'if (3 === 32) ;',
  6433. '']));
  6434. end;
  6435. procedure TTestModule.TestSet_ConstInt;
  6436. begin
  6437. StartProgram(false);
  6438. Add([
  6439. 'const',
  6440. ' Months = [1..12];',
  6441. ' Mirror = [-12..-1]+Months;',
  6442. 'var',
  6443. ' i: smallint;',
  6444. 'begin',
  6445. ' if 3 in Months then;',
  6446. ' if i in Months+[i] then;',
  6447. ' if i in Months+Mirror then;',
  6448. ' if i in [4..6,8] then;',
  6449. '']);
  6450. ConvertProgram;
  6451. CheckSource('TestSet_ConstInt',
  6452. LinesToStr([ // statements
  6453. 'this.Months = rtl.createSet(null, 1, 12);',
  6454. 'this.Mirror = rtl.unionSet(rtl.createSet(null, -12, -1), this.Months);',
  6455. 'this.i = 0;',
  6456. '']),
  6457. LinesToStr([
  6458. 'if (3 in $mod.Months) ;',
  6459. 'if ($mod.i in rtl.unionSet($mod.Months, rtl.createSet($mod.i))) ;',
  6460. 'if ($mod.i in rtl.unionSet($mod.Months, $mod.Mirror)) ;',
  6461. 'if ($mod.i in rtl.createSet(null, 4, 6, 8)) ;',
  6462. '']));
  6463. end;
  6464. procedure TTestModule.TestSet_InFunction;
  6465. begin
  6466. StartProgram(false);
  6467. Add([
  6468. 'const',
  6469. ' TEnum = 3;',
  6470. ' TSetOfEnum = 4;',
  6471. ' TSetOfAno = 5;',
  6472. 'procedure DoIt;',
  6473. 'type',
  6474. ' TEnum = (red, blue);',
  6475. ' TSetOfEnum = set of TEnum;',
  6476. ' TSetOfAno = set of (up,down);',
  6477. 'var',
  6478. ' e: TEnum;',
  6479. ' se: TSetOfEnum;',
  6480. ' sa: TSetOfAno;',
  6481. 'begin',
  6482. ' se:=[e];',
  6483. ' sa:=[up];',
  6484. 'end;',
  6485. 'begin',
  6486. '']);
  6487. ConvertProgram;
  6488. CheckSource('TestSet_InFunction',
  6489. LinesToStr([ // statements
  6490. 'this.TEnum = 3;',
  6491. 'this.TSetOfEnum = 4;',
  6492. 'this.TSetOfAno = 5;',
  6493. 'var TEnum$1 = {',
  6494. ' "0": "red",',
  6495. ' red: 0,',
  6496. ' "1": "blue",',
  6497. ' blue: 1',
  6498. '};',
  6499. 'var TSetOfAno$a = {',
  6500. ' "0": "up",',
  6501. ' up: 0,',
  6502. ' "1": "down",',
  6503. ' down: 1',
  6504. '};',
  6505. 'this.DoIt = function () {',
  6506. ' var e = 0;',
  6507. ' var se = {};',
  6508. ' var sa = {};',
  6509. ' se = rtl.createSet(e);',
  6510. ' sa = rtl.createSet(TSetOfAno$a.up);',
  6511. '};',
  6512. '']),
  6513. LinesToStr([
  6514. '']));
  6515. end;
  6516. procedure TTestModule.TestSet_ForIn;
  6517. begin
  6518. StartProgram(false);
  6519. Add([
  6520. 'type',
  6521. ' TEnum = (Red, Green, Blue);',
  6522. ' TEnumRg = green..blue;',
  6523. ' TSetOfEnum = set of TEnum;',
  6524. ' TSetOfEnumRg = set of TEnumRg;',
  6525. 'var',
  6526. ' e, e2: TEnum;',
  6527. ' er: TEnum;',
  6528. ' s: TSetOfEnum;',
  6529. 'begin',
  6530. ' for e in TSetOfEnum do ;',
  6531. ' for e in TSetOfEnumRg do ;',
  6532. ' for e in [] do e2:=e;',
  6533. ' for e in [red..green] do e2:=e;',
  6534. ' for e in [green,blue] do e2:=e;',
  6535. ' for e in [red,blue] do e2:=e;',
  6536. ' for e in s do e2:=e;',
  6537. ' for er in TSetOfEnumRg do ;',
  6538. '']);
  6539. ConvertProgram;
  6540. CheckSource('TestSet_ForIn',
  6541. LinesToStr([ // statements
  6542. 'this.TEnum = {',
  6543. ' "0":"Red",',
  6544. ' Red:0,',
  6545. ' "1":"Green",',
  6546. ' Green:1,',
  6547. ' "2":"Blue",',
  6548. ' Blue:2',
  6549. ' };',
  6550. 'this.e = 0;',
  6551. 'this.e2 = 0;',
  6552. 'this.er = 0;',
  6553. 'this.s = {};',
  6554. '']),
  6555. LinesToStr([
  6556. 'for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  6557. 'for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  6558. 'for ($mod.e = 0; $mod.e <= 1; $mod.e++) $mod.e2 = $mod.e;',
  6559. 'for ($mod.e = 1; $mod.e <= 2; $mod.e++) $mod.e2 = $mod.e;',
  6560. 'for ($mod.e in rtl.createSet($mod.TEnum.Red, $mod.TEnum.Blue)) $mod.e2 = $mod.e;',
  6561. 'for (var $l in $mod.s){',
  6562. ' $mod.e = +$l;',
  6563. ' $mod.e2 = $mod.e;',
  6564. '};',
  6565. 'for ($mod.er = 1; $mod.er <= 2; $mod.er++) ;',
  6566. '']));
  6567. end;
  6568. procedure TTestModule.TestNestBegin;
  6569. begin
  6570. StartProgram(false);
  6571. Add('begin');
  6572. Add(' begin');
  6573. Add(' begin');
  6574. Add(' end;');
  6575. Add(' begin');
  6576. Add(' if true then ;');
  6577. Add(' end;');
  6578. Add(' end;');
  6579. ConvertProgram;
  6580. CheckSource('TestNestBegin',
  6581. '',
  6582. 'if (true) ;');
  6583. end;
  6584. procedure TTestModule.TestUnitImplVars;
  6585. begin
  6586. StartUnit(false);
  6587. Add('interface');
  6588. Add('implementation');
  6589. Add('var');
  6590. Add(' V1:longint;');
  6591. Add(' V2:longint = 3;');
  6592. Add(' V3:string = ''abc'';');
  6593. ConvertUnit;
  6594. CheckSource('TestUnitImplVars',
  6595. LinesToStr([ // statements
  6596. 'var $impl = $mod.$impl;',
  6597. '']),
  6598. '', // this.$init
  6599. LinesToStr([ // implementation
  6600. '$impl.V1 = 0;',
  6601. '$impl.V2 = 3;',
  6602. '$impl.V3 = "abc";',
  6603. '']) );
  6604. end;
  6605. procedure TTestModule.TestUnitImplConsts;
  6606. begin
  6607. StartUnit(false);
  6608. Add('interface');
  6609. Add('implementation');
  6610. Add('const');
  6611. Add(' v1 = 3;');
  6612. Add(' v2:longint = 4;');
  6613. Add(' v3:string = ''abc'';');
  6614. ConvertUnit;
  6615. CheckSource('TestUnitImplConsts',
  6616. LinesToStr([ // statements
  6617. 'var $impl = $mod.$impl;',
  6618. '']),
  6619. '', // this.$init
  6620. LinesToStr([ // implementation
  6621. '$impl.v1 = 3;',
  6622. '$impl.v2 = 4;',
  6623. '$impl.v3 = "abc";',
  6624. '']) );
  6625. end;
  6626. procedure TTestModule.TestUnitImplRecord;
  6627. begin
  6628. StartUnit(false);
  6629. Add('interface');
  6630. Add('implementation');
  6631. Add('type');
  6632. Add(' TMyRecord = record');
  6633. Add(' i: longint;');
  6634. Add(' end;');
  6635. Add('var aRec: TMyRecord;');
  6636. Add('initialization');
  6637. Add(' arec.i:=3;');
  6638. ConvertUnit;
  6639. CheckSource('TestUnitImplRecord',
  6640. LinesToStr([ // statements
  6641. 'var $impl = $mod.$impl;',
  6642. '']),
  6643. // this.$init
  6644. '$impl.aRec.i = 3;',
  6645. LinesToStr([ // implementation
  6646. 'rtl.recNewT($impl, "TMyRecord", function () {',
  6647. ' this.i = 0;',
  6648. ' this.$eq = function (b) {',
  6649. ' return this.i === b.i;',
  6650. ' };',
  6651. ' this.$assign = function (s) {',
  6652. ' this.i = s.i;',
  6653. ' return this;',
  6654. ' };',
  6655. '});',
  6656. '$impl.aRec = $impl.TMyRecord.$new();',
  6657. '']) );
  6658. end;
  6659. procedure TTestModule.TestRenameJSNameConflict;
  6660. begin
  6661. StartProgram(false);
  6662. Add('var apply: longint;');
  6663. Add('var bind: longint;');
  6664. Add('var call: longint;');
  6665. Add('begin');
  6666. ConvertProgram;
  6667. CheckSource('TestRenameJSNameConflict',
  6668. LinesToStr([ // statements
  6669. 'this.Apply = 0;',
  6670. 'this.Bind = 0;',
  6671. 'this.Call = 0;'
  6672. ]),
  6673. LinesToStr([ // this.$main
  6674. ''
  6675. ]));
  6676. end;
  6677. procedure TTestModule.TestLocalConst;
  6678. begin
  6679. StartProgram(false);
  6680. Add('procedure DoIt;');
  6681. Add('const');
  6682. Add(' cA: longint = 1;');
  6683. Add(' cB = 2;');
  6684. Add(' procedure Sub;');
  6685. Add(' const');
  6686. Add(' csA = 3;');
  6687. Add(' cB: double = 4;');
  6688. Add(' begin');
  6689. Add(' cb:=cb+csa;');
  6690. Add(' ca:=ca+csa+5;');
  6691. Add(' end;');
  6692. Add('begin');
  6693. Add(' ca:=ca+cb+6;');
  6694. Add('end;');
  6695. Add('begin');
  6696. ConvertProgram;
  6697. CheckSource('TestLocalConst',
  6698. LinesToStr([
  6699. 'var cA = 1;',
  6700. 'var cB = 2;',
  6701. 'var csA = 3;',
  6702. 'var cB$1 = 4;',
  6703. 'this.DoIt = function () {',
  6704. ' function Sub() {',
  6705. ' cB$1 = cB$1 + 3;',
  6706. ' cA = cA + 3 + 5;',
  6707. ' };',
  6708. ' cA = cA + 2 + 6;',
  6709. '};'
  6710. ]),
  6711. LinesToStr([
  6712. ]));
  6713. end;
  6714. procedure TTestModule.TestVarExternal;
  6715. begin
  6716. StartProgram(false);
  6717. Add('var');
  6718. Add(' NaN: double; external name ''Global.NaN'';');
  6719. Add(' d: double;');
  6720. Add('begin');
  6721. Add(' d:=NaN;');
  6722. ConvertProgram;
  6723. CheckSource('TestVarExternal',
  6724. LinesToStr([
  6725. 'this.d = 0.0;'
  6726. ]),
  6727. LinesToStr([
  6728. '$mod.d = Global.NaN;'
  6729. ]));
  6730. end;
  6731. procedure TTestModule.TestVarExternalOtherUnit;
  6732. begin
  6733. AddModuleWithIntfImplSrc('unit2.pas',
  6734. LinesToStr([
  6735. 'var NaN: double; external name ''Global.NaN'';',
  6736. 'var iV: longint;'
  6737. ]),
  6738. '');
  6739. StartUnit(true);
  6740. Add('interface');
  6741. Add('uses unit2;');
  6742. Add('implementation');
  6743. Add('var');
  6744. Add(' d: double;');
  6745. Add(' i: longint; external name ''$i'';');
  6746. Add('begin');
  6747. Add(' d:=nan;');
  6748. Add(' d:=uNit2.nan;');
  6749. Add(' d:=test1.d;');
  6750. Add(' i:=iv;');
  6751. Add(' i:=uNit2.iv;');
  6752. Add(' i:=test1.i;');
  6753. ConvertUnit;
  6754. CheckSource('TestVarExternalOtherUnit',
  6755. LinesToStr([
  6756. 'var $impl = $mod.$impl;',
  6757. '']),
  6758. LinesToStr([ // this.$init
  6759. '$impl.d = Global.NaN;',
  6760. '$impl.d = Global.NaN;',
  6761. '$impl.d = $impl.d;',
  6762. '$i = pas.unit2.iV;',
  6763. '$i = pas.unit2.iV;',
  6764. '$i = $i;',
  6765. '']),
  6766. LinesToStr([ // implementation
  6767. '$impl.d = 0.0;',
  6768. '']) );
  6769. end;
  6770. procedure TTestModule.TestVarAbsoluteFail;
  6771. begin
  6772. StartProgram(false);
  6773. Add([
  6774. 'var',
  6775. ' a: longint;',
  6776. ' b: longword absolute a;',
  6777. 'begin']);
  6778. SetExpectedPasResolverError('Invalid variable modifier "absolute"',nInvalidVariableModifier);
  6779. ConvertProgram;
  6780. end;
  6781. procedure TTestModule.TestConstExternal;
  6782. begin
  6783. StartProgram(false);
  6784. Add([
  6785. 'const',
  6786. ' PI: double; external name ''Global.PI'';',
  6787. ' Tau = 2*pi;',
  6788. 'var d: double;',
  6789. 'begin',
  6790. ' d:=pi;',
  6791. ' d:=tau+pi;']);
  6792. ConvertProgram;
  6793. CheckSource('TestConstExternal',
  6794. LinesToStr([
  6795. 'this.Tau = 2*Global.PI;',
  6796. 'this.d = 0.0;'
  6797. ]),
  6798. LinesToStr([
  6799. '$mod.d = Global.PI;',
  6800. '$mod.d = $mod.Tau + Global.PI;'
  6801. ]));
  6802. end;
  6803. procedure TTestModule.TestDouble;
  6804. begin
  6805. StartProgram(false);
  6806. Add([
  6807. 'type',
  6808. ' TDateTime = double;',
  6809. 'const',
  6810. ' a = TDateTime(2.7);',
  6811. ' b = a + TDateTime(1.7);',
  6812. ' c = 0.9 + 0.1;',
  6813. ' f0_1 = 0.1;',
  6814. ' f0_3 = 0.3;',
  6815. ' fn0_1 = -0.1;',
  6816. ' fn0_3 = -0.3;',
  6817. ' fn0_003 = -0.003;',
  6818. ' fn0_123456789 = -0.123456789;',
  6819. ' fn300_0 = -300.0;',
  6820. ' fn123456_0 = -123456.0;',
  6821. ' fn1234567_8 = -1234567.8;',
  6822. ' fn12345678_9 = -12345678.9;',
  6823. ' f1_0En12 = 1E-12;',
  6824. ' fn1_0En12 = -1E-12;',
  6825. ' maxdouble = 1.7e+308;',
  6826. ' mindouble = -1.7e+308;',
  6827. ' MinSafeIntDouble = -$1fffffffffffff;',
  6828. ' MinSafeIntDouble2 = -$20000000000000-1;',
  6829. ' MaxSafeIntDouble = $1fffffffffffff;',
  6830. ' DZeroResolution = 1E-12;',
  6831. ' Minus1 = -1E-12;',
  6832. ' EPS = 1E-9;',
  6833. ' DELTA = 0.001;',
  6834. ' Big = 129.789E+100;',
  6835. ' Test0_15 = 0.15;',
  6836. ' Test999 = 2.9999999999999;',
  6837. ' Test111999 = 211199999999999000.0;',
  6838. ' TestMinus111999 = -211199999999999000.0;',
  6839. ' Inf = 1.0 / 0.0;',
  6840. ' NegInf = -1.0 / 0.0;',
  6841. 'procedure Run(d: double); external name ''Run'';',
  6842. 'var',
  6843. ' d: double = b;',
  6844. 'begin',
  6845. ' d:=1.0;',
  6846. ' d:=1.0/3.0;',
  6847. ' d:=1.0/(3-2-1);',
  6848. ' d:=1/3;',
  6849. ' d:=5.0E-324;',
  6850. ' d:=1.7E308;',
  6851. ' d:=001.00E00;',
  6852. ' d:=002.00E001;',
  6853. ' d:=003.000E000;',
  6854. ' d:=-004.00E-00;',
  6855. ' d:=-005.00E-001;',
  6856. ' d:=10**3;',
  6857. ' d:=10 mod 3;',
  6858. ' d:=10 div 3;',
  6859. ' d:=c;',
  6860. ' d:=f0_1;',
  6861. ' d:=f0_3;',
  6862. ' d:=fn0_1;',
  6863. ' d:=fn0_3;',
  6864. ' d:=fn0_003;',
  6865. ' d:=fn0_123456789;',
  6866. ' d:=fn300_0;',
  6867. ' d:=fn123456_0;',
  6868. ' d:=fn1234567_8;',
  6869. ' d:=fn12345678_9;',
  6870. ' d:=f1_0En12;',
  6871. ' d:=fn1_0En12;',
  6872. ' d:=maxdouble;',
  6873. ' d:=mindouble;',
  6874. ' d:=MinSafeIntDouble;',
  6875. ' d:=double(MinSafeIntDouble);',
  6876. ' d:=MinSafeIntDouble2;',
  6877. ' d:=double(MinSafeIntDouble2);',
  6878. ' d:=MaxSafeIntDouble;',
  6879. ' d:=default(double);',
  6880. ' Run(Inf);',
  6881. ' Run(NegInf);',
  6882. '']);
  6883. ConvertProgram;
  6884. CheckSource('TestDouble',
  6885. LinesToStr([
  6886. 'this.a = 2.7;',
  6887. 'this.b = 2.7 + 1.7;',
  6888. 'this.c = 0.9 + 0.1;',
  6889. 'this.f0_1 = 0.1;',
  6890. 'this.f0_3 = 0.3;',
  6891. 'this.fn0_1 = -0.1;',
  6892. 'this.fn0_3 = -0.3;',
  6893. 'this.fn0_003 = -0.003;',
  6894. 'this.fn0_123456789 = -0.123456789;',
  6895. 'this.fn300_0 = -300.0;',
  6896. 'this.fn123456_0 = -123456.0;',
  6897. 'this.fn1234567_8 = -1234567.8;',
  6898. 'this.fn12345678_9 = -12345678.9;',
  6899. 'this.f1_0En12 = 1E-12;',
  6900. 'this.fn1_0En12 = -1E-12;',
  6901. 'this.maxdouble = 1.7e+308;',
  6902. 'this.mindouble = -1.7e+308;',
  6903. 'this.MinSafeIntDouble = -0x1fffffffffffff;',
  6904. 'this.MinSafeIntDouble2 = -0x20000000000000 - 1;',
  6905. 'this.MaxSafeIntDouble = 0x1fffffffffffff;',
  6906. 'this.DZeroResolution = 1E-12;',
  6907. 'this.Minus1 = -1E-12;',
  6908. 'this.EPS = 1E-9;',
  6909. 'this.DELTA = 0.001;',
  6910. 'this.Big = 129.789E+100;',
  6911. 'this.Test0_15 = 0.15;',
  6912. 'this.Test999 = 2.9999999999999;',
  6913. 'this.Test111999 = 211199999999999000.0;',
  6914. 'this.TestMinus111999 = -211199999999999000.0;',
  6915. 'this.Inf = 1.0 / 0.0;',
  6916. 'this.NegInf = -1.0 / 0.0;',
  6917. 'this.d = 4.4;',
  6918. '']),
  6919. LinesToStr([
  6920. '$mod.d = 1.0;',
  6921. '$mod.d = 1.0 / 3.0;',
  6922. '$mod.d = 1.0 / (3 - 2 - 1);',
  6923. '$mod.d = 1 / 3;',
  6924. '$mod.d = 5.0E-324;',
  6925. '$mod.d = 1.7E308;',
  6926. '$mod.d = 1.00E0;',
  6927. '$mod.d = 2.00E1;',
  6928. '$mod.d = 3.000E0;',
  6929. '$mod.d = -4.00E-0;',
  6930. '$mod.d = -5.00E-1;',
  6931. '$mod.d = Math.pow(10, 3);',
  6932. '$mod.d = 10 % 3;',
  6933. '$mod.d = rtl.trunc(10 / 3);',
  6934. '$mod.d = 1;',
  6935. '$mod.d = 0.1;',
  6936. '$mod.d = 0.3;',
  6937. '$mod.d = -0.1;',
  6938. '$mod.d = -0.3;',
  6939. '$mod.d = -0.003;',
  6940. '$mod.d = -0.123456789;',
  6941. '$mod.d = -300;',
  6942. '$mod.d = -123456;',
  6943. '$mod.d = -1234567.8;',
  6944. '$mod.d = -1.23456789E7;',
  6945. '$mod.d = 1E-12;',
  6946. '$mod.d = -1E-12;',
  6947. '$mod.d = 1.7E308;',
  6948. '$mod.d = -1.7E308;',
  6949. '$mod.d = -9007199254740991;',
  6950. '$mod.d = -9007199254740991;',
  6951. '$mod.d = -9.007199254740992E15;',
  6952. '$mod.d = -9.007199254740992E15;',
  6953. '$mod.d = 9007199254740991;',
  6954. '$mod.d = 0.0;',
  6955. 'Run(1 / 0);',
  6956. 'Run(-1 / 0);',
  6957. '']));
  6958. end;
  6959. procedure TTestModule.TestInteger;
  6960. begin
  6961. StartProgram(false);
  6962. Add([
  6963. 'const',
  6964. ' MinInt = low(NativeInt);',
  6965. ' MaxInt = high(NativeInt);',
  6966. 'type',
  6967. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  6968. 'const',
  6969. ' a = low(TMyInt)+High(TMyInt);',
  6970. 'var',
  6971. ' i: TMyInt;',
  6972. 'begin',
  6973. ' i:=-MinInt;',
  6974. ' i:=default(TMyInt);',
  6975. ' i:=low(i)+high(i);',
  6976. '']);
  6977. ConvertProgram;
  6978. CheckSource('TestIntegerRange',
  6979. LinesToStr([
  6980. 'this.MinInt = -9007199254740991;',
  6981. 'this.MaxInt = 9007199254740991;',
  6982. 'this.a = -9007199254740991 + 9007199254740991;',
  6983. 'this.i = 0;',
  6984. '']),
  6985. LinesToStr([
  6986. '$mod.i = - -9007199254740991;',
  6987. '$mod.i = -9007199254740991;',
  6988. '$mod.i = -9007199254740991 + 9007199254740991;',
  6989. '']));
  6990. end;
  6991. procedure TTestModule.TestIntegerRange;
  6992. begin
  6993. StartProgram(false);
  6994. Add([
  6995. 'const',
  6996. ' MinInt = -1;',
  6997. ' MaxInt = +1;',
  6998. 'type',
  6999. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  7000. ' TInt2 = 1..3;',
  7001. 'const',
  7002. ' a = low(TMyInt)+High(TMyInt);',
  7003. ' b = low(TInt2)+High(TInt2);',
  7004. ' s1 = [1];',
  7005. ' s2 = [1,2];',
  7006. ' s3 = [1..3];',
  7007. ' s4 = [low(shortint)..high(shortint)];',
  7008. ' s5 = [succ(low(shortint))..pred(high(shortint))];',
  7009. ' s6 = 1 in s2;',
  7010. 'var',
  7011. ' i: TMyInt;',
  7012. ' i2: TInt2;',
  7013. 'begin',
  7014. ' i:=i2;',
  7015. ' i:=default(TMyInt);',
  7016. ' if i=i2 then ;',
  7017. ' i:=ord(i2);',
  7018. '']);
  7019. ConvertProgram;
  7020. CheckSource('TestIntegerRange',
  7021. LinesToStr([
  7022. 'this.MinInt = -1;',
  7023. 'this.MaxInt = +1;',
  7024. 'this.a = -1 + 1;',
  7025. 'this.b = 1 + 3;',
  7026. 'this.s1 = rtl.createSet(1);',
  7027. 'this.s2 = rtl.createSet(1, 2);',
  7028. 'this.s3 = rtl.createSet(null, 1, 3);',
  7029. 'this.s4 = rtl.createSet(null, -128, 127);',
  7030. 'this.s5 = rtl.createSet(null, -128 + 1, 127 - 1);',
  7031. 'this.s6 = 1 in this.s2;',
  7032. 'this.i = 0;',
  7033. 'this.i2 = 0;',
  7034. '']),
  7035. LinesToStr([
  7036. '$mod.i = $mod.i2;',
  7037. '$mod.i = -1;',
  7038. 'if ($mod.i === $mod.i2) ;',
  7039. '$mod.i = $mod.i2;',
  7040. '']));
  7041. end;
  7042. procedure TTestModule.TestIntegerTypecasts;
  7043. begin
  7044. StartProgram(false);
  7045. Add([
  7046. 'var',
  7047. ' i: nativeint;',
  7048. ' b: byte;',
  7049. ' sh: shortint;',
  7050. ' w: word;',
  7051. ' sm: smallint;',
  7052. ' lw: longword;',
  7053. ' li: longint;',
  7054. 'begin',
  7055. ' b:=byte(i);',
  7056. ' sh:=shortint(i);',
  7057. ' w:=word(i);',
  7058. ' sm:=smallint(i);',
  7059. ' lw:=longword(i);',
  7060. ' li:=longint(i);',
  7061. '']);
  7062. ConvertProgram;
  7063. CheckSource('TestIntegerTypecasts',
  7064. LinesToStr([
  7065. 'this.i = 0;',
  7066. 'this.b = 0;',
  7067. 'this.sh = 0;',
  7068. 'this.w = 0;',
  7069. 'this.sm = 0;',
  7070. 'this.lw = 0;',
  7071. 'this.li = 0;',
  7072. '']),
  7073. LinesToStr([
  7074. '$mod.b = $mod.i & 255;',
  7075. '$mod.sh = (($mod.i & 255) << 24) >> 24;',
  7076. '$mod.w = $mod.i & 65535;',
  7077. '$mod.sm = (($mod.i & 65535) << 16) >> 16;',
  7078. '$mod.lw = $mod.i >>> 0;',
  7079. '$mod.li = $mod.i & 0xFFFFFFFF;',
  7080. '']));
  7081. end;
  7082. procedure TTestModule.TestInteger_BitwiseShrNativeInt;
  7083. begin
  7084. StartProgram(false);
  7085. Add([
  7086. 'var',
  7087. ' i,j: nativeint;',
  7088. 'begin',
  7089. ' i:=i shr 0;',
  7090. ' i:=i shr 1;',
  7091. ' i:=i shr 3;',
  7092. ' i:=i shr 54;',
  7093. ' i:=j shr i;',
  7094. '']);
  7095. ConvertProgram;
  7096. CheckResolverUnexpectedHints;
  7097. CheckSource('TestInteger_BitwiseShrNativeInt',
  7098. LinesToStr([
  7099. 'this.i = 0;',
  7100. 'this.j = 0;',
  7101. '']),
  7102. LinesToStr([
  7103. '$mod.i = $mod.i;',
  7104. '$mod.i = Math.floor($mod.i / 2);',
  7105. '$mod.i = Math.floor($mod.i / 8);',
  7106. '$mod.i = 0;',
  7107. '$mod.i = rtl.shr($mod.j, $mod.i);',
  7108. '']));
  7109. end;
  7110. procedure TTestModule.TestInteger_BitwiseShlNativeInt;
  7111. begin
  7112. StartProgram(false);
  7113. Add([
  7114. 'var',
  7115. ' i: nativeint;',
  7116. 'begin',
  7117. ' i:=i shl 0;',
  7118. ' i:=i shl 54;',
  7119. ' i:=123456789012 shl 1;',
  7120. ' i:=i shl 1;',
  7121. '']);
  7122. ConvertProgram;
  7123. CheckResolverUnexpectedHints;
  7124. CheckSource('TestInteger_BitwiseShrNativeInt',
  7125. LinesToStr([
  7126. 'this.i = 0;',
  7127. '']),
  7128. LinesToStr([
  7129. '$mod.i = $mod.i;',
  7130. '$mod.i = 0;',
  7131. '$mod.i = 246913578024;',
  7132. '$mod.i = rtl.shl($mod.i, 1);',
  7133. '']));
  7134. end;
  7135. procedure TTestModule.TestInteger_SystemFunc;
  7136. begin
  7137. StartProgram(true);
  7138. Add([
  7139. 'var',
  7140. ' i: byte;',
  7141. ' s: string;',
  7142. 'begin',
  7143. ' system.inc(i);',
  7144. ' system.str(i,s);',
  7145. ' s:=system.str(i);',
  7146. ' i:=system.low(i);',
  7147. ' i:=system.high(i);',
  7148. ' i:=system.pred(i);',
  7149. ' i:=system.succ(i);',
  7150. ' i:=system.ord(i);',
  7151. '']);
  7152. ConvertProgram;
  7153. CheckResolverUnexpectedHints;
  7154. CheckSource('TestInteger_SystemFunc',
  7155. LinesToStr([
  7156. 'this.i = 0;',
  7157. 'this.s = "";',
  7158. '']),
  7159. LinesToStr([
  7160. '$mod.i += 1;',
  7161. '$mod.s = "" + $mod.i;',
  7162. '$mod.s = "" + $mod.i;',
  7163. '$mod.i = 0;',
  7164. '$mod.i = 255;',
  7165. '$mod.i = $mod.i - 1;',
  7166. '$mod.i = $mod.i + 1;',
  7167. '$mod.i = $mod.i;',
  7168. '']));
  7169. end;
  7170. procedure TTestModule.TestInteger_AssignOutsideConst;
  7171. begin
  7172. StartProgram(false);
  7173. Add([
  7174. 'const',
  7175. ' MinInt = low(longint);',
  7176. ' MaxInt = high(longint);',
  7177. 'type',
  7178. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  7179. 'var',
  7180. ' i: TMyInt;',
  7181. ' aByte: byte;',
  7182. ' aShortInt: shortint;',
  7183. ' aWord: word;',
  7184. ' aSmallInt: smallint;',
  7185. ' aLongWord: longword;',
  7186. ' aLongInt: longint;',
  7187. ' aNativeInt: nativeint;',
  7188. ' aNativeUInt: nativeuint;',
  7189. 'begin',
  7190. ' aByte:=$FF;',
  7191. ' aByte:=$100;',
  7192. ' aByte:=-1;',
  7193. ' aByte:=-127;',
  7194. ' aByte:=-128;',
  7195. ' aByte:=-254;',
  7196. ' aByte:=-255;',
  7197. ' aByte:=-256;',
  7198. ' aShortInt:=127;',
  7199. ' aShortInt:=128;',
  7200. ' aShortInt:=-128;',
  7201. ' aShortInt:=-129;',
  7202. ' aWord:=$ffff;',
  7203. ' aWord:=$10000;',
  7204. ' aWord:=-1;',
  7205. ' aWord:=-$ffff;',
  7206. ' aWord:=-$10000;',
  7207. ' aWord:=-$10001;',
  7208. ' aSmallInt:=$7fff;',
  7209. ' aSmallInt:=$8000;',
  7210. ' aSmallInt:=-$8000;',
  7211. ' aSmallInt:=-$8001;',
  7212. ' aLongWord:=$ffffffff;',
  7213. ' aLongWord:=$100000000;',
  7214. ' aLongWord:=-1;',
  7215. ' aLongWord:=-$ffffffff;',
  7216. ' aNativeInt:=$1fffffffffffff;',
  7217. ' aNativeInt:=-$1fffffffffffff;',
  7218. ' aNativeUInt:=$1fffffffffffff;',
  7219. ' aNativeUInt:=-$1fffffffffffff;',
  7220. '']);
  7221. ConvertProgram;
  7222. CheckSource('TestInteger_AssignOutsideConst',
  7223. LinesToStr([
  7224. 'this.MinInt = -2147483648;',
  7225. 'this.MaxInt = 2147483647;',
  7226. 'this.i = 0;',
  7227. 'this.aByte = 0;',
  7228. 'this.aShortInt = 0;',
  7229. 'this.aWord = 0;',
  7230. 'this.aSmallInt = 0;',
  7231. 'this.aLongWord = 0;',
  7232. 'this.aLongInt = 0;',
  7233. 'this.aNativeInt = 0;',
  7234. 'this.aNativeUInt = 0;',
  7235. '']),
  7236. LinesToStr([
  7237. '$mod.aByte = 0xFF;',
  7238. '$mod.aByte = 0;',
  7239. '$mod.aByte = 255;',
  7240. '$mod.aByte = 129;',
  7241. '$mod.aByte = 128;',
  7242. '$mod.aByte = 2;',
  7243. '$mod.aByte = 1;',
  7244. '$mod.aByte = 0;',
  7245. '$mod.aShortInt = 127;',
  7246. '$mod.aShortInt = -128;',
  7247. '$mod.aShortInt = -128;',
  7248. '$mod.aShortInt = 127;',
  7249. '$mod.aWord = 0xffff;',
  7250. '$mod.aWord = 0;',
  7251. '$mod.aWord = 65535;',
  7252. '$mod.aWord = 1;',
  7253. '$mod.aWord = 0;',
  7254. '$mod.aWord = 65535;',
  7255. '$mod.aSmallInt = 0x7fff;',
  7256. '$mod.aSmallInt = -32768;',
  7257. '$mod.aSmallInt = -0x8000;',
  7258. '$mod.aSmallInt = 32767;',
  7259. '$mod.aLongWord = 0xffffffff;',
  7260. '$mod.aLongWord = 0;',
  7261. '$mod.aLongWord = 4294967295;',
  7262. '$mod.aLongWord = 1;',
  7263. '$mod.aNativeInt = 0x1fffffffffffff;',
  7264. '$mod.aNativeInt = -0x1fffffffffffff;',
  7265. '$mod.aNativeUInt = 0x1fffffffffffff;',
  7266. '$mod.aNativeUInt = 1;',
  7267. '']));
  7268. end;
  7269. procedure TTestModule.TestCurrency;
  7270. begin
  7271. StartProgram(false);
  7272. Add([
  7273. 'type',
  7274. ' TCoin = currency;',
  7275. 'const',
  7276. ' a = TCoin(2.7);',
  7277. ' b = a + TCoin(1.7);',
  7278. ' MinSafeIntCurrency: TCoin = -92233720368.5477;',
  7279. ' MaxSafeIntCurrency: TCoin = 92233720368.5477;',
  7280. 'var',
  7281. ' c: TCoin = b;',
  7282. ' i: nativeint;',
  7283. ' d: double;',
  7284. ' j: jsvalue;',
  7285. 'function DoIt(c: currency): currency; begin end;',
  7286. 'function GetIt(d: double): double; begin end;',
  7287. 'procedure Write(v: jsvalue); begin end;',
  7288. 'begin',
  7289. ' c:=1.0;',
  7290. ' c:=0.1;',
  7291. ' c:=1.0/3.0;',
  7292. ' c:=1/3;',
  7293. ' c:=a;',
  7294. ' d:=c;',
  7295. ' c:=d;',
  7296. ' c:=currency(c);',
  7297. ' c:=currency(d);',
  7298. ' d:=double(c);',
  7299. ' c:=i;',
  7300. ' c:=currency(i);',
  7301. //' i:=c;', not allowed
  7302. ' i:=nativeint(c);',
  7303. ' c:=c+a;',
  7304. ' c:=-c-a;',
  7305. ' c:=d+c;',
  7306. ' c:=c+d;',
  7307. ' c:=d-c;',
  7308. ' c:=c-d;',
  7309. ' c:=c*a;',
  7310. ' c:=a*c;',
  7311. ' c:=d*c;',
  7312. ' c:=c*d;',
  7313. ' c:=c/a;',
  7314. ' c:=a/c;',
  7315. ' c:=d/c;',
  7316. ' c:=c/d;',
  7317. ' c:=c**a;',
  7318. ' c:=a**c;',
  7319. ' c:=d**c;',
  7320. ' c:=c**d;',
  7321. ' if c=c then ;',
  7322. ' if c=a then ;',
  7323. ' if a=c then ;',
  7324. ' if d=c then ;',
  7325. ' if c=d then ;',
  7326. ' c:=DoIt(c);',
  7327. ' c:=DoIt(i);',
  7328. ' c:=DoIt(d);',
  7329. ' c:=GetIt(c);',
  7330. ' j:=c;',
  7331. ' Write(c);',
  7332. ' c:=default(currency);',
  7333. ' j:=str(c);',
  7334. ' j:=str(c:0:3);',
  7335. '']);
  7336. ConvertProgram;
  7337. CheckSource('TestCurrency',
  7338. LinesToStr([
  7339. 'this.a = 27000;',
  7340. 'this.b = this.a + 17000;',
  7341. 'this.MinSafeIntCurrency = -92233720368.5477;',
  7342. 'this.MaxSafeIntCurrency = 92233720368.5477;',
  7343. 'this.c = this.b;',
  7344. 'this.i = 0;',
  7345. 'this.d = 0.0;',
  7346. 'this.j = undefined;',
  7347. 'this.DoIt = function (c) {',
  7348. ' var Result = 0;',
  7349. ' return Result;',
  7350. '};',
  7351. 'this.GetIt = function (d) {',
  7352. ' var Result = 0.0;',
  7353. ' return Result;',
  7354. '};',
  7355. 'this.Write = function (v) {',
  7356. '};',
  7357. '']),
  7358. LinesToStr([
  7359. '$mod.c = 10000;',
  7360. '$mod.c = 1000;',
  7361. '$mod.c = rtl.trunc((1.0 / 3.0) * 10000);',
  7362. '$mod.c = rtl.trunc((1 / 3) * 10000);',
  7363. '$mod.c = $mod.a;',
  7364. '$mod.d = $mod.c / 10000;',
  7365. '$mod.c = rtl.trunc($mod.d * 10000);',
  7366. '$mod.c = $mod.c;',
  7367. '$mod.c = $mod.d * 10000;',
  7368. '$mod.d = $mod.c / 10000;',
  7369. '$mod.c = $mod.i * 10000;',
  7370. '$mod.c = $mod.i * 10000;',
  7371. '$mod.i = rtl.trunc($mod.c / 10000);',
  7372. '$mod.c = $mod.c + $mod.a;',
  7373. '$mod.c = -$mod.c - $mod.a;',
  7374. '$mod.c = ($mod.d * 10000) + $mod.c;',
  7375. '$mod.c = $mod.c + ($mod.d * 10000);',
  7376. '$mod.c = ($mod.d * 10000) - $mod.c;',
  7377. '$mod.c = $mod.c - ($mod.d * 10000);',
  7378. '$mod.c = ($mod.c * $mod.a) / 10000;',
  7379. '$mod.c = ($mod.a * $mod.c) / 10000;',
  7380. '$mod.c = $mod.d * $mod.c;',
  7381. '$mod.c = $mod.c * $mod.d;',
  7382. '$mod.c = rtl.trunc(($mod.c / $mod.a) * 10000);',
  7383. '$mod.c = rtl.trunc(($mod.a / $mod.c) * 10000);',
  7384. '$mod.c = rtl.trunc($mod.d / $mod.c);',
  7385. '$mod.c = rtl.trunc($mod.c / $mod.d);',
  7386. '$mod.c = rtl.trunc(Math.pow($mod.c / 10000, $mod.a / 10000) * 10000);',
  7387. '$mod.c = rtl.trunc(Math.pow($mod.a / 10000, $mod.c / 10000) * 10000);',
  7388. '$mod.c = rtl.trunc(Math.pow($mod.d, $mod.c / 10000) * 10000);',
  7389. '$mod.c = rtl.trunc(Math.pow($mod.c / 10000, $mod.d) * 10000);',
  7390. 'if ($mod.c === $mod.c) ;',
  7391. 'if ($mod.c === $mod.a) ;',
  7392. 'if ($mod.a === $mod.c) ;',
  7393. 'if (($mod.d * 10000) === $mod.c) ;',
  7394. 'if ($mod.c === ($mod.d * 10000)) ;',
  7395. '$mod.c = $mod.DoIt($mod.c);',
  7396. '$mod.c = $mod.DoIt($mod.i * 10000);',
  7397. '$mod.c = $mod.DoIt($mod.d * 10000);',
  7398. '$mod.c = rtl.trunc($mod.GetIt($mod.c / 10000) * 10000);',
  7399. '$mod.j = $mod.c / 10000;',
  7400. '$mod.Write($mod.c / 10000);',
  7401. '$mod.c = 0;',
  7402. '$mod.j = rtl.floatToStr($mod.c / 10000);',
  7403. '$mod.j = rtl.floatToStr($mod.c / 10000, 0, 3);',
  7404. '']));
  7405. end;
  7406. procedure TTestModule.TestForBoolDo;
  7407. begin
  7408. StartProgram(false);
  7409. Add([
  7410. 'var b: boolean;',
  7411. 'begin',
  7412. ' for b:=false to true do ;',
  7413. ' for b:=b downto false do ;',
  7414. ' for b in boolean do ;',
  7415. '']);
  7416. ConvertProgram;
  7417. CheckSource('TestForBoolDo',
  7418. LinesToStr([ // statements
  7419. 'this.b = false;']),
  7420. LinesToStr([ // this.$main
  7421. 'for (var $l = 0; $l <= 1; $l++) $mod.b = $l !== 0;',
  7422. 'for (var $l1 = +$mod.b; $l1 >= 0; $l1--) $mod.b = $l1 !== 0;',
  7423. 'for (var $l2 = 0; $l2 <= 1; $l2++) $mod.b = $l2 !== 0;',
  7424. '']));
  7425. end;
  7426. procedure TTestModule.TestForIntDo;
  7427. begin
  7428. StartProgram(false);
  7429. Add([
  7430. 'var i: longint;',
  7431. 'begin',
  7432. ' for i:=3 to 5 do ;',
  7433. ' for i:=i downto 2 do ;',
  7434. ' for i in byte do ;',
  7435. '']);
  7436. ConvertProgram;
  7437. CheckSource('TestForIntDo',
  7438. LinesToStr([ // statements
  7439. 'this.i = 0;']),
  7440. LinesToStr([ // this.$main
  7441. 'for ($mod.i = 3; $mod.i <= 5; $mod.i++) ;',
  7442. 'for (var $l = $mod.i; $l >= 2; $l--) $mod.i = $l;',
  7443. 'for (var $l1 = 0; $l1 <= 255; $l1++) $mod.i = $l1;',
  7444. '']));
  7445. end;
  7446. procedure TTestModule.TestForIntInDo;
  7447. begin
  7448. StartProgram(false);
  7449. Add([
  7450. 'type',
  7451. ' TSetOfInt = set of byte;',
  7452. ' TIntRg = 3..7;',
  7453. ' TSetOfIntRg = set of TIntRg;',
  7454. 'var',
  7455. ' i,i2: longint;',
  7456. ' a1: array of byte;',
  7457. ' a2: array[1..3] of byte;',
  7458. ' soi: TSetOfInt;',
  7459. ' soir: TSetOfIntRg;',
  7460. ' ir: TIntRg;',
  7461. 'begin',
  7462. ' for i in byte do ;',
  7463. ' for i in a1 do ;',
  7464. ' for i in a2 do ;',
  7465. ' for i in [11..13] do ;',
  7466. ' for i in TSetOfInt do ;',
  7467. ' for i in TIntRg do ;',
  7468. ' for i in soi do i2:=i;',
  7469. ' for i in TSetOfIntRg do ;',
  7470. ' for i in soir do ;',
  7471. ' for ir in TIntRg do ;',
  7472. ' for ir in TSetOfIntRg do ;',
  7473. ' for ir in soir do ;',
  7474. '']);
  7475. ConvertProgram;
  7476. CheckSource('TestForIntInDo',
  7477. LinesToStr([ // statements
  7478. 'this.i = 0;',
  7479. 'this.i2 = 0;',
  7480. 'this.a1 = [];',
  7481. 'this.a2 = rtl.arraySetLength(null, 0, 3);',
  7482. 'this.soi = {};',
  7483. 'this.soir = {};',
  7484. 'this.ir = 0;',
  7485. '']),
  7486. LinesToStr([ // this.$main
  7487. 'for (var $l = 0; $l <= 255; $l++) $mod.i = $l;',
  7488. 'for (var $in = $mod.a1, $l1 = 0, $end = rtl.length($in) - 1; $l1 <= $end; $l1++) $mod.i = $in[$l1];',
  7489. 'for (var $in1 = $mod.a2, $l2 = 0, $end1 = rtl.length($in1) - 1; $l2 <= $end1; $l2++) $mod.i = $in1[$l2];',
  7490. 'for (var $l3 = 11; $l3 <= 13; $l3++) $mod.i = $l3;',
  7491. 'for (var $l4 = 0; $l4 <= 255; $l4++) $mod.i = $l4;',
  7492. 'for (var $l5 = 3; $l5 <= 7; $l5++) $mod.i = $l5;',
  7493. 'for (var $l6 in $mod.soi) {',
  7494. ' $mod.i = +$l6;',
  7495. ' $mod.i2 = $mod.i;',
  7496. '};',
  7497. 'for (var $l7 = 3; $l7 <= 7; $l7++) $mod.i = $l7;',
  7498. 'for (var $l8 in $mod.soir) $mod.i = +$l8;',
  7499. 'for (var $l9 = 3; $l9 <= 7; $l9++) $mod.ir = $l9;',
  7500. 'for (var $l10 = 3; $l10 <= 7; $l10++) $mod.ir = $l10;',
  7501. 'for (var $l11 in $mod.soir) $mod.ir = +$l11;',
  7502. '']));
  7503. end;
  7504. procedure TTestModule.TestCharConst;
  7505. begin
  7506. StartProgram(false);
  7507. Add([
  7508. 'const',
  7509. ' a = #$00F3;',
  7510. ' c: char = ''1'';',
  7511. ' wc: widechar = ''ä'';',
  7512. 'begin',
  7513. ' c:=#0;',
  7514. ' c:=#1;',
  7515. ' c:=#9;',
  7516. ' c:=#10;',
  7517. ' c:=#13;',
  7518. ' c:=#31;',
  7519. ' c:=#32;',
  7520. ' c:=#$A;',
  7521. ' c:=#$0A;',
  7522. ' c:=#$b;',
  7523. ' c:=#$0b;',
  7524. ' c:=^A;',
  7525. ' c:=''"'';',
  7526. ' c:=default(char);',
  7527. ' c:=#$00E4;', // ä
  7528. ' c:=''ä'';',
  7529. ' c:=#$E4;', // ä
  7530. ' c:=#$D800;', // invalid UTF-16
  7531. ' c:=#$DFFF;', // invalid UTF-16
  7532. ' c:=#$FFFF;', // last UCS-2
  7533. ' c:=high(c);', // last UCS-2
  7534. ' c:=#269;',
  7535. '']);
  7536. ConvertProgram;
  7537. CheckSource('TestCharConst',
  7538. LinesToStr([
  7539. 'this.a="ó";',
  7540. 'this.c="1";',
  7541. 'this.wc="ä";'
  7542. ]),
  7543. LinesToStr([
  7544. '$mod.c="\x00";',
  7545. '$mod.c="\x01";',
  7546. '$mod.c="\t";',
  7547. '$mod.c="\n";',
  7548. '$mod.c="\r";',
  7549. '$mod.c="\x1F";',
  7550. '$mod.c=" ";',
  7551. '$mod.c="\n";',
  7552. '$mod.c="\n";',
  7553. '$mod.c="\x0B";',
  7554. '$mod.c="\x0B";',
  7555. '$mod.c="\x01";',
  7556. '$mod.c=''"'';',
  7557. '$mod.c="\x00";',
  7558. '$mod.c = "ä";',
  7559. '$mod.c = "ä";',
  7560. '$mod.c = "ä";',
  7561. '$mod.c="\uD800";',
  7562. '$mod.c="\uDFFF";',
  7563. '$mod.c="\uFFFF";',
  7564. '$mod.c="\uFFFF";',
  7565. '$mod.c = "č";',
  7566. '']));
  7567. end;
  7568. procedure TTestModule.TestChar_Compare;
  7569. begin
  7570. StartProgram(false);
  7571. Add('var');
  7572. Add(' c: char;');
  7573. Add(' b: boolean;');
  7574. Add('begin');
  7575. Add(' b:=c=''1'';');
  7576. Add(' b:=''2''=c;');
  7577. Add(' b:=''3''=''4'';');
  7578. Add(' b:=c<>''5'';');
  7579. Add(' b:=''6''<>c;');
  7580. Add(' b:=c>''7'';');
  7581. Add(' b:=''8''>c;');
  7582. Add(' b:=c>=''9'';');
  7583. Add(' b:=''A''>=c;');
  7584. Add(' b:=c<''B'';');
  7585. Add(' b:=''C''<c;');
  7586. Add(' b:=c<=''D'';');
  7587. Add(' b:=''E''<=c;');
  7588. ConvertProgram;
  7589. CheckSource('TestChar_Compare',
  7590. LinesToStr([
  7591. 'this.c="";',
  7592. 'this.b = false;'
  7593. ]),
  7594. LinesToStr([
  7595. '$mod.b = $mod.c === "1";',
  7596. '$mod.b = "2" === $mod.c;',
  7597. '$mod.b = "3" === "4";',
  7598. '$mod.b = $mod.c !== "5";',
  7599. '$mod.b = "6" !== $mod.c;',
  7600. '$mod.b = $mod.c > "7";',
  7601. '$mod.b = "8" > $mod.c;',
  7602. '$mod.b = $mod.c >= "9";',
  7603. '$mod.b = "A" >= $mod.c;',
  7604. '$mod.b = $mod.c < "B";',
  7605. '$mod.b = "C" < $mod.c;',
  7606. '$mod.b = $mod.c <= "D";',
  7607. '$mod.b = "E" <= $mod.c;',
  7608. '']));
  7609. end;
  7610. procedure TTestModule.TestChar_BuiltInProcs;
  7611. begin
  7612. StartProgram(false);
  7613. Add([
  7614. 'var',
  7615. ' c: char;',
  7616. ' i: longint;',
  7617. ' s: string;',
  7618. 'begin',
  7619. ' i:=ord(c);',
  7620. ' i:=ord(s[i]);',
  7621. ' c:=chr(i);',
  7622. ' c:=pred(c);',
  7623. ' c:=succ(c);',
  7624. ' c:=low(c);',
  7625. ' c:=high(c);',
  7626. ' i:=byte(c);',
  7627. ' i:=word(c);',
  7628. ' i:=longint(c);',
  7629. '']);
  7630. ConvertProgram;
  7631. CheckSource('TestChar_BuiltInProcs',
  7632. LinesToStr([
  7633. 'this.c = "";',
  7634. 'this.i = 0;',
  7635. 'this.s = "";'
  7636. ]),
  7637. LinesToStr([
  7638. '$mod.i = $mod.c.charCodeAt();',
  7639. '$mod.i = $mod.s.charCodeAt($mod.i-1);',
  7640. '$mod.c = String.fromCharCode($mod.i);',
  7641. '$mod.c = String.fromCharCode($mod.c.charCodeAt() - 1);',
  7642. '$mod.c = String.fromCharCode($mod.c.charCodeAt() + 1);',
  7643. '$mod.c = "\x00";',
  7644. '$mod.c = "\uFFFF";',
  7645. '$mod.i = $mod.c.charCodeAt() & 255;',
  7646. '$mod.i = $mod.c.charCodeAt();',
  7647. '$mod.i = $mod.c.charCodeAt() & 0xFFFFFFFF;',
  7648. '']));
  7649. end;
  7650. procedure TTestModule.TestStringConst;
  7651. begin
  7652. StartProgram(false);
  7653. Add([
  7654. '{$H+}',
  7655. 'const',
  7656. ' a = #$00F3#$017C;', // first <256, then >=256
  7657. ' b = string(''a'');',
  7658. ' c = string(''ä'');',
  7659. ' d = UnicodeString(''b'');',
  7660. ' e = UnicodeString(''ö'');',
  7661. ' f = low(a)+high(b);',
  7662. ' g: word = low(a);',
  7663. 'var',
  7664. ' s: string = ''abc'';',
  7665. ' i: longint;',
  7666. 'begin',
  7667. ' s:='''';',
  7668. ' s:=#13#10;',
  7669. ' s:=#9''foo'';',
  7670. ' s:=#$A9;',
  7671. ' s:=''foo''#13''bar'';',
  7672. ' s:=''"'';',
  7673. ' s:=''"''''"'';',
  7674. ' s:=#$20AC;', // euro
  7675. ' s:=#$10437;', // outside BMP
  7676. ' s:=''abc''#$20AC;', // ascii,#
  7677. ' s:=''ä''#$20AC;', // non ascii,#
  7678. ' s:=#$20AC''abc'';', // #, ascii
  7679. ' s:=#$20AC''ä'';', // #, non ascii
  7680. ' s:=default(string);',
  7681. ' s:=concat(s);',
  7682. ' s:=concat(s,''a'',s);',
  7683. ' s:=#250#269;',
  7684. ' i:=low(s)+high(a);',
  7685. //' s:=#$2F804;',
  7686. // ToDo: \uD87E\uDC04 -> \u{2F804}
  7687. '']);
  7688. ConvertProgram;
  7689. CheckSource('TestStringConst',
  7690. LinesToStr([
  7691. 'this.a = "óż";',
  7692. 'this.b = "a";',
  7693. 'this.c = "ä";',
  7694. 'this.d = "b";',
  7695. 'this.e = "ö";',
  7696. 'this.f = 1 + this.b.length;',
  7697. 'this.g = 1;',
  7698. 'this.s="abc";',
  7699. 'this.i = 0;',
  7700. '']),
  7701. LinesToStr([
  7702. '$mod.s="";',
  7703. '$mod.s="\r\n";',
  7704. '$mod.s="\tfoo";',
  7705. '$mod.s="©";',
  7706. '$mod.s="foo\rbar";',
  7707. '$mod.s=''"'';',
  7708. '$mod.s=''"\''"'';',
  7709. '$mod.s="€";',
  7710. '$mod.s="'#$F0#$90#$90#$B7'";',
  7711. '$mod.s = "abc€";',
  7712. '$mod.s = "ä€";',
  7713. '$mod.s = "€abc";',
  7714. '$mod.s = "ۊ";',
  7715. '$mod.s="";',
  7716. '$mod.s = $mod.s;',
  7717. '$mod.s = $mod.s.concat("a", $mod.s);',
  7718. '$mod.s = "úč";',
  7719. '$mod.i = 1 + $mod.a.length;',
  7720. '']));
  7721. end;
  7722. procedure TTestModule.TestStringConst_InvalidUTF16;
  7723. begin
  7724. StartProgram(false);
  7725. Add([
  7726. 'const',
  7727. ' a: char = #$D87E;',
  7728. ' b: string = #$D87E;',
  7729. ' c: string = #$D87E#43;',
  7730. 'begin',
  7731. ' c:=''abc''#$D87E;',
  7732. ' c:=#0#1#2;',
  7733. ' c:=#127;',
  7734. ' c:=#128;',
  7735. ' c:=#255;',
  7736. ' c:=#256;',
  7737. '']);
  7738. ConvertProgram;
  7739. CheckSource('TestStringConst',
  7740. LinesToStr([
  7741. 'this.a = "\uD87E";',
  7742. 'this.b = "\uD87E";',
  7743. 'this.c = "\uD87E+";',
  7744. '']),
  7745. LinesToStr([
  7746. '$mod.c = "abc\uD87E";',
  7747. '$mod.c = "\x00\x01\x02";',
  7748. '$mod.c = "'#127'";',
  7749. '$mod.c = "'#$c2#$80'";',
  7750. '$mod.c = "'#$c3#$BF'";',
  7751. '$mod.c = "'#$c4#$80'";',
  7752. '']));
  7753. end;
  7754. procedure TTestModule.TestStringConstSurrogate;
  7755. begin
  7756. StartProgram(false);
  7757. Add([
  7758. 'var',
  7759. ' s: string;',
  7760. 'begin',
  7761. ' s:=''😊'';', // 1F60A
  7762. '']);
  7763. ConvertProgram;
  7764. CheckSource('TestStringConstSurrogate',
  7765. LinesToStr([
  7766. 'this.s="";'
  7767. ]),
  7768. LinesToStr([
  7769. '$mod.s="😊";'
  7770. ]));
  7771. end;
  7772. procedure TTestModule.TestString_Length;
  7773. begin
  7774. StartProgram(false);
  7775. Add('const c = ''foo'';');
  7776. Add('var');
  7777. Add(' s: string;');
  7778. Add(' i: longint;');
  7779. Add('begin');
  7780. Add(' i:=length(s);');
  7781. Add(' i:=length(s+s);');
  7782. Add(' i:=length(''abc'');');
  7783. Add(' i:=length(c);');
  7784. ConvertProgram;
  7785. CheckSource('TestString_Length',
  7786. LinesToStr([
  7787. 'this.c = "foo";',
  7788. 'this.s = "";',
  7789. 'this.i = 0;',
  7790. '']),
  7791. LinesToStr([
  7792. '$mod.i = $mod.s.length;',
  7793. '$mod.i = ($mod.s+$mod.s).length;',
  7794. '$mod.i = "abc".length;',
  7795. '$mod.i = $mod.c.length;',
  7796. '']));
  7797. end;
  7798. procedure TTestModule.TestString_Compare;
  7799. begin
  7800. StartProgram(false);
  7801. Add('var');
  7802. Add(' s, t: string;');
  7803. Add(' b: boolean;');
  7804. Add('begin');
  7805. Add(' b:=s=t;');
  7806. Add(' b:=s<>t;');
  7807. Add(' b:=s>t;');
  7808. Add(' b:=s>=t;');
  7809. Add(' b:=s<t;');
  7810. Add(' b:=s<=t;');
  7811. ConvertProgram;
  7812. CheckSource('TestString_Compare',
  7813. LinesToStr([ // statements
  7814. 'this.s = "";',
  7815. 'this.t = "";',
  7816. 'this.b =false;'
  7817. ]),
  7818. LinesToStr([ // this.$main
  7819. '$mod.b = $mod.s === $mod.t;',
  7820. '$mod.b = $mod.s !== $mod.t;',
  7821. '$mod.b = $mod.s > $mod.t;',
  7822. '$mod.b = $mod.s >= $mod.t;',
  7823. '$mod.b = $mod.s < $mod.t;',
  7824. '$mod.b = $mod.s <= $mod.t;',
  7825. '']));
  7826. end;
  7827. procedure TTestModule.TestString_SetLength;
  7828. begin
  7829. StartProgram(false);
  7830. Add([
  7831. 'procedure DoIt(var s: string);',
  7832. 'begin',
  7833. ' SetLength(s,2);',
  7834. 'end;',
  7835. 'var s: string;',
  7836. 'begin',
  7837. ' SetLength(s,3);',
  7838. '']);
  7839. ConvertProgram;
  7840. CheckSource('TestString_SetLength',
  7841. LinesToStr([ // statements
  7842. 'this.DoIt = function (s) {',
  7843. ' s.set(rtl.strSetLength(s.get(), 2));',
  7844. '};',
  7845. 'this.s = "";',
  7846. '']),
  7847. LinesToStr([ // this.$main
  7848. '$mod.s = rtl.strSetLength($mod.s, 3);'
  7849. ]));
  7850. end;
  7851. procedure TTestModule.TestString_CharAt;
  7852. begin
  7853. StartProgram(false);
  7854. Add([
  7855. 'var',
  7856. ' s: string;',
  7857. ' c: char;',
  7858. ' b: boolean;',
  7859. 'begin',
  7860. ' b:= s[1] = c;',
  7861. ' b:= c = s[1];',
  7862. ' b:= c <> s[1];',
  7863. ' b:= c > s[1];',
  7864. ' b:= c >= s[1];',
  7865. ' b:= c < s[2];',
  7866. ' b:= c <= s[1];',
  7867. ' s[1] := c;',
  7868. ' s[2+3] := c;']);
  7869. ConvertProgram;
  7870. CheckSource('TestString_CharAt',
  7871. LinesToStr([ // statements
  7872. 'this.s = "";',
  7873. 'this.c = "";',
  7874. 'this.b = false;'
  7875. ]),
  7876. LinesToStr([ // this.$main
  7877. '$mod.b = $mod.s.charAt(0) === $mod.c;',
  7878. '$mod.b = $mod.c === $mod.s.charAt(0);',
  7879. '$mod.b = $mod.c !== $mod.s.charAt(0);',
  7880. '$mod.b = $mod.c > $mod.s.charAt(0);',
  7881. '$mod.b = $mod.c >= $mod.s.charAt(0);',
  7882. '$mod.b = $mod.c < $mod.s.charAt(1);',
  7883. '$mod.b = $mod.c <= $mod.s.charAt(0);',
  7884. '$mod.s = rtl.setCharAt($mod.s, 0, $mod.c);',
  7885. '$mod.s = rtl.setCharAt($mod.s, (2 + 3) - 1, $mod.c);',
  7886. '']));
  7887. end;
  7888. procedure TTestModule.TestStringHMinusFail;
  7889. begin
  7890. StartProgram(false);
  7891. Add([
  7892. '{$H-}',
  7893. 'var s: string;',
  7894. 'begin']);
  7895. ConvertProgram;
  7896. CheckHint(mtWarning,nWarnIllegalCompilerDirectiveX,'Warning: test1.pp(3,6) : Illegal compiler directive "H-"');
  7897. end;
  7898. procedure TTestModule.TestStr;
  7899. begin
  7900. StartProgram(false);
  7901. Add('var');
  7902. Add(' b: boolean;');
  7903. Add(' i: longint;');
  7904. Add(' d: double;');
  7905. Add(' s: string;');
  7906. Add('begin');
  7907. Add(' str(b,s);');
  7908. Add(' str(i,s);');
  7909. Add(' str(d,s);');
  7910. Add(' str(i:3,s);');
  7911. Add(' str(d:3:2,s);');
  7912. Add(' Str(12.456:12:1,s);');
  7913. Add(' Str(12.456:12,s);');
  7914. Add(' s:=str(b);');
  7915. Add(' s:=str(i);');
  7916. Add(' s:=str(d);');
  7917. Add(' s:=str(i,i);');
  7918. Add(' s:=str(i:3);');
  7919. Add(' s:=str(d:3:2);');
  7920. Add(' s:=str(i:4,i);');
  7921. Add(' s:=str(i,i:5);');
  7922. Add(' s:=str(i:4,i:5);');
  7923. Add(' s:=str(s,s);');
  7924. Add(' s:=str(s,''foo'');');
  7925. ConvertProgram;
  7926. CheckSource('TestStr',
  7927. LinesToStr([ // statements
  7928. 'this.b = false;',
  7929. 'this.i = 0;',
  7930. 'this.d = 0.0;',
  7931. 'this.s = "";',
  7932. '']),
  7933. LinesToStr([ // this.$main
  7934. '$mod.s = ""+$mod.b;',
  7935. '$mod.s = ""+$mod.i;',
  7936. '$mod.s = rtl.floatToStr($mod.d);',
  7937. '$mod.s = rtl.spaceLeft(""+$mod.i,3);',
  7938. '$mod.s = rtl.floatToStr($mod.d,3,2);',
  7939. '$mod.s = rtl.floatToStr(12.456,12,1);',
  7940. '$mod.s = rtl.floatToStr(12.456,12);',
  7941. '$mod.s = ""+$mod.b;',
  7942. '$mod.s = ""+$mod.i;',
  7943. '$mod.s = rtl.floatToStr($mod.d);',
  7944. '$mod.s = ""+$mod.i+$mod.i;',
  7945. '$mod.s = rtl.spaceLeft(""+$mod.i,3);',
  7946. '$mod.s = rtl.floatToStr($mod.d,3,2);',
  7947. '$mod.s = rtl.spaceLeft("" + $mod.i, 4) + $mod.i;',
  7948. '$mod.s = "" + $mod.i + rtl.spaceLeft("" + $mod.i, 5);',
  7949. '$mod.s = rtl.spaceLeft("" + $mod.i, 4) + rtl.spaceLeft("" + $mod.i, 5);',
  7950. '$mod.s = $mod.s + $mod.s;',
  7951. '$mod.s = $mod.s + "foo";',
  7952. '']));
  7953. end;
  7954. procedure TTestModule.TestBaseType_AnsiStringFail;
  7955. begin
  7956. StartProgram(false);
  7957. Add('var s: AnsiString');
  7958. SetExpectedPasResolverError('identifier not found "AnsiString"',PasResolveEval.nIdentifierNotFound);
  7959. ConvertProgram;
  7960. end;
  7961. procedure TTestModule.TestBaseType_WideStringFail;
  7962. begin
  7963. StartProgram(false);
  7964. Add('var s: WideString');
  7965. SetExpectedPasResolverError('identifier not found "WideString"',PasResolveEval.nIdentifierNotFound);
  7966. ConvertProgram;
  7967. end;
  7968. procedure TTestModule.TestBaseType_ShortStringFail;
  7969. begin
  7970. StartProgram(false);
  7971. Add('var s: ShortString');
  7972. SetExpectedPasResolverError('identifier not found "ShortString"',PasResolveEval.nIdentifierNotFound);
  7973. ConvertProgram;
  7974. end;
  7975. procedure TTestModule.TestBaseType_RawByteStringFail;
  7976. begin
  7977. StartProgram(false);
  7978. Add('var s: RawByteString');
  7979. SetExpectedPasResolverError('identifier not found "RawByteString"',PasResolveEval.nIdentifierNotFound);
  7980. ConvertProgram;
  7981. end;
  7982. procedure TTestModule.TestTypeShortstring_Fail;
  7983. begin
  7984. StartProgram(false);
  7985. Add('type t = string[12];');
  7986. Add('var s: t;');
  7987. Add('begin');
  7988. SetExpectedPasResolverError('illegal qualifier "["',nIllegalQualifier);
  7989. ConvertProgram;
  7990. end;
  7991. procedure TTestModule.TestCharSet_Custom;
  7992. begin
  7993. StartProgram(false);
  7994. Add([
  7995. 'type',
  7996. ' TCharRg = ''a''..''z'';',
  7997. ' TSetOfCharRg = set of TCharRg;',
  7998. ' TCharRg2 = ''m''..''p'';',
  7999. 'const',
  8000. ' crg: TCharRg = ''b'';',
  8001. 'var',
  8002. ' c: char;',
  8003. ' crg2: TCharRg2;',
  8004. ' s: TSetOfCharRg;',
  8005. 'begin',
  8006. ' c:=crg;',
  8007. ' crg:=c;',
  8008. ' crg2:=crg;',
  8009. ' if c=crg then ;',
  8010. ' if crg=c then ;',
  8011. ' if crg=crg2 then ;',
  8012. ' if c in s then ;',
  8013. ' if crg2 in s then ;',
  8014. ' c:=default(TCharRg);',
  8015. '']);
  8016. ConvertProgram;
  8017. CheckSource('TestCharSet_Custom',
  8018. LinesToStr([ // statements
  8019. 'this.crg = "b";',
  8020. 'this.c = "";',
  8021. 'this.crg2 = "m";',
  8022. 'this.s = {};',
  8023. '']),
  8024. LinesToStr([ // this.$main
  8025. '$mod.c = $mod.crg;',
  8026. '$mod.crg = $mod.c;',
  8027. '$mod.crg2 = $mod.crg;',
  8028. 'if ($mod.c === $mod.crg) ;',
  8029. 'if ($mod.crg === $mod.c) ;',
  8030. 'if ($mod.crg === $mod.crg2) ;',
  8031. 'if ($mod.c.charCodeAt() in $mod.s) ;',
  8032. 'if ($mod.crg2.charCodeAt() in $mod.s) ;',
  8033. '$mod.c = "a";',
  8034. '']));
  8035. end;
  8036. procedure TTestModule.TestWideChar;
  8037. begin
  8038. StartProgram(false);
  8039. Add([
  8040. 'procedure Fly(var c: char);',
  8041. 'begin',
  8042. 'end;',
  8043. 'procedure Run(var c: widechar);',
  8044. 'begin',
  8045. 'end;',
  8046. 'var',
  8047. ' c: char;',
  8048. ' wc: widechar;',
  8049. ' w: word;',
  8050. 'begin',
  8051. ' Fly(wc);',
  8052. ' Run(c);',
  8053. ' wc:=WideChar(w);',
  8054. ' w:=ord(wc);',
  8055. '']);
  8056. ConvertProgram;
  8057. CheckSource('TestWideChar_VarArg',
  8058. LinesToStr([ // statements
  8059. 'this.Fly = function (c) {',
  8060. '};',
  8061. 'this.Run = function (c) {',
  8062. '};',
  8063. 'this.c = "";',
  8064. 'this.wc = "";',
  8065. 'this.w = 0;',
  8066. '']),
  8067. LinesToStr([ // this.$main
  8068. '$mod.Fly({',
  8069. ' p: $mod,',
  8070. ' get: function () {',
  8071. ' return this.p.wc;',
  8072. ' },',
  8073. ' set: function (v) {',
  8074. ' this.p.wc = v;',
  8075. ' }',
  8076. '});',
  8077. '$mod.Run({',
  8078. ' p: $mod,',
  8079. ' get: function () {',
  8080. ' return this.p.c;',
  8081. ' },',
  8082. ' set: function (v) {',
  8083. ' this.p.c = v;',
  8084. ' }',
  8085. '});',
  8086. '$mod.wc = String.fromCharCode($mod.w);',
  8087. '$mod.w = $mod.wc.charCodeAt();',
  8088. '',
  8089. '']));
  8090. end;
  8091. procedure TTestModule.TestForCharDo;
  8092. begin
  8093. StartProgram(false);
  8094. Add([
  8095. 'var c: char;',
  8096. 'begin',
  8097. ' for c:=''a'' to ''c'' do ;',
  8098. ' for c:=c downto ''a'' do ;',
  8099. ' for c:=''Б'' to ''Я'' do ;',
  8100. '']);
  8101. ConvertProgram;
  8102. CheckSource('TestForCharDo',
  8103. LinesToStr([ // statements
  8104. 'this.c = "";']),
  8105. LinesToStr([ // this.$main
  8106. 'for (var $l = 97; $l <= 99; $l++) $mod.c = String.fromCharCode($l);',
  8107. 'for (var $l1 = $mod.c.charCodeAt(); $l1 >= 97; $l1--) $mod.c = String.fromCharCode($l1);',
  8108. 'for (var $l2 = 1041; $l2 <= 1071; $l2++) $mod.c = String.fromCharCode($l2);',
  8109. '']));
  8110. end;
  8111. procedure TTestModule.TestForCharInDo;
  8112. begin
  8113. StartProgram(false);
  8114. Add([
  8115. 'type',
  8116. ' TSetOfChar = set of char;',
  8117. ' TCharRg = ''a''..''z'';',
  8118. ' TSetOfCharRg = set of TCharRg;',
  8119. 'const Foo = ''foo'';',
  8120. 'var',
  8121. ' c,c2: char;',
  8122. ' s: string;',
  8123. ' a1: array of char;',
  8124. ' a2: array[1..3] of char;',
  8125. ' soc: TSetOfChar;',
  8126. ' socr: TSetOfCharRg;',
  8127. ' cr: TCharRg;',
  8128. 'begin',
  8129. ' for c in foo do ;',
  8130. ' for c in s do ;',
  8131. ' for c in char do ;',
  8132. ' for c in a1 do ;',
  8133. ' for c in a2 do ;',
  8134. ' for c in [''1''..''3''] do ;',
  8135. ' for c in TSetOfChar do ;',
  8136. ' for c in TCharRg do ;',
  8137. ' for c in soc do c2:=c;',
  8138. ' for c in TSetOfCharRg do ;',
  8139. ' for c in socr do ;',
  8140. ' for cr in TCharRg do ;',
  8141. ' for cr in TSetOfCharRg do ;',
  8142. ' for cr in socr do ;',
  8143. '']);
  8144. ConvertProgram;
  8145. CheckSource('TestForCharInDo',
  8146. LinesToStr([ // statements
  8147. 'this.Foo = "foo";',
  8148. 'this.c = "";',
  8149. 'this.c2 = "";',
  8150. 'this.s = "";',
  8151. 'this.a1 = [];',
  8152. 'this.a2 = rtl.arraySetLength(null, "", 3);',
  8153. 'this.soc = {};',
  8154. 'this.socr = {};',
  8155. 'this.cr = "a";',
  8156. '']),
  8157. LinesToStr([ // this.$main
  8158. 'for (var $in = $mod.Foo, $l = 0, $end = $in.length - 1; $l <= $end; $l++) $mod.c = $in.charAt($l);',
  8159. 'for (var $in1 = $mod.s, $l1 = 0, $end1 = $in1.length - 1; $l1 <= $end1; $l1++) $mod.c = $in1.charAt($l1);',
  8160. 'for (var $l2 = 0; $l2 <= 65535; $l2++) $mod.c = String.fromCharCode($l2);',
  8161. 'for (var $in2 = $mod.a1, $l3 = 0, $end2 = rtl.length($in2) - 1; $l3 <= $end2; $l3++) $mod.c = $in2[$l3];',
  8162. 'for (var $in3 = $mod.a2, $l4 = 0, $end3 = rtl.length($in3) - 1; $l4 <= $end3; $l4++) $mod.c = $in3[$l4];',
  8163. 'for (var $l5 = 49; $l5 <= 51; $l5++) $mod.c = String.fromCharCode($l5);',
  8164. 'for (var $l6 = 0; $l6 <= 65535; $l6++) $mod.c = String.fromCharCode($l6);',
  8165. 'for (var $l7 = 97; $l7 <= 122; $l7++) $mod.c = String.fromCharCode($l7);',
  8166. 'for (var $l8 in $mod.soc) {',
  8167. ' $mod.c = String.fromCharCode($l8);',
  8168. ' $mod.c2 = $mod.c;',
  8169. '};',
  8170. 'for (var $l9 = 97; $l9 <= 122; $l9++) $mod.c = String.fromCharCode($l9);',
  8171. 'for (var $l10 in $mod.socr) $mod.c = String.fromCharCode($l10);',
  8172. 'for (var $l11 = 97; $l11 <= 122; $l11++) $mod.cr = String.fromCharCode($l11);',
  8173. 'for (var $l12 = 97; $l12 <= 122; $l12++) $mod.cr = String.fromCharCode($l12);',
  8174. 'for (var $l13 in $mod.socr) $mod.cr = String.fromCharCode($l13);',
  8175. '']));
  8176. end;
  8177. procedure TTestModule.TestProcTwoArgs;
  8178. begin
  8179. StartProgram(false);
  8180. Add('procedure Test(a,b: longint);');
  8181. Add('begin');
  8182. Add('end;');
  8183. Add('begin');
  8184. ConvertProgram;
  8185. CheckSource('TestProcTwoArgs',
  8186. LinesToStr([ // statements
  8187. 'this.Test = function (a,b) {',
  8188. '};'
  8189. ]),
  8190. LinesToStr([ // this.$main
  8191. ''
  8192. ]));
  8193. end;
  8194. procedure TTestModule.TestProc_DefaultValue;
  8195. begin
  8196. StartProgram(false);
  8197. Add('procedure p1(i: longint = 1);');
  8198. Add('begin');
  8199. Add('end;');
  8200. Add('procedure p2(i: longint = 1; c: char = ''a'');');
  8201. Add('begin');
  8202. Add('end;');
  8203. Add('procedure p3(d: double = 1.0; b: boolean = false; s: string = ''abc'');');
  8204. Add('begin');
  8205. Add('end;');
  8206. Add('begin');
  8207. Add(' p1;');
  8208. Add(' p1();');
  8209. Add(' p1(11);');
  8210. Add(' p2;');
  8211. Add(' p2();');
  8212. Add(' p2(12);');
  8213. Add(' p2(13,''b'');');
  8214. Add(' p3();');
  8215. ConvertProgram;
  8216. CheckSource('TestProc_DefaultValue',
  8217. LinesToStr([ // statements
  8218. 'this.p1 = function (i) {',
  8219. '};',
  8220. 'this.p2 = function (i,c) {',
  8221. '};',
  8222. 'this.p3 = function (d,b,s) {',
  8223. '};'
  8224. ]),
  8225. LinesToStr([ // this.$main
  8226. ' $mod.p1(1);',
  8227. ' $mod.p1(1);',
  8228. ' $mod.p1(11);',
  8229. ' $mod.p2(1,"a");',
  8230. ' $mod.p2(1,"a");',
  8231. ' $mod.p2(12,"a");',
  8232. ' $mod.p2(13,"b");',
  8233. ' $mod.p3(1.0,false,"abc");'
  8234. ]));
  8235. end;
  8236. procedure TTestModule.TestFunctionInt;
  8237. begin
  8238. StartProgram(false);
  8239. Add('function MyTest(Bar: longint): longint;');
  8240. Add('begin');
  8241. Add(' Result:=2*bar');
  8242. Add('end;');
  8243. Add('begin');
  8244. ConvertProgram;
  8245. CheckSource('TestFunctionInt',
  8246. LinesToStr([ // statements
  8247. 'this.MyTest = function (Bar) {',
  8248. ' var Result = 0;',
  8249. ' Result = 2*Bar;',
  8250. ' return Result;',
  8251. '};'
  8252. ]),
  8253. LinesToStr([ // this.$main
  8254. ''
  8255. ]));
  8256. end;
  8257. procedure TTestModule.TestFunctionString;
  8258. begin
  8259. StartProgram(false);
  8260. Add('function Test(Bar: string): string;');
  8261. Add('begin');
  8262. Add(' Result:=bar+BAR');
  8263. Add('end;');
  8264. Add('begin');
  8265. ConvertProgram;
  8266. CheckSource('TestFunctionString',
  8267. LinesToStr([ // statements
  8268. 'this.Test = function (Bar) {',
  8269. ' var Result = "";',
  8270. ' Result = Bar+Bar;',
  8271. ' return Result;',
  8272. '};'
  8273. ]),
  8274. LinesToStr([ // this.$main
  8275. ''
  8276. ]));
  8277. end;
  8278. procedure TTestModule.TestIfThen;
  8279. begin
  8280. StartProgram(false);
  8281. Add([
  8282. 'var b: boolean;',
  8283. 'begin',
  8284. ' if b then ;',
  8285. ' if b then else ;']);
  8286. ConvertProgram;
  8287. CheckSource('TestIfThen',
  8288. LinesToStr([ // statements
  8289. 'this.b = false;',
  8290. '']),
  8291. LinesToStr([ // this.$main
  8292. 'if ($mod.b) ;',
  8293. 'if ($mod.b) ;',
  8294. '']));
  8295. end;
  8296. procedure TTestModule.TestForLoop;
  8297. begin
  8298. StartProgram(false);
  8299. Add('var');
  8300. Add(' vI, vJ, vN: longint;');
  8301. Add('begin');
  8302. Add(' VJ:=0;');
  8303. Add(' VN:=3;');
  8304. Add(' for VI:=1 to VN do');
  8305. Add(' begin');
  8306. Add(' VJ:=VJ+VI;');
  8307. Add(' end;');
  8308. ConvertProgram;
  8309. CheckSource('TestForLoop',
  8310. LinesToStr([ // statements
  8311. 'this.vI = 0;',
  8312. 'this.vJ = 0;',
  8313. 'this.vN = 0;'
  8314. ]),
  8315. LinesToStr([ // this.$main
  8316. ' $mod.vJ = 0;',
  8317. ' $mod.vN = 3;',
  8318. ' for (var $l = 1, $end = $mod.vN; $l <= $end; $l++) {',
  8319. ' $mod.vI = $l;',
  8320. ' $mod.vJ = $mod.vJ + $mod.vI;',
  8321. ' };',
  8322. '']));
  8323. end;
  8324. procedure TTestModule.TestForLoopInsideFunction;
  8325. begin
  8326. StartProgram(false);
  8327. Add('function SumNumbers(Count: longint): longint;');
  8328. Add('var');
  8329. Add(' vI, vJ: longint;');
  8330. Add('begin');
  8331. Add(' vj:=0;');
  8332. Add(' for vi:=1 to count do');
  8333. Add(' begin');
  8334. Add(' vj:=vj+vi;');
  8335. Add(' end;');
  8336. Add('end;');
  8337. Add('begin');
  8338. Add(' sumnumbers(3);');
  8339. ConvertProgram;
  8340. CheckSource('TestForLoopInsideFunction',
  8341. LinesToStr([ // statements
  8342. 'this.SumNumbers = function (Count) {',
  8343. ' var Result = 0;',
  8344. ' var vI = 0;',
  8345. ' var vJ = 0;',
  8346. ' vJ = 0;',
  8347. ' for (var $l = 1, $end = Count; $l <= $end; $l++) {',
  8348. ' vI = $l;',
  8349. ' vJ = vJ + vI;',
  8350. ' };',
  8351. ' return Result;',
  8352. '};'
  8353. ]),
  8354. LinesToStr([ // $mod.$main
  8355. ' $mod.SumNumbers(3);'
  8356. ]));
  8357. end;
  8358. procedure TTestModule.TestForLoop_ReadVarAfter;
  8359. begin
  8360. StartProgram(false);
  8361. Add('var');
  8362. Add(' vI: longint;');
  8363. Add('begin');
  8364. Add(' for vi:=1 to 2 do ;');
  8365. Add(' if vi=3 then ;');
  8366. ConvertProgram;
  8367. CheckSource('TestForLoop',
  8368. LinesToStr([ // statements
  8369. 'this.vI = 0;'
  8370. ]),
  8371. LinesToStr([ // this.$main
  8372. ' for ($mod.vI = 1; $mod.vI <= 2; $mod.vI++) ;',
  8373. ' if ($mod.vI===3) ;'
  8374. ]));
  8375. end;
  8376. procedure TTestModule.TestForLoop_Nested;
  8377. begin
  8378. StartProgram(false);
  8379. Add('function SumNumbers(Count: longint): longint;');
  8380. Add('var');
  8381. Add(' vI, vJ, vK: longint;');
  8382. Add('begin');
  8383. Add(' VK:=0;');
  8384. Add(' for VI:=1 to count do');
  8385. Add(' begin');
  8386. Add(' for vj:=1 to vi do');
  8387. Add(' begin');
  8388. Add(' vk:=VK+VI;');
  8389. Add(' end;');
  8390. Add(' end;');
  8391. Add('end;');
  8392. Add('begin');
  8393. Add(' sumnumbers(3);');
  8394. ConvertProgram;
  8395. CheckSource('TestForLoopInFunction',
  8396. LinesToStr([ // statements
  8397. 'this.SumNumbers = function (Count) {',
  8398. ' var Result = 0;',
  8399. ' var vI = 0;',
  8400. ' var vJ = 0;',
  8401. ' var vK = 0;',
  8402. ' vK = 0;',
  8403. ' for (var $l = 1, $end = Count; $l <= $end; $l++) {',
  8404. ' vI = $l;',
  8405. ' for (var $l1 = 1, $end1 = vI; $l1 <= $end1; $l1++) {',
  8406. ' vJ = $l1;',
  8407. ' vK = vK + vI;',
  8408. ' };',
  8409. ' };',
  8410. ' return Result;',
  8411. '};'
  8412. ]),
  8413. LinesToStr([ // $mod.$main
  8414. ' $mod.SumNumbers(3);'
  8415. ]));
  8416. end;
  8417. procedure TTestModule.TestRepeatUntil;
  8418. begin
  8419. StartProgram(false);
  8420. Add('var');
  8421. Add(' vI, vJ, vN: longint;');
  8422. Add('begin');
  8423. Add(' vn:=3;');
  8424. Add(' vj:=0;');
  8425. Add(' VI:=0;');
  8426. Add(' repeat');
  8427. Add(' VI:=vi+1;');
  8428. Add(' vj:=VJ+vI;');
  8429. Add(' until vi>=vn');
  8430. ConvertProgram;
  8431. CheckSource('TestRepeatUntil',
  8432. LinesToStr([ // statements
  8433. 'this.vI = 0;',
  8434. 'this.vJ = 0;',
  8435. 'this.vN = 0;'
  8436. ]),
  8437. LinesToStr([ // $mod.$main
  8438. ' $mod.vN = 3;',
  8439. ' $mod.vJ = 0;',
  8440. ' $mod.vI = 0;',
  8441. ' do{',
  8442. ' $mod.vI = $mod.vI + 1;',
  8443. ' $mod.vJ = $mod.vJ + $mod.vI;',
  8444. ' }while(!($mod.vI>=$mod.vN));'
  8445. ]));
  8446. end;
  8447. procedure TTestModule.TestAsmBlock;
  8448. begin
  8449. StartProgram(false);
  8450. Add([
  8451. 'var',
  8452. ' vI: longint;',
  8453. 'begin',
  8454. ' vi:=1;',
  8455. ' asm',
  8456. ' if (vI===1) {',
  8457. ' vI=2;',
  8458. //' console.log(''end;'');', ToDo
  8459. ' }',
  8460. ' if (vI===2){ vI=3; }',
  8461. ' end;',
  8462. ' VI:=4;']);
  8463. ConvertProgram;
  8464. CheckSource('TestAsmBlock',
  8465. LinesToStr([ // statements
  8466. 'this.vI = 0;'
  8467. ]),
  8468. LinesToStr([ // $mod.$main
  8469. '$mod.vI = 1;',
  8470. 'if (vI===1) {',
  8471. ' vI=2;',
  8472. '}',
  8473. 'if (vI===2){ vI=3; }',
  8474. ';',
  8475. '$mod.vI = 4;'
  8476. ]));
  8477. end;
  8478. procedure TTestModule.TestAsmPas_Impl;
  8479. begin
  8480. StartUnit(false);
  8481. Add('interface');
  8482. Add('const cIntf: longint = 1;');
  8483. Add('var vIntf: longint;');
  8484. Add('implementation');
  8485. Add('const cImpl: longint = 2;');
  8486. Add('var vImpl: longint;');
  8487. Add('procedure DoIt;');
  8488. Add('const cLoc: longint = 3;');
  8489. Add('var vLoc: longint;');
  8490. Add('begin;');
  8491. Add(' asm');
  8492. //Add(' pas(vIntf)=pas(cIntf);');
  8493. //Add(' pas(vImpl)=pas(cImpl);');
  8494. //Add(' pas(vLoc)=pas(cLoc);');
  8495. Add(' end;');
  8496. Add('end;');
  8497. ConvertUnit;
  8498. CheckSource('TestAsmPas_Impl',
  8499. LinesToStr([
  8500. 'var $impl = $mod.$impl;',
  8501. 'this.cIntf = 1;',
  8502. 'this.vIntf = 0;',
  8503. '']),
  8504. '', // this.$init
  8505. LinesToStr([ // implementation
  8506. '$impl.cImpl = 2;',
  8507. '$impl.vImpl = 0;',
  8508. 'var cLoc = 3;',
  8509. '$impl.DoIt = function () {',
  8510. ' var vLoc = 0;',
  8511. '};',
  8512. '']) );
  8513. end;
  8514. procedure TTestModule.TestTryFinally;
  8515. begin
  8516. StartProgram(false);
  8517. Add('var i: longint;');
  8518. Add('begin');
  8519. Add(' try');
  8520. Add(' i:=0; i:=2 div i;');
  8521. Add(' finally');
  8522. Add(' i:=3');
  8523. Add(' end;');
  8524. ConvertProgram;
  8525. CheckSource('TestTryFinally',
  8526. LinesToStr([ // statements
  8527. 'this.i = 0;'
  8528. ]),
  8529. LinesToStr([ // $mod.$main
  8530. 'try {',
  8531. ' $mod.i = 0;',
  8532. ' $mod.i = rtl.trunc(2 / $mod.i);',
  8533. '} finally {',
  8534. ' $mod.i = 3;',
  8535. '};'
  8536. ]));
  8537. end;
  8538. procedure TTestModule.TestTryExcept;
  8539. begin
  8540. StartProgram(false);
  8541. Add([
  8542. 'type',
  8543. ' TObject = class end;',
  8544. ' Exception = class Msg: string; end;',
  8545. ' EInvalidCast = class(Exception) end;',
  8546. 'var vI: longint;',
  8547. 'begin',
  8548. ' try',
  8549. ' vi:=1;',
  8550. ' except',
  8551. ' vi:=2',
  8552. ' end;',
  8553. ' try',
  8554. ' vi:=3;',
  8555. ' except',
  8556. ' raise;',
  8557. ' end;',
  8558. ' try',
  8559. ' VI:=4;',
  8560. ' except',
  8561. ' on einvalidcast do',
  8562. ' raise;',
  8563. ' on E: exception do',
  8564. ' if e.msg='''' then',
  8565. ' raise e;',
  8566. ' else',
  8567. ' vi:=5',
  8568. ' end;',
  8569. ' try',
  8570. ' VI:=6;',
  8571. ' except',
  8572. ' on einvalidcast do ;',
  8573. ' end;',
  8574. '']);
  8575. ConvertProgram;
  8576. CheckSource('TestTryExcept',
  8577. LinesToStr([ // statements
  8578. 'rtl.createClass(this, "TObject", null, function () {',
  8579. ' this.$init = function () {',
  8580. ' };',
  8581. ' this.$final = function () {',
  8582. ' };',
  8583. '});',
  8584. 'rtl.createClass(this, "Exception", this.TObject, function () {',
  8585. ' this.$init = function () {',
  8586. ' $mod.TObject.$init.call(this);',
  8587. ' this.Msg = "";',
  8588. ' };',
  8589. '});',
  8590. 'rtl.createClass(this, "EInvalidCast", this.Exception, function () {',
  8591. '});',
  8592. 'this.vI = 0;'
  8593. ]),
  8594. LinesToStr([ // $mod.$main
  8595. 'try {',
  8596. ' $mod.vI = 1;',
  8597. '} catch ($e) {',
  8598. ' $mod.vI = 2;',
  8599. '};',
  8600. 'try {',
  8601. ' $mod.vI = 3;',
  8602. '} catch ($e) {',
  8603. ' throw $e;',
  8604. '};',
  8605. 'try {',
  8606. ' $mod.vI = 4;',
  8607. '} catch ($e) {',
  8608. ' if ($mod.EInvalidCast.isPrototypeOf($e)){',
  8609. ' throw $e',
  8610. ' } else if ($mod.Exception.isPrototypeOf($e)) {',
  8611. ' var E = $e;',
  8612. ' if (E.Msg === "") throw E;',
  8613. ' } else {',
  8614. ' $mod.vI = 5;',
  8615. ' }',
  8616. '};',
  8617. 'try {',
  8618. ' $mod.vI = 6;',
  8619. '} catch ($e) {',
  8620. ' if ($mod.EInvalidCast.isPrototypeOf($e)){' ,
  8621. ' } else throw $e',
  8622. '};',
  8623. '']));
  8624. end;
  8625. procedure TTestModule.TestTryExcept_ReservedWords;
  8626. begin
  8627. StartProgram(false);
  8628. Add([
  8629. 'type',
  8630. ' TObject = class end;',
  8631. ' Exception = class',
  8632. ' Symbol: string;',
  8633. ' end;',
  8634. 'var &try: longint;',
  8635. 'begin',
  8636. ' try',
  8637. ' &try:=4;',
  8638. ' except',
  8639. ' on Error: exception do',
  8640. ' if errOR.symBol='''' then',
  8641. ' raise ERRor;',
  8642. ' end;',
  8643. '']);
  8644. ConvertProgram;
  8645. CheckSource('TestTryExcept_ReservedWords',
  8646. LinesToStr([ // statements
  8647. 'rtl.createClass(this, "TObject", null, function () {',
  8648. ' this.$init = function () {',
  8649. ' };',
  8650. ' this.$final = function () {',
  8651. ' };',
  8652. '});',
  8653. 'rtl.createClass(this, "Exception", this.TObject, function () {',
  8654. ' this.$init = function () {',
  8655. ' $mod.TObject.$init.call(this);',
  8656. ' this.Symbol = "";',
  8657. ' };',
  8658. '});',
  8659. 'this.Try = 0;',
  8660. '']),
  8661. LinesToStr([ // $mod.$main
  8662. 'try {',
  8663. ' $mod.Try = 4;',
  8664. '} catch ($e) {',
  8665. ' if ($mod.Exception.isPrototypeOf($e)) {',
  8666. ' var error = $e;',
  8667. ' if (error.Symbol === "") throw error;',
  8668. ' } else throw $e',
  8669. '};',
  8670. '']));
  8671. end;
  8672. procedure TTestModule.TestIfThenRaiseElse;
  8673. begin
  8674. StartProgram(false);
  8675. Add([
  8676. 'type',
  8677. ' TObject = class',
  8678. ' constructor Create;',
  8679. ' end;',
  8680. 'constructor TObject.Create;',
  8681. 'begin',
  8682. 'end;',
  8683. 'var b: boolean;',
  8684. 'begin',
  8685. ' if b then',
  8686. ' raise TObject.Create',
  8687. ' else',
  8688. ' b:=false;',
  8689. '']);
  8690. ConvertProgram;
  8691. CheckSource('TestIfThenRaiseElse',
  8692. LinesToStr([ // statements
  8693. 'rtl.createClass(this, "TObject", null, function () {',
  8694. ' this.$init = function () {',
  8695. ' };',
  8696. ' this.$final = function () {',
  8697. ' };',
  8698. ' this.Create = function () {',
  8699. ' return this;',
  8700. ' };',
  8701. '});',
  8702. 'this.b = false;',
  8703. '']),
  8704. LinesToStr([ // $mod.$main
  8705. 'if ($mod.b) {',
  8706. ' throw $mod.TObject.$create("Create")}',
  8707. ' else $mod.b = false;',
  8708. '']));
  8709. end;
  8710. procedure TTestModule.TestCaseOf;
  8711. begin
  8712. StartProgram(false);
  8713. Add([
  8714. 'const e: longint; external name ''$e'';',
  8715. 'var vI: longint;',
  8716. 'begin',
  8717. ' case vi of',
  8718. ' 1: ;',
  8719. ' 2: vi:=3;',
  8720. ' e: ;',
  8721. ' else',
  8722. ' VI:=4',
  8723. ' end;']);
  8724. ConvertProgram;
  8725. CheckSource('TestCaseOf',
  8726. LinesToStr([ // statements
  8727. 'this.vI = 0;'
  8728. ]),
  8729. LinesToStr([ // $mod.$main
  8730. 'var $tmp = $mod.vI;',
  8731. 'if ($tmp === 1) {}',
  8732. 'else if ($tmp === 2) {',
  8733. ' $mod.vI = 3}',
  8734. ' else if ($tmp === $e) {}',
  8735. 'else {',
  8736. ' $mod.vI = 4;',
  8737. '};'
  8738. ]));
  8739. end;
  8740. procedure TTestModule.TestCaseOf_UseSwitch;
  8741. begin
  8742. StartProgram(false);
  8743. Converter.UseSwitchStatement:=true;
  8744. Add('var Vi: longint;');
  8745. Add('begin');
  8746. Add(' case vi of');
  8747. Add(' 1: ;');
  8748. Add(' 2: VI:=3;');
  8749. Add(' else');
  8750. Add(' vi:=4');
  8751. Add(' end;');
  8752. ConvertProgram;
  8753. CheckSource('TestCaseOf_UseSwitch',
  8754. LinesToStr([ // statements
  8755. 'this.Vi = 0;'
  8756. ]),
  8757. LinesToStr([ // $mod.$main
  8758. 'switch ($mod.Vi) {',
  8759. 'case 1:',
  8760. ' break;',
  8761. 'case 2:',
  8762. ' $mod.Vi = 3;',
  8763. ' break;',
  8764. 'default:',
  8765. ' $mod.Vi = 4;',
  8766. '};'
  8767. ]));
  8768. end;
  8769. procedure TTestModule.TestCaseOfNoElse;
  8770. begin
  8771. StartProgram(false);
  8772. Add('var Vi: longint;');
  8773. Add('begin');
  8774. Add(' case vi of');
  8775. Add(' 1: begin vi:=2; VI:=3; end;');
  8776. Add(' end;');
  8777. ConvertProgram;
  8778. CheckSource('TestCaseOfNoElse',
  8779. LinesToStr([ // statements
  8780. 'this.Vi = 0;'
  8781. ]),
  8782. LinesToStr([ // $mod.$main
  8783. 'var $tmp = $mod.Vi;',
  8784. 'if ($tmp === 1) {',
  8785. ' $mod.Vi = 2;',
  8786. ' $mod.Vi = 3;',
  8787. '};'
  8788. ]));
  8789. end;
  8790. procedure TTestModule.TestCaseOfNoElse_UseSwitch;
  8791. begin
  8792. StartProgram(false);
  8793. Converter.UseSwitchStatement:=true;
  8794. Add('var vI: longint;');
  8795. Add('begin');
  8796. Add(' case vi of');
  8797. Add(' 1: begin VI:=2; vi:=3; end;');
  8798. Add(' end;');
  8799. ConvertProgram;
  8800. CheckSource('TestCaseOfNoElse_UseSwitch',
  8801. LinesToStr([ // statements
  8802. 'this.vI = 0;'
  8803. ]),
  8804. LinesToStr([ // $mod.$main
  8805. 'switch ($mod.vI) {',
  8806. 'case 1:',
  8807. ' $mod.vI = 2;',
  8808. ' $mod.vI = 3;',
  8809. ' break;',
  8810. '};'
  8811. ]));
  8812. end;
  8813. procedure TTestModule.TestCaseOfRange;
  8814. begin
  8815. StartProgram(false);
  8816. Add('var vI: longint;');
  8817. Add('begin');
  8818. Add(' case vi of');
  8819. Add(' 1..3: vi:=14;');
  8820. Add(' 4,5: vi:=16;');
  8821. Add(' 6..7,9..10: ;');
  8822. Add(' else ;');
  8823. Add(' end;');
  8824. ConvertProgram;
  8825. CheckSource('TestCaseOfRange',
  8826. LinesToStr([ // statements
  8827. 'this.vI = 0;'
  8828. ]),
  8829. LinesToStr([ // $mod.$main
  8830. 'var $tmp = $mod.vI;',
  8831. 'if (($tmp >= 1) && ($tmp <= 3)){',
  8832. ' $mod.vI = 14',
  8833. '} else if (($tmp === 4) || ($tmp === 5)){',
  8834. ' $mod.vI = 16',
  8835. '} else if ((($tmp >= 6) && ($tmp <= 7)) || (($tmp >= 9) && ($tmp <= 10))) ;'
  8836. ]));
  8837. end;
  8838. procedure TTestModule.TestCaseOfString;
  8839. begin
  8840. StartProgram(false);
  8841. Add([
  8842. 'var s,h: string;',
  8843. 'begin',
  8844. ' case s of',
  8845. ' ''foo'': s:=h;',
  8846. ' ''a''..''z'': h:=s;',
  8847. ' ''ў'', ''ё'': ;',
  8848. ' ''Б''..''Я'': ;',
  8849. ' end;',
  8850. '']);
  8851. ConvertProgram;
  8852. CheckSource('TestCaseOfString',
  8853. LinesToStr([ // statements
  8854. 'this.s = "";',
  8855. 'this.h = "";',
  8856. '']),
  8857. LinesToStr([ // $mod.$main
  8858. 'var $tmp = $mod.s;',
  8859. 'if ($tmp === "foo") {',
  8860. ' $mod.s = $mod.h}',
  8861. ' else if (($tmp.length === 1) && ($tmp >= "a") && ($tmp <= "z")) {',
  8862. ' $mod.h = $mod.s}',
  8863. ' else if (($tmp === "ў") || ($tmp === "ё")) {}',
  8864. ' else if (($tmp.length === 1) && ($tmp >= "Б") && ($tmp <= "Я")) ;',
  8865. '']));
  8866. end;
  8867. procedure TTestModule.TestCaseOfChar;
  8868. begin
  8869. StartProgram(false);
  8870. Add([
  8871. 'var s,h: char;',
  8872. 'begin',
  8873. ' case s of',
  8874. ' ''a''..''z'': h:=s;',
  8875. ' ''ä'': ;',
  8876. ' ''ў'', ''ё'': ;',
  8877. ' ''Б''..''Я'': ;',
  8878. ' end;',
  8879. '']);
  8880. ConvertProgram;
  8881. CheckSource('TestCaseOfString',
  8882. LinesToStr([ // statements
  8883. 'this.s = "";',
  8884. 'this.h = "";',
  8885. '']),
  8886. LinesToStr([ // $mod.$main
  8887. 'var $tmp = $mod.s;',
  8888. 'if (($tmp >= "a") && ($tmp <= "z")) {',
  8889. ' $mod.h = $mod.s}',
  8890. ' else if ($tmp === "ä") {}',
  8891. ' else if (($tmp === "ў") || ($tmp === "ё")) {}',
  8892. ' else if (($tmp >= "Б") && ($tmp <= "Я")) ;',
  8893. '']));
  8894. end;
  8895. procedure TTestModule.TestCaseOfExternalClassConst;
  8896. begin
  8897. StartProgram(false);
  8898. Add([
  8899. '{$modeswitch externalclass}',
  8900. 'type',
  8901. ' TBird = class external name ''Bird''',
  8902. ' const e: longint;',
  8903. ' end;',
  8904. 'var vI: longint;',
  8905. 'begin',
  8906. ' case vi of',
  8907. ' 1: vi:=3;',
  8908. ' TBird.e: ;',
  8909. ' end;']);
  8910. ConvertProgram;
  8911. CheckSource('TestCaseOfExternalClassConst',
  8912. LinesToStr([ // statements
  8913. 'this.vI = 0;'
  8914. ]),
  8915. LinesToStr([ // $mod.$main
  8916. 'var $tmp = $mod.vI;',
  8917. 'if ($tmp === 1) {',
  8918. ' $mod.vI = 3}',
  8919. ' else if ($tmp === Bird.e) ;'
  8920. ]));
  8921. end;
  8922. procedure TTestModule.TestDebugger;
  8923. begin
  8924. StartProgram(false);
  8925. Add([
  8926. 'procedure DoIt;',
  8927. 'begin',
  8928. ' deBugger;',
  8929. ' DeBugger();',
  8930. 'end;',
  8931. 'begin',
  8932. ' Debugger;']);
  8933. ConvertProgram;
  8934. CheckSource('TestDebugger',
  8935. LinesToStr([ // statements
  8936. 'this.DoIt = function () {',
  8937. ' debugger;',
  8938. ' debugger;',
  8939. '};',
  8940. '']),
  8941. LinesToStr([ // $mod.$main
  8942. 'debugger;',
  8943. '']));
  8944. end;
  8945. procedure TTestModule.TestArray_Dynamic;
  8946. begin
  8947. StartProgram(false);
  8948. Add([
  8949. 'type',
  8950. ' TArrayInt = array of longint;',
  8951. 'var',
  8952. ' Arr: TArrayInt;',
  8953. ' i: longint;',
  8954. ' b: boolean;',
  8955. 'begin',
  8956. ' SetLength(arr,3);',
  8957. ' arr[0]:=4;',
  8958. ' arr[1]:=length(arr)+arr[0];',
  8959. ' arr[i]:=5;',
  8960. ' arr[arr[i]]:=arr[6];',
  8961. ' i:=low(arr);',
  8962. ' i:=high(arr);',
  8963. ' b:=Assigned(arr);',
  8964. ' Arr:=default(TArrayInt);']);
  8965. ConvertProgram;
  8966. CheckSource('TestArray_Dynamic',
  8967. LinesToStr([ // statements
  8968. 'this.Arr = [];',
  8969. 'this.i = 0;',
  8970. 'this.b = false;'
  8971. ]),
  8972. LinesToStr([ // $mod.$main
  8973. '$mod.Arr = rtl.arraySetLength($mod.Arr,0,3);',
  8974. '$mod.Arr[0] = 4;',
  8975. '$mod.Arr[1] = rtl.length($mod.Arr) + $mod.Arr[0];',
  8976. '$mod.Arr[$mod.i] = 5;',
  8977. '$mod.Arr[$mod.Arr[$mod.i]] = $mod.Arr[6];',
  8978. '$mod.i = 0;',
  8979. '$mod.i = rtl.length($mod.Arr) - 1;',
  8980. '$mod.b = rtl.length($mod.Arr) > 0;',
  8981. '$mod.Arr = [];',
  8982. '']));
  8983. end;
  8984. procedure TTestModule.TestArray_Dynamic_Nil;
  8985. begin
  8986. StartProgram(false);
  8987. Add('type');
  8988. Add(' TArrayInt = array of longint;');
  8989. Add('var');
  8990. Add(' Arr: TArrayInt;');
  8991. Add('procedure DoIt(const i: TArrayInt; j: TArrayInt); begin end;');
  8992. Add('begin');
  8993. Add(' arr:=nil;');
  8994. Add(' if arr=nil then;');
  8995. Add(' if nil=arr then;');
  8996. Add(' if arr<>nil then;');
  8997. Add(' if nil<>arr then;');
  8998. Add(' DoIt(nil,nil);');
  8999. ConvertProgram;
  9000. CheckSource('TestArray_Dynamic',
  9001. LinesToStr([ // statements
  9002. 'this.Arr = [];',
  9003. 'this.DoIt = function(i,j){',
  9004. '};'
  9005. ]),
  9006. LinesToStr([ // $mod.$main
  9007. '$mod.Arr = [];',
  9008. 'if (rtl.length($mod.Arr) === 0) ;',
  9009. 'if (rtl.length($mod.Arr) === 0) ;',
  9010. 'if (rtl.length($mod.Arr) > 0) ;',
  9011. 'if (rtl.length($mod.Arr) > 0) ;',
  9012. '$mod.DoIt([],[]);',
  9013. '']));
  9014. end;
  9015. procedure TTestModule.TestArray_DynMultiDimensional;
  9016. begin
  9017. StartProgram(false);
  9018. Add([
  9019. 'type',
  9020. ' TArrayInt = array of longint;',
  9021. ' TArrayArrayInt = array of TArrayInt;',
  9022. 'var',
  9023. ' Arr: TArrayInt;',
  9024. ' Arr2: TArrayArrayInt;',
  9025. ' i: longint;',
  9026. 'begin',
  9027. ' arr2:=nil;',
  9028. ' if arr2=nil then;',
  9029. ' if nil=arr2 then;',
  9030. ' i:=low(arr2);',
  9031. ' i:=low(arr2[1]);',
  9032. ' i:=high(arr2);',
  9033. ' i:=high(arr2[2]);',
  9034. ' arr2[3]:=arr;',
  9035. ' arr2[4][5]:=i;',
  9036. ' i:=arr2[6][7];',
  9037. ' arr2[8,9]:=i;',
  9038. ' i:=arr2[10,11];',
  9039. ' SetLength(arr2,14);',
  9040. ' SetLength(arr2[15],16);']);
  9041. ConvertProgram;
  9042. CheckSource('TestArray_Dynamic',
  9043. LinesToStr([ // statements
  9044. 'this.Arr = [];',
  9045. 'this.Arr2 = [];',
  9046. 'this.i = 0;'
  9047. ]),
  9048. LinesToStr([ // $mod.$main
  9049. '$mod.Arr2 = [];',
  9050. 'if (rtl.length($mod.Arr2) === 0) ;',
  9051. 'if (rtl.length($mod.Arr2) === 0) ;',
  9052. '$mod.i = 0;',
  9053. '$mod.i = 0;',
  9054. '$mod.i = rtl.length($mod.Arr2) - 1;',
  9055. '$mod.i = rtl.length($mod.Arr2[2]) - 1;',
  9056. '$mod.Arr2[3] = rtl.arrayRef($mod.Arr);',
  9057. '$mod.Arr2[4][5] = $mod.i;',
  9058. '$mod.i = $mod.Arr2[6][7];',
  9059. '$mod.Arr2[8][9] = $mod.i;',
  9060. '$mod.i = $mod.Arr2[10][11];',
  9061. '$mod.Arr2 = rtl.arraySetLength($mod.Arr2, [], 14);',
  9062. '$mod.Arr2[15] = rtl.arraySetLength($mod.Arr2[15], 0, 16);',
  9063. '']));
  9064. end;
  9065. procedure TTestModule.TestArray_DynamicAssign;
  9066. begin
  9067. StartProgram(false);
  9068. Add([
  9069. 'type',
  9070. ' TArrayInt = array of longint;',
  9071. ' TArrayArrayInt = array of TArrayInt;',
  9072. 'procedure Run(a: TArrayInt; const b: TArrayInt; constref c: TArrayInt);',
  9073. 'begin',
  9074. 'end;',
  9075. 'procedure Fly(var a: TArrayInt);',
  9076. 'begin',
  9077. 'end;',
  9078. 'var',
  9079. ' Arr: TArrayInt;',
  9080. ' Arr2: TArrayArrayInt;',
  9081. 'begin',
  9082. ' arr:=nil;',
  9083. ' arr2:=nil;',
  9084. ' arr2[1]:=nil;',
  9085. ' arr2[2]:=arr;',
  9086. ' Run(arr,arr,arr);',
  9087. ' Fly(arr);',
  9088. ' Run(arr2[4],arr2[5],arr2[6]);',
  9089. ' Fly(arr2[7]);',
  9090. '']);
  9091. ConvertProgram;
  9092. CheckSource('TestArray_DynamicAssign',
  9093. LinesToStr([ // statements
  9094. 'this.Run = function (a, b, c) {',
  9095. '};',
  9096. 'this.Fly = function (a) {',
  9097. '};',
  9098. 'this.Arr = [];',
  9099. 'this.Arr2 = [];',
  9100. '']),
  9101. LinesToStr([ // $mod.$main
  9102. '$mod.Arr = [];',
  9103. '$mod.Arr2 = [];',
  9104. '$mod.Arr2[1] = [];',
  9105. '$mod.Arr2[2] = rtl.arrayRef($mod.Arr);',
  9106. '$mod.Run(rtl.arrayRef($mod.Arr), $mod.Arr, $mod.Arr);',
  9107. '$mod.Fly({',
  9108. ' p: $mod,',
  9109. ' get: function () {',
  9110. ' return this.p.Arr;',
  9111. ' },',
  9112. ' set: function (v) {',
  9113. ' this.p.Arr = v;',
  9114. ' }',
  9115. '});',
  9116. '$mod.Run(rtl.arrayRef($mod.Arr2[4]), $mod.Arr2[5], $mod.Arr2[6]);',
  9117. '$mod.Fly({',
  9118. ' a: 7,',
  9119. ' p: $mod.Arr2,',
  9120. ' get: function () {',
  9121. ' return this.p[this.a];',
  9122. ' },',
  9123. ' set: function (v) {',
  9124. ' this.p[this.a] = v;',
  9125. ' }',
  9126. '});',
  9127. '']));
  9128. end;
  9129. procedure TTestModule.TestArray_StaticInt;
  9130. begin
  9131. StartProgram(false);
  9132. Add('type');
  9133. Add(' TArrayInt = array[2..4] of longint;');
  9134. Add('var');
  9135. Add(' Arr: TArrayInt;');
  9136. Add(' Arr2: TArrayInt = (5,6,7);');
  9137. Add(' i: longint;');
  9138. Add(' b: boolean;');
  9139. Add('begin');
  9140. Add(' arr[2]:=4;');
  9141. Add(' arr[3]:=arr[2]+arr[3];');
  9142. Add(' arr[i]:=5;');
  9143. Add(' arr[arr[i]]:=arr[high(arr)];');
  9144. Add(' i:=low(arr);');
  9145. Add(' i:=high(arr);');
  9146. Add(' b:=arr[2]=arr[3];');
  9147. Add(' arr:=default(TArrayInt);');
  9148. ConvertProgram;
  9149. CheckSource('TestArray_StaticInt',
  9150. LinesToStr([ // statements
  9151. 'this.Arr = rtl.arraySetLength(null,0,3);',
  9152. 'this.Arr2 = [5, 6, 7];',
  9153. 'this.i = 0;',
  9154. 'this.b = false;'
  9155. ]),
  9156. LinesToStr([ // $mod.$main
  9157. '$mod.Arr[0] = 4;',
  9158. '$mod.Arr[1] = $mod.Arr[0] + $mod.Arr[1];',
  9159. '$mod.Arr[$mod.i-2] = 5;',
  9160. '$mod.Arr[$mod.Arr[$mod.i-2]-2] = $mod.Arr[2];',
  9161. '$mod.i = 2;',
  9162. '$mod.i = 4;',
  9163. '$mod.b = $mod.Arr[0] === $mod.Arr[1];',
  9164. '$mod.Arr = rtl.arraySetLength(null,0,3);',
  9165. '']));
  9166. end;
  9167. procedure TTestModule.TestArray_StaticBool;
  9168. begin
  9169. StartProgram(false);
  9170. Add('type');
  9171. Add(' TBools = array[boolean] of boolean;');
  9172. Add(' TBool2 = array[true..true] of boolean;');
  9173. Add('var');
  9174. Add(' Arr: TBools;');
  9175. Add(' Arr2: TBool2;');
  9176. Add(' Arr3: TBools = (true,false);');
  9177. Add(' b: boolean;');
  9178. Add('begin');
  9179. Add(' b:=low(arr);');
  9180. Add(' b:=high(arr);');
  9181. Add(' arr[true]:=false;');
  9182. Add(' arr[false]:=arr[b] or arr[true];');
  9183. Add(' arr[b]:=true;');
  9184. Add(' arr[arr[b]]:=arr[high(arr)];');
  9185. Add(' b:=arr[false]=arr[true];');
  9186. Add(' b:=low(arr2);');
  9187. Add(' b:=high(arr2);');
  9188. Add(' arr2[true]:=true;');
  9189. Add(' arr2[true]:=arr2[true] and arr2[b];');
  9190. Add(' arr2[b]:=false;');
  9191. ConvertProgram;
  9192. CheckSource('TestArray_StaticBool',
  9193. LinesToStr([ // statements
  9194. 'this.Arr = rtl.arraySetLength(null,false,2);',
  9195. 'this.Arr2 = rtl.arraySetLength(null,false,1);',
  9196. 'this.Arr3 = [true, false];',
  9197. 'this.b = false;'
  9198. ]),
  9199. LinesToStr([ // $mod.$main
  9200. '$mod.b = false;',
  9201. '$mod.b = true;',
  9202. '$mod.Arr[1] = false;',
  9203. '$mod.Arr[0] = $mod.Arr[+$mod.b] || $mod.Arr[1];',
  9204. '$mod.Arr[+$mod.b] = true;',
  9205. '$mod.Arr[+$mod.Arr[+$mod.b]] = $mod.Arr[1];',
  9206. '$mod.b = $mod.Arr[0] === $mod.Arr[1];',
  9207. '$mod.b = true;',
  9208. '$mod.b = true;',
  9209. '$mod.Arr2[0] = true;',
  9210. '$mod.Arr2[0] = $mod.Arr2[0] && $mod.Arr2[1-$mod.b];',
  9211. '$mod.Arr2[1-$mod.b] = false;',
  9212. '']));
  9213. end;
  9214. procedure TTestModule.TestArray_StaticChar;
  9215. begin
  9216. StartProgram(false);
  9217. Add([
  9218. 'type',
  9219. ' TChars = array[char] of char;',
  9220. ' TChars2 = array[''a''..''z''] of char;',
  9221. 'var',
  9222. ' Arr: TChars;',
  9223. ' Arr2: TChars2;',
  9224. ' Arr3: array[2..4] of char = (''p'',''a'',''s'');',
  9225. ' Arr4: array[11..13] of char = ''pas'';',
  9226. ' Arr5: array[21..22] of char = ''äö'';',
  9227. ' Arr6: array[31..32] of char = ''ä''+''ö'';',
  9228. ' c: char;',
  9229. ' b: boolean;',
  9230. 'begin',
  9231. ' c:=low(arr);',
  9232. ' c:=high(arr);',
  9233. ' arr[''B'']:=''a'';',
  9234. ' arr[''D'']:=arr[c];',
  9235. ' arr[c]:=arr[''d''];',
  9236. ' arr[arr[c]]:=arr[high(arr)];',
  9237. ' b:=arr[low(arr)]=arr[''e''];',
  9238. ' c:=low(arr2);',
  9239. ' c:=high(arr2);',
  9240. ' arr2[''b'']:=''f'';',
  9241. ' arr2[''a'']:=arr2[c];',
  9242. ' arr2[c]:=arr2[''g''];']);
  9243. ConvertProgram;
  9244. CheckSource('TestArray_StaticChar',
  9245. LinesToStr([ // statements
  9246. 'this.Arr = rtl.arraySetLength(null, "", 65536);',
  9247. 'this.Arr2 = rtl.arraySetLength(null, "", 26);',
  9248. 'this.Arr3 = ["p", "a", "s"];',
  9249. 'this.Arr4 = ["p", "a", "s"];',
  9250. 'this.Arr5 = ["ä", "ö"];',
  9251. 'this.Arr6 = ["ä", "ö"];',
  9252. 'this.c = "";',
  9253. 'this.b = false;',
  9254. '']),
  9255. LinesToStr([ // $mod.$main
  9256. '$mod.c = "\x00";',
  9257. '$mod.c = "\uFFFF";',
  9258. '$mod.Arr[66] = "a";',
  9259. '$mod.Arr[68] = $mod.Arr[$mod.c.charCodeAt()];',
  9260. '$mod.Arr[$mod.c.charCodeAt()] = $mod.Arr[100];',
  9261. '$mod.Arr[$mod.Arr[$mod.c.charCodeAt()].charCodeAt()] = $mod.Arr[65535];',
  9262. '$mod.b = $mod.Arr[0] === $mod.Arr[101];',
  9263. '$mod.c = "a";',
  9264. '$mod.c = "z";',
  9265. '$mod.Arr2[1] = "f";',
  9266. '$mod.Arr2[0] = $mod.Arr2[$mod.c.charCodeAt() - 97];',
  9267. '$mod.Arr2[$mod.c.charCodeAt() - 97] = $mod.Arr2[6];',
  9268. '']));
  9269. end;
  9270. procedure TTestModule.TestArray_StaticMultiDim;
  9271. begin
  9272. StartProgram(false);
  9273. Add([
  9274. 'type',
  9275. ' TArrayInt = array[1..3] of longint;',
  9276. ' TArrayArrayInt = array[5..6] of TArrayInt;',
  9277. 'var',
  9278. ' Arr: TArrayInt;',
  9279. ' Arr2: TArrayArrayInt;',
  9280. ' Arr3: array[boolean] of TArrayInt = ((11,12,13),(21,22,23));',
  9281. ' i: longint;',
  9282. 'begin',
  9283. ' i:=low(arr);',
  9284. ' i:=low(arr2);',
  9285. ' i:=low(arr2[5]);',
  9286. ' i:=high(arr);',
  9287. ' i:=high(arr2);',
  9288. ' i:=high(arr2[6]);',
  9289. ' arr2[5]:=arr;',
  9290. ' arr2[6][2]:=i;',
  9291. ' i:=arr2[6][3];',
  9292. ' arr2[6,3]:=i;',
  9293. ' i:=arr2[5,2];',
  9294. ' arr2:=arr2;',// clone multi dim static array
  9295. ' arr3:=arr3;',// clone anonymous multi dim static array
  9296. '']);
  9297. ConvertProgram;
  9298. CheckSource('TestArray_StaticMultiDim',
  9299. LinesToStr([ // statements
  9300. 'this.TArrayArrayInt$clone = function (a) {',
  9301. ' var r = [];',
  9302. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  9303. ' return r;',
  9304. '};',
  9305. 'this.Arr = rtl.arraySetLength(null, 0, 3);',
  9306. 'this.Arr2 = rtl.arraySetLength(null, 0, 2, 3);',
  9307. 'this.Arr3$a$clone = function (a) {',
  9308. ' var r = [];',
  9309. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  9310. ' return r;',
  9311. '};',
  9312. 'this.Arr3 = [[11, 12, 13], [21, 22, 23]];',
  9313. 'this.i = 0;'
  9314. ]),
  9315. LinesToStr([ // $mod.$main
  9316. '$mod.i = 1;',
  9317. '$mod.i = 5;',
  9318. '$mod.i = 1;',
  9319. '$mod.i = 3;',
  9320. '$mod.i = 6;',
  9321. '$mod.i = 3;',
  9322. '$mod.Arr2[0] = $mod.Arr.slice(0);',
  9323. '$mod.Arr2[1][1] = $mod.i;',
  9324. '$mod.i = $mod.Arr2[1][2];',
  9325. '$mod.Arr2[1][2] = $mod.i;',
  9326. '$mod.i = $mod.Arr2[0][1];',
  9327. '$mod.Arr2 = $mod.TArrayArrayInt$clone($mod.Arr2);',
  9328. '$mod.Arr3 = $mod.Arr3$a$clone($mod.Arr3);',
  9329. '']));
  9330. end;
  9331. procedure TTestModule.TestArray_StaticInFunction;
  9332. begin
  9333. StartProgram(false);
  9334. Add([
  9335. 'const TArrayInt = 3;',
  9336. 'const TArrayArrayInt = 4;',
  9337. 'procedure DoIt;',
  9338. 'type',
  9339. ' TArrayInt = array[1..3] of longint;',
  9340. ' TArrayArrayInt = array[5..6] of TArrayInt;',
  9341. 'var',
  9342. ' Arr: TArrayInt;',
  9343. ' Arr2: TArrayArrayInt;',
  9344. ' Arr3: array[boolean] of TArrayInt = ((11,12,13),(21,22,23));',
  9345. ' i: longint;',
  9346. 'begin',
  9347. ' arr2[5]:=arr;',
  9348. ' arr2:=arr2;',// clone multi dim static array
  9349. ' arr3:=arr3;',// clone multi dim anonymous static array
  9350. 'end;',
  9351. 'begin',
  9352. '']);
  9353. ConvertProgram;
  9354. CheckSource('TestArray_StaticInFunction',
  9355. LinesToStr([ // statements
  9356. 'this.TArrayInt = 3;',
  9357. 'this.TArrayArrayInt = 4;',
  9358. 'var TArrayArrayInt$1$clone = function (a) {',
  9359. ' var r = [];',
  9360. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  9361. ' return r;',
  9362. '};',
  9363. 'var Arr3$a$clone = function (a) {',
  9364. ' var r = [];',
  9365. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  9366. ' return r;',
  9367. '};',
  9368. 'this.DoIt = function () {',
  9369. ' var Arr = rtl.arraySetLength(null, 0, 3);',
  9370. ' var Arr2 = rtl.arraySetLength(null, 0, 2, 3);',
  9371. ' var Arr3 = [[11, 12, 13], [21, 22, 23]];',
  9372. ' var i = 0;',
  9373. ' Arr2[0] = Arr.slice(0);',
  9374. ' Arr2 = TArrayArrayInt$1$clone(Arr2);',
  9375. ' Arr3 = Arr3$a$clone(Arr3);',
  9376. '};',
  9377. '']),
  9378. LinesToStr([ // $mod.$main
  9379. '']));
  9380. end;
  9381. procedure TTestModule.TestArray_StaticMultiDimEqualNotImplemented;
  9382. begin
  9383. StartProgram(false);
  9384. Add([
  9385. 'type',
  9386. ' TArrayInt = array[1..3,1..2] of longint;',
  9387. 'var',
  9388. ' a,b: TArrayInt;',
  9389. 'begin',
  9390. ' if a=b then ;',
  9391. '']);
  9392. SetExpectedPasResolverError('compare static array is not supported',
  9393. nXIsNotSupported);
  9394. ConvertProgram;
  9395. end;
  9396. procedure TTestModule.TestArrayOfRecord;
  9397. begin
  9398. StartProgram(false);
  9399. Add([
  9400. 'type',
  9401. ' TRec = record',
  9402. ' Int: longint;',
  9403. ' end;',
  9404. ' TArrayRec = array of TRec;',
  9405. 'procedure DoIt(vd: TRec; const vc: TRec; var vv: TRec);',
  9406. 'begin',
  9407. 'end;',
  9408. 'var',
  9409. ' Arr: TArrayRec;',
  9410. ' r: TRec;',
  9411. ' i: longint;',
  9412. 'begin',
  9413. ' SetLength(arr,3);',
  9414. ' arr[0].int:=4;',
  9415. ' arr[1].int:=length(arr)+arr[2].int;',
  9416. ' arr[arr[i].int].int:=arr[5].int;',
  9417. ' arr[7]:=r;',
  9418. ' r:=arr[8];',
  9419. ' i:=low(arr);',
  9420. ' i:=high(arr);',
  9421. ' DoIt(Arr[9],Arr[10],Arr[11]);']);
  9422. ConvertProgram;
  9423. CheckSource('TestArrayOfRecord',
  9424. LinesToStr([ // statements
  9425. 'rtl.recNewT(this, "TRec", function () {',
  9426. ' this.Int = 0;',
  9427. ' this.$eq = function (b) {',
  9428. ' return this.Int === b.Int;',
  9429. ' };',
  9430. ' this.$assign = function (s) {',
  9431. ' this.Int = s.Int;',
  9432. ' return this;',
  9433. ' };',
  9434. '});',
  9435. 'this.DoIt = function (vd, vc, vv) {',
  9436. '};',
  9437. 'this.Arr = [];',
  9438. 'this.r = this.TRec.$new();',
  9439. 'this.i = 0;'
  9440. ]),
  9441. LinesToStr([ // $mod.$main
  9442. '$mod.Arr = rtl.arraySetLength($mod.Arr,$mod.TRec,3);',
  9443. '$mod.Arr[0].Int = 4;',
  9444. '$mod.Arr[1].Int = rtl.length($mod.Arr)+$mod.Arr[2].Int;',
  9445. '$mod.Arr[$mod.Arr[$mod.i].Int].Int = $mod.Arr[5].Int;',
  9446. '$mod.Arr[7].$assign($mod.r);',
  9447. '$mod.r.$assign($mod.Arr[8]);',
  9448. '$mod.i = 0;',
  9449. '$mod.i = rtl.length($mod.Arr)-1;',
  9450. '$mod.DoIt($mod.TRec.$clone($mod.Arr[9]), $mod.Arr[10], $mod.Arr[11]);',
  9451. '']));
  9452. end;
  9453. procedure TTestModule.TestArray_StaticRecord;
  9454. begin
  9455. StartProgram(false);
  9456. Add([
  9457. 'type',
  9458. ' TRec = record',
  9459. ' Int: longint;',
  9460. ' end;',
  9461. ' TArrayRec = array[1..2] of TRec;',
  9462. 'var',
  9463. ' Arr: TArrayRec;',
  9464. 'begin',
  9465. ' arr[1].int:=length(arr)+low(arr)+high(arr);',
  9466. '']);
  9467. ConvertProgram;
  9468. CheckSource('TestArray_StaticRecord',
  9469. LinesToStr([ // statements
  9470. 'rtl.recNewT(this, "TRec", function () {',
  9471. ' this.Int = 0;',
  9472. ' this.$eq = function (b) {',
  9473. ' return this.Int === b.Int;',
  9474. ' };',
  9475. ' this.$assign = function (s) {',
  9476. ' this.Int = s.Int;',
  9477. ' return this;',
  9478. ' };',
  9479. '});',
  9480. 'this.TArrayRec$clone = function (a) {',
  9481. ' var r = [];',
  9482. ' for (var i = 0; i < 2; i++) r.push($mod.TRec.$clone(a[i]));',
  9483. ' return r;',
  9484. '};',
  9485. 'this.Arr = rtl.arraySetLength(null, this.TRec, 2);',
  9486. '']),
  9487. LinesToStr([ // $mod.$main
  9488. '$mod.Arr[0].Int = 2 + 1 + 2;']));
  9489. end;
  9490. procedure TTestModule.TestArrayOfSet;
  9491. begin
  9492. StartProgram(false);
  9493. Add([
  9494. 'type',
  9495. ' TFlag = (big,small);',
  9496. ' TSetOfFlag = set of tflag;',
  9497. ' TArrayFlag = array of TSetOfFlag;',
  9498. 'procedure DoIt(const a: Tarrayflag);',
  9499. 'begin',
  9500. 'end;',
  9501. 'var',
  9502. ' f: TFlag;',
  9503. ' s: TSetOfFlag;',
  9504. ' Arr: TArrayFlag;',
  9505. ' i: longint;',
  9506. 'begin',
  9507. ' SetLength(arr,3);',
  9508. ' arr[0]:=s;',
  9509. ' arr[1]:=[big];',
  9510. ' arr[2]:=[big]+s;',
  9511. ' arr[3]:=s+[big];',
  9512. ' arr[4]:=arr[5];',
  9513. ' s:=arr[6];',
  9514. ' i:=low(arr);',
  9515. ' i:=high(arr);',
  9516. ' DoIt(arr);',
  9517. ' DoIt([s]);',
  9518. ' DoIt([[],s]);',
  9519. ' DoIt([s,[]]);',
  9520. '']);
  9521. ConvertProgram;
  9522. CheckSource('TestArrayOfSet',
  9523. LinesToStr([ // statements
  9524. 'this.TFlag = {',
  9525. ' "0": "big",',
  9526. ' big: 0,',
  9527. ' "1": "small",',
  9528. ' small: 1',
  9529. '};',
  9530. 'this.DoIt = function (a) {',
  9531. '};',
  9532. 'this.f = 0;',
  9533. 'this.s = {};',
  9534. 'this.Arr = [];',
  9535. 'this.i = 0;',
  9536. '']),
  9537. LinesToStr([ // $mod.$main
  9538. '$mod.Arr = rtl.arraySetLength($mod.Arr, {}, 3);',
  9539. '$mod.Arr[0] = rtl.refSet($mod.s);',
  9540. '$mod.Arr[1] = rtl.createSet($mod.TFlag.big);',
  9541. '$mod.Arr[2] = rtl.unionSet(rtl.createSet($mod.TFlag.big), $mod.s);',
  9542. '$mod.Arr[3] = rtl.unionSet($mod.s, rtl.createSet($mod.TFlag.big));',
  9543. '$mod.Arr[4] = rtl.refSet($mod.Arr[5]);',
  9544. '$mod.s = rtl.refSet($mod.Arr[6]);',
  9545. '$mod.i = 0;',
  9546. '$mod.i = rtl.length($mod.Arr) - 1;',
  9547. '$mod.DoIt($mod.Arr);',
  9548. '$mod.DoIt([rtl.refSet($mod.s)]);',
  9549. '$mod.DoIt([{}, rtl.refSet($mod.s)]);',
  9550. '$mod.DoIt([rtl.refSet($mod.s), {}]);',
  9551. '']));
  9552. end;
  9553. procedure TTestModule.TestArray_DynAsParam;
  9554. begin
  9555. StartProgram(false);
  9556. Add([
  9557. 'type integer = longint;',
  9558. 'type TArrInt = array of integer;',
  9559. 'procedure DoIt(vG: TArrInt; const vH: TArrInt; var vI: TArrInt);',
  9560. 'var vJ: TArrInt;',
  9561. 'begin',
  9562. ' vg:=vg;',
  9563. ' vj:=vh;',
  9564. ' vi:=vi;',
  9565. ' doit(vg,vg,vg);',
  9566. ' doit(vh,vh,vj);',
  9567. ' doit(vi,vi,vi);',
  9568. ' doit(vj,vj,vj);',
  9569. 'end;',
  9570. 'var i: TArrInt;',
  9571. 'begin',
  9572. ' doit(i,i,i);']);
  9573. ConvertProgram;
  9574. CheckSource('TestArray_DynAsParams',
  9575. LinesToStr([ // statements
  9576. 'this.DoIt = function (vG,vH,vI) {',
  9577. ' var vJ = [];',
  9578. ' vG = rtl.arrayRef(vG);',
  9579. ' vJ = rtl.arrayRef(vH);',
  9580. ' vI.set(rtl.arrayRef(vI.get()));',
  9581. ' $mod.DoIt(rtl.arrayRef(vG), vG, {',
  9582. ' get: function () {',
  9583. ' return vG;',
  9584. ' },',
  9585. ' set: function (v) {',
  9586. ' vG = v;',
  9587. ' }',
  9588. ' });',
  9589. ' $mod.DoIt(rtl.arrayRef(vH), vH, {',
  9590. ' get: function () {',
  9591. ' return vJ;',
  9592. ' },',
  9593. ' set: function (v) {',
  9594. ' vJ = v;',
  9595. ' }',
  9596. ' });',
  9597. ' $mod.DoIt(rtl.arrayRef(vI.get()), vI.get(), vI);',
  9598. ' $mod.DoIt(rtl.arrayRef(vJ), vJ, {',
  9599. ' get: function () {',
  9600. ' return vJ;',
  9601. ' },',
  9602. ' set: function (v) {',
  9603. ' vJ = v;',
  9604. ' }',
  9605. ' });',
  9606. '};',
  9607. 'this.i = [];'
  9608. ]),
  9609. LinesToStr([
  9610. '$mod.DoIt(rtl.arrayRef($mod.i),$mod.i,{',
  9611. ' p: $mod,',
  9612. ' get: function () {',
  9613. ' return this.p.i;',
  9614. ' },',
  9615. ' set: function (v) {',
  9616. ' this.p.i = v;',
  9617. ' }',
  9618. '});'
  9619. ]));
  9620. end;
  9621. procedure TTestModule.TestArray_StaticAsParam;
  9622. begin
  9623. StartProgram(false);
  9624. Add([
  9625. 'type integer = longint;',
  9626. 'type TArrInt = array[1..2] of integer;',
  9627. 'procedure DoIt(vG: TArrInt; const vH: TArrInt; var vI: TArrInt);',
  9628. 'var vJ: TArrInt;',
  9629. 'begin',
  9630. ' vg:=vg;',
  9631. ' vj:=vh;',
  9632. ' vi:=vi;',
  9633. ' doit(vg,vg,vg);',
  9634. ' doit(vh,vh,vj);',
  9635. ' doit(vi,vi,vi);',
  9636. ' doit(vj,vj,vj);',
  9637. 'end;',
  9638. 'var i: TArrInt;',
  9639. 'begin',
  9640. ' doit(i,i,i);']);
  9641. ConvertProgram;
  9642. CheckSource('TestArray_StaticAsParams',
  9643. LinesToStr([ // statements
  9644. 'this.DoIt = function (vG,vH,vI) {',
  9645. ' var vJ = rtl.arraySetLength(null, 0, 2);',
  9646. ' vG = vG.slice(0);',
  9647. ' vJ = vH.slice(0);',
  9648. ' vI.set(vI.get().slice(0));',
  9649. ' $mod.DoIt(vG.slice(0), vG, {',
  9650. ' get: function () {',
  9651. ' return vG;',
  9652. ' },',
  9653. ' set: function (v) {',
  9654. ' vG = v;',
  9655. ' }',
  9656. ' });',
  9657. ' $mod.DoIt(vH.slice(0), vH, {',
  9658. ' get: function () {',
  9659. ' return vJ;',
  9660. ' },',
  9661. ' set: function (v) {',
  9662. ' vJ = v;',
  9663. ' }',
  9664. ' });',
  9665. ' $mod.DoIt(vI.get().slice(0), vI.get(), vI);',
  9666. ' $mod.DoIt(vJ.slice(0), vJ, {',
  9667. ' get: function () {',
  9668. ' return vJ;',
  9669. ' },',
  9670. ' set: function (v) {',
  9671. ' vJ = v;',
  9672. ' }',
  9673. ' });',
  9674. '};',
  9675. 'this.i = rtl.arraySetLength(null, 0, 2);'
  9676. ]),
  9677. LinesToStr([
  9678. '$mod.DoIt($mod.i.slice(0),$mod.i,{',
  9679. ' p: $mod,',
  9680. ' get: function () {',
  9681. ' return this.p.i;',
  9682. ' },',
  9683. ' set: function (v) {',
  9684. ' this.p.i = v;',
  9685. ' }',
  9686. '});'
  9687. ]));
  9688. end;
  9689. procedure TTestModule.TestArrayElement_AsParams;
  9690. begin
  9691. StartProgram(false);
  9692. Add('type integer = longint;');
  9693. Add('type TArrayInt = array of integer;');
  9694. Add('procedure DoIt(vG: Integer; const vH: Integer; var vI: Integer);');
  9695. Add('var vJ: tarrayint;');
  9696. Add('begin');
  9697. Add(' vi:=vi;');
  9698. Add(' doit(vi,vi,vi);');
  9699. Add(' doit(vj[1+1],vj[1+2],vj[1+3]);');
  9700. Add('end;');
  9701. Add('var a: TArrayInt;');
  9702. Add('begin');
  9703. Add(' doit(a[1+4],a[1+5],a[1+6]);');
  9704. ConvertProgram;
  9705. CheckSource('TestArrayElement_AsParams',
  9706. LinesToStr([ // statements
  9707. 'this.DoIt = function (vG,vH,vI) {',
  9708. ' var vJ = [];',
  9709. ' vI.set(vI.get());',
  9710. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  9711. ' $mod.DoIt(vJ[1+1], vJ[1+2], {',
  9712. ' a:1+3,',
  9713. ' p:vJ,',
  9714. ' get: function () {',
  9715. ' return this.p[this.a];',
  9716. ' },',
  9717. ' set: function (v) {',
  9718. ' this.p[this.a] = v;',
  9719. ' }',
  9720. ' });',
  9721. '};',
  9722. 'this.a = [];'
  9723. ]),
  9724. LinesToStr([
  9725. '$mod.DoIt($mod.a[1+4],$mod.a[1+5],{',
  9726. ' a: 1+6,',
  9727. ' p: $mod.a,',
  9728. ' get: function () {',
  9729. ' return this.p[this.a];',
  9730. ' },',
  9731. ' set: function (v) {',
  9732. ' this.p[this.a] = v;',
  9733. ' }',
  9734. '});'
  9735. ]));
  9736. end;
  9737. procedure TTestModule.TestArrayElementFromFuncResult_AsParams;
  9738. begin
  9739. StartProgram(false);
  9740. Add('type Integer = longint;');
  9741. Add('type TArrayInt = array of integer;');
  9742. Add('function GetArr(vB: integer = 0): tarrayint;');
  9743. Add('begin');
  9744. Add('end;');
  9745. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  9746. Add('begin');
  9747. Add('end;');
  9748. Add('begin');
  9749. Add(' doit(getarr[1+1],getarr[1+2],getarr[1+3]);');
  9750. Add(' doit(getarr()[2+1],getarr()[2+2],getarr()[2+3]);');
  9751. Add(' doit(getarr(7)[3+1],getarr(8)[3+2],getarr(9)[3+3]);');
  9752. ConvertProgram;
  9753. CheckSource('TestArrayElementFromFuncResult_AsParams',
  9754. LinesToStr([ // statements
  9755. 'this.GetArr = function (vB) {',
  9756. ' var Result = [];',
  9757. ' return Result;',
  9758. '};',
  9759. 'this.DoIt = function (vG,vH,vI) {',
  9760. '};'
  9761. ]),
  9762. LinesToStr([
  9763. '$mod.DoIt($mod.GetArr(0)[1+1],$mod.GetArr(0)[1+2],{',
  9764. ' a: 1+3,',
  9765. ' p: $mod.GetArr(0),',
  9766. ' get: function () {',
  9767. ' return this.p[this.a];',
  9768. ' },',
  9769. ' set: function (v) {',
  9770. ' this.p[this.a] = v;',
  9771. ' }',
  9772. '});',
  9773. '$mod.DoIt($mod.GetArr(0)[2+1],$mod.GetArr(0)[2+2],{',
  9774. ' a: 2+3,',
  9775. ' p: $mod.GetArr(0),',
  9776. ' get: function () {',
  9777. ' return this.p[this.a];',
  9778. ' },',
  9779. ' set: function (v) {',
  9780. ' this.p[this.a] = v;',
  9781. ' }',
  9782. '});',
  9783. '$mod.DoIt($mod.GetArr(7)[3+1],$mod.GetArr(8)[3+2],{',
  9784. ' a: 3+3,',
  9785. ' p: $mod.GetArr(9),',
  9786. ' get: function () {',
  9787. ' return this.p[this.a];',
  9788. ' },',
  9789. ' set: function (v) {',
  9790. ' this.p[this.a] = v;',
  9791. ' }',
  9792. '});',
  9793. '']));
  9794. end;
  9795. procedure TTestModule.TestArrayEnumTypeRange;
  9796. begin
  9797. StartProgram(false);
  9798. Add([
  9799. 'type',
  9800. ' TEnum = (red,blue);',
  9801. ' TEnumArray = array[TEnum] of longint;',
  9802. 'var',
  9803. ' e: TEnum;',
  9804. ' i: longint;',
  9805. ' a: TEnumArray;',
  9806. ' numbers: TEnumArray = (1,2);',
  9807. ' names: array[TEnum] of string = (''red'',''blue'');',
  9808. 'begin',
  9809. ' e:=low(a);',
  9810. ' e:=high(a);',
  9811. ' i:=a[red];',
  9812. ' a[e]:=a[e];']);
  9813. ConvertProgram;
  9814. CheckSource('TestArrayEnumTypeRange',
  9815. LinesToStr([ // statements
  9816. ' this.TEnum = {',
  9817. ' "0": "red",',
  9818. ' red: 0,',
  9819. ' "1": "blue",',
  9820. ' blue: 1',
  9821. '};',
  9822. 'this.e = 0;',
  9823. 'this.i = 0;',
  9824. 'this.a = rtl.arraySetLength(null,0,2);',
  9825. 'this.numbers = [1, 2];',
  9826. 'this.names = ["red", "blue"];',
  9827. '']),
  9828. LinesToStr([ // $mod.$main
  9829. '$mod.e = $mod.TEnum.red;',
  9830. '$mod.e = $mod.TEnum.blue;',
  9831. '$mod.i = $mod.a[$mod.TEnum.red];',
  9832. '$mod.a[$mod.e] = $mod.a[$mod.e];',
  9833. '']));
  9834. end;
  9835. procedure TTestModule.TestArray_SetLengthOutArg;
  9836. begin
  9837. StartProgram(false);
  9838. Add([
  9839. 'type TArrInt = array of longint;',
  9840. 'procedure DoIt(out a: TArrInt);',
  9841. 'begin',
  9842. ' SetLength(a,2);',
  9843. 'end;',
  9844. 'begin',
  9845. '']);
  9846. ConvertProgram;
  9847. CheckSource('TestArray_SetLengthOutArg',
  9848. LinesToStr([ // statements
  9849. 'this.DoIt = function (a) {',
  9850. ' a.set(rtl.arraySetLength(a.get(), 0, 2));',
  9851. '};',
  9852. '']),
  9853. LinesToStr([
  9854. '']));
  9855. end;
  9856. procedure TTestModule.TestArray_SetLengthProperty;
  9857. begin
  9858. StartProgram(false);
  9859. Add('type');
  9860. Add(' TArrInt = array of longint;');
  9861. Add(' TObject = class');
  9862. Add(' function GetColors: TArrInt; external name ''GetColors'';');
  9863. Add(' procedure SetColors(const Value: TArrInt); external name ''SetColors'';');
  9864. Add(' property Colors: TArrInt read GetColors write SetColors;');
  9865. Add(' end;');
  9866. Add('var Obj: TObject;');
  9867. Add('begin');
  9868. Add(' SetLength(Obj.Colors,2);');
  9869. ConvertProgram;
  9870. CheckSource('TestArray_SetLengthProperty',
  9871. LinesToStr([ // statements
  9872. 'rtl.createClass(this, "TObject", null, function () {',
  9873. ' this.$init = function () {',
  9874. ' };',
  9875. ' this.$final = function () {',
  9876. ' };',
  9877. '});',
  9878. 'this.Obj = null;',
  9879. '']),
  9880. LinesToStr([
  9881. '$mod.Obj.SetColors(rtl.arraySetLength($mod.Obj.GetColors(), 0, 2));',
  9882. '']));
  9883. end;
  9884. procedure TTestModule.TestArray_SetLengthMultiDim;
  9885. begin
  9886. StartProgram(false);
  9887. Add([
  9888. 'type',
  9889. ' TArrArrInt = array of array of longint;',
  9890. ' TArrStaInt = array of array[1..2] of longint;',
  9891. 'var',
  9892. ' a: TArrArrInt;',
  9893. ' b: TArrStaInt;',
  9894. 'begin',
  9895. ' SetLength(a,2);',
  9896. ' SetLength(a,3,4);',
  9897. ' SetLength(b,5);',
  9898. '']);
  9899. ConvertProgram;
  9900. CheckSource('TestArray_SetLengthMultiDim',
  9901. LinesToStr([ // statements
  9902. 'this.a = [];',
  9903. 'this.b = [];',
  9904. '']),
  9905. LinesToStr([
  9906. '$mod.a = rtl.arraySetLength($mod.a, [], 2);',
  9907. '$mod.a = rtl.arraySetLength($mod.a, 0, 3, 4);',
  9908. '$mod.b = rtl.arraySetLength($mod.b, 0, 5, "s", 2);',
  9909. '']));
  9910. end;
  9911. procedure TTestModule.TestArray_SetLengthDynOfStatic;
  9912. begin
  9913. StartProgram(false);
  9914. Add([
  9915. 'type',
  9916. ' TStaArr1 = array[1..3] of boolean;',
  9917. //' TStaArr2 = array[5..6] of TStaArr1;',
  9918. ' TDynArr1StaArr1 = array of TStaArr1;',
  9919. //' TDynArr1StaArr2 = array of TStaArr2;',
  9920. ' TDynArr2StaArr1 = array of TDynArr1StaArr1;',
  9921. //' TDynArr2StaArr2 = array of TDynArr1StaArr2;',
  9922. 'var',
  9923. ' DynArr1StaArr1: TDynArr1StaArr1;',
  9924. //' DynArr1StaArr2: TDynArr1StaArr1;',
  9925. ' DynArr2StaArr1: TDynArr2StaArr1;',
  9926. //' DynArr2StaArr2: TDynArr2StaArr2;',
  9927. 'begin',
  9928. ' SetLength(DynArr1StaArr1,11);',
  9929. ' SetLength(DynArr2StaArr1,12);',
  9930. ' SetLength(DynArr2StaArr1[13],14);',
  9931. ' SetLength(DynArr2StaArr1,15,16);',
  9932. //' SetLength(DynArr1StaArr2,21);',
  9933. //' SetLength(DynArr2StaArr2,22);',
  9934. //' SetLength(DynArr2StaArr2[23],24);',
  9935. //' SetLength(DynArr2StaArr2,25,26);',
  9936. '']);
  9937. ConvertProgram;
  9938. CheckSource('TestArray_DynOfStatic',
  9939. LinesToStr([ // statements
  9940. 'this.DynArr1StaArr1 = [];',
  9941. 'this.DynArr2StaArr1 = [];',
  9942. '']),
  9943. LinesToStr([ // $mod.$main
  9944. '$mod.DynArr1StaArr1 = rtl.arraySetLength($mod.DynArr1StaArr1, false, 11, "s", 3);',
  9945. '$mod.DynArr2StaArr1 = rtl.arraySetLength($mod.DynArr2StaArr1, [], 12);',
  9946. '$mod.DynArr2StaArr1[13] = rtl.arraySetLength($mod.DynArr2StaArr1[13], false, 14, "s", 3);',
  9947. '$mod.DynArr2StaArr1 = rtl.arraySetLength(',
  9948. ' $mod.DynArr2StaArr1,',
  9949. ' false,',
  9950. ' 15,',
  9951. ' 16,',
  9952. ' "s",',
  9953. ' 3',
  9954. ');',
  9955. '']));
  9956. end;
  9957. procedure TTestModule.TestArray_OpenArrayOfString;
  9958. begin
  9959. StartProgram(false);
  9960. Add('procedure DoIt(const a: array of String);');
  9961. Add('var');
  9962. Add(' i: longint;');
  9963. Add(' s: string;');
  9964. Add('begin');
  9965. Add(' for i:=low(a) to high(a) do s:=a[length(a)-i-1];');
  9966. Add('end;');
  9967. Add('var s: string;');
  9968. Add('begin');
  9969. Add(' DoIt([]);');
  9970. Add(' DoIt([s,''foo'','''',s+s]);');
  9971. ConvertProgram;
  9972. CheckSource('TestArray_OpenArrayOfString',
  9973. LinesToStr([ // statements
  9974. 'this.DoIt = function (a) {',
  9975. ' var i = 0;',
  9976. ' var s = "";',
  9977. ' for (var $l = 0, $end = rtl.length(a) - 1; $l <= $end; $l++) {',
  9978. ' i = $l;',
  9979. ' s = a[rtl.length(a) - i - 1];',
  9980. ' };',
  9981. '};',
  9982. 'this.s = "";',
  9983. '']),
  9984. LinesToStr([
  9985. '$mod.DoIt([]);',
  9986. '$mod.DoIt([$mod.s, "foo", "", $mod.s + $mod.s]);',
  9987. '']));
  9988. end;
  9989. procedure TTestModule.TestArray_ArrayOfCharAssignString;
  9990. begin
  9991. StartProgram(false);
  9992. Add([
  9993. 'type TArr = array of char;',
  9994. 'var',
  9995. ' c: char;',
  9996. ' s: string;',
  9997. ' a: TArr;',
  9998. 'procedure Run(const a: array of char);',
  9999. 'begin',
  10000. ' Run(c);',
  10001. ' Run(s);',
  10002. 'end;',
  10003. 'begin',
  10004. ' a:=c;',
  10005. ' a:=s;',
  10006. ' a:=#13;',
  10007. ' a:=''Foo'';',
  10008. ' Run(c);',
  10009. ' Run(s);',
  10010. '']);
  10011. ConvertProgram;
  10012. CheckSource('TestArray_ArrayOfCharAssignString',
  10013. LinesToStr([ // statements
  10014. 'this.c = "";',
  10015. 'this.s = "";',
  10016. 'this.a = [];',
  10017. 'this.Run = function (a) {',
  10018. ' $mod.Run($mod.c.split(""));',
  10019. ' $mod.Run($mod.s.split(""));',
  10020. '};',
  10021. '']),
  10022. LinesToStr([
  10023. '$mod.a = $mod.c.split("");',
  10024. '$mod.a = $mod.s.split("");',
  10025. '$mod.a = "\r".split("");',
  10026. '$mod.a = "Foo".split("");',
  10027. '$mod.Run($mod.c.split(""));',
  10028. '$mod.Run($mod.s.split(""));',
  10029. '']));
  10030. end;
  10031. procedure TTestModule.TestArray_ConstRef;
  10032. begin
  10033. StartProgram(false);
  10034. Add([
  10035. 'type TArr = array of word;',
  10036. 'procedure Run(constref a: TArr);',
  10037. 'begin',
  10038. 'end;',
  10039. 'procedure Fly(a: TArr; var b: TArr; out c: TArr; const d: TArr; constref e: TArr);',
  10040. 'var l: TArr;',
  10041. 'begin',
  10042. ' Run(l);',
  10043. ' Run(a);',
  10044. ' Run(b);',
  10045. ' Run(c);',
  10046. ' Run(d);',
  10047. ' Run(e);',
  10048. 'end;',
  10049. 'begin',
  10050. '']);
  10051. ConvertProgram;
  10052. CheckResolverUnexpectedHints();
  10053. CheckSource('TestArray_ConstRef',
  10054. LinesToStr([ // statements
  10055. 'this.Run = function (a) {',
  10056. '};',
  10057. 'this.Fly = function (a, b, c, d, e) {',
  10058. ' var l = [];',
  10059. ' $mod.Run(l);',
  10060. ' $mod.Run(a);',
  10061. ' $mod.Run(b.get());',
  10062. ' $mod.Run(c.get());',
  10063. ' $mod.Run(d);',
  10064. ' $mod.Run(e);',
  10065. '};',
  10066. '']),
  10067. LinesToStr([
  10068. '']));
  10069. end;
  10070. procedure TTestModule.TestArray_Concat;
  10071. begin
  10072. StartProgram(false);
  10073. Add([
  10074. 'type',
  10075. ' integer = longint;',
  10076. ' TFlag = (big,small);',
  10077. ' TFlags = set of TFlag;',
  10078. ' TRec = record',
  10079. ' i: integer;',
  10080. ' end;',
  10081. ' TArrInt = array of integer;',
  10082. ' TArrRec = array of TRec;',
  10083. ' TArrFlag = array of TFlag;',
  10084. ' TArrSet = array of TFlags;',
  10085. ' TArrJSValue = array of jsvalue;',
  10086. 'var',
  10087. ' ArrInt: tarrint;',
  10088. ' ArrRec: tarrrec;',
  10089. ' ArrFlag: tarrflag;',
  10090. ' ArrSet: tarrset;',
  10091. ' ArrJSValue: tarrjsvalue;',
  10092. 'begin',
  10093. ' arrint:=concat(arrint);',
  10094. ' arrint:=concat(arrint,arrint);',
  10095. ' arrint:=concat(arrint,arrint,arrint);',
  10096. ' arrrec:=concat(arrrec);',
  10097. ' arrrec:=concat(arrrec,arrrec);',
  10098. ' arrrec:=concat(arrrec,arrrec,arrrec);',
  10099. ' arrset:=concat(arrset);',
  10100. ' arrset:=concat(arrset,arrset);',
  10101. ' arrset:=concat(arrset,arrset,arrset);',
  10102. ' arrjsvalue:=concat(arrjsvalue);',
  10103. ' arrjsvalue:=concat(arrjsvalue,arrjsvalue);',
  10104. ' arrjsvalue:=concat(arrjsvalue,arrjsvalue,arrjsvalue);',
  10105. ' arrint:=concat([1],arrint);',
  10106. ' arrflag:=concat([big]);',
  10107. ' arrflag:=concat([big],arrflag);',
  10108. ' arrflag:=concat(arrflag,[small]);',
  10109. '']);
  10110. ConvertProgram;
  10111. CheckSource('TestArray_Concat',
  10112. LinesToStr([ // statements
  10113. 'this.TFlag = {',
  10114. ' "0": "big",',
  10115. ' big: 0,',
  10116. ' "1": "small",',
  10117. ' small: 1',
  10118. '};',
  10119. 'rtl.recNewT(this, "TRec", function () {',
  10120. ' this.i = 0;',
  10121. ' this.$eq = function (b) {',
  10122. ' return this.i === b.i;',
  10123. ' };',
  10124. ' this.$assign = function (s) {',
  10125. ' this.i = s.i;',
  10126. ' return this;',
  10127. ' };',
  10128. '});',
  10129. 'this.ArrInt = [];',
  10130. 'this.ArrRec = [];',
  10131. 'this.ArrFlag = [];',
  10132. 'this.ArrSet = [];',
  10133. 'this.ArrJSValue = [];',
  10134. '']),
  10135. LinesToStr([ // $mod.$main
  10136. '$mod.ArrInt = rtl.arrayRef($mod.ArrInt);',
  10137. '$mod.ArrInt = rtl.arrayConcatN($mod.ArrInt, $mod.ArrInt);',
  10138. '$mod.ArrInt = rtl.arrayConcatN($mod.ArrInt, $mod.ArrInt, $mod.ArrInt);',
  10139. '$mod.ArrRec = rtl.arrayRef($mod.ArrRec);',
  10140. '$mod.ArrRec = rtl.arrayConcat($mod.TRec, $mod.ArrRec, $mod.ArrRec);',
  10141. '$mod.ArrRec = rtl.arrayConcat($mod.TRec, $mod.ArrRec, $mod.ArrRec, $mod.ArrRec);',
  10142. '$mod.ArrSet = rtl.arrayRef($mod.ArrSet);',
  10143. '$mod.ArrSet = rtl.arrayConcat("refSet", $mod.ArrSet, $mod.ArrSet);',
  10144. '$mod.ArrSet = rtl.arrayConcat("refSet", $mod.ArrSet, $mod.ArrSet, $mod.ArrSet);',
  10145. '$mod.ArrJSValue = rtl.arrayRef($mod.ArrJSValue);',
  10146. '$mod.ArrJSValue = rtl.arrayConcatN($mod.ArrJSValue, $mod.ArrJSValue);',
  10147. '$mod.ArrJSValue = rtl.arrayConcatN($mod.ArrJSValue, $mod.ArrJSValue, $mod.ArrJSValue);',
  10148. '$mod.ArrInt = rtl.arrayConcatN([1], $mod.ArrInt);',
  10149. '$mod.ArrFlag = [$mod.TFlag.big];',
  10150. '$mod.ArrFlag = rtl.arrayConcatN([$mod.TFlag.big], $mod.ArrFlag);',
  10151. '$mod.ArrFlag = rtl.arrayConcatN($mod.ArrFlag, [$mod.TFlag.small]);',
  10152. '']));
  10153. end;
  10154. procedure TTestModule.TestArray_Copy;
  10155. begin
  10156. StartProgram(false);
  10157. Add([
  10158. 'type',
  10159. ' integer = longint;',
  10160. ' TFlag = (big,small);',
  10161. ' TFlags = set of TFlag;',
  10162. ' TRec = record',
  10163. ' i: integer;',
  10164. ' end;',
  10165. ' TArrInt = array of integer;',
  10166. ' TArrRec = array of TRec;',
  10167. ' TArrSet = array of TFlags;',
  10168. ' TArrJSValue = array of jsvalue;',
  10169. 'var',
  10170. ' ArrInt: tarrint;',
  10171. ' ArrRec: tarrrec;',
  10172. ' ArrSet: tarrset;',
  10173. ' ArrJSValue: tarrjsvalue;',
  10174. 'begin',
  10175. ' arrint:=copy(arrint);',
  10176. ' arrint:=copy(arrint,2);',
  10177. ' arrint:=copy(arrint,3,4);',
  10178. ' arrint:=copy([1,1],1,2);',
  10179. ' arrrec:=copy(arrrec);',
  10180. ' arrrec:=copy(arrrec,5);',
  10181. ' arrrec:=copy(arrrec,6,7);',
  10182. ' arrset:=copy(arrset);',
  10183. ' arrset:=copy(arrset,8);',
  10184. ' arrset:=copy(arrset,9,10);',
  10185. ' arrjsvalue:=copy(arrjsvalue);',
  10186. ' arrjsvalue:=copy(arrjsvalue,11);',
  10187. ' arrjsvalue:=copy(arrjsvalue,12,13);',
  10188. ' ']);
  10189. ConvertProgram;
  10190. CheckSource('TestArray_Copy',
  10191. LinesToStr([ // statements
  10192. 'this.TFlag = {',
  10193. ' "0": "big",',
  10194. ' big: 0,',
  10195. ' "1": "small",',
  10196. ' small: 1',
  10197. '};',
  10198. 'rtl.recNewT(this, "TRec", function () {',
  10199. ' this.i = 0;',
  10200. ' this.$eq = function (b) {',
  10201. ' return this.i === b.i;',
  10202. ' };',
  10203. ' this.$assign = function (s) {',
  10204. ' this.i = s.i;',
  10205. ' return this;',
  10206. ' };',
  10207. '});',
  10208. 'this.ArrInt = [];',
  10209. 'this.ArrRec = [];',
  10210. 'this.ArrSet = [];',
  10211. 'this.ArrJSValue = [];',
  10212. '']),
  10213. LinesToStr([ // $mod.$main
  10214. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 0);',
  10215. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 2);',
  10216. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 3, 4);',
  10217. '$mod.ArrInt = rtl.arrayCopy(0, [1, 1], 1, 2);',
  10218. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 0);',
  10219. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 5);',
  10220. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 6, 7);',
  10221. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 0);',
  10222. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 8);',
  10223. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 9, 10);',
  10224. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 0);',
  10225. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 11);',
  10226. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 12, 13);',
  10227. '']));
  10228. end;
  10229. procedure TTestModule.TestArray_InsertDelete;
  10230. begin
  10231. StartProgram(false);
  10232. Add([
  10233. 'type',
  10234. ' integer = longint;',
  10235. ' TFlag = (big,small);',
  10236. ' TFlags = set of TFlag;',
  10237. ' TRec = record',
  10238. ' i: integer;',
  10239. ' end;',
  10240. ' TArrInt = array of integer;',
  10241. ' TArrRec = array of TRec;',
  10242. ' TArrSet = array of TFlags;',
  10243. ' TArrJSValue = array of jsvalue;',
  10244. ' TArrArrInt = array of TArrInt;',
  10245. 'var',
  10246. ' ArrInt: tarrint;',
  10247. ' ArrRec: tarrrec;',
  10248. ' ArrSet: tarrset;',
  10249. ' ArrJSValue: tarrjsvalue;',
  10250. ' ArrArrInt: TArrArrInt;',
  10251. 'begin',
  10252. ' Insert(1,arrint,2);',
  10253. ' Insert(arrint[3],arrint,4);',
  10254. ' Insert(arrrec[5],arrrec,6);',
  10255. ' Insert(arrset[7],arrset,7);',
  10256. ' Insert(arrjsvalue[8],arrjsvalue,9);',
  10257. ' Insert(10,arrjsvalue,11);',
  10258. ' Insert([23],arrarrint,22);',
  10259. ' Delete(arrint,12,13);',
  10260. ' Delete(arrrec,14,15);',
  10261. ' Delete(arrset,17,18);',
  10262. ' Delete(arrjsvalue,19,10);']);
  10263. ConvertProgram;
  10264. CheckSource('TestArray_InsertDelete',
  10265. LinesToStr([ // statements
  10266. 'this.TFlag = {',
  10267. ' "0": "big",',
  10268. ' big: 0,',
  10269. ' "1": "small",',
  10270. ' small: 1',
  10271. '};',
  10272. 'rtl.recNewT(this, "TRec", function () {',
  10273. ' this.i = 0;',
  10274. ' this.$eq = function (b) {',
  10275. ' return this.i === b.i;',
  10276. ' };',
  10277. ' this.$assign = function (s) {',
  10278. ' this.i = s.i;',
  10279. ' return this;',
  10280. ' };',
  10281. '});',
  10282. 'this.ArrInt = [];',
  10283. 'this.ArrRec = [];',
  10284. 'this.ArrSet = [];',
  10285. 'this.ArrJSValue = [];',
  10286. 'this.ArrArrInt = [];',
  10287. '']),
  10288. LinesToStr([ // $mod.$main
  10289. '$mod.ArrInt = rtl.arrayInsert(1, $mod.ArrInt, 2);',
  10290. '$mod.ArrInt = rtl.arrayInsert($mod.ArrInt[3], $mod.ArrInt, 4);',
  10291. '$mod.ArrRec = rtl.arrayInsert($mod.ArrRec[5], $mod.ArrRec, 6);',
  10292. '$mod.ArrSet = rtl.arrayInsert($mod.ArrSet[7], $mod.ArrSet, 7);',
  10293. '$mod.ArrJSValue = rtl.arrayInsert($mod.ArrJSValue[8], $mod.ArrJSValue, 9);',
  10294. '$mod.ArrJSValue = rtl.arrayInsert(10, $mod.ArrJSValue, 11);',
  10295. '$mod.ArrArrInt = rtl.arrayInsert([23], $mod.ArrArrInt, 22);',
  10296. '$mod.ArrInt.splice(12, 13);',
  10297. '$mod.ArrRec.splice(14, 15);',
  10298. '$mod.ArrSet.splice(17, 18);',
  10299. '$mod.ArrJSValue.splice(19, 10);',
  10300. '']));
  10301. end;
  10302. procedure TTestModule.TestArray_DynArrayConstObjFPC;
  10303. begin
  10304. Parser.Options:=Parser.Options+[po_cassignments];
  10305. StartProgram(false);
  10306. Add([
  10307. '{$modeswitch arrayoperators}',
  10308. 'type',
  10309. ' integer = longint;',
  10310. ' TArrInt = array of integer;',
  10311. ' TArrStr = array of string;',
  10312. 'const',
  10313. ' Ints: TArrInt = (1,2,3);',
  10314. ' Aliases: TarrStr = (''foo'',''b'');',
  10315. ' OneInt: TArrInt = (7);',
  10316. ' OneStr: array of integer = (7);',
  10317. ' Chars: array of char = ''aoc'';',
  10318. ' Names: array of string = (''a'',''foo'');',
  10319. ' NameCount = low(Names)+high(Names)+length(Names);',
  10320. 'var i: integer;',
  10321. 'begin',
  10322. ' Ints:=[];',
  10323. ' Ints:=[1,1];',
  10324. ' Ints:=[1]+[2];',
  10325. ' Ints:=[2];',
  10326. ' Ints:=[]+ints;',
  10327. ' Ints:=Ints+[];',
  10328. ' Ints:=Ints+OneInt;',
  10329. ' Ints:=Ints+[1,1];',
  10330. ' Ints:=[i,i]+Ints;',
  10331. ' Ints:=[1]+[i]+[3];',
  10332. '']);
  10333. ConvertProgram;
  10334. CheckSource('TestArray_DynArrayConstObjFPC',
  10335. LinesToStr([ // statements
  10336. 'this.Ints = [1, 2, 3];',
  10337. 'this.Aliases = ["foo", "b"];',
  10338. 'this.OneInt = [7];',
  10339. 'this.OneStr = [7];',
  10340. 'this.Chars = ["a", "o", "c"];',
  10341. 'this.Names = ["a", "foo"];',
  10342. 'this.NameCount = 0 + (rtl.length(this.Names) - 1) + rtl.length(this.Names);',
  10343. 'this.i = 0;',
  10344. '']),
  10345. LinesToStr([ // $mod.$main
  10346. '$mod.Ints = [];',
  10347. '$mod.Ints = [1, 1];',
  10348. '$mod.Ints = rtl.arrayConcatN([1], [2]);',
  10349. '$mod.Ints = [2];',
  10350. '$mod.Ints = rtl.arrayConcatN([], $mod.Ints);',
  10351. '$mod.Ints = rtl.arrayConcatN($mod.Ints, []);',
  10352. '$mod.Ints = rtl.arrayConcatN($mod.Ints, $mod.OneInt);',
  10353. '$mod.Ints = rtl.arrayConcatN($mod.Ints, [1, 1]);',
  10354. '$mod.Ints = rtl.arrayConcatN([$mod.i, $mod.i], $mod.Ints);',
  10355. '$mod.Ints = rtl.arrayConcatN(rtl.arrayConcatN([1], [$mod.i]), [3]);',
  10356. '']));
  10357. end;
  10358. procedure TTestModule.TestArray_DynArrayConstDelphi;
  10359. begin
  10360. StartProgram(false);
  10361. // Note: const c = [1,1]; defines a set!
  10362. Add([
  10363. '{$mode delphi}',
  10364. 'type',
  10365. ' integer = longint;',
  10366. ' TArrInt = array of integer;',
  10367. ' TArrStr = array of string;',
  10368. 'const',
  10369. ' Ints: TArrInt = [1,1,2];',
  10370. ' Aliases: TarrStr = [''foo'',''b''];',
  10371. ' OneInt: TArrInt = [7];',
  10372. ' OneStr: array of integer = [7]+[8];',
  10373. ' Chars: array of char = ''aoc'';',
  10374. ' Names: array of string = [''a'',''a''];',
  10375. ' NameCount = low(Names)+high(Names)+length(Names);',
  10376. 'begin',
  10377. '']);
  10378. ConvertProgram;
  10379. CheckSource('TestArray_DynArrayConstDelphi',
  10380. LinesToStr([ // statements
  10381. 'this.Ints = [1, 1, 2];',
  10382. 'this.Aliases = ["foo", "b"];',
  10383. 'this.OneInt = [7];',
  10384. 'this.OneStr = rtl.arrayConcatN([7],[8]);',
  10385. 'this.Chars = ["a", "o", "c"];',
  10386. 'this.Names = ["a", "a"];',
  10387. 'this.NameCount = 0 + (rtl.length(this.Names) - 1) + rtl.length(this.Names);',
  10388. '']),
  10389. LinesToStr([ // $mod.$main
  10390. '']));
  10391. end;
  10392. procedure TTestModule.TestArray_ArrayLitAsParam;
  10393. begin
  10394. StartProgram(false);
  10395. Add([
  10396. '{$modeswitch arrayoperators}',
  10397. 'type',
  10398. ' integer = longint;',
  10399. ' TArrInt = array of integer;',
  10400. ' TArrSet = array of (red,green,blue);',
  10401. 'procedure DoOpenInt(const a: array of integer); forward;',
  10402. 'procedure DoInt(const a: TArrInt);',
  10403. 'begin',
  10404. ' DoInt(a+[1]);',
  10405. ' DoInt([1]+a);',
  10406. ' DoOpenInt(a);',
  10407. ' DoOpenInt(a+[1]);',
  10408. ' DoOpenInt([1]+a);',
  10409. 'end;',
  10410. 'procedure DoOpenInt(const a: array of integer);',
  10411. 'begin',
  10412. ' DoOpenInt(a+[1]);',
  10413. ' DoOpenInt([1]+a);',
  10414. ' DoInt(a);',
  10415. ' DoInt(a+[1]);',
  10416. ' DoInt([1]+a);',
  10417. 'end;',
  10418. 'procedure DoSet(const a: TArrSet);',
  10419. 'begin',
  10420. ' DoSet(a+[red]);',
  10421. ' DoSet([blue]+a);',
  10422. 'end;',
  10423. 'var',
  10424. ' i: TArrInt;',
  10425. ' s: TArrSet;',
  10426. 'begin',
  10427. ' DoInt([1]);',
  10428. ' DoInt([1]+[2]);',
  10429. ' DoInt(i+[1]);',
  10430. ' DoInt([1]+i);',
  10431. ' DoOpenInt([1]);',
  10432. ' DoOpenInt([1]+[2]);',
  10433. ' DoOpenInt(i+[1]);',
  10434. ' DoOpenInt([1]+i);',
  10435. ' DoSet([red]);',
  10436. ' DoSet([blue]+[green]);',
  10437. ' DoSet(s+[blue]);',
  10438. ' DoSet([red]+s);',
  10439. '']);
  10440. ConvertProgram;
  10441. CheckSource('TestArray_ArrayLitAsParam',
  10442. LinesToStr([ // statements
  10443. 'this.TArrSet$a = {',
  10444. ' "0": "red",',
  10445. ' red: 0,',
  10446. ' "1": "green",',
  10447. ' green: 1,',
  10448. ' "2": "blue",',
  10449. ' blue: 2',
  10450. '};',
  10451. 'this.DoInt = function (a) {',
  10452. ' $mod.DoInt(rtl.arrayConcatN(a, [1]));',
  10453. ' $mod.DoInt(rtl.arrayConcatN([1], a));',
  10454. ' $mod.DoOpenInt(a);',
  10455. ' $mod.DoOpenInt(rtl.arrayConcatN(a, [1]));',
  10456. ' $mod.DoOpenInt(rtl.arrayConcatN([1], a));',
  10457. '};',
  10458. 'this.DoOpenInt = function (a) {',
  10459. ' $mod.DoOpenInt(rtl.arrayConcatN(a, [1]));',
  10460. ' $mod.DoOpenInt(rtl.arrayConcatN([1], a));',
  10461. ' $mod.DoInt(a);',
  10462. ' $mod.DoInt(rtl.arrayConcatN(a, [1]));',
  10463. ' $mod.DoInt(rtl.arrayConcatN([1], a));',
  10464. '};',
  10465. 'this.DoSet = function (a) {',
  10466. ' $mod.DoSet(rtl.arrayConcatN(a, [$mod.TArrSet$a.red]));',
  10467. ' $mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.blue], a));',
  10468. '};',
  10469. 'this.i = [];',
  10470. 'this.s = [];',
  10471. '']),
  10472. LinesToStr([ // $mod.$main
  10473. '$mod.DoInt([1]);',
  10474. '$mod.DoInt(rtl.arrayConcatN([1], [2]));',
  10475. '$mod.DoInt(rtl.arrayConcatN($mod.i, [1]));',
  10476. '$mod.DoInt(rtl.arrayConcatN([1], $mod.i));',
  10477. '$mod.DoOpenInt([1]);',
  10478. '$mod.DoOpenInt(rtl.arrayConcatN([1], [2]));',
  10479. '$mod.DoOpenInt(rtl.arrayConcatN($mod.i, [1]));',
  10480. '$mod.DoOpenInt(rtl.arrayConcatN([1], $mod.i));',
  10481. '$mod.DoSet([$mod.TArrSet$a.red]);',
  10482. '$mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.blue], [$mod.TArrSet$a.green]));',
  10483. '$mod.DoSet(rtl.arrayConcatN($mod.s, [$mod.TArrSet$a.blue]));',
  10484. '$mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.red], $mod.s));',
  10485. '']));
  10486. end;
  10487. procedure TTestModule.TestArray_ArrayLitMultiDimAsParam;
  10488. begin
  10489. StartProgram(false);
  10490. Add([
  10491. '{$modeswitch arrayoperators}',
  10492. 'type',
  10493. ' integer = longint;',
  10494. ' TArrInt = array of integer;',
  10495. ' TArrArrInt = array of TArrInt;',
  10496. 'procedure DoInt(const a: TArrArrInt);',
  10497. 'begin',
  10498. ' DoInt(a+[[1]]);',
  10499. ' DoInt([[1]]+a);',
  10500. ' DoInt(a);',
  10501. 'end;',
  10502. 'var',
  10503. ' i: TArrInt;',
  10504. ' a: TArrArrInt;',
  10505. 'begin',
  10506. ' a:=[[1]];',
  10507. ' a:=[i];',
  10508. ' a:=a+[i];',
  10509. ' a:=[i]+a;',
  10510. ' a:=[[1]+i];',
  10511. ' a:=[[1]+[2]];',
  10512. ' a:=[i+[2]];',
  10513. ' DoInt([[1]]);',
  10514. ' DoInt([[1]+[2],[3,4],[5]]);',
  10515. ' DoInt([i+[1]]+a);',
  10516. ' DoInt([i]+a);',
  10517. '']);
  10518. ConvertProgram;
  10519. CheckSource('TestArray_ArrayLitMultiDimAsParam',
  10520. LinesToStr([ // statements
  10521. 'this.DoInt = function (a) {',
  10522. ' $mod.DoInt(rtl.arrayConcatN(a, [[1]]));',
  10523. ' $mod.DoInt(rtl.arrayConcatN([[1]], a));',
  10524. ' $mod.DoInt(a);',
  10525. '};',
  10526. 'this.i = [];',
  10527. 'this.a = [];',
  10528. '']),
  10529. LinesToStr([ // $mod.$main
  10530. '$mod.a = [[1]];',
  10531. '$mod.a = [$mod.i];',
  10532. '$mod.a = rtl.arrayConcatN($mod.a, [$mod.i]);',
  10533. '$mod.a = rtl.arrayConcatN([$mod.i], $mod.a);',
  10534. '$mod.a = [rtl.arrayConcatN([1], $mod.i)];',
  10535. '$mod.a = [rtl.arrayConcatN([1], [2])];',
  10536. '$mod.a = [rtl.arrayConcatN($mod.i, [2])];',
  10537. '$mod.DoInt([[1]]);',
  10538. '$mod.DoInt([rtl.arrayConcatN([1], [2]), [3, 4], [5]]);',
  10539. '$mod.DoInt(rtl.arrayConcatN([rtl.arrayConcatN($mod.i, [1])], $mod.a));',
  10540. '$mod.DoInt(rtl.arrayConcatN([$mod.i], $mod.a));',
  10541. '']));
  10542. end;
  10543. procedure TTestModule.TestArray_ArrayLitStaticAsParam;
  10544. begin
  10545. StartProgram(false);
  10546. Add([
  10547. '{$modeswitch arrayoperators}',
  10548. 'type',
  10549. ' integer = longint;',
  10550. ' TArrInt = array[1..2] of integer;',
  10551. ' TArrArrInt = array of TArrInt;',
  10552. 'procedure DoInt(const a: TArrArrInt);',
  10553. 'begin',
  10554. ' DoInt(a+[[1,2]]);',
  10555. ' DoInt([[1,2]]+a);',
  10556. ' DoInt(a);',
  10557. 'end;',
  10558. 'var',
  10559. ' i: TArrInt;',
  10560. ' a: TArrArrInt;',
  10561. 'begin',
  10562. ' a:=[[1,1]];',
  10563. ' a:=[i];',
  10564. ' a:=a+[i];',
  10565. ' a:=[i]+a;',
  10566. ' DoInt([[1,1]]);',
  10567. ' DoInt([[1,2],[3,4]]);',
  10568. '']);
  10569. ConvertProgram;
  10570. CheckSource('TestArray_ArrayLitStaticAsParam',
  10571. LinesToStr([ // statements
  10572. 'this.DoInt = function (a) {',
  10573. ' $mod.DoInt(rtl.arrayConcatN(a, [[1, 2]]));',
  10574. ' $mod.DoInt(rtl.arrayConcatN([[1, 2]], a));',
  10575. ' $mod.DoInt(a);',
  10576. '};',
  10577. 'this.i = rtl.arraySetLength(null, 0, 2);',
  10578. 'this.a = [];',
  10579. '']),
  10580. LinesToStr([ // $mod.$main
  10581. '$mod.a = [[1, 1]];',
  10582. '$mod.a = [$mod.i.slice(0)];',
  10583. '$mod.a = rtl.arrayConcatN($mod.a, [$mod.i.slice(0)]);',
  10584. '$mod.a = rtl.arrayConcatN([$mod.i.slice(0)], $mod.a);',
  10585. '$mod.DoInt([[1, 1]]);',
  10586. '$mod.DoInt([[1, 2], [3, 4]]);',
  10587. '']));
  10588. end;
  10589. procedure TTestModule.TestArray_ForInArrOfString;
  10590. begin
  10591. StartProgram(false);
  10592. Add([
  10593. 'type',
  10594. 'type',
  10595. ' TMonthNameArray = array [1..12] of string;',
  10596. ' TMonthNames = TMonthNameArray;',
  10597. ' TObject = class',
  10598. ' private',
  10599. ' function GetLongMonthNames: TMonthNames; virtual; abstract;',
  10600. ' public',
  10601. ' Property LongMonthNames : TMonthNames Read GetLongMonthNames;',
  10602. ' end;',
  10603. 'var',
  10604. ' f: TObject;',
  10605. ' Month: string;',
  10606. ' Names: array of string = (''a'',''foo'',''bar'');',
  10607. ' i: longint;',
  10608. 'begin',
  10609. ' for Month in f.LongMonthNames do ;',
  10610. ' for Month in Names do ;',
  10611. ' for i:=low(Names) to high(Names) do ;',
  10612. '']);
  10613. ConvertProgram;
  10614. CheckSource('TestArray_ForInArrOfString',
  10615. LinesToStr([ // statements
  10616. 'rtl.createClass(this, "TObject", null, function () {',
  10617. ' this.$init = function () {',
  10618. ' };',
  10619. ' this.$final = function () {',
  10620. ' };',
  10621. '});',
  10622. 'this.f = null;',
  10623. 'this.Month = "";',
  10624. 'this.Names = ["a", "foo", "bar"];',
  10625. 'this.i = 0;',
  10626. '']),
  10627. LinesToStr([ // $mod.$main
  10628. 'for (var $in = $mod.f.GetLongMonthNames(), $l = 0, $end = rtl.length($in) - 1; $l <= $end; $l++) $mod.Month = $in[$l];',
  10629. 'for (var $in1 = $mod.Names, $l1 = 0, $end1 = rtl.length($in1) - 1; $l1 <= $end1; $l1++) $mod.Month = $in1[$l1];',
  10630. 'for (var $l2 = 0, $end2 = rtl.length($mod.Names) - 1; $l2 <= $end2; $l2++) $mod.i = $l2;',
  10631. '']));
  10632. end;
  10633. procedure TTestModule.TestExternalClass_TypeCastArrayToExternalClass;
  10634. begin
  10635. StartProgram(false);
  10636. Add([
  10637. '{$modeswitch externalclass}',
  10638. 'type',
  10639. ' TJSObject = class external name ''Object''',
  10640. ' end;',
  10641. ' TJSArray = class external name ''Array''',
  10642. ' class function isArray(Value: JSValue) : boolean;',
  10643. ' function concat() : TJSArray; varargs;',
  10644. ' end;',
  10645. 'var',
  10646. ' aObj: TJSArray;',
  10647. ' a: array of longint;',
  10648. ' o: TJSObject;',
  10649. 'begin',
  10650. ' if TJSArray.isArray(65) then ;',
  10651. ' aObj:=TJSArray(a).concat(a);',
  10652. ' o:=TJSObject(a);']);
  10653. ConvertProgram;
  10654. CheckSource('TestExternalClass_TypeCastArrayToExternalClass',
  10655. LinesToStr([ // statements
  10656. 'this.aObj = null;',
  10657. 'this.a = [];',
  10658. 'this.o = null;',
  10659. '']),
  10660. LinesToStr([ // $mod.$main
  10661. 'if (Array.isArray(65)) ;',
  10662. '$mod.aObj = $mod.a.concat($mod.a);',
  10663. '$mod.o = $mod.a;',
  10664. '']));
  10665. end;
  10666. procedure TTestModule.TestExternalClass_TypeCastArrayFromExternalClass;
  10667. begin
  10668. StartProgram(false);
  10669. Add([
  10670. '{$modeswitch externalclass}',
  10671. 'type',
  10672. ' TArrStr = array of string;',
  10673. ' TJSArray = class external name ''Array''',
  10674. ' end;',
  10675. ' TJSObject = class external name ''Object''',
  10676. ' end;',
  10677. 'var',
  10678. ' aObj: TJSArray;',
  10679. ' a: TArrStr;',
  10680. ' jo: TJSObject;',
  10681. 'begin',
  10682. ' a:=TArrStr(aObj);',
  10683. ' TArrStr(aObj)[1]:=TArrStr(aObj)[2];',
  10684. ' a:=TarrStr(jo);',
  10685. '']);
  10686. ConvertProgram;
  10687. CheckSource('TestExternalClass_TypeCastArrayFromExternalClass',
  10688. LinesToStr([ // statements
  10689. 'this.aObj = null;',
  10690. 'this.a = [];',
  10691. 'this.jo = null;',
  10692. '']),
  10693. LinesToStr([ // $mod.$main
  10694. '$mod.a = $mod.aObj;',
  10695. '$mod.aObj[1] = $mod.aObj[2];',
  10696. '$mod.a = $mod.jo;',
  10697. '']));
  10698. end;
  10699. procedure TTestModule.TestArrayOfConst_TVarRec;
  10700. begin
  10701. StartProgram(true,[supTVarRec]);
  10702. Add([
  10703. 'procedure Say(args: array of const);',
  10704. 'var',
  10705. ' i: longint;',
  10706. ' v: TVarRec;',
  10707. 'begin',
  10708. ' for i:=low(args) to high(args) do begin',
  10709. ' v:=args[i];',
  10710. ' case v.vtype of',
  10711. ' vtInteger: if length(args)=args[i].vInteger then ;',
  10712. ' end;',
  10713. ' end;',
  10714. ' for v in args do ;',
  10715. ' args:=nil;',
  10716. ' SetLength(args,2);',
  10717. 'end;',
  10718. 'begin']);
  10719. ConvertProgram;
  10720. CheckSource('TestArrayOfConst_TVarRec',
  10721. LinesToStr([ // statements
  10722. 'this.Say = function (args) {',
  10723. ' var i = 0;',
  10724. ' var v = pas.system.TVarRec.$new();',
  10725. ' for (var $l = 0, $end = rtl.length(args) - 1; $l <= $end; $l++) {',
  10726. ' i = $l;',
  10727. ' v.$assign(args[i]);',
  10728. ' var $tmp = v.VType;',
  10729. ' if ($tmp === 0) if (rtl.length(args) === args[i].VJSValue) ;',
  10730. ' };',
  10731. ' for (var $in = args, $l1 = 0, $end1 = rtl.length($in) - 1; $l1 <= $end1; $l1++) v = $in[$l1];',
  10732. ' args = [];',
  10733. ' args = rtl.arraySetLength(args, pas.system.TVarRec, 2);',
  10734. '};',
  10735. '']),
  10736. LinesToStr([ // $mod.$main
  10737. ]));
  10738. end;
  10739. procedure TTestModule.TestArrayOfConst_PassBaseTypes;
  10740. begin
  10741. StartProgram(true,[supTVarRec]);
  10742. Add([
  10743. 'procedure Say(args: array of const);',
  10744. 'begin',
  10745. ' Say(args);',
  10746. 'end;',
  10747. 'var',
  10748. ' p: Pointer;',
  10749. ' j: jsvalue;',
  10750. ' c: currency;',
  10751. 'begin',
  10752. ' Say([]);',
  10753. ' Say([1]);',
  10754. ' Say([''c'',''foo'',nil,true,1.3,p,j,c]);',
  10755. '']);
  10756. ConvertProgram;
  10757. CheckSource('TestArrayOfConst_PassBaseTypes',
  10758. LinesToStr([ // statements
  10759. 'this.Say = function (args) {',
  10760. ' $mod.Say(args);',
  10761. '};',
  10762. 'this.p = null;',
  10763. 'this.j = undefined;',
  10764. 'this.c = 0;',
  10765. '']),
  10766. LinesToStr([ // $mod.$main
  10767. '$mod.Say([]);',
  10768. '$mod.Say(pas.system.VarRecs(0, 1));',
  10769. '$mod.Say(pas.system.VarRecs(',
  10770. ' 9,',
  10771. ' "c",',
  10772. ' 18,',
  10773. ' "foo",',
  10774. ' 5,',
  10775. ' null,',
  10776. ' 1,',
  10777. ' true,',
  10778. ' 3,',
  10779. ' 1.3,',
  10780. ' 5,',
  10781. ' $mod.p,',
  10782. ' 20,',
  10783. ' $mod.j,',
  10784. ' 12,',
  10785. ' $mod.c',
  10786. ' ));',
  10787. '']));
  10788. end;
  10789. procedure TTestModule.TestArrayOfConst_PassObj;
  10790. begin
  10791. StartProgram(true,[supTVarRec]);
  10792. Add([
  10793. '{$interfaces corba}',
  10794. 'type',
  10795. ' TObject = class',
  10796. ' end;',
  10797. ' TClass = class of TObject;',
  10798. ' IUnknown = interface',
  10799. ' end;',
  10800. 'procedure Say(args: array of const);',
  10801. 'begin',
  10802. 'end;',
  10803. 'var',
  10804. ' o: TObject;',
  10805. ' c: TClass;',
  10806. ' i: IUnknown;',
  10807. 'begin',
  10808. ' Say([o,c,TObject]);',
  10809. ' Say([nil,i]);',
  10810. '']);
  10811. ConvertProgram;
  10812. CheckSource('TestArrayOfConst_PassObj',
  10813. LinesToStr([ // statements
  10814. 'rtl.createClass(this, "TObject", null, function () {',
  10815. ' this.$init = function () {',
  10816. ' };',
  10817. ' this.$final = function () {',
  10818. ' };',
  10819. '});',
  10820. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  10821. 'this.Say = function (args) {',
  10822. '};',
  10823. 'this.o = null;',
  10824. 'this.c = null;',
  10825. 'this.i = null;',
  10826. '']),
  10827. LinesToStr([ // $mod.$main
  10828. '$mod.Say(pas.system.VarRecs(',
  10829. ' 7,',
  10830. ' $mod.o,',
  10831. ' 8,',
  10832. ' $mod.c,',
  10833. ' 8,',
  10834. ' $mod.TObject',
  10835. '));',
  10836. '$mod.Say(pas.system.VarRecs(5, null, 14, $mod.i));',
  10837. '']));
  10838. end;
  10839. procedure TTestModule.TestRecord_Empty;
  10840. begin
  10841. StartProgram(false);
  10842. Add([
  10843. 'type',
  10844. ' TRecA = record',
  10845. ' end;',
  10846. 'var a,b: TRecA;',
  10847. 'begin',
  10848. ' if a=b then ;']);
  10849. ConvertProgram;
  10850. CheckSource('TestRecord_Empty',
  10851. LinesToStr([ // statements
  10852. 'rtl.recNewT(this, "TRecA", function () {',
  10853. ' this.$eq = function (b) {',
  10854. ' return true;',
  10855. ' };',
  10856. ' this.$assign = function (s) {',
  10857. ' return this;',
  10858. ' };',
  10859. '});',
  10860. 'this.a = this.TRecA.$new();',
  10861. 'this.b = this.TRecA.$new();',
  10862. '']),
  10863. LinesToStr([ // $mod.$main
  10864. 'if ($mod.a.$eq($mod.b)) ;'
  10865. ]));
  10866. end;
  10867. procedure TTestModule.TestRecord_Var;
  10868. begin
  10869. StartProgram(false);
  10870. Add('type');
  10871. Add(' TRecA = record');
  10872. Add(' Bold: longint;');
  10873. Add(' end;');
  10874. Add('var Rec: TRecA;');
  10875. Add('begin');
  10876. Add(' rec.bold:=123');
  10877. ConvertProgram;
  10878. CheckSource('TestRecord_Var',
  10879. LinesToStr([ // statements
  10880. 'rtl.recNewT(this, "TRecA", function () {',
  10881. ' this.Bold = 0;',
  10882. ' this.$eq = function (b) {',
  10883. ' return this.Bold === b.Bold;',
  10884. ' };',
  10885. ' this.$assign = function (s) {',
  10886. ' this.Bold = s.Bold;',
  10887. ' return this;',
  10888. ' };',
  10889. '});',
  10890. 'this.Rec = this.TRecA.$new();',
  10891. '']),
  10892. LinesToStr([ // $mod.$main
  10893. '$mod.Rec.Bold = 123;'
  10894. ]));
  10895. end;
  10896. procedure TTestModule.TestRecord_VarExternal;
  10897. begin
  10898. StartProgram(false);
  10899. Add([
  10900. '{$modeswitch externalclass}',
  10901. 'type',
  10902. ' TRecA = record',
  10903. ' i: byte;',
  10904. ' length_: longint external name ''length'';',
  10905. ' end;',
  10906. 'var Rec: TRecA;',
  10907. 'begin',
  10908. ' rec.length_ := rec.length_',
  10909. '']);
  10910. ConvertProgram;
  10911. CheckSource('TestRecord_VarExternal',
  10912. LinesToStr([ // statements
  10913. 'rtl.recNewT(this, "TRecA", function () {',
  10914. ' this.i = 0;',
  10915. ' this.$eq = function (b) {',
  10916. ' return (this.i === b.i) && (this.length === b.length);',
  10917. ' };',
  10918. ' this.$assign = function (s) {',
  10919. ' this.i = s.i;',
  10920. ' this.length = s.length;',
  10921. ' return this;',
  10922. ' };',
  10923. '});',
  10924. 'this.Rec = this.TRecA.$new();',
  10925. '']),
  10926. LinesToStr([ // $mod.$main
  10927. '$mod.Rec.length = $mod.Rec.length;'
  10928. ]));
  10929. end;
  10930. procedure TTestModule.TestRecord_WithDo;
  10931. begin
  10932. StartProgram(false);
  10933. Add('type');
  10934. Add(' TRec = record');
  10935. Add(' vI: longint;');
  10936. Add(' end;');
  10937. Add('var');
  10938. Add(' Int: longint;');
  10939. Add(' r: TRec;');
  10940. Add('begin');
  10941. Add(' with r do');
  10942. Add(' int:=vi;');
  10943. Add(' with r do begin');
  10944. Add(' int:=vi;');
  10945. Add(' vi:=int;');
  10946. Add(' end;');
  10947. ConvertProgram;
  10948. CheckSource('TestWithRecordDo',
  10949. LinesToStr([ // statements
  10950. 'rtl.recNewT(this, "TRec", function () {',
  10951. ' this.vI = 0;',
  10952. ' this.$eq = function (b) {',
  10953. ' return this.vI === b.vI;',
  10954. ' };',
  10955. ' this.$assign = function (s) {',
  10956. ' this.vI = s.vI;',
  10957. ' return this;',
  10958. ' };',
  10959. '});',
  10960. 'this.Int = 0;',
  10961. 'this.r = this.TRec.$new();',
  10962. '']),
  10963. LinesToStr([ // $mod.$main
  10964. 'var $with = $mod.r;',
  10965. '$mod.Int = $with.vI;',
  10966. 'var $with1 = $mod.r;',
  10967. '$mod.Int = $with1.vI;',
  10968. '$with1.vI = $mod.Int;'
  10969. ]));
  10970. end;
  10971. procedure TTestModule.TestRecord_Assign;
  10972. begin
  10973. StartProgram(false);
  10974. Add([
  10975. 'type',
  10976. ' TEnum = (red,green);',
  10977. ' TEnums = set of TEnum;',
  10978. ' TSmallRec = record',
  10979. ' N: longint;',
  10980. ' end;',
  10981. ' TBigRec = record',
  10982. ' Int: longint;',
  10983. ' D: double;',
  10984. ' Arr: array of longint;',
  10985. ' Arr2: array[1..2] of longint;',
  10986. ' Small: TSmallRec;',
  10987. ' Enums: TEnums;',
  10988. ' end;',
  10989. 'var',
  10990. ' r, s: TBigRec;',
  10991. 'begin',
  10992. ' r:=s;',
  10993. ' r:=default(TBigRec);',
  10994. ' r:=default(s);',
  10995. '']);
  10996. ConvertProgram;
  10997. CheckSource('TestRecord_Assign',
  10998. LinesToStr([ // statements
  10999. 'this.TEnum = {',
  11000. ' "0": "red",',
  11001. ' red: 0,',
  11002. ' "1": "green",',
  11003. ' green: 1',
  11004. '};',
  11005. 'rtl.recNewT(this, "TSmallRec", function () {',
  11006. ' this.N = 0;',
  11007. ' this.$eq = function (b) {',
  11008. ' return this.N === b.N;',
  11009. ' };',
  11010. ' this.$assign = function (s) {',
  11011. ' this.N = s.N;',
  11012. ' return this;',
  11013. ' };',
  11014. '});',
  11015. 'rtl.recNewT(this, "TBigRec", function () {',
  11016. ' this.Int = 0;',
  11017. ' this.D = 0.0;',
  11018. ' this.$new = function () {',
  11019. ' var r = Object.create(this);',
  11020. ' r.Arr = [];',
  11021. ' r.Arr2 = rtl.arraySetLength(null, 0, 2);',
  11022. ' r.Small = $mod.TSmallRec.$new();',
  11023. ' r.Enums = {};',
  11024. ' return r;',
  11025. ' };',
  11026. ' this.$eq = function (b) {',
  11027. ' return (this.Int === b.Int) && (this.D === b.D) && (this.Arr === b.Arr) && rtl.arrayEq(this.Arr2, b.Arr2) && this.Small.$eq(b.Small) && rtl.eqSet(this.Enums, b.Enums);',
  11028. ' };',
  11029. ' this.$assign = function (s) {',
  11030. ' this.Int = s.Int;',
  11031. ' this.D = s.D;',
  11032. ' this.Arr = rtl.arrayRef(s.Arr);',
  11033. ' this.Arr2 = s.Arr2.slice(0);',
  11034. ' this.Small.$assign(s.Small);',
  11035. ' this.Enums = rtl.refSet(s.Enums);',
  11036. ' return this;',
  11037. ' };',
  11038. '});',
  11039. 'this.r = this.TBigRec.$new();',
  11040. 'this.s = this.TBigRec.$new();',
  11041. '']),
  11042. LinesToStr([ // $mod.$main
  11043. '$mod.r.$assign($mod.s);',
  11044. '$mod.r.$assign($mod.TBigRec.$new());',
  11045. '$mod.r.$assign($mod.TBigRec.$new());',
  11046. '']));
  11047. end;
  11048. procedure TTestModule.TestRecord_AsParams;
  11049. begin
  11050. StartProgram(false);
  11051. Add([
  11052. 'type',
  11053. ' integer = longint;',
  11054. ' TRecord = record',
  11055. ' i: integer;',
  11056. ' end;',
  11057. 'procedure DoIt(vD: TRecord; const vC: TRecord; var vV: TRecord; var U);',
  11058. 'var vL: TRecord;',
  11059. 'begin',
  11060. ' vd:=vd;',
  11061. ' vd.i:=vd.i;',
  11062. ' vl:=vc;',
  11063. ' vv:=vv;',
  11064. ' vv.i:=vv.i;',
  11065. ' U:=vl;',
  11066. ' U:=vd;',
  11067. ' U:=vc;',
  11068. ' U:=vv;',
  11069. ' vl:=TRecord(U);',
  11070. ' vd:=TRecord(U);',
  11071. ' vv:=TRecord(U);',
  11072. ' doit(vd,vd,vd,vd);',
  11073. ' doit(vc,vc,vl,vl);',
  11074. ' doit(vv,vv,vv,vv);',
  11075. ' doit(vl,vl,vl,vl);',
  11076. ' TRecord(U).i:=3;',
  11077. 'end;',
  11078. 'var i: TRecord;',
  11079. 'begin',
  11080. ' doit(i,i,i,i);',
  11081. '']);
  11082. ConvertProgram;
  11083. CheckSource('TestRecord_AsParams',
  11084. LinesToStr([ // statements
  11085. 'rtl.recNewT(this, "TRecord", function () {',
  11086. ' this.i = 0;',
  11087. ' this.$eq = function (b) {',
  11088. ' return this.i === b.i;',
  11089. ' };',
  11090. ' this.$assign = function (s) {',
  11091. ' this.i = s.i;',
  11092. ' return this;',
  11093. ' };',
  11094. '});',
  11095. 'this.DoIt = function (vD, vC, vV, U) {',
  11096. ' var vL = $mod.TRecord.$new();',
  11097. ' vD.$assign(vD);',
  11098. ' vD.i = vD.i;',
  11099. ' vL.$assign(vC);',
  11100. ' vV.$assign(vV);',
  11101. ' vV.i = vV.i;',
  11102. ' U.$assign(vL);',
  11103. ' U.$assign(vD);',
  11104. ' U.$assign(vC);',
  11105. ' U.$assign(vV);',
  11106. ' vL.$assign(U);',
  11107. ' vD.$assign(U);',
  11108. ' vV.$assign(U);',
  11109. ' $mod.DoIt($mod.TRecord.$clone(vD), vD, vD, vD);',
  11110. ' $mod.DoIt($mod.TRecord.$clone(vC), vC, vL, vL);',
  11111. ' $mod.DoIt($mod.TRecord.$clone(vV), vV, vV, vV);',
  11112. ' $mod.DoIt($mod.TRecord.$clone(vL), vL, vL, vL);',
  11113. ' U.i = 3;',
  11114. '};',
  11115. 'this.i = this.TRecord.$new();'
  11116. ]),
  11117. LinesToStr([
  11118. '$mod.DoIt($mod.TRecord.$clone($mod.i), $mod.i, $mod.i, $mod.i);',
  11119. '']));
  11120. end;
  11121. procedure TTestModule.TestRecord_ConstRef;
  11122. begin
  11123. StartProgram(false);
  11124. Add([
  11125. 'type TRec = record i: word; end;',
  11126. 'procedure Run(constref a: TRec);',
  11127. 'begin',
  11128. 'end;',
  11129. 'procedure Fly(a: TRec; var b: TRec; out c: TRec; const d: TRec; constref e: TRec);',
  11130. 'var l: TRec;',
  11131. 'begin',
  11132. ' Run(l);',
  11133. ' Run(a);',
  11134. ' Run(b);',
  11135. ' Run(c);',
  11136. ' Run(d);',
  11137. ' Run(e);',
  11138. 'end;',
  11139. 'begin',
  11140. '']);
  11141. ConvertProgram;
  11142. CheckResolverUnexpectedHints();
  11143. CheckSource('TestRecord_ConstRef',
  11144. LinesToStr([ // statements
  11145. 'rtl.recNewT(this, "TRec", function () {',
  11146. ' this.i = 0;',
  11147. ' this.$eq = function (b) {',
  11148. ' return this.i === b.i;',
  11149. ' };',
  11150. ' this.$assign = function (s) {',
  11151. ' this.i = s.i;',
  11152. ' return this;',
  11153. ' };',
  11154. '});',
  11155. 'this.Run = function (a) {',
  11156. '};',
  11157. 'this.Fly = function (a, b, c, d, e) {',
  11158. ' var l = $mod.TRec.$new();',
  11159. ' $mod.Run(l);',
  11160. ' $mod.Run(a);',
  11161. ' $mod.Run(b);',
  11162. ' $mod.Run(c);',
  11163. ' $mod.Run(d);',
  11164. ' $mod.Run(e);',
  11165. '};',
  11166. '']),
  11167. LinesToStr([
  11168. '']));
  11169. end;
  11170. procedure TTestModule.TestRecordElement_AsParams;
  11171. begin
  11172. StartProgram(false);
  11173. Add('type');
  11174. Add(' integer = longint;');
  11175. Add(' TRecord = record');
  11176. Add(' i: integer;');
  11177. Add(' end;');
  11178. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  11179. Add('var vJ: TRecord;');
  11180. Add('begin');
  11181. Add(' doit(vj.i,vj.i,vj.i);');
  11182. Add('end;');
  11183. Add('var r: TRecord;');
  11184. Add('begin');
  11185. Add(' doit(r.i,r.i,r.i);');
  11186. ConvertProgram;
  11187. CheckSource('TestRecordElement_AsParams',
  11188. LinesToStr([ // statements
  11189. 'rtl.recNewT(this, "TRecord", function () {',
  11190. ' this.i = 0;',
  11191. ' this.$eq = function (b) {',
  11192. ' return this.i === b.i;',
  11193. ' };',
  11194. ' this.$assign = function (s) {',
  11195. ' this.i = s.i;',
  11196. ' return this;',
  11197. ' };',
  11198. '});',
  11199. 'this.DoIt = function (vG,vH,vI) {',
  11200. ' var vJ = $mod.TRecord.$new();',
  11201. ' $mod.DoIt(vJ.i, vJ.i, {',
  11202. ' p: vJ,',
  11203. ' get: function () {',
  11204. ' return this.p.i;',
  11205. ' },',
  11206. ' set: function (v) {',
  11207. ' this.p.i = v;',
  11208. ' }',
  11209. ' });',
  11210. '};',
  11211. 'this.r = this.TRecord.$new();'
  11212. ]),
  11213. LinesToStr([
  11214. '$mod.DoIt($mod.r.i,$mod.r.i,{',
  11215. ' p: $mod.r,',
  11216. ' get: function () {',
  11217. ' return this.p.i;',
  11218. ' },',
  11219. ' set: function (v) {',
  11220. ' this.p.i = v;',
  11221. ' }',
  11222. '});'
  11223. ]));
  11224. end;
  11225. procedure TTestModule.TestRecordElementFromFuncResult_AsParams;
  11226. begin
  11227. StartProgram(false);
  11228. Add('type');
  11229. Add(' integer = longint;');
  11230. Add(' TRecord = record');
  11231. Add(' i: integer;');
  11232. Add(' end;');
  11233. Add('function GetRec(vB: integer = 0): TRecord;');
  11234. Add('begin');
  11235. Add('end;');
  11236. Add('procedure DoIt(vG: integer; const vH: integer);');
  11237. Add('begin');
  11238. Add('end;');
  11239. Add('begin');
  11240. Add(' doit(getrec.i,getrec.i);');
  11241. Add(' doit(getrec().i,getrec().i);');
  11242. Add(' doit(getrec(1).i,getrec(2).i);');
  11243. ConvertProgram;
  11244. CheckSource('TestRecordElementFromFuncResult_AsParams',
  11245. LinesToStr([ // statements
  11246. 'rtl.recNewT(this, "TRecord", function () {',
  11247. ' this.i = 0;',
  11248. ' this.$eq = function (b) {',
  11249. ' return this.i === b.i;',
  11250. ' };',
  11251. ' this.$assign = function (s) {',
  11252. ' this.i = s.i;',
  11253. ' return this;',
  11254. ' };',
  11255. '});',
  11256. 'this.GetRec = function (vB) {',
  11257. ' var Result = $mod.TRecord.$new();',
  11258. ' return Result;',
  11259. '};',
  11260. 'this.DoIt = function (vG, vH) {',
  11261. '};',
  11262. '']),
  11263. LinesToStr([
  11264. '$mod.DoIt($mod.GetRec(0).i,$mod.GetRec(0).i);',
  11265. '$mod.DoIt($mod.GetRec(0).i,$mod.GetRec(0).i);',
  11266. '$mod.DoIt($mod.GetRec(1).i,$mod.GetRec(2).i);',
  11267. '']));
  11268. end;
  11269. procedure TTestModule.TestRecordElementFromWith_AsParams;
  11270. begin
  11271. StartProgram(false);
  11272. Add('type');
  11273. Add(' integer = longint;');
  11274. Add(' TRecord = record');
  11275. Add(' i: integer;');
  11276. Add(' end;');
  11277. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  11278. Add('begin');
  11279. Add('end;');
  11280. Add('var r: trecord;');
  11281. Add('begin');
  11282. Add(' with r do ');
  11283. Add(' doit(i,i,i);');
  11284. ConvertProgram;
  11285. CheckSource('TestRecordElementFromWith_AsParams',
  11286. LinesToStr([ // statements
  11287. 'rtl.recNewT(this, "TRecord", function () {',
  11288. ' this.i = 0;',
  11289. ' this.$eq = function (b) {',
  11290. ' return this.i === b.i;',
  11291. ' };',
  11292. ' this.$assign = function (s) {',
  11293. ' this.i = s.i;',
  11294. ' return this;',
  11295. ' };',
  11296. '});',
  11297. 'this.DoIt = function (vG,vH,vI) {',
  11298. '};',
  11299. 'this.r = this.TRecord.$new();'
  11300. ]),
  11301. LinesToStr([
  11302. 'var $with = $mod.r;',
  11303. '$mod.DoIt($with.i,$with.i,{',
  11304. ' p: $with,',
  11305. ' get: function () {',
  11306. ' return this.p.i;',
  11307. ' },',
  11308. ' set: function (v) {',
  11309. ' this.p.i = v;',
  11310. ' }',
  11311. '});',
  11312. '']));
  11313. end;
  11314. procedure TTestModule.TestRecord_Equal;
  11315. begin
  11316. StartProgram(false);
  11317. Add('type');
  11318. Add(' integer = longint;');
  11319. Add(' TFlag = (red,blue);');
  11320. Add(' TFlags = set of TFlag;');
  11321. Add(' TProc = procedure;');
  11322. Add(' TRecord = record');
  11323. Add(' i: integer;');
  11324. Add(' Event: TProc;');
  11325. Add(' f: TFlags;');
  11326. Add(' end;');
  11327. Add(' TNested = record');
  11328. Add(' r: TRecord;');
  11329. Add(' end;');
  11330. Add('var');
  11331. Add(' b: boolean;');
  11332. Add(' r,s: trecord;');
  11333. Add('begin');
  11334. Add(' b:=r=s;');
  11335. Add(' b:=r<>s;');
  11336. ConvertProgram;
  11337. CheckSource('TestRecord_Equal',
  11338. LinesToStr([ // statements
  11339. 'this.TFlag = {',
  11340. ' "0": "red",',
  11341. ' red: 0,',
  11342. ' "1": "blue",',
  11343. ' blue: 1',
  11344. '};',
  11345. 'rtl.recNewT(this, "TRecord", function () {',
  11346. ' this.i = 0;',
  11347. ' this.Event = null;',
  11348. ' this.$new = function () {',
  11349. ' var r = Object.create(this);',
  11350. ' r.f = {};',
  11351. ' return r;',
  11352. ' };',
  11353. ' this.$eq = function (b) {',
  11354. ' return (this.i === b.i) && rtl.eqCallback(this.Event, b.Event) && rtl.eqSet(this.f, b.f);',
  11355. ' };',
  11356. ' this.$assign = function (s) {',
  11357. ' this.i = s.i;',
  11358. ' this.Event = s.Event;',
  11359. ' this.f = rtl.refSet(s.f);',
  11360. ' return this;',
  11361. ' };',
  11362. '});',
  11363. 'rtl.recNewT(this, "TNested", function () {',
  11364. ' this.$new = function () {',
  11365. ' var r = Object.create(this);',
  11366. ' r.r = $mod.TRecord.$new();',
  11367. ' return r;',
  11368. ' };',
  11369. ' this.$eq = function (b) {',
  11370. ' return this.r.$eq(b.r);',
  11371. ' };',
  11372. ' this.$assign = function (s) {',
  11373. ' this.r.$assign(s.r);',
  11374. ' return this;',
  11375. ' };',
  11376. '});',
  11377. 'this.b = false;',
  11378. 'this.r = this.TRecord.$new();',
  11379. 'this.s = this.TRecord.$new();',
  11380. '']),
  11381. LinesToStr([
  11382. '$mod.b = $mod.r.$eq($mod.s);',
  11383. '$mod.b = !$mod.r.$eq($mod.s);',
  11384. '']));
  11385. end;
  11386. procedure TTestModule.TestRecord_JSValue;
  11387. begin
  11388. StartProgram(false);
  11389. Add([
  11390. 'type',
  11391. ' TRecord = record',
  11392. ' i: longint;',
  11393. ' end;',
  11394. 'procedure Fly(d: jsvalue; const c: jsvalue);',
  11395. 'begin',
  11396. 'end;',
  11397. 'procedure Run(d: TRecord; const c: TRecord; var v: TRecord);',
  11398. 'begin',
  11399. ' if jsvalue(d) then ;',
  11400. ' if jsvalue(c) then ;',
  11401. ' if jsvalue(v) then ;',
  11402. 'end;',
  11403. 'var',
  11404. ' Jv: jsvalue;',
  11405. ' Rec: trecord;',
  11406. 'begin',
  11407. ' rec:=trecord(jv);',
  11408. ' jv:=rec;',
  11409. ' Fly(rec,rec);',
  11410. ' Fly(@rec,@rec);',
  11411. ' if jsvalue(Rec) then ;',
  11412. ' Run(trecord(jv),trecord(jv),rec);',
  11413. '']);
  11414. ConvertProgram;
  11415. CheckSource('TestRecord_JSValue',
  11416. LinesToStr([ // statements
  11417. 'rtl.recNewT(this, "TRecord", function () {',
  11418. ' this.i = 0;',
  11419. ' this.$eq = function (b) {',
  11420. ' return this.i === b.i;',
  11421. ' };',
  11422. ' this.$assign = function (s) {',
  11423. ' this.i = s.i;',
  11424. ' return this;',
  11425. ' };',
  11426. '});',
  11427. 'this.Fly = function (d, c) {',
  11428. '};',
  11429. 'this.Run = function (d, c, v) {',
  11430. ' if (d) ;',
  11431. ' if (c) ;',
  11432. ' if (v) ;',
  11433. '};',
  11434. 'this.Jv = undefined;',
  11435. 'this.Rec = this.TRecord.$new();',
  11436. '']),
  11437. LinesToStr([
  11438. '$mod.Rec.$assign(rtl.getObject($mod.Jv));',
  11439. '$mod.Jv = $mod.Rec;',
  11440. '$mod.Fly($mod.TRecord.$clone($mod.Rec), $mod.Rec);',
  11441. '$mod.Fly($mod.Rec, $mod.Rec);',
  11442. 'if ($mod.Rec) ;',
  11443. '$mod.Run($mod.TRecord.$clone(rtl.getObject($mod.Jv)), rtl.getObject($mod.Jv), $mod.Rec);',
  11444. '']));
  11445. end;
  11446. procedure TTestModule.TestRecord_VariantFail;
  11447. begin
  11448. StartProgram(false);
  11449. Add([
  11450. 'type',
  11451. ' TRec = record',
  11452. ' case word of',
  11453. ' 0: (b0, b1: Byte);',
  11454. ' 1: (i: word);',
  11455. ' end;',
  11456. 'begin']);
  11457. SetExpectedPasResolverError('variant record is not supported',
  11458. nXIsNotSupported);
  11459. ConvertProgram;
  11460. end;
  11461. procedure TTestModule.TestRecord_FieldArray;
  11462. begin
  11463. StartProgram(false);
  11464. Add([
  11465. 'type',
  11466. ' TArrInt = array[3..4] of longint;',
  11467. ' TArrArrInt = array[3..4] of longint;',
  11468. ' TRec = record',
  11469. ' a: array of longint;',
  11470. ' s: array[1..2] of longint;',
  11471. ' m: array[1..2,3..4] of longint;',
  11472. ' o: TArrArrInt;',
  11473. ' end;',
  11474. 'begin']);
  11475. ConvertProgram;
  11476. CheckSource('TestRecord_FieldArray',
  11477. LinesToStr([ // statements
  11478. 'rtl.recNewT(this, "TRec", function () {',
  11479. ' this.$new = function () {',
  11480. ' var r = Object.create(this);',
  11481. ' r.a = [];',
  11482. ' r.s = rtl.arraySetLength(null, 0, 2);',
  11483. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  11484. ' r.o = rtl.arraySetLength(null, 0, 2);',
  11485. ' return r;',
  11486. ' };',
  11487. ' this.$eq = function (b) {',
  11488. ' return (this.a === b.a) && rtl.arrayEq(this.s, b.s) && rtl.arrayEq(this.m, b.m) && rtl.arrayEq(this.o, b.o);',
  11489. ' };',
  11490. ' this.$assign = function (s) {',
  11491. ' this.a = rtl.arrayRef(s.a);',
  11492. ' this.s = s.s.slice(0);',
  11493. ' this.m = s.m.slice(0);',
  11494. ' this.o = s.o.slice(0);',
  11495. ' return this;',
  11496. ' };',
  11497. '});',
  11498. '']),
  11499. LinesToStr([ // $mod.$main
  11500. '']));
  11501. end;
  11502. procedure TTestModule.TestRecord_Const;
  11503. begin
  11504. StartProgram(false);
  11505. Add([
  11506. 'type',
  11507. ' TArrInt = array[3..4] of longint;',
  11508. ' TPoint = record x,y: longint; end;',
  11509. ' TRec = record',
  11510. ' i: longint;',
  11511. ' a: array of longint;',
  11512. ' s: array[1..2] of longint;',
  11513. ' m: array[1..2,3..4] of longint;',
  11514. ' p: TPoint;',
  11515. ' end;',
  11516. ' TPoints = array of TPoint;',
  11517. 'const',
  11518. ' r: TRec = (',
  11519. ' i:1;',
  11520. ' a:(2,3);',
  11521. ' s:(4,5);',
  11522. ' m:( (11,12), (13,14) );',
  11523. ' p: (x:21; y:22)',
  11524. ' );',
  11525. ' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
  11526. 'begin']);
  11527. ConvertProgram;
  11528. CheckSource('TestRecord_Const',
  11529. LinesToStr([ // statements
  11530. 'rtl.recNewT(this, "TPoint", function () {',
  11531. ' this.x = 0;',
  11532. ' this.y = 0;',
  11533. ' this.$eq = function (b) {',
  11534. ' return (this.x === b.x) && (this.y === b.y);',
  11535. ' };',
  11536. ' this.$assign = function (s) {',
  11537. ' this.x = s.x;',
  11538. ' this.y = s.y;',
  11539. ' return this;',
  11540. ' };',
  11541. '});',
  11542. 'rtl.recNewT(this, "TRec", function () {',
  11543. ' this.i = 0;',
  11544. ' this.$new = function () {',
  11545. ' var r = Object.create(this);',
  11546. ' r.a = [];',
  11547. ' r.s = rtl.arraySetLength(null, 0, 2);',
  11548. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  11549. ' r.p = $mod.TPoint.$new();',
  11550. ' return r;',
  11551. ' };',
  11552. ' this.$eq = function (b) {',
  11553. ' return (this.i === b.i) && (this.a === b.a) && rtl.arrayEq(this.s, b.s) && rtl.arrayEq(this.m, b.m) && this.p.$eq(b.p);',
  11554. ' };',
  11555. ' this.$assign = function (s) {',
  11556. ' this.i = s.i;',
  11557. ' this.a = rtl.arrayRef(s.a);',
  11558. ' this.s = s.s.slice(0);',
  11559. ' this.m = s.m.slice(0);',
  11560. ' this.p.$assign(s.p);',
  11561. ' return this;',
  11562. ' };',
  11563. '});',
  11564. 'this.r = this.TRec.$clone({',
  11565. ' i: 1,',
  11566. ' a: [2, 3],',
  11567. ' s: [4, 5],',
  11568. ' m: [[11, 12], [13, 14]],',
  11569. ' p: this.TPoint.$clone({',
  11570. ' x: 21,',
  11571. ' y: 22',
  11572. ' })',
  11573. '});',
  11574. 'this.p = [this.TPoint.$clone({',
  11575. ' x: 1,',
  11576. ' y: 2',
  11577. '}), this.TPoint.$clone({',
  11578. ' x: 3,',
  11579. ' y: 4',
  11580. '})];',
  11581. '']),
  11582. LinesToStr([ // $mod.$main
  11583. '']));
  11584. end;
  11585. procedure TTestModule.TestRecord_TypecastFail;
  11586. begin
  11587. StartProgram(false);
  11588. Add([
  11589. 'type',
  11590. ' TPoint = record x,y: longint; end;',
  11591. ' TRec = record l: longint end;',
  11592. 'var p: TPoint;',
  11593. 'begin',
  11594. ' if TRec(p).l=2 then ;']);
  11595. SetExpectedPasResolverError('Illegal type conversion: "TPoint" to "record TRec"',
  11596. nIllegalTypeConversionTo);
  11597. ConvertProgram;
  11598. end;
  11599. procedure TTestModule.TestRecord_InFunction;
  11600. begin
  11601. StartProgram(false);
  11602. Add([
  11603. 'var TPoint: longint = 3;',
  11604. 'procedure DoIt;',
  11605. 'type',
  11606. ' TPoint = record x,y: longint; end;',
  11607. ' TPoints = array of TPoint;',
  11608. 'var',
  11609. ' r: TPoint;',
  11610. ' p: TPoints;',
  11611. 'begin',
  11612. ' SetLength(p,2);',
  11613. 'end;',
  11614. 'begin']);
  11615. ConvertProgram;
  11616. CheckSource('TestRecord_InFunction',
  11617. LinesToStr([ // statements
  11618. 'this.TPoint = 3;',
  11619. 'var TPoint$1 = rtl.recNewT(null, "", function () {',
  11620. ' this.x = 0;',
  11621. ' this.y = 0;',
  11622. ' this.$eq = function (b) {',
  11623. ' return (this.x === b.x) && (this.y === b.y);',
  11624. ' };',
  11625. ' this.$assign = function (s) {',
  11626. ' this.x = s.x;',
  11627. ' this.y = s.y;',
  11628. ' return this;',
  11629. ' };',
  11630. '});',
  11631. 'this.DoIt = function () {',
  11632. ' var r = TPoint$1.$new();',
  11633. ' var p = [];',
  11634. ' p = rtl.arraySetLength(p, TPoint$1, 2);',
  11635. '};',
  11636. '']),
  11637. LinesToStr([ // $mod.$main
  11638. '']));
  11639. end;
  11640. procedure TTestModule.TestRecord_AnonymousFail;
  11641. begin
  11642. StartProgram(false);
  11643. Add([
  11644. 'var',
  11645. ' r: record x: word end;',
  11646. 'begin']);
  11647. SetExpectedPasResolverError('not yet implemented: :TPasRecordType [20190408224556] "anonymous record type"',
  11648. nNotYetImplemented);
  11649. ConvertProgram;
  11650. end;
  11651. procedure TTestModule.TestAdvRecord_Function;
  11652. begin
  11653. StartProgram(false);
  11654. Parser.Options:=Parser.Options+[po_cassignments];
  11655. Add([
  11656. '{$modeswitch AdvancedRecords}',
  11657. 'type',
  11658. ' TPoint = record',
  11659. ' x,y: word;',
  11660. ' function Add(const apt: TPoint): TPoint;',
  11661. ' end;',
  11662. 'function TPoint.Add(const apt: TPoint): TPoint;',
  11663. 'begin',
  11664. ' Result:=Self;',
  11665. ' Result.x+=apt.x;',
  11666. ' Result.y:=Result.y+apt.y;',
  11667. ' Self:=apt;',
  11668. 'end;',
  11669. 'var p,q: TPoint;',
  11670. 'begin',
  11671. ' p.add(q);',
  11672. ' p:=default(TPoint);',
  11673. ' p:=q;',
  11674. '']);
  11675. ConvertProgram;
  11676. CheckSource('TestAdvRecord_Function',
  11677. LinesToStr([ // statements
  11678. 'rtl.recNewT(this, "TPoint", function () {',
  11679. ' this.x = 0;',
  11680. ' this.y = 0;',
  11681. ' this.$eq = function (b) {',
  11682. ' return (this.x === b.x) && (this.y === b.y);',
  11683. ' };',
  11684. ' this.$assign = function (s) {',
  11685. ' this.x = s.x;',
  11686. ' this.y = s.y;',
  11687. ' return this;',
  11688. ' };',
  11689. ' this.Add = function (apt) {',
  11690. ' var Result = $mod.TPoint.$new();',
  11691. ' Result.$assign(this);',
  11692. ' Result.x += apt.x;',
  11693. ' Result.y = Result.y + apt.y;',
  11694. ' this.$assign(apt);',
  11695. ' return Result;',
  11696. ' };',
  11697. '});',
  11698. 'this.p = this.TPoint.$new();',
  11699. 'this.q = this.TPoint.$new();',
  11700. '']),
  11701. LinesToStr([ // $mod.$main
  11702. '$mod.p.Add($mod.q);',
  11703. '$mod.p.$assign($mod.TPoint.$new());',
  11704. '$mod.p.$assign($mod.q);',
  11705. '']));
  11706. end;
  11707. procedure TTestModule.TestAdvRecord_Property;
  11708. begin
  11709. StartProgram(false);
  11710. Add([
  11711. '{$modeswitch AdvancedRecords}',
  11712. 'type',
  11713. ' TPoint = record',
  11714. ' x,y: word;',
  11715. ' strict private',
  11716. ' function GetSize: longword;',
  11717. ' procedure SetSize(Value: longword);',
  11718. ' public',
  11719. ' property Size: longword read GetSize write SetSize;',
  11720. ' property Left: word read x write y;',
  11721. ' end;',
  11722. 'procedure SetSize(Value: longword); begin end;',// check auto rename
  11723. 'function TPoint.GetSize: longword;',
  11724. 'begin',
  11725. ' x:=y;',
  11726. ' Size:=Size;',
  11727. ' Left:=Left;',
  11728. 'end;',
  11729. 'procedure TPoint.SetSize(Value: longword);',
  11730. 'begin',
  11731. 'end;',
  11732. 'var p,q: TPoint;',
  11733. 'begin',
  11734. ' p.Size:=q.Size;',
  11735. ' p.Left:=q.Left;',
  11736. '']);
  11737. ConvertProgram;
  11738. CheckSource('TestAdvRecord_Property',
  11739. LinesToStr([ // statements
  11740. 'rtl.recNewT(this, "TPoint", function () {',
  11741. ' this.x = 0;',
  11742. ' this.y = 0;',
  11743. ' this.$eq = function (b) {',
  11744. ' return (this.x === b.x) && (this.y === b.y);',
  11745. ' };',
  11746. ' this.$assign = function (s) {',
  11747. ' this.x = s.x;',
  11748. ' this.y = s.y;',
  11749. ' return this;',
  11750. ' };',
  11751. ' this.GetSize = function () {',
  11752. ' var Result = 0;',
  11753. ' this.x = this.y;',
  11754. ' this.SetSize(this.GetSize());',
  11755. ' this.y = this.x;',
  11756. ' return Result;',
  11757. ' };',
  11758. ' this.SetSize = function (Value) {',
  11759. ' };',
  11760. '});',
  11761. 'this.SetSize = function (Value) {',
  11762. '};',
  11763. 'this.p = this.TPoint.$new();',
  11764. 'this.q = this.TPoint.$new();',
  11765. '']),
  11766. LinesToStr([ // $mod.$main
  11767. '$mod.p.SetSize($mod.q.GetSize());',
  11768. '$mod.p.y = $mod.q.x;',
  11769. '']));
  11770. end;
  11771. procedure TTestModule.TestAdvRecord_PropertyDefault;
  11772. begin
  11773. StartProgram(false);
  11774. Add([
  11775. '{$modeswitch AdvancedRecords}',
  11776. 'type',
  11777. ' TPoint = record',
  11778. ' strict private',
  11779. ' function GetItems(Index: word): word;',
  11780. ' procedure SetItems(Index: word; Value: word);',
  11781. ' public',
  11782. ' property Items[Index: word]: word read GetItems write SetItems; default;',
  11783. ' end;',
  11784. 'function TPoint.GetItems(Index: word): word;',
  11785. 'begin',
  11786. ' Items[index]:=Items[index];',
  11787. ' self.Items[index]:=self.Items[index];',
  11788. 'end;',
  11789. 'procedure TPoint.SetItems(Index: word; Value: word);',
  11790. 'begin',
  11791. 'end;',
  11792. 'var p: TPoint;',
  11793. 'begin',
  11794. ' p[1]:=p[2];',
  11795. ' p.Items[3]:=p.Items[4];',
  11796. '']);
  11797. ConvertProgram;
  11798. CheckSource('TestAdvRecord_PropertyDefault',
  11799. LinesToStr([ // statements
  11800. 'rtl.recNewT(this, "TPoint", function () {',
  11801. ' this.$eq = function (b) {',
  11802. ' return true;',
  11803. ' };',
  11804. ' this.$assign = function (s) {',
  11805. ' return this;',
  11806. ' };',
  11807. ' this.GetItems = function (Index) {',
  11808. ' var Result = 0;',
  11809. ' this.SetItems(Index, this.GetItems(Index));',
  11810. ' this.SetItems(Index, this.GetItems(Index));',
  11811. ' return Result;',
  11812. ' };',
  11813. ' this.SetItems = function (Index, Value) {',
  11814. ' };',
  11815. '});',
  11816. 'this.p = this.TPoint.$new();',
  11817. '']),
  11818. LinesToStr([ // $mod.$main
  11819. '$mod.p.SetItems(1, $mod.p.GetItems(2));',
  11820. '$mod.p.SetItems(3, $mod.p.GetItems(4));',
  11821. '']));
  11822. end;
  11823. procedure TTestModule.TestAdvRecord_Property_ClassMethod;
  11824. begin
  11825. StartProgram(false);
  11826. Add([
  11827. '{$modeswitch AdvancedRecords}',
  11828. 'type',
  11829. ' TRec = record',
  11830. ' class var',
  11831. ' Fx: longint;',
  11832. ' Fy: longint;',
  11833. ' class function GetInt: longint; static;',
  11834. ' class procedure SetInt(Value: longint); static;',
  11835. ' class procedure DoIt; static;',
  11836. ' class property IntA: longint read Fx write Fy;',
  11837. ' class property IntB: longint read GetInt write SetInt;',
  11838. ' end;',
  11839. 'class function trec.getint: longint;',
  11840. 'begin',
  11841. ' result:=fx;',
  11842. 'end;',
  11843. 'class procedure trec.setint(value: longint);',
  11844. 'begin',
  11845. 'end;',
  11846. 'class procedure trec.doit;',
  11847. 'begin',
  11848. ' IntA:=IntA+1;',
  11849. ' IntB:=IntB+1;',
  11850. 'end;',
  11851. 'var r: trec;',
  11852. 'begin',
  11853. ' trec.inta:=trec.inta+1;',
  11854. ' if trec.intb=2 then;',
  11855. ' trec.intb:=trec.intb+2;',
  11856. ' trec.setint(trec.inta);',
  11857. ' r.inta:=r.inta+1;',
  11858. ' if r.intb=2 then;',
  11859. ' r.intb:=r.intb+2;',
  11860. ' r.setint(r.inta);']);
  11861. ConvertProgram;
  11862. CheckSource('TestAdvRecord_Property_ClassMethod',
  11863. LinesToStr([ // statements
  11864. 'rtl.recNewT(this, "TRec", function () {',
  11865. ' this.Fx = 0;',
  11866. ' this.Fy = 0;',
  11867. ' this.$eq = function (b) {',
  11868. ' return true;',
  11869. ' };',
  11870. ' this.$assign = function (s) {',
  11871. ' return this;',
  11872. ' };',
  11873. ' this.GetInt = function () {',
  11874. ' var Result = 0;',
  11875. ' Result = $mod.TRec.Fx;',
  11876. ' return Result;',
  11877. ' };',
  11878. ' this.SetInt = function (Value) {',
  11879. ' };',
  11880. ' this.DoIt = function () {',
  11881. ' $mod.TRec.Fy = $mod.TRec.Fx + 1;',
  11882. ' $mod.TRec.SetInt($mod.TRec.GetInt() + 1);',
  11883. ' };',
  11884. '}, true);',
  11885. 'this.r = this.TRec.$new();',
  11886. '']),
  11887. LinesToStr([ // $mod.$main
  11888. '$mod.TRec.Fy = $mod.TRec.Fx + 1;',
  11889. 'if ($mod.TRec.GetInt() === 2) ;',
  11890. '$mod.TRec.SetInt($mod.TRec.GetInt() + 2);',
  11891. '$mod.TRec.SetInt($mod.TRec.Fx);',
  11892. '$mod.TRec.Fy = $mod.r.Fx + 1;',
  11893. 'if ($mod.TRec.GetInt() === 2) ;',
  11894. '$mod.TRec.SetInt($mod.TRec.GetInt() + 2);',
  11895. '$mod.TRec.SetInt($mod.r.Fx);',
  11896. '']));
  11897. end;
  11898. procedure TTestModule.TestAdvRecord_Const;
  11899. begin
  11900. StartProgram(false);
  11901. Add([
  11902. '{$modeswitch AdvancedRecords}',
  11903. 'type',
  11904. ' TArrInt = array[3..4] of longint;',
  11905. ' TPoint = record',
  11906. ' x,y: longint;',
  11907. ' class var Count: nativeint;',
  11908. ' end;',
  11909. ' TRec = record',
  11910. ' i: longint;',
  11911. ' a: array of longint;',
  11912. ' s: array[1..2] of longint;',
  11913. ' m: array[1..2,3..4] of longint;',
  11914. ' p: TPoint;',
  11915. ' end;',
  11916. ' TPoints = array of TPoint;',
  11917. 'const',
  11918. ' r: TRec = (',
  11919. ' i:1;',
  11920. ' a:(2,3);',
  11921. ' s:(4,5);',
  11922. ' m:( (11,12), (13,14) );',
  11923. ' p: (x:21)',
  11924. ' );',
  11925. ' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
  11926. 'begin']);
  11927. ConvertProgram;
  11928. CheckSource('TestAdvRecord_Const',
  11929. LinesToStr([ // statements
  11930. 'rtl.recNewT(this, "TPoint", function () {',
  11931. ' this.x = 0;',
  11932. ' this.y = 0;',
  11933. ' this.Count = 0;',
  11934. ' this.$eq = function (b) {',
  11935. ' return (this.x === b.x) && (this.y === b.y);',
  11936. ' };',
  11937. ' this.$assign = function (s) {',
  11938. ' this.x = s.x;',
  11939. ' this.y = s.y;',
  11940. ' return this;',
  11941. ' };',
  11942. '}, true);',
  11943. 'rtl.recNewT(this, "TRec", function () {',
  11944. ' this.i = 0;',
  11945. ' this.$new = function () {',
  11946. ' var r = Object.create(this);',
  11947. ' r.a = [];',
  11948. ' r.s = rtl.arraySetLength(null, 0, 2);',
  11949. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  11950. ' r.p = $mod.TPoint.$new();',
  11951. ' return r;',
  11952. ' };',
  11953. ' this.$eq = function (b) {',
  11954. ' return (this.i === b.i) && (this.a === b.a) && rtl.arrayEq(this.s, b.s) && rtl.arrayEq(this.m, b.m) && this.p.$eq(b.p);',
  11955. ' };',
  11956. ' this.$assign = function (s) {',
  11957. ' this.i = s.i;',
  11958. ' this.a = rtl.arrayRef(s.a);',
  11959. ' this.s = s.s.slice(0);',
  11960. ' this.m = s.m.slice(0);',
  11961. ' this.p.$assign(s.p);',
  11962. ' return this;',
  11963. ' };',
  11964. '});',
  11965. 'this.r = this.TRec.$clone({',
  11966. ' i: 1,',
  11967. ' a: [2, 3],',
  11968. ' s: [4, 5],',
  11969. ' m: [[11, 12], [13, 14]],',
  11970. ' p: this.TPoint.$clone({',
  11971. ' x: 21,',
  11972. ' y: 0',
  11973. ' })',
  11974. '});',
  11975. 'this.p = [this.TPoint.$clone({',
  11976. ' x: 1,',
  11977. ' y: 2',
  11978. '}), this.TPoint.$clone({',
  11979. ' x: 3,',
  11980. ' y: 4',
  11981. '})];',
  11982. '']),
  11983. LinesToStr([ // $mod.$main
  11984. '']));
  11985. end;
  11986. procedure TTestModule.TestAdvRecord_ExternalField;
  11987. begin
  11988. StartProgram(false);
  11989. Add([
  11990. '{$modeswitch AdvancedRecords}',
  11991. '{$modeswitch externalclass}',
  11992. 'type',
  11993. ' TCar = record',
  11994. ' public',
  11995. ' Intern: longint external name ''$Intern'';',
  11996. ' Intern2: longint external name ''$Intern2'';',
  11997. ' Bracket: longint external name ''["A B"]'';',
  11998. ' procedure DoIt;',
  11999. ' end;',
  12000. 'procedure tcar.doit;',
  12001. 'begin',
  12002. ' Intern:=Intern+1;',
  12003. ' Intern2:=Intern2+2;',
  12004. ' Bracket:=Bracket+3;',
  12005. 'end;',
  12006. 'var Rec: TCar = (intern: 11; intern2: 12; bracket: 13);',
  12007. 'begin',
  12008. ' Rec.intern:=Rec.intern+1;',
  12009. ' Rec.intern2:=Rec.intern2+2;',
  12010. ' Rec.Bracket:=Rec.Bracket+3;',
  12011. ' with Rec do begin',
  12012. ' intern:=intern+1;',
  12013. ' intern2:=intern2+2;',
  12014. ' Bracket:=Bracket+3;',
  12015. ' end;']);
  12016. ConvertProgram;
  12017. CheckSource('TestAdvRecord_ExternalField',
  12018. LinesToStr([ // statements
  12019. 'rtl.recNewT(this, "TCar", function () {',
  12020. ' this.$eq = function (b) {',
  12021. ' return (this.$Intern === b.$Intern) && (this.$Intern2 === b.$Intern2) && (this["A B"] === b["A B"]);',
  12022. ' };',
  12023. ' this.$assign = function (s) {',
  12024. ' this.$Intern = s.$Intern;',
  12025. ' this.$Intern2 = s.$Intern2;',
  12026. ' this["A B"] = s["A B"];',
  12027. ' return this;',
  12028. ' };',
  12029. ' this.DoIt = function () {',
  12030. ' this.$Intern = this.$Intern + 1;',
  12031. ' this.$Intern2 = this.$Intern2 + 2;',
  12032. ' this["A B"] = this["A B"] + 3;',
  12033. ' };',
  12034. '});',
  12035. 'this.Rec = this.TCar.$clone({',
  12036. ' $Intern: 11,',
  12037. ' $Intern2: 12,',
  12038. ' "A B": 13',
  12039. '});',
  12040. '']),
  12041. LinesToStr([ // $mod.$main
  12042. '$mod.Rec.$Intern = $mod.Rec.$Intern + 1;',
  12043. '$mod.Rec.$Intern2 = $mod.Rec.$Intern2 + 2;',
  12044. '$mod.Rec["A B"] = $mod.Rec["A B"] + 3;',
  12045. 'var $with = $mod.Rec;',
  12046. '$with.$Intern = $with.$Intern + 1;',
  12047. '$with.$Intern2 = $with.$Intern2 + 2;',
  12048. '$with["A B"] = $with["A B"] + 3;',
  12049. '']));
  12050. end;
  12051. procedure TTestModule.TestAdvRecord_SubRecord;
  12052. begin
  12053. StartProgram(false);
  12054. Add([
  12055. '{$modeswitch AdvancedRecords}',
  12056. 'type',
  12057. ' TRec = record',
  12058. ' type',
  12059. ' TPoint = record',
  12060. ' x,y: longint;',
  12061. ' class var Count: nativeint;',
  12062. ' procedure DoIt;',
  12063. ' class procedure DoThat; static;',
  12064. ' end;',
  12065. ' var',
  12066. ' i: longint;',
  12067. ' p: TPoint;',
  12068. ' procedure DoSome;',
  12069. ' end;',
  12070. 'const',
  12071. ' r: TRec = (',
  12072. ' i:1;',
  12073. ' p: (x:21;y:22)',
  12074. ' );',
  12075. 'procedure TRec.DoSome;',
  12076. 'begin',
  12077. ' p.x:=p.y+1;',
  12078. ' p.Count:=p.Count+2;',
  12079. 'end;',
  12080. 'procedure TRec.TPoint.DoIt;',
  12081. 'begin',
  12082. ' Count:=Count+3;',
  12083. 'end;',
  12084. 'class procedure TRec.TPoint.DoThat;',
  12085. 'begin',
  12086. ' Count:=Count+4;',
  12087. 'end;',
  12088. 'begin']);
  12089. ConvertProgram;
  12090. CheckSource('TestAdvRecord_SubRecord',
  12091. LinesToStr([ // statements
  12092. 'rtl.recNewT(this, "TRec", function () {',
  12093. ' rtl.recNewT(this, "TPoint", function () {',
  12094. ' this.x = 0;',
  12095. ' this.y = 0;',
  12096. ' this.Count = 0;',
  12097. ' this.$eq = function (b) {',
  12098. ' return (this.x === b.x) && (this.y === b.y);',
  12099. ' };',
  12100. ' this.$assign = function (s) {',
  12101. ' this.x = s.x;',
  12102. ' this.y = s.y;',
  12103. ' return this;',
  12104. ' };',
  12105. ' this.DoIt = function () {',
  12106. ' $mod.TRec.TPoint.Count = this.Count + 3;',
  12107. ' };',
  12108. ' this.DoThat = function () {',
  12109. ' $mod.TRec.TPoint.Count = $mod.TRec.TPoint.Count + 4;',
  12110. ' };',
  12111. ' }, true);',
  12112. ' this.i = 0;',
  12113. ' this.$new = function () {',
  12114. ' var r = Object.create(this);',
  12115. ' r.p = this.TPoint.$new();',
  12116. ' return r;',
  12117. ' };',
  12118. ' this.$eq = function (b) {',
  12119. ' return (this.i === b.i) && this.p.$eq(b.p);',
  12120. ' };',
  12121. ' this.$assign = function (s) {',
  12122. ' this.i = s.i;',
  12123. ' this.p.$assign(s.p);',
  12124. ' return this;',
  12125. ' };',
  12126. ' this.DoSome = function () {',
  12127. ' this.p.x = this.p.y + 1;',
  12128. ' this.TPoint.Count = this.p.Count + 2;',
  12129. ' };',
  12130. '}, true);',
  12131. 'this.r = this.TRec.$clone({',
  12132. ' i: 1,',
  12133. ' p: this.TRec.TPoint.$clone({',
  12134. ' x: 21,',
  12135. ' y: 22',
  12136. ' })',
  12137. '});',
  12138. '']),
  12139. LinesToStr([ // $mod.$main
  12140. '']));
  12141. end;
  12142. procedure TTestModule.TestAdvRecord_SubClass;
  12143. begin
  12144. StartProgram(false);
  12145. Add([
  12146. '{$modeswitch AdvancedRecords}',
  12147. 'type',
  12148. ' TObject = class end;',
  12149. ' TPoint = record',
  12150. ' type',
  12151. ' TBird = class',
  12152. ' procedure DoIt;',
  12153. ' class procedure Glob;',
  12154. ' end;',
  12155. ' procedure DoIt(b: TBird);',
  12156. ' end;',
  12157. 'procedure TPoint.TBird.DoIt;',
  12158. 'begin',
  12159. ' doit;',
  12160. ' self.doit;',
  12161. ' glob;',
  12162. ' self.glob;',
  12163. 'end;',
  12164. 'class procedure TPoint.TBird.Glob;',
  12165. 'begin',
  12166. ' glob;',
  12167. ' self.glob;',
  12168. 'end;',
  12169. 'procedure TPoint.DoIt(b: TBird);',
  12170. 'begin',
  12171. ' b.doit;',
  12172. ' b.glob;',
  12173. ' TBird.glob;',
  12174. 'end;',
  12175. 'begin',
  12176. '']);
  12177. ConvertProgram;
  12178. CheckSource('TestAdvRecord_SubClass',
  12179. LinesToStr([ // statements
  12180. 'rtl.createClass(this, "TObject", null, function () {',
  12181. ' this.$init = function () {',
  12182. ' };',
  12183. ' this.$final = function () {',
  12184. ' };',
  12185. '});',
  12186. 'rtl.recNewT(this, "TPoint", function () {',
  12187. ' rtl.createClass(this, "TBird", $mod.TObject, function () {',
  12188. ' this.DoIt = function () {',
  12189. ' this.DoIt();',
  12190. ' this.DoIt();',
  12191. ' this.$class.Glob();',
  12192. ' this.$class.Glob();',
  12193. ' };',
  12194. ' this.Glob = function () {',
  12195. ' this.Glob();',
  12196. ' this.Glob();',
  12197. ' };',
  12198. ' }, "TPoint.TBird");',
  12199. ' this.$eq = function (b) {',
  12200. ' return true;',
  12201. ' };',
  12202. ' this.$assign = function (s) {',
  12203. ' return this;',
  12204. ' };',
  12205. ' this.DoIt = function (b) {',
  12206. ' b.DoIt();',
  12207. ' b.$class.Glob();',
  12208. ' this.TBird.Glob();',
  12209. ' };',
  12210. '}, true);',
  12211. '']),
  12212. LinesToStr([ // $mod.$main
  12213. '']));
  12214. end;
  12215. procedure TTestModule.TestAdvRecord_SubInterfaceFail;
  12216. begin
  12217. StartProgram(false);
  12218. Add([
  12219. '{$modeswitch AdvancedRecords}',
  12220. 'type',
  12221. ' IUnknown = interface end;',
  12222. ' TPoint = record',
  12223. ' type IBird = interface end;',
  12224. ' end;',
  12225. 'begin',
  12226. '']);
  12227. SetExpectedPasResolverError('not yet implemented: IBird:TPasClassType [20190105143752] "interface inside record"',
  12228. nNotYetImplemented);
  12229. ParseProgram;
  12230. end;
  12231. procedure TTestModule.TestAdvRecord_Constructor;
  12232. begin
  12233. StartProgram(false);
  12234. Add([
  12235. '{$modeswitch AdvancedRecords}',
  12236. 'type',
  12237. ' TPoint = record',
  12238. ' x,y: longint;',
  12239. ' class procedure Run(w: longint = 13); static;',
  12240. ' constructor Create(ax: longint; ay: longint = -1);',
  12241. ' end;',
  12242. 'class procedure tpoint.run(w: longint);',
  12243. 'begin',
  12244. ' run;',
  12245. ' run();',
  12246. 'end;',
  12247. 'constructor tpoint.create(ax,ay: longint);',
  12248. 'begin',
  12249. ' x:=ax;',
  12250. ' self.y:=ay;',
  12251. ' run;',
  12252. ' run(ax);',
  12253. 'end;',
  12254. 'var r: TPoint;',
  12255. 'begin',
  12256. ' r:=TPoint.Create(1,2);',
  12257. ' with TPoint do r:=Create(1,2);',
  12258. ' r.Create(3);',
  12259. ' r:=r.Create(4);',
  12260. '']);
  12261. ConvertProgram;
  12262. CheckSource('TestAdvRecord_Constructor',
  12263. LinesToStr([ // statements
  12264. 'rtl.recNewT(this, "TPoint", function () {',
  12265. ' this.x = 0;',
  12266. ' this.y = 0;',
  12267. ' this.$eq = function (b) {',
  12268. ' return (this.x === b.x) && (this.y === b.y);',
  12269. ' };',
  12270. ' this.$assign = function (s) {',
  12271. ' this.x = s.x;',
  12272. ' this.y = s.y;',
  12273. ' return this;',
  12274. ' };',
  12275. ' this.Run = function (w) {',
  12276. ' $mod.TPoint.Run(13);',
  12277. ' $mod.TPoint.Run(13);',
  12278. ' };',
  12279. ' this.Create = function (ax, ay) {',
  12280. ' this.x = ax;',
  12281. ' this.y = ay;',
  12282. ' this.Run(13);',
  12283. ' this.Run(ax);',
  12284. ' return this;',
  12285. ' };',
  12286. '});',
  12287. 'this.r = this.TPoint.$new();',
  12288. '']),
  12289. LinesToStr([ // $mod.$main
  12290. '$mod.r.$assign($mod.TPoint.$new().Create(1, 2));',
  12291. 'var $with = $mod.TPoint;',
  12292. '$mod.r.$assign($with.$new().Create(1, 2));',
  12293. '$mod.r.Create(3, -1);',
  12294. '$mod.r.$assign($mod.r.Create(4, -1));',
  12295. '']));
  12296. end;
  12297. procedure TTestModule.TestAdvRecord_ClassConstructor_Program;
  12298. begin
  12299. StartProgram(false);
  12300. Add([
  12301. '{$modeswitch AdvancedRecords}',
  12302. 'type',
  12303. ' TPoint = record',
  12304. ' class var x: longint;',
  12305. ' class procedure Fly; static;',
  12306. ' class constructor Init;',
  12307. ' end;',
  12308. 'var count: word;',
  12309. 'class procedure Tpoint.Fly;',
  12310. 'begin',
  12311. 'end;',
  12312. 'class constructor tpoint.init;',
  12313. 'begin',
  12314. ' count:=count+1;',
  12315. ' x:=x+3;',
  12316. ' tpoint.x:=tpoint.x+4;',
  12317. ' fly;',
  12318. ' tpoint.fly;',
  12319. 'end;',
  12320. 'var r: TPoint;',
  12321. 'begin',
  12322. ' r.x:=r.x+10;',
  12323. ' r.Fly;',
  12324. ' r.Fly();',
  12325. '']);
  12326. ConvertProgram;
  12327. CheckSource('TestAdvRecord_ClassConstructor_Program',
  12328. LinesToStr([ // statements
  12329. 'rtl.recNewT(this, "TPoint", function () {',
  12330. ' this.x = 0;',
  12331. ' this.$eq = function (b) {',
  12332. ' return true;',
  12333. ' };',
  12334. ' this.$assign = function (s) {',
  12335. ' return this;',
  12336. ' };',
  12337. ' this.Fly = function () {',
  12338. ' };',
  12339. '}, true);',
  12340. 'this.count = 0;',
  12341. 'this.r = this.TPoint.$new();',
  12342. '']),
  12343. LinesToStr([ // $mod.$main
  12344. '(function () {',
  12345. ' $mod.count = $mod.count + 1;',
  12346. ' $mod.TPoint.x = $mod.TPoint.x + 3;',
  12347. ' $mod.TPoint.x = $mod.TPoint.x + 4;',
  12348. ' $mod.TPoint.Fly();',
  12349. ' $mod.TPoint.Fly();',
  12350. '})();',
  12351. '$mod.TPoint.x = $mod.r.x + 10;',
  12352. '$mod.TPoint.Fly();',
  12353. '$mod.TPoint.Fly();',
  12354. '']));
  12355. end;
  12356. procedure TTestModule.TestAdvRecord_ClassConstructor_Unit;
  12357. begin
  12358. StartUnit(false);
  12359. Add([
  12360. 'interface',
  12361. '{$modeswitch AdvancedRecords}',
  12362. 'type',
  12363. ' TPoint = record',
  12364. ' class var x: longint;',
  12365. ' class procedure Fly; static;',
  12366. ' class constructor Init;',
  12367. ' end;',
  12368. 'implementation',
  12369. 'var count: word;',
  12370. 'class procedure Tpoint.Fly;',
  12371. 'begin',
  12372. 'end;',
  12373. 'class constructor tpoint.init;',
  12374. 'begin',
  12375. ' count:=count+1;',
  12376. ' x:=3;',
  12377. ' tpoint.x:=4;',
  12378. ' fly;',
  12379. ' tpoint.fly;',
  12380. 'end;',
  12381. '']);
  12382. ConvertUnit;
  12383. CheckSource('TestAdvRecord_ClassConstructor_Unit',
  12384. LinesToStr([ // statements
  12385. 'var $impl = $mod.$impl;',
  12386. 'rtl.recNewT(this, "TPoint", function () {',
  12387. ' this.x = 0;',
  12388. ' this.$eq = function (b) {',
  12389. ' return true;',
  12390. ' };',
  12391. ' this.$assign = function (s) {',
  12392. ' return this;',
  12393. ' };',
  12394. ' this.Fly = function () {',
  12395. ' };',
  12396. '}, true);',
  12397. '']),
  12398. LinesToStr([ // $mod.$init
  12399. '(function () {',
  12400. ' $impl.count = $impl.count + 1;',
  12401. ' $mod.TPoint.x = 3;',
  12402. ' $mod.TPoint.x = 4;',
  12403. ' $mod.TPoint.Fly();',
  12404. ' $mod.TPoint.Fly();',
  12405. '})();',
  12406. '']),
  12407. LinesToStr([ // $mod.$main
  12408. '$impl.count = 0;',
  12409. '']));
  12410. end;
  12411. procedure TTestModule.TestClass_TObjectDefaultConstructor;
  12412. begin
  12413. StartProgram(false);
  12414. Add(['type',
  12415. ' TObject = class',
  12416. ' public',
  12417. ' constructor Create;',
  12418. ' destructor Destroy;',
  12419. ' end;',
  12420. ' TBird = TObject;',
  12421. 'constructor tobject.create;',
  12422. 'begin end;',
  12423. 'destructor tobject.destroy;',
  12424. 'begin end;',
  12425. 'var Obj: tobject;',
  12426. 'begin',
  12427. ' obj:=tobject.create;',
  12428. ' obj:=tobject.create();',
  12429. ' obj:=tbird.create;',
  12430. ' obj:=tbird.create();',
  12431. ' obj:=obj.create();',
  12432. ' obj.destroy;',
  12433. '']);
  12434. ConvertProgram;
  12435. CheckSource('TestClass_TObjectDefaultConstructor',
  12436. LinesToStr([ // statements
  12437. 'rtl.createClass(this,"TObject",null,function(){',
  12438. ' this.$init = function () {',
  12439. ' };',
  12440. ' this.$final = function () {',
  12441. ' };',
  12442. ' this.Create = function(){',
  12443. ' return this;',
  12444. ' };',
  12445. ' this.Destroy = function(){',
  12446. ' };',
  12447. '});',
  12448. 'this.Obj = null;'
  12449. ]),
  12450. LinesToStr([ // $mod.$main
  12451. '$mod.Obj = $mod.TObject.$create("Create");',
  12452. '$mod.Obj = $mod.TObject.$create("Create");',
  12453. '$mod.Obj = $mod.TObject.$create("Create");',
  12454. '$mod.Obj = $mod.TObject.$create("Create");',
  12455. '$mod.Obj = $mod.Obj.Create();',
  12456. '$mod.Obj.$destroy("Destroy");',
  12457. '']));
  12458. end;
  12459. procedure TTestModule.TestClass_TObjectConstructorWithParams;
  12460. begin
  12461. StartProgram(false);
  12462. Add('type');
  12463. Add(' TObject = class');
  12464. Add(' public');
  12465. Add(' constructor Create(Par: longint);');
  12466. Add(' end;');
  12467. Add('constructor tobject.create(par: longint);');
  12468. Add('begin end;');
  12469. Add('var Obj: tobject;');
  12470. Add('begin');
  12471. Add(' obj:=tobject.create(3);');
  12472. ConvertProgram;
  12473. CheckSource('TestClass_TObjectConstructorWithParams',
  12474. LinesToStr([ // statements
  12475. 'rtl.createClass(this,"TObject",null,function(){',
  12476. ' this.$init = function () {',
  12477. ' };',
  12478. ' this.$final = function () {',
  12479. ' };',
  12480. ' this.Create = function(Par){',
  12481. ' return this;',
  12482. ' };',
  12483. '});',
  12484. 'this.Obj = null;'
  12485. ]),
  12486. LinesToStr([ // $mod.$main
  12487. '$mod.Obj = $mod.TObject.$create("Create",[3]);'
  12488. ]));
  12489. end;
  12490. procedure TTestModule.TestClass_TObjectConstructorWithDefaultParam;
  12491. begin
  12492. StartProgram(false);
  12493. Add('type');
  12494. Add(' TObject = class');
  12495. Add(' public');
  12496. Add(' constructor Create;');
  12497. Add(' end;');
  12498. Add(' TTest = class(TObject)');
  12499. Add(' public');
  12500. Add(' constructor Create(const Par: longint = 1);');
  12501. Add(' end;');
  12502. Add('constructor tobject.create;');
  12503. Add('begin end;');
  12504. Add('constructor ttest.create(const par: longint);');
  12505. Add('begin end;');
  12506. Add('var t: ttest;');
  12507. Add('begin');
  12508. Add(' t:=ttest.create;');
  12509. Add(' t:=ttest.create(2);');
  12510. ConvertProgram;
  12511. CheckSource('TestClass_TObjectConstructorWithDefaultParam',
  12512. LinesToStr([ // statements
  12513. 'rtl.createClass(this,"TObject",null,function(){',
  12514. ' this.$init = function () {',
  12515. ' };',
  12516. ' this.$final = function () {',
  12517. ' };',
  12518. ' this.Create = function(){',
  12519. ' return this;',
  12520. ' };',
  12521. '});',
  12522. 'rtl.createClass(this, "TTest", this.TObject, function () {',
  12523. ' this.Create$1 = function (Par) {',
  12524. ' return this;',
  12525. ' };',
  12526. '});',
  12527. 'this.t = null;'
  12528. ]),
  12529. LinesToStr([ // $mod.$main
  12530. '$mod.t = $mod.TTest.$create("Create$1", [1]);',
  12531. '$mod.t = $mod.TTest.$create("Create$1", [2]);'
  12532. ]));
  12533. end;
  12534. procedure TTestModule.TestClass_Var;
  12535. begin
  12536. StartProgram(false);
  12537. Add([
  12538. 'type',
  12539. ' TObject = class',
  12540. ' public',
  12541. ' vI: longint;',
  12542. ' constructor Create(Par: longint);',
  12543. ' end;',
  12544. 'constructor tobject.create(par: longint);',
  12545. 'begin',
  12546. ' vi:=par+3',
  12547. 'end;',
  12548. 'var Obj: tobject;',
  12549. 'begin',
  12550. ' obj:=tobject.create(4);',
  12551. ' obj.vi:=obj.VI+5;']);
  12552. ConvertProgram;
  12553. CheckSource('TestClass_Var',
  12554. LinesToStr([ // statements
  12555. 'rtl.createClass(this,"TObject",null,function(){',
  12556. ' this.$init = function () {',
  12557. ' this.vI = 0;',
  12558. ' };',
  12559. ' this.$final = function () {',
  12560. ' };',
  12561. ' this.Create = function(Par){',
  12562. ' this.vI = Par+3;',
  12563. ' return this;',
  12564. ' };',
  12565. '});',
  12566. 'this.Obj = null;'
  12567. ]),
  12568. LinesToStr([ // $mod.$main
  12569. '$mod.Obj = $mod.TObject.$create("Create",[4]);',
  12570. '$mod.Obj.vI = $mod.Obj.vI + 5;'
  12571. ]));
  12572. end;
  12573. procedure TTestModule.TestClass_Method;
  12574. begin
  12575. StartProgram(false);
  12576. Add('type');
  12577. Add(' TObject = class');
  12578. Add(' public');
  12579. Add(' vI: longint;');
  12580. Add(' Sub: TObject;');
  12581. Add(' constructor Create;');
  12582. Add(' function GetIt(Par: longint): tobject;');
  12583. Add(' end;');
  12584. Add('constructor tobject.create; begin end;');
  12585. Add('function tobject.getit(par: longint): tobject;');
  12586. Add('begin');
  12587. Add(' Self.vi:=par+3;');
  12588. Add(' Result:=self.sub;');
  12589. Add('end;');
  12590. Add('var Obj: tobject;');
  12591. Add('begin');
  12592. Add(' obj:=tobject.create;');
  12593. Add(' obj.getit(4);');
  12594. Add(' obj.sub.sub:=nil;');
  12595. Add(' obj.sub.getit(5);');
  12596. Add(' obj.sub.getit(6).SUB:=nil;');
  12597. Add(' obj.sub.getit(7).GETIT(8);');
  12598. Add(' obj.sub.getit(9).SuB.getit(10);');
  12599. ConvertProgram;
  12600. CheckSource('TestClass_Method',
  12601. LinesToStr([ // statements
  12602. 'rtl.createClass(this,"TObject",null,function(){',
  12603. ' this.$init = function () {',
  12604. ' this.vI = 0;',
  12605. ' this.Sub = null;',
  12606. ' };',
  12607. ' this.$final = function () {',
  12608. ' this.Sub = undefined;',
  12609. ' };',
  12610. ' this.Create = function(){',
  12611. ' return this;',
  12612. ' };',
  12613. ' this.GetIt = function(Par){',
  12614. ' var Result = null;',
  12615. ' this.vI = Par + 3;',
  12616. ' Result = this.Sub;',
  12617. ' return Result;',
  12618. ' };',
  12619. '});',
  12620. 'this.Obj = null;'
  12621. ]),
  12622. LinesToStr([ // $mod.$main
  12623. '$mod.Obj = $mod.TObject.$create("Create");',
  12624. '$mod.Obj.GetIt(4);',
  12625. '$mod.Obj.Sub.Sub=null;',
  12626. '$mod.Obj.Sub.GetIt(5);',
  12627. '$mod.Obj.Sub.GetIt(6).Sub=null;',
  12628. '$mod.Obj.Sub.GetIt(7).GetIt(8);',
  12629. '$mod.Obj.Sub.GetIt(9).Sub.GetIt(10);'
  12630. ]));
  12631. end;
  12632. procedure TTestModule.TestClass_Implementation;
  12633. begin
  12634. StartUnit(false);
  12635. Add([
  12636. 'interface',
  12637. 'type',
  12638. ' TObject = class',
  12639. ' constructor Create;',
  12640. ' end;',
  12641. 'implementation',
  12642. 'type',
  12643. ' TIntClass = class',
  12644. ' constructor Create; reintroduce;',
  12645. ' class procedure DoGlob;',
  12646. ' end;',
  12647. 'constructor tintclass.create;',
  12648. 'begin',
  12649. ' inherited;',
  12650. ' inherited create;',
  12651. ' doglob;',
  12652. 'end;',
  12653. 'class procedure tintclass.doglob;',
  12654. 'begin',
  12655. 'end;',
  12656. 'constructor tobject.create;',
  12657. 'var',
  12658. ' iC: tintclass;',
  12659. 'begin',
  12660. ' ic:=tintclass.create;',
  12661. ' tintclass.doglob;',
  12662. ' ic.doglob;',
  12663. 'end;',
  12664. 'initialization',
  12665. ' tintclass.doglob;',
  12666. '']);
  12667. ConvertUnit;
  12668. CheckSource('TestClass_Implementation',
  12669. LinesToStr([ // statements
  12670. 'var $impl = $mod.$impl;',
  12671. 'rtl.createClass(this, "TObject", null, function () {',
  12672. ' this.$init = function () {',
  12673. ' };',
  12674. ' this.$final = function () {',
  12675. ' };',
  12676. ' this.Create = function () {',
  12677. ' var iC = null;',
  12678. ' iC = $impl.TIntClass.$create("Create$1");',
  12679. ' $impl.TIntClass.DoGlob();',
  12680. ' iC.$class.DoGlob();',
  12681. ' return this;',
  12682. ' };',
  12683. '});',
  12684. '']),
  12685. LinesToStr([ // $mod.$main
  12686. '$impl.TIntClass.DoGlob();',
  12687. '']),
  12688. LinesToStr([
  12689. 'rtl.createClass($impl, "TIntClass", $mod.TObject, function () {',
  12690. ' this.Create$1 = function () {',
  12691. ' $mod.TObject.Create.call(this);',
  12692. ' $mod.TObject.Create.call(this);',
  12693. ' this.$class.DoGlob();',
  12694. ' return this;',
  12695. ' };',
  12696. ' this.DoGlob = function () {',
  12697. ' };',
  12698. '});',
  12699. '']));
  12700. end;
  12701. procedure TTestModule.TestClass_Inheritance;
  12702. begin
  12703. StartProgram(false);
  12704. Add('type');
  12705. Add(' TObject = class');
  12706. Add(' public');
  12707. Add(' constructor Create;');
  12708. Add(' end;');
  12709. Add(' TClassA = class');
  12710. Add(' end;');
  12711. Add(' TClassB = class(TObject)');
  12712. Add(' procedure ProcB;');
  12713. Add(' end;');
  12714. Add('constructor tobject.create; begin end;');
  12715. Add('procedure tclassb.procb; begin end;');
  12716. Add('var');
  12717. Add(' oO: TObject;');
  12718. Add(' oA: TClassA;');
  12719. Add(' oB: TClassB;');
  12720. Add('begin');
  12721. Add(' oO:=tobject.Create;');
  12722. Add(' oA:=tclassa.Create;');
  12723. Add(' ob:=tclassb.Create;');
  12724. Add(' if oo is tclassa then ;');
  12725. Add(' ob:=oo as tclassb;');
  12726. Add(' (oo as tclassb).procb;');
  12727. ConvertProgram;
  12728. CheckSource('TestClass_Inheritance',
  12729. LinesToStr([ // statements
  12730. 'rtl.createClass(this,"TObject",null,function(){',
  12731. ' this.$init = function () {',
  12732. ' };',
  12733. ' this.$final = function () {',
  12734. ' };',
  12735. ' this.Create = function () {',
  12736. ' return this;',
  12737. ' };',
  12738. '});',
  12739. 'rtl.createClass(this,"TClassA",this.TObject,function(){',
  12740. '});',
  12741. 'rtl.createClass(this,"TClassB",this.TObject,function(){',
  12742. ' this.ProcB = function () {',
  12743. ' };',
  12744. '});',
  12745. 'this.oO = null;',
  12746. 'this.oA = null;',
  12747. 'this.oB = null;'
  12748. ]),
  12749. LinesToStr([ // $mod.$main
  12750. '$mod.oO = $mod.TObject.$create("Create");',
  12751. '$mod.oA = $mod.TClassA.$create("Create");',
  12752. '$mod.oB = $mod.TClassB.$create("Create");',
  12753. 'if ($mod.TClassA.isPrototypeOf($mod.oO));',
  12754. '$mod.oB = rtl.as($mod.oO, $mod.TClassB);',
  12755. 'rtl.as($mod.oO, $mod.TClassB).ProcB();'
  12756. ]));
  12757. end;
  12758. procedure TTestModule.TestClass_TypeAlias;
  12759. begin
  12760. StartProgram(false);
  12761. Add([
  12762. '{$interfaces corba}',
  12763. 'type',
  12764. ' IObject = interface',
  12765. ' end;',
  12766. ' IBird = type IObject;',
  12767. ' TObject = class',
  12768. ' end;',
  12769. ' TBird = type TObject;',
  12770. 'var',
  12771. ' oObj: TObject;',
  12772. ' oBird: TBird;',
  12773. ' IntfObj: IObject;',
  12774. ' IntfBird: IBird;',
  12775. 'begin',
  12776. ' oObj:=oBird;',
  12777. '']);
  12778. ConvertProgram;
  12779. CheckSource('TestClass_TypeAlias',
  12780. LinesToStr([ // statements
  12781. 'rtl.createInterface(this, "IObject", "{B92D5841-6F2A-306A-8000-000000000000}", [], null);',
  12782. 'rtl.createInterface(this, "IBird", "{4B0D080B-C0F6-387B-AE88-F10981585074}", [], this.IObject);',
  12783. 'rtl.createClass(this, "TObject", null, function () {',
  12784. ' this.$init = function () {',
  12785. ' };',
  12786. ' this.$final = function () {',
  12787. ' };',
  12788. '});',
  12789. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  12790. '});',
  12791. 'this.oObj = null;',
  12792. 'this.oBird = null;',
  12793. 'this.IntfObj = null;',
  12794. 'this.IntfBird = null;',
  12795. '']),
  12796. LinesToStr([ // $mod.$main
  12797. '$mod.oObj = $mod.oBird;',
  12798. '']));
  12799. end;
  12800. procedure TTestModule.TestClass_AbstractMethod;
  12801. begin
  12802. StartProgram(false);
  12803. Add('type');
  12804. Add(' TObject = class');
  12805. Add(' public');
  12806. Add(' procedure DoIt; virtual; abstract;');
  12807. Add(' end;');
  12808. Add('begin');
  12809. ConvertProgram;
  12810. CheckSource('TestClass_AbstractMethod',
  12811. LinesToStr([ // statements
  12812. 'rtl.createClass(this,"TObject",null,function(){',
  12813. ' this.$init = function () {',
  12814. ' };',
  12815. ' this.$final = function () {',
  12816. ' };',
  12817. '});'
  12818. ]),
  12819. LinesToStr([ // this.$main
  12820. ''
  12821. ]));
  12822. end;
  12823. procedure TTestModule.TestClass_CallInherited_ProcNoParams;
  12824. begin
  12825. StartProgram(false);
  12826. Add([
  12827. 'type',
  12828. ' TObject = class',
  12829. ' procedure DoAbstract; virtual; abstract;',
  12830. ' procedure DoVirtual; virtual;',
  12831. ' procedure DoIt;',
  12832. ' end;',
  12833. ' TA = class',
  12834. ' procedure doabstract; override;',
  12835. ' procedure dovirtual; override;',
  12836. ' procedure DoSome;',
  12837. ' end;',
  12838. 'procedure tobject.dovirtual;',
  12839. 'begin',
  12840. ' inherited; // call non existing ancestor -> ignore silently',
  12841. 'end;',
  12842. 'procedure tobject.doit;',
  12843. 'begin',
  12844. 'end;',
  12845. 'procedure ta.doabstract;',
  12846. 'begin',
  12847. ' inherited dovirtual; // call TObject.DoVirtual',
  12848. 'end;',
  12849. 'procedure ta.dovirtual;',
  12850. 'begin',
  12851. ' inherited; // call TObject.DoVirtual',
  12852. ' inherited dovirtual; // call TObject.DoVirtual',
  12853. ' inherited dovirtual(); // call TObject.DoVirtual',
  12854. ' doit;',
  12855. ' doit();',
  12856. 'end;',
  12857. 'procedure ta.dosome;',
  12858. 'begin',
  12859. ' inherited; // call non existing ancestor method -> silently ignore',
  12860. 'end;',
  12861. 'begin']);
  12862. ConvertProgram;
  12863. CheckSource('TestClass_CallInherited_ProcNoParams',
  12864. LinesToStr([ // statements
  12865. 'rtl.createClass(this,"TObject",null,function(){',
  12866. ' this.$init = function () {',
  12867. ' };',
  12868. ' this.$final = function () {',
  12869. ' };',
  12870. ' this.DoVirtual = function () {',
  12871. ' };',
  12872. ' this.DoIt = function () {',
  12873. ' };',
  12874. '});',
  12875. 'rtl.createClass(this, "TA", this.TObject, function () {',
  12876. ' this.DoAbstract = function () {',
  12877. ' $mod.TObject.DoVirtual.call(this);',
  12878. ' };',
  12879. ' this.DoVirtual = function () {',
  12880. ' $mod.TObject.DoVirtual.call(this);',
  12881. ' $mod.TObject.DoVirtual.call(this);',
  12882. ' $mod.TObject.DoVirtual.call(this);',
  12883. ' this.DoIt();',
  12884. ' this.DoIt();',
  12885. ' };',
  12886. ' this.DoSome = function () {',
  12887. ' };',
  12888. '});'
  12889. ]),
  12890. LinesToStr([ // this.$main
  12891. ''
  12892. ]));
  12893. end;
  12894. procedure TTestModule.TestClass_CallInherited_WithParams;
  12895. begin
  12896. StartProgram(false);
  12897. Add([
  12898. 'type',
  12899. ' TObject = class',
  12900. ' procedure DoAbstract(pA: longint; pB: longint = 0); virtual; abstract;',
  12901. ' procedure DoVirtual(pA: longint; pB: longint = 0); virtual;',
  12902. ' procedure DoIt(pA: longint; pB: longint = 0);',
  12903. ' procedure DoIt2(pA: longint = 1; pB: longint = 2);',
  12904. ' function GetIt(pA: longint = 1; pB: longint = 2): longint;',
  12905. ' end;',
  12906. ' TClassA = class',
  12907. ' procedure DoAbstract(pA: longint; pB: longint = 0); override;',
  12908. ' procedure DoVirtual(pA: longint; pB: longint = 0); override;',
  12909. ' function GetIt(pA: longint = 1; pB: longint = 2): longint;',
  12910. ' end;',
  12911. 'procedure tobject.dovirtual(pa: longint; pb: longint = 0);',
  12912. 'begin',
  12913. 'end;',
  12914. 'procedure tobject.doit(pa: longint; pb: longint = 0);',
  12915. 'begin',
  12916. 'end;',
  12917. 'procedure tobject.doit2(pa: longint; pb: longint = 0);',
  12918. 'begin',
  12919. 'end;',
  12920. 'function tobject.getit(pa: longint; pb: longint = 0): longint;',
  12921. 'begin',
  12922. 'end;',
  12923. 'procedure tclassa.doabstract(pa: longint; pb: longint = 0);',
  12924. 'begin',
  12925. ' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)',
  12926. ' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)',
  12927. 'end;',
  12928. 'procedure tclassa.dovirtual(pa: longint; pb: longint = 0);',
  12929. 'begin',
  12930. ' inherited; // call TObject.DoVirtual(pA,pB)',
  12931. ' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)',
  12932. ' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)',
  12933. ' doit(pa,pb);',
  12934. ' doit(pa);',
  12935. ' doit2(pa);',
  12936. ' doit2;',
  12937. 'end;',
  12938. 'function tclassa.getit(pa: longint; pb: longint = 0): longint;',
  12939. 'begin',
  12940. ' pa:=inherited;',
  12941. 'end;',
  12942. 'begin']);
  12943. ConvertProgram;
  12944. CheckSource('TestClass_CallInherited_WithParams',
  12945. LinesToStr([ // statements
  12946. 'rtl.createClass(this,"TObject",null,function(){',
  12947. ' this.$init = function () {',
  12948. ' };',
  12949. ' this.$final = function () {',
  12950. ' };',
  12951. ' this.DoVirtual = function (pA,pB) {',
  12952. ' };',
  12953. ' this.DoIt = function (pA,pB) {',
  12954. ' };',
  12955. ' this.DoIt2 = function (pA,pB) {',
  12956. ' };',
  12957. ' this.GetIt = function (pA, pB) {',
  12958. ' var Result = 0;',
  12959. ' return Result;',
  12960. ' };',
  12961. '});',
  12962. 'rtl.createClass(this, "TClassA", this.TObject, function () {',
  12963. ' this.DoAbstract = function (pA,pB) {',
  12964. ' $mod.TObject.DoVirtual.call(this,pA,pB);',
  12965. ' $mod.TObject.DoVirtual.call(this,pA,0);',
  12966. ' };',
  12967. ' this.DoVirtual = function (pA,pB) {',
  12968. ' $mod.TObject.DoVirtual.apply(this, arguments);',
  12969. ' $mod.TObject.DoVirtual.call(this,pA,pB);',
  12970. ' $mod.TObject.DoVirtual.call(this,pA,0);',
  12971. ' this.DoIt(pA,pB);',
  12972. ' this.DoIt(pA,0);',
  12973. ' this.DoIt2(pA,2);',
  12974. ' this.DoIt2(1,2);',
  12975. ' };',
  12976. ' this.GetIt$1 = function (pA, pB) {',
  12977. ' var Result = 0;',
  12978. ' pA = $mod.TObject.GetIt.apply(this, arguments);',
  12979. ' return Result;',
  12980. ' };',
  12981. '});'
  12982. ]),
  12983. LinesToStr([ // this.$main
  12984. ''
  12985. ]));
  12986. end;
  12987. procedure TTestModule.TestClasS_CallInheritedConstructor;
  12988. begin
  12989. StartProgram(false);
  12990. Add('type');
  12991. Add(' TObject = class');
  12992. Add(' constructor Create; virtual;');
  12993. Add(' constructor CreateWithB(b: boolean);');
  12994. Add(' end;');
  12995. Add(' TA = class');
  12996. Add(' constructor Create; override;');
  12997. Add(' constructor CreateWithC(c: char);');
  12998. Add(' procedure DoIt;');
  12999. Add(' class function DoSome: TObject;');
  13000. Add(' end;');
  13001. Add('constructor tobject.create;');
  13002. Add('begin');
  13003. Add(' inherited; // call non existing ancestor -> ignore silently');
  13004. Add('end;');
  13005. Add('constructor tobject.createwithb(b: boolean);');
  13006. Add('begin');
  13007. Add(' inherited; // call non existing ancestor -> ignore silently');
  13008. Add(' create; // normal call');
  13009. Add('end;');
  13010. Add('constructor ta.create;');
  13011. Add('begin');
  13012. Add(' inherited; // normal call TObject.Create');
  13013. Add(' inherited create; // normal call TObject.Create');
  13014. Add(' inherited createwithb(false); // normal call TObject.CreateWithB');
  13015. Add('end;');
  13016. Add('constructor ta.createwithc(c: char);');
  13017. Add('begin');
  13018. Add(' inherited create; // call TObject.Create');
  13019. Add(' inherited createwithb(true); // call TObject.CreateWithB');
  13020. Add(' doit;');
  13021. Add(' doit();');
  13022. Add(' dosome;');
  13023. Add('end;');
  13024. Add('procedure ta.doit;');
  13025. Add('begin');
  13026. Add(' create; // normal call');
  13027. Add(' createwithb(false); // normal call');
  13028. Add(' createwithc(''c''); // normal call');
  13029. Add('end;');
  13030. Add('class function ta.dosome: TObject;');
  13031. Add('begin');
  13032. Add(' Result:=create; // constructor');
  13033. Add(' Result:=createwithb(true); // constructor');
  13034. Add(' Result:=createwithc(''c''); // constructor');
  13035. Add('end;');
  13036. Add('begin');
  13037. ConvertProgram;
  13038. CheckSource('TestClass_CallInheritedConstructor',
  13039. LinesToStr([ // statements
  13040. 'rtl.createClass(this,"TObject",null,function(){',
  13041. ' this.$init = function () {',
  13042. ' };',
  13043. ' this.$final = function () {',
  13044. ' };',
  13045. ' this.Create = function () {',
  13046. ' return this;',
  13047. ' };',
  13048. ' this.CreateWithB = function (b) {',
  13049. ' this.Create();',
  13050. ' return this;',
  13051. ' };',
  13052. '});',
  13053. 'rtl.createClass(this, "TA", this.TObject, function () {',
  13054. ' this.Create = function () {',
  13055. ' $mod.TObject.Create.call(this);',
  13056. ' $mod.TObject.Create.call(this);',
  13057. ' $mod.TObject.CreateWithB.call(this, false);',
  13058. ' return this;',
  13059. ' };',
  13060. ' this.CreateWithC = function (c) {',
  13061. ' $mod.TObject.Create.call(this);',
  13062. ' $mod.TObject.CreateWithB.call(this, true);',
  13063. ' this.DoIt();',
  13064. ' this.DoIt();',
  13065. ' this.$class.DoSome();',
  13066. ' return this;',
  13067. ' };',
  13068. ' this.DoIt = function () {',
  13069. ' this.Create();',
  13070. ' this.CreateWithB(false);',
  13071. ' this.CreateWithC("c");',
  13072. ' };',
  13073. ' this.DoSome = function () {',
  13074. ' var Result = null;',
  13075. ' Result = this.$create("Create");',
  13076. ' Result = this.$create("CreateWithB", [true]);',
  13077. ' Result = this.$create("CreateWithC", ["c"]);',
  13078. ' return Result;',
  13079. ' };',
  13080. '});'
  13081. ]),
  13082. LinesToStr([ // this.$main
  13083. ''
  13084. ]));
  13085. end;
  13086. procedure TTestModule.TestClass_ClassVar_Assign;
  13087. begin
  13088. StartProgram(false);
  13089. Add([
  13090. 'type',
  13091. ' TObject = class',
  13092. ' public',
  13093. ' class var vI: longint;',
  13094. ' class var Sub: TObject;',
  13095. ' constructor Create;',
  13096. ' class function GetIt(var Par: longint): tobject;',
  13097. ' end;',
  13098. 'constructor tobject.create;',
  13099. 'begin',
  13100. ' vi:=vi+1;',
  13101. ' Self.vi:=Self.vi+1;',
  13102. ' inc(vi);',
  13103. 'end;',
  13104. 'class function tobject.getit(var par: longint): tobject;',
  13105. 'begin',
  13106. ' vi:=vi+3;',
  13107. ' Self.vi:=Self.vi+4;',
  13108. ' inc(vi);',
  13109. ' Result:=self.sub;',
  13110. ' GetIt(vi);',
  13111. 'end;',
  13112. 'var Obj: tobject;',
  13113. 'begin',
  13114. ' obj:=tobject.create;',
  13115. ' tobject.vi:=3;',
  13116. ' if tobject.vi=4 then ;',
  13117. ' tobject.sub:=nil;',
  13118. ' obj.sub:=nil;',
  13119. ' obj.sub.sub:=nil;']);
  13120. ConvertProgram;
  13121. CheckSource('TestClass_ClassVar_Assign',
  13122. LinesToStr([ // statements
  13123. 'rtl.createClass(this,"TObject",null,function(){',
  13124. ' this.vI = 0;',
  13125. ' this.Sub = null;',
  13126. ' this.$init = function () {',
  13127. ' };',
  13128. ' this.$final = function () {',
  13129. ' };',
  13130. ' this.Create = function(){',
  13131. ' $mod.TObject.vI = this.vI+1;',
  13132. ' $mod.TObject.vI = this.vI+1;',
  13133. ' $mod.TObject.vI += 1;',
  13134. ' return this;',
  13135. ' };',
  13136. ' this.GetIt = function(Par){',
  13137. ' var Result = null;',
  13138. ' $mod.TObject.vI = this.vI + 3;',
  13139. ' $mod.TObject.vI = this.vI + 4;',
  13140. ' $mod.TObject.vI += 1;',
  13141. ' Result = this.Sub;',
  13142. ' this.GetIt({',
  13143. ' p: $mod.TObject,',
  13144. ' get: function () {',
  13145. ' return this.p.vI;',
  13146. ' },',
  13147. ' set: function (v) {',
  13148. ' this.p.vI = v;',
  13149. ' }',
  13150. ' });',
  13151. ' return Result;',
  13152. ' };',
  13153. '});',
  13154. 'this.Obj = null;'
  13155. ]),
  13156. LinesToStr([ // $mod.$main
  13157. '$mod.Obj = $mod.TObject.$create("Create");',
  13158. '$mod.TObject.vI = 3;',
  13159. 'if ($mod.TObject.vI === 4);',
  13160. '$mod.TObject.Sub=null;',
  13161. '$mod.TObject.Sub=null;',
  13162. '$mod.TObject.Sub=null;',
  13163. '']));
  13164. end;
  13165. procedure TTestModule.TestClass_CallClassMethod;
  13166. begin
  13167. StartProgram(false);
  13168. Add('type');
  13169. Add(' TObject = class');
  13170. Add(' public');
  13171. Add(' class var vI: longint;');
  13172. Add(' class var Sub: TObject;');
  13173. Add(' constructor Create;');
  13174. Add(' function GetMore(Par: longint): longint;');
  13175. Add(' class function GetIt(Par: longint): tobject;');
  13176. Add(' end;');
  13177. Add('constructor tobject.create;');
  13178. Add('begin');
  13179. Add(' sub:=getit(3);');
  13180. Add(' vi:=getmore(4);');
  13181. Add(' sub:=Self.getit(5);');
  13182. Add(' vi:=Self.getmore(6);');
  13183. Add('end;');
  13184. Add('function tobject.getmore(par: longint): longint;');
  13185. Add('begin');
  13186. Add(' sub:=getit(11);');
  13187. Add(' vi:=getmore(12);');
  13188. Add(' sub:=self.getit(13);');
  13189. Add(' vi:=self.getmore(14);');
  13190. Add('end;');
  13191. Add('class function tobject.getit(par: longint): tobject;');
  13192. Add('begin');
  13193. Add(' sub:=getit(21);');
  13194. Add(' vi:=sub.getmore(22);');
  13195. Add(' sub:=self.getit(23);');
  13196. Add(' vi:=self.sub.getmore(24);');
  13197. Add('end;');
  13198. Add('var Obj: tobject;');
  13199. Add('begin');
  13200. Add(' obj:=tobject.create;');
  13201. Add(' tobject.getit(5);');
  13202. Add(' obj.getit(6);');
  13203. Add(' obj.sub.getit(7);');
  13204. Add(' obj.sub.getit(8).SUB:=nil;');
  13205. Add(' obj.sub.getit(9).GETIT(10);');
  13206. Add(' obj.sub.getit(11).SuB.getit(12);');
  13207. ConvertProgram;
  13208. CheckSource('TestClass_CallClassMethod',
  13209. LinesToStr([ // statements
  13210. 'rtl.createClass(this,"TObject",null,function(){',
  13211. ' this.vI = 0;',
  13212. ' this.Sub = null;',
  13213. ' this.$init = function () {',
  13214. ' };',
  13215. ' this.$final = function () {',
  13216. ' };',
  13217. ' this.Create = function(){',
  13218. ' $mod.TObject.Sub = this.$class.GetIt(3);',
  13219. ' $mod.TObject.vI = this.GetMore(4);',
  13220. ' $mod.TObject.Sub = this.$class.GetIt(5);',
  13221. ' $mod.TObject.vI = this.GetMore(6);',
  13222. ' return this;',
  13223. ' };',
  13224. ' this.GetMore = function(Par){',
  13225. ' var Result = 0;',
  13226. ' $mod.TObject.Sub = this.$class.GetIt(11);',
  13227. ' $mod.TObject.vI = this.GetMore(12);',
  13228. ' $mod.TObject.Sub = this.$class.GetIt(13);',
  13229. ' $mod.TObject.vI = this.GetMore(14);',
  13230. ' return Result;',
  13231. ' };',
  13232. ' this.GetIt = function(Par){',
  13233. ' var Result = null;',
  13234. ' $mod.TObject.Sub = this.GetIt(21);',
  13235. ' $mod.TObject.vI = this.Sub.GetMore(22);',
  13236. ' $mod.TObject.Sub = this.GetIt(23);',
  13237. ' $mod.TObject.vI = this.Sub.GetMore(24);',
  13238. ' return Result;',
  13239. ' };',
  13240. '});',
  13241. 'this.Obj = null;'
  13242. ]),
  13243. LinesToStr([ // $mod.$main
  13244. '$mod.Obj = $mod.TObject.$create("Create");',
  13245. '$mod.TObject.GetIt(5);',
  13246. '$mod.Obj.$class.GetIt(6);',
  13247. '$mod.Obj.Sub.$class.GetIt(7);',
  13248. '$mod.TObject.Sub=null;',
  13249. '$mod.Obj.Sub.$class.GetIt(9).$class.GetIt(10);',
  13250. '$mod.Obj.Sub.$class.GetIt(11).Sub.$class.GetIt(12);',
  13251. '']));
  13252. end;
  13253. procedure TTestModule.TestClass_CallClassMethodStatic;
  13254. begin
  13255. StartProgram(false);
  13256. Add([
  13257. 'type',
  13258. ' TObject = class',
  13259. ' public',
  13260. ' class function Fly: tobject; static;',
  13261. ' end;',
  13262. 'class function tobject.Fly: tobject;',
  13263. 'begin',
  13264. ' Result.Fly;',
  13265. ' Result.Fly();',
  13266. ' Fly;',
  13267. ' Fly();',
  13268. ' Fly.Fly;',
  13269. ' Fly.Fly();',
  13270. 'end;',
  13271. 'var Obj: tobject;',
  13272. 'begin',
  13273. ' obj.Fly;',
  13274. ' obj.Fly();',
  13275. ' with obj do begin',
  13276. ' Fly;',
  13277. ' Fly();',
  13278. ' end;',
  13279. '']);
  13280. ConvertProgram;
  13281. CheckSource('TestClass_CallClassMethodStatic',
  13282. LinesToStr([ // statements
  13283. 'rtl.createClass(this, "TObject", null, function () {',
  13284. ' this.$init = function () {',
  13285. ' };',
  13286. ' this.$final = function () {',
  13287. ' };',
  13288. ' this.Fly = function () {',
  13289. ' var Result = null;',
  13290. ' $mod.TObject.Fly();',
  13291. ' $mod.TObject.Fly();',
  13292. ' $mod.TObject.Fly();',
  13293. ' $mod.TObject.Fly();',
  13294. ' $mod.TObject.Fly();',
  13295. ' $mod.TObject.Fly();',
  13296. ' return Result;',
  13297. ' };',
  13298. '});',
  13299. 'this.Obj = null;'
  13300. ]),
  13301. LinesToStr([ // $mod.$main
  13302. '$mod.TObject.Fly();',
  13303. '$mod.TObject.Fly();',
  13304. 'var $with = $mod.Obj;',
  13305. '$with.Fly();',
  13306. '$with.Fly();',
  13307. '']));
  13308. end;
  13309. procedure TTestModule.TestClass_Property;
  13310. begin
  13311. StartProgram(false);
  13312. Add('type');
  13313. Add(' TObject = class');
  13314. Add(' Fx: longint;');
  13315. Add(' Fy: longint;');
  13316. Add(' function GetInt: longint;');
  13317. Add(' procedure SetInt(Value: longint);');
  13318. Add(' procedure DoIt;');
  13319. Add(' property IntA: longint read Fx write Fy;');
  13320. Add(' property IntB: longint read GetInt write SetInt;');
  13321. Add(' end;');
  13322. Add('function tobject.getint: longint;');
  13323. Add('begin');
  13324. Add(' result:=fx;');
  13325. Add('end;');
  13326. Add('procedure tobject.setint(value: longint);');
  13327. Add('begin');
  13328. Add(' if value=fy then exit;');
  13329. Add(' fy:=value;');
  13330. Add('end;');
  13331. Add('procedure tobject.doit;');
  13332. Add('begin');
  13333. Add(' IntA:=IntA+1;');
  13334. Add(' Self.IntA:=Self.IntA+1;');
  13335. Add(' IntB:=IntB+1;');
  13336. Add(' Self.IntB:=Self.IntB+1;');
  13337. Add('end;');
  13338. Add('var Obj: tobject;');
  13339. Add('begin');
  13340. Add(' obj.inta:=obj.inta+1;');
  13341. Add(' if obj.intb=2 then;');
  13342. Add(' obj.intb:=obj.intb+2;');
  13343. Add(' obj.setint(obj.inta);');
  13344. ConvertProgram;
  13345. CheckSource('TestClass_Property',
  13346. LinesToStr([ // statements
  13347. 'rtl.createClass(this, "TObject", null, function () {',
  13348. ' this.$init = function () {',
  13349. ' this.Fx = 0;',
  13350. ' this.Fy = 0;',
  13351. ' };',
  13352. ' this.$final = function () {',
  13353. ' };',
  13354. ' this.GetInt = function () {',
  13355. ' var Result = 0;',
  13356. ' Result = this.Fx;',
  13357. ' return Result;',
  13358. ' };',
  13359. ' this.SetInt = function (Value) {',
  13360. ' if (Value === this.Fy) return;',
  13361. ' this.Fy = Value;',
  13362. ' };',
  13363. ' this.DoIt = function () {',
  13364. ' this.Fy = this.Fx + 1;',
  13365. ' this.Fy = this.Fx + 1;',
  13366. ' this.SetInt(this.GetInt() + 1);',
  13367. ' this.SetInt(this.GetInt() + 1);',
  13368. ' };',
  13369. '});',
  13370. 'this.Obj = null;'
  13371. ]),
  13372. LinesToStr([ // $mod.$main
  13373. '$mod.Obj.Fy = $mod.Obj.Fx + 1;',
  13374. 'if ($mod.Obj.GetInt() === 2);',
  13375. '$mod.Obj.SetInt($mod.Obj.GetInt() + 2);',
  13376. '$mod.Obj.SetInt($mod.Obj.Fx);'
  13377. ]));
  13378. end;
  13379. procedure TTestModule.TestClass_Property_ClassMethod;
  13380. begin
  13381. StartProgram(false);
  13382. Add([
  13383. 'type',
  13384. ' TObject = class',
  13385. ' class var Fx: longint;',
  13386. ' class var Fy: longint;',
  13387. ' class function GetInt: longint;',
  13388. ' class procedure SetInt(Value: longint);',
  13389. ' end;',
  13390. ' TBird = class',
  13391. ' class procedure DoIt;',
  13392. ' class property IntA: longint read Fx write Fy;',
  13393. ' class property IntB: longint read GetInt write SetInt;',
  13394. ' end;',
  13395. 'class function tobject.getint: longint;',
  13396. 'begin',
  13397. ' result:=fx;',
  13398. 'end;',
  13399. 'class procedure tobject.setint(value: longint);',
  13400. 'begin',
  13401. 'end;',
  13402. 'class procedure tbird.doit;',
  13403. 'begin',
  13404. ' FX:=3;',
  13405. ' IntA:=IntA+1;',
  13406. ' Self.IntA:=Self.IntA+1;',
  13407. ' IntB:=IntB+1;',
  13408. ' Self.IntB:=Self.IntB+1;',
  13409. ' with Self do begin',
  13410. ' FX:=11;',
  13411. ' IntA:=IntA+12;',
  13412. ' IntB:=IntB+13;',
  13413. ' end;',
  13414. 'end;',
  13415. 'var Obj: tbird;',
  13416. 'begin',
  13417. ' tbird.fx:=tbird.fx+1;',
  13418. ' tbird.inta:=tbird.inta+1;',
  13419. ' if tbird.intb=2 then;',
  13420. ' tbird.intb:=tbird.intb+2;',
  13421. ' tbird.setint(tbird.inta);',
  13422. ' obj.inta:=obj.inta+1;',
  13423. ' if obj.intb=2 then;',
  13424. ' obj.intb:=obj.intb+2;',
  13425. ' obj.setint(obj.inta);',
  13426. ' with Tbird do begin',
  13427. ' FX:=FY+1;',
  13428. ' inta:=inta+2;',
  13429. ' intb:=intb+3;',
  13430. ' end;',
  13431. ' with Obj do begin',
  13432. ' FX:=FY+1;',
  13433. ' inta:=inta+2;',
  13434. ' intb:=intb+3;',
  13435. ' end;',
  13436. '']);
  13437. ConvertProgram;
  13438. CheckSource('TestClass_Property_ClassMethod',
  13439. LinesToStr([ // statements
  13440. 'rtl.createClass(this, "TObject", null, function () {',
  13441. ' this.Fx = 0;',
  13442. ' this.Fy = 0;',
  13443. ' this.$init = function () {',
  13444. ' };',
  13445. ' this.$final = function () {',
  13446. ' };',
  13447. ' this.GetInt = function () {',
  13448. ' var Result = 0;',
  13449. ' Result = this.Fx;',
  13450. ' return Result;',
  13451. ' };',
  13452. ' this.SetInt = function (Value) {',
  13453. ' };',
  13454. '});',
  13455. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  13456. ' this.DoIt = function () {',
  13457. ' $mod.TObject.Fx = 3;',
  13458. ' $mod.TObject.Fy = this.Fx + 1;',
  13459. ' $mod.TObject.Fy = this.Fx + 1;',
  13460. ' this.SetInt(this.GetInt() + 1);',
  13461. ' this.SetInt(this.GetInt() + 1);',
  13462. ' $mod.TObject.Fx = 11;',
  13463. ' $mod.TObject.Fy = this.Fx + 12;',
  13464. ' this.SetInt(this.GetInt() + 13);',
  13465. ' };',
  13466. '});',
  13467. 'this.Obj = null;'
  13468. ]),
  13469. LinesToStr([ // $mod.$main
  13470. '$mod.TObject.Fx = $mod.TBird.Fx + 1;',
  13471. '$mod.TObject.Fy = $mod.TBird.Fx + 1;',
  13472. 'if ($mod.TBird.GetInt() === 2);',
  13473. '$mod.TBird.SetInt($mod.TBird.GetInt() + 2);',
  13474. '$mod.TBird.SetInt($mod.TBird.Fx);',
  13475. '$mod.TObject.Fy = $mod.Obj.Fx + 1;',
  13476. 'if ($mod.Obj.$class.GetInt() === 2);',
  13477. '$mod.Obj.$class.SetInt($mod.Obj.$class.GetInt() + 2);',
  13478. '$mod.Obj.$class.SetInt($mod.Obj.Fx);',
  13479. 'var $with = $mod.TBird;',
  13480. '$mod.TObject.Fx = $with.Fy + 1;',
  13481. '$mod.TObject.Fy = $with.Fx + 2;',
  13482. '$with.SetInt($with.GetInt() + 3);',
  13483. 'var $with1 = $mod.Obj;',
  13484. '$mod.TObject.Fx = $with1.Fy + 1;',
  13485. '$mod.TObject.Fy = $with1.Fx + 2;',
  13486. '$with1.$class.SetInt($with1.$class.GetInt() + 3);',
  13487. '']));
  13488. end;
  13489. procedure TTestModule.TestClass_Property_Indexed;
  13490. begin
  13491. StartProgram(false);
  13492. Add([
  13493. 'type',
  13494. ' TObject = class',
  13495. ' FItems: array of longint;',
  13496. ' function GetItems(Index: longint): longint;',
  13497. ' procedure SetItems(Index: longint; Value: longint);',
  13498. ' procedure DoIt;',
  13499. ' property Items[Index: longint]: longint read getitems write setitems;',
  13500. ' end;',
  13501. 'function tobject.getitems(index: longint): longint;',
  13502. 'begin',
  13503. ' Result:=fitems[index];',
  13504. 'end;',
  13505. 'procedure tobject.setitems(index: longint; value: longint);',
  13506. 'begin',
  13507. ' fitems[index]:=value;',
  13508. 'end;',
  13509. 'procedure tobject.doit;',
  13510. 'begin',
  13511. ' items[1]:=2;',
  13512. ' items[3]:=items[4];',
  13513. ' self.items[5]:=self.items[6];',
  13514. ' items[items[7]]:=items[items[8]];',
  13515. 'end;',
  13516. 'var Obj: tobject;',
  13517. 'begin',
  13518. ' obj.Items[11]:=obj.Items[12];',
  13519. '']);
  13520. ConvertProgram;
  13521. CheckSource('TestClass_Property_Indexed',
  13522. LinesToStr([ // statements
  13523. 'rtl.createClass(this, "TObject", null, function () {',
  13524. ' this.$init = function () {',
  13525. ' this.FItems = [];',
  13526. ' };',
  13527. ' this.$final = function () {',
  13528. ' this.FItems = undefined;',
  13529. ' };',
  13530. ' this.GetItems = function (Index) {',
  13531. ' var Result = 0;',
  13532. ' Result = this.FItems[Index];',
  13533. ' return Result;',
  13534. ' };',
  13535. ' this.SetItems = function (Index, Value) {',
  13536. ' this.FItems[Index] = Value;',
  13537. ' };',
  13538. ' this.DoIt = function () {',
  13539. ' this.SetItems(1, 2);',
  13540. ' this.SetItems(3,this.GetItems(4));',
  13541. ' this.SetItems(5,this.GetItems(6));',
  13542. ' this.SetItems(this.GetItems(7), this.GetItems(this.GetItems(8)));',
  13543. ' };',
  13544. '});',
  13545. 'this.Obj = null;'
  13546. ]),
  13547. LinesToStr([ // $mod.$main
  13548. '$mod.Obj.SetItems(11,$mod.Obj.GetItems(12));'
  13549. ]));
  13550. end;
  13551. procedure TTestModule.TestClass_Property_IndexSpec;
  13552. begin
  13553. StartProgram(false);
  13554. Add([
  13555. 'type',
  13556. ' TEnum = (red, blue);',
  13557. ' TObject = class',
  13558. ' function GetIntBool(Index: longint): boolean; virtual; abstract;',
  13559. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  13560. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  13561. ' procedure SetEnumBool(Index: TEnum; b: boolean); virtual; abstract;',
  13562. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  13563. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  13564. ' property B1: boolean index 1 read GetIntBool write SetIntBool;',
  13565. ' property B2: boolean index TEnum.blue read GetEnumBool write SetEnumBool;',
  13566. ' property B3: boolean index ord(red) read GetIntBool write SetIntBool;',
  13567. ' property I1[A: String]: boolean index ord(blue) read GetStrIntBool write SetStrIntBool;',
  13568. ' end;',
  13569. 'procedure DoIt(b: boolean); begin end;',
  13570. 'var',
  13571. ' o: TObject;',
  13572. 'begin',
  13573. ' o.B1:=o.B1;',
  13574. ' o.B2:=o.B2;',
  13575. ' o.B3:=o.B3;',
  13576. ' o.I1[''a'']:=o.I1[''b''];',
  13577. ' doit(o.b1);',
  13578. ' doit(o.b2);',
  13579. ' doit(o.i1[''c'']);',
  13580. '']);
  13581. ConvertProgram;
  13582. CheckSource('TestClass_Property_IndexSpec',
  13583. LinesToStr([ // statements
  13584. 'this.TEnum = {',
  13585. ' "0": "red",',
  13586. ' red: 0,',
  13587. ' "1": "blue",',
  13588. ' blue: 1',
  13589. '};',
  13590. 'rtl.createClass(this, "TObject", null, function () {',
  13591. ' this.$init = function () {',
  13592. ' };',
  13593. ' this.$final = function () {',
  13594. ' };',
  13595. '});',
  13596. 'this.DoIt = function (b) {',
  13597. '};',
  13598. 'this.o = null;',
  13599. '']),
  13600. LinesToStr([ // $mod.$main
  13601. '$mod.o.SetIntBool(1, $mod.o.GetIntBool(1));',
  13602. '$mod.o.SetEnumBool($mod.TEnum.blue, $mod.o.GetEnumBool($mod.TEnum.blue));',
  13603. '$mod.o.SetIntBool(0, $mod.o.GetIntBool(0));',
  13604. '$mod.o.SetStrIntBool("a", 1, $mod.o.GetStrIntBool("b", 1));',
  13605. '$mod.DoIt($mod.o.GetIntBool(1));',
  13606. '$mod.DoIt($mod.o.GetEnumBool($mod.TEnum.blue));',
  13607. '$mod.DoIt($mod.o.GetStrIntBool("c", 1));',
  13608. '']));
  13609. end;
  13610. procedure TTestModule.TestClass_PropertyOfTypeArray;
  13611. begin
  13612. StartProgram(false);
  13613. Add('type');
  13614. Add(' TArray = array of longint;');
  13615. Add(' TObject = class');
  13616. Add(' FItems: TArray;');
  13617. Add(' function GetItems: tarray;');
  13618. Add(' procedure SetItems(Value: tarray);');
  13619. Add(' property Items: tarray read getitems write setitems;');
  13620. Add(' procedure SetNumbers(const Value: tarray);');
  13621. Add(' property Numbers: tarray write setnumbers;');
  13622. Add(' end;');
  13623. Add('function tobject.getitems: tarray;');
  13624. Add('begin');
  13625. Add(' Result:=fitems;');
  13626. Add('end;');
  13627. Add('procedure tobject.setitems(value: tarray);');
  13628. Add('begin');
  13629. Add(' fitems:=value;');
  13630. Add(' fitems:=nil;');
  13631. Add(' Items:=nil;');
  13632. Add(' Items:=Items;');
  13633. Add(' Items[1]:=2;');
  13634. Add(' fitems[3]:=Items[4];');
  13635. Add(' Items[5]:=Items[6];');
  13636. Add(' Self.Items[7]:=8;');
  13637. Add(' Self.Items[9]:=Self.Items[10];');
  13638. Add(' Items[Items[11]]:=Items[Items[12]];');
  13639. Add('end;');
  13640. Add('procedure tobject.SetNumbers(const Value: tarray);');
  13641. Add('begin;');
  13642. Add(' Numbers:=nil;');
  13643. Add(' Numbers:=Value;');
  13644. Add(' Self.Numbers:=Value;');
  13645. Add('end;');
  13646. Add('var Obj: tobject;');
  13647. Add('begin');
  13648. Add(' obj.items:=nil;');
  13649. Add(' obj.items:=obj.items;');
  13650. Add(' obj.items[11]:=obj.items[12];');
  13651. ConvertProgram;
  13652. CheckSource('TestClass_PropertyOfTypeArray',
  13653. LinesToStr([ // statements
  13654. 'rtl.createClass(this, "TObject", null, function () {',
  13655. ' this.$init = function () {',
  13656. ' this.FItems = [];',
  13657. ' };',
  13658. ' this.$final = function () {',
  13659. ' this.FItems = undefined;',
  13660. ' };',
  13661. ' this.GetItems = function () {',
  13662. ' var Result = [];',
  13663. ' Result = rtl.arrayRef(this.FItems);',
  13664. ' return Result;',
  13665. ' };',
  13666. ' this.SetItems = function (Value) {',
  13667. ' this.FItems = rtl.arrayRef(Value);',
  13668. ' this.FItems = [];',
  13669. ' this.SetItems([]);',
  13670. ' this.SetItems(rtl.arrayRef(this.GetItems()));',
  13671. ' this.GetItems()[1] = 2;',
  13672. ' this.FItems[3] = this.GetItems()[4];',
  13673. ' this.GetItems()[5] = this.GetItems()[6];',
  13674. ' this.GetItems()[7] = 8;',
  13675. ' this.GetItems()[9] = this.GetItems()[10];',
  13676. ' this.GetItems()[this.GetItems()[11]] = this.GetItems()[this.GetItems()[12]];',
  13677. ' };',
  13678. ' this.SetNumbers = function (Value) {',
  13679. ' this.SetNumbers([]);',
  13680. ' this.SetNumbers(Value);',
  13681. ' this.SetNumbers(Value);',
  13682. ' };',
  13683. '});',
  13684. 'this.Obj = null;'
  13685. ]),
  13686. LinesToStr([ // $mod.$main
  13687. '$mod.Obj.SetItems([]);',
  13688. '$mod.Obj.SetItems($mod.Obj.GetItems());',
  13689. '$mod.Obj.GetItems()[11] = $mod.Obj.GetItems()[12];'
  13690. ]));
  13691. end;
  13692. procedure TTestModule.TestClass_PropertyDefault;
  13693. begin
  13694. StartProgram(false);
  13695. Add([
  13696. 'type',
  13697. ' TArray = array of longint;',
  13698. ' TObject = class',
  13699. ' end;',
  13700. ' TBird = class',
  13701. ' FItems: TArray;',
  13702. ' function GetItems(Index: longint): longint;',
  13703. ' procedure SetItems(Index, Value: longint);',
  13704. ' property Items[Index: longint]: longint read getitems write setitems; default;',
  13705. ' end;',
  13706. 'function TBird.getitems(index: longint): longint;',
  13707. 'begin',
  13708. 'end;',
  13709. 'procedure TBird.setitems(index, value: longint);',
  13710. 'begin',
  13711. ' Self[1]:=2;',
  13712. ' Self[3]:=Self[index];',
  13713. ' Self[index]:=Self[Self[value]];',
  13714. ' Self[Self[4]]:=value;',
  13715. 'end;',
  13716. 'var',
  13717. ' Bird: TBird;',
  13718. ' Obj: TObject;',
  13719. 'begin',
  13720. ' bird[11]:=12;',
  13721. ' bird[13]:=bird[14];',
  13722. ' bird[Bird[15]]:=bird[Bird[15]];',
  13723. ' TBird(obj)[16]:=TBird(obj)[17];',
  13724. ' (obj as tbird)[18]:=19;',
  13725. '']);
  13726. ConvertProgram;
  13727. CheckSource('TestClass_PropertyDefault',
  13728. LinesToStr([ // statements
  13729. 'rtl.createClass(this, "TObject", null, function () {',
  13730. ' this.$init = function () {',
  13731. ' };',
  13732. ' this.$final = function () {',
  13733. ' };',
  13734. '});',
  13735. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  13736. ' this.$init = function () {',
  13737. ' $mod.TObject.$init.call(this);',
  13738. ' this.FItems = [];',
  13739. ' };',
  13740. ' this.$final = function () {',
  13741. ' this.FItems = undefined;',
  13742. ' $mod.TObject.$final.call(this);',
  13743. ' };',
  13744. ' this.GetItems = function (Index) {',
  13745. ' var Result = 0;',
  13746. ' return Result;',
  13747. ' };',
  13748. ' this.SetItems = function (Index, Value) {',
  13749. ' this.SetItems(1, 2);',
  13750. ' this.SetItems(3, this.GetItems(Index));',
  13751. ' this.SetItems(Index, this.GetItems(this.GetItems(Value)));',
  13752. ' this.SetItems(this.GetItems(4), Value);',
  13753. ' };',
  13754. '});',
  13755. 'this.Bird = null;',
  13756. 'this.Obj = null;',
  13757. '']),
  13758. LinesToStr([ // $mod.$main
  13759. '$mod.Bird.SetItems(11, 12);',
  13760. '$mod.Bird.SetItems(13, $mod.Bird.GetItems(14));',
  13761. '$mod.Bird.SetItems($mod.Bird.GetItems(15), $mod.Bird.GetItems($mod.Bird.GetItems(15)));',
  13762. '$mod.Obj.SetItems(16, $mod.Obj.GetItems(17));',
  13763. 'rtl.as($mod.Obj, $mod.TBird).SetItems(18, 19);',
  13764. '']));
  13765. end;
  13766. procedure TTestModule.TestClass_PropertyDefault_TypecastToOtherDefault;
  13767. begin
  13768. StartProgram(false);
  13769. Add([
  13770. 'type',
  13771. ' TObject = class end;',
  13772. ' TAlphaList = class',
  13773. ' function GetAlphas(Index: boolean): Pointer; virtual; abstract;',
  13774. ' procedure SetAlphas(Index: boolean; Value: Pointer); virtual; abstract;',
  13775. ' property Alphas[Index: boolean]: Pointer read getAlphas write setAlphas; default;',
  13776. ' end;',
  13777. ' TBetaList = class',
  13778. ' function GetBetas(Index: longint): Pointer; virtual; abstract;',
  13779. ' procedure SetBetas(Index: longint; Value: Pointer); virtual; abstract;',
  13780. ' property Betas[Index: longint]: Pointer read getBetas write setBetas; default;',
  13781. ' end;',
  13782. ' TBird = class',
  13783. ' procedure DoIt;',
  13784. ' end;',
  13785. 'procedure TBird.DoIt;',
  13786. 'var',
  13787. ' List: TAlphaList;',
  13788. 'begin',
  13789. ' if TBetaList(List[true])[3]=nil then ;',
  13790. ' TBetaList(List[false])[5]:=nil;',
  13791. 'end;',
  13792. 'var',
  13793. ' List: TAlphaList;',
  13794. 'begin',
  13795. ' if TBetaList(List[true])[3]=nil then ;',
  13796. ' TBetaList(List[false])[5]:=nil;',
  13797. '']);
  13798. ConvertProgram;
  13799. CheckSource('TestClass_PropertyDefault_TypecastToOtherDefault',
  13800. LinesToStr([ // statements
  13801. 'rtl.createClass(this, "TObject", null, function () {',
  13802. ' this.$init = function () {',
  13803. ' };',
  13804. ' this.$final = function () {',
  13805. ' };',
  13806. '});',
  13807. 'rtl.createClass(this, "TAlphaList", this.TObject, function () {',
  13808. '});',
  13809. 'rtl.createClass(this, "TBetaList", this.TObject, function () {',
  13810. '});',
  13811. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  13812. ' this.DoIt = function () {',
  13813. ' var List = null;',
  13814. ' if (List.GetAlphas(true).GetBetas(3) === null) ;',
  13815. ' List.GetAlphas(false).SetBetas(5, null);',
  13816. ' };',
  13817. '});',
  13818. 'this.List = null;',
  13819. '']),
  13820. LinesToStr([ // $mod.$main
  13821. 'if ($mod.List.GetAlphas(true).GetBetas(3) === null) ;',
  13822. '$mod.List.GetAlphas(false).SetBetas(5, null);',
  13823. '']));
  13824. end;
  13825. procedure TTestModule.TestClass_PropertyOverride;
  13826. begin
  13827. StartProgram(false);
  13828. Add('type');
  13829. Add(' integer = longint;');
  13830. Add(' TObject = class');
  13831. Add(' FItem: integer;');
  13832. Add(' function GetItem: integer; external name ''GetItem'';');
  13833. Add(' procedure SetItem(Value: integer); external name ''SetItem'';');
  13834. Add(' property Item: integer read getitem write setitem;');
  13835. Add(' end;');
  13836. Add(' TCar = class');
  13837. Add(' FBag: integer;');
  13838. Add(' function GetBag: integer; external name ''GetBag'';');
  13839. Add(' property Item read getbag;');
  13840. Add(' end;');
  13841. Add('var');
  13842. Add(' Obj: tobject;');
  13843. Add(' Car: tcar;');
  13844. Add('begin');
  13845. Add(' Obj.Item:=Obj.Item;');
  13846. Add(' Car.Item:=Car.Item;');
  13847. ConvertProgram;
  13848. CheckSource('TestClass_PropertyOverride',
  13849. LinesToStr([ // statements
  13850. 'rtl.createClass(this, "TObject", null, function () {',
  13851. ' this.$init = function () {',
  13852. ' this.FItem = 0;',
  13853. ' };',
  13854. ' this.$final = function () {',
  13855. ' };',
  13856. '});',
  13857. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  13858. ' this.$init = function () {',
  13859. ' $mod.TObject.$init.call(this);',
  13860. ' this.FBag = 0;',
  13861. ' };',
  13862. '});',
  13863. 'this.Obj = null;',
  13864. 'this.Car = null;',
  13865. '']),
  13866. LinesToStr([ // $mod.$main
  13867. '$mod.Obj.SetItem($mod.Obj.GetItem());',
  13868. '$mod.Car.SetItem($mod.Car.GetBag());',
  13869. '']));
  13870. end;
  13871. procedure TTestModule.TestClass_PropertyIncVisibility;
  13872. begin
  13873. AddModuleWithIntfImplSrc('unit1.pp',
  13874. LinesToStr([
  13875. 'type',
  13876. ' TNumber = longint;',
  13877. ' TInteger = longint;',
  13878. ' TObject = class',
  13879. ' private',
  13880. ' function GetItems(Index: TNumber): TInteger; virtual; abstract;',
  13881. ' procedure SetItems(Index: TInteger; Value: TNumber); virtual; abstract;',
  13882. ' protected',
  13883. ' property Items[Index: TNumber]: longint read GetItems write SetItems;',
  13884. ' end;']),
  13885. LinesToStr([
  13886. '']));
  13887. StartProgram(true);
  13888. Add([
  13889. 'uses unit1;',
  13890. 'type',
  13891. ' TBird = class',
  13892. ' public',
  13893. ' property Items;',
  13894. ' end;',
  13895. 'procedure DoIt(i: TInteger);',
  13896. 'begin',
  13897. 'end;',
  13898. 'var b: TBird;',
  13899. 'begin',
  13900. ' b.Items[1]:=2;',
  13901. ' b.Items[3]:=b.Items[4];',
  13902. ' DoIt(b.Items[5]);',
  13903. '']);
  13904. ConvertProgram;
  13905. CheckSource('TestClass_PropertyIncVisibility',
  13906. LinesToStr([ // statements
  13907. 'rtl.createClass(this, "TBird", pas.unit1.TObject, function () {',
  13908. '});',
  13909. 'this.DoIt = function (i) {',
  13910. '};',
  13911. 'this.b = null;'
  13912. ]),
  13913. LinesToStr([ // $mod.$main
  13914. '$mod.b.SetItems(1, 2);',
  13915. '$mod.b.SetItems(3, $mod.b.GetItems(4));',
  13916. '$mod.DoIt($mod.b.GetItems(5));'
  13917. ]));
  13918. end;
  13919. procedure TTestModule.TestClass_Assigned;
  13920. begin
  13921. StartProgram(false);
  13922. Add('type');
  13923. Add(' TObject = class');
  13924. Add(' end;');
  13925. Add('var');
  13926. Add(' Obj: tobject;');
  13927. Add(' b: boolean;');
  13928. Add('begin');
  13929. Add(' if Assigned(obj) then ;');
  13930. Add(' b:=Assigned(obj) or false;');
  13931. ConvertProgram;
  13932. CheckSource('TestClass_Assigned',
  13933. LinesToStr([ // statements
  13934. 'rtl.createClass(this, "TObject", null, function () {',
  13935. ' this.$init = function () {',
  13936. ' };',
  13937. ' this.$final = function () {',
  13938. ' };',
  13939. '});',
  13940. 'this.Obj = null;',
  13941. 'this.b = false;'
  13942. ]),
  13943. LinesToStr([ // $mod.$main
  13944. 'if ($mod.Obj != null);',
  13945. '$mod.b = ($mod.Obj != null) || false;'
  13946. ]));
  13947. end;
  13948. procedure TTestModule.TestClass_WithClassDoCreate;
  13949. begin
  13950. StartProgram(false);
  13951. Add('type');
  13952. Add(' TObject = class');
  13953. Add(' aBool: boolean;');
  13954. Add(' Arr: array of boolean;');
  13955. Add(' constructor Create;');
  13956. Add(' end;');
  13957. Add('constructor TObject.Create; begin end;');
  13958. Add('var');
  13959. Add(' Obj: tobject;');
  13960. Add(' b: boolean;');
  13961. Add('begin');
  13962. Add(' with tobject.create do begin');
  13963. Add(' b:=abool;');
  13964. Add(' abool:=b;');
  13965. Add(' b:=arr[1];');
  13966. Add(' arr[2]:=b;');
  13967. Add(' end;');
  13968. Add(' with tobject do');
  13969. Add(' obj:=create;');
  13970. Add(' with obj do begin');
  13971. Add(' create;');
  13972. Add(' b:=abool;');
  13973. Add(' abool:=b;');
  13974. Add(' b:=arr[3];');
  13975. Add(' arr[4]:=b;');
  13976. Add(' end;');
  13977. ConvertProgram;
  13978. CheckSource('TestClass_WithClassDoCreate',
  13979. LinesToStr([ // statements
  13980. 'rtl.createClass(this, "TObject", null, function () {',
  13981. ' this.$init = function () {',
  13982. ' this.aBool = false;',
  13983. ' this.Arr = [];',
  13984. ' };',
  13985. ' this.$final = function () {',
  13986. ' this.Arr = undefined;',
  13987. ' };',
  13988. ' this.Create = function () {',
  13989. ' return this;',
  13990. ' };',
  13991. '});',
  13992. 'this.Obj = null;',
  13993. 'this.b = false;'
  13994. ]),
  13995. LinesToStr([ // $mod.$main
  13996. 'var $with = $mod.TObject.$create("Create");',
  13997. '$mod.b = $with.aBool;',
  13998. '$with.aBool = $mod.b;',
  13999. '$mod.b = $with.Arr[1];',
  14000. '$with.Arr[2] = $mod.b;',
  14001. 'var $with1 = $mod.TObject;',
  14002. '$mod.Obj = $with1.$create("Create");',
  14003. 'var $with2 = $mod.Obj;',
  14004. '$with2.Create();',
  14005. '$mod.b = $with2.aBool;',
  14006. '$with2.aBool = $mod.b;',
  14007. '$mod.b = $with2.Arr[3];',
  14008. '$with2.Arr[4] = $mod.b;',
  14009. '']));
  14010. end;
  14011. procedure TTestModule.TestClass_WithClassInstDoProperty;
  14012. begin
  14013. StartProgram(false);
  14014. Add('type');
  14015. Add(' TObject = class');
  14016. Add(' FInt: longint;');
  14017. Add(' constructor Create;');
  14018. Add(' function GetSize: longint;');
  14019. Add(' procedure SetSize(Value: longint);');
  14020. Add(' property Int: longint read FInt write FInt;');
  14021. Add(' property Size: longint read GetSize write SetSize;');
  14022. Add(' end;');
  14023. Add('constructor TObject.Create; begin end;');
  14024. Add('function TObject.GetSize: longint; begin; end;');
  14025. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  14026. Add('var');
  14027. Add(' Obj: tobject;');
  14028. Add(' i: longint;');
  14029. Add('begin');
  14030. Add(' with TObject.Create do begin');
  14031. Add(' i:=int;');
  14032. Add(' int:=i;');
  14033. Add(' i:=size;');
  14034. Add(' size:=i;');
  14035. Add(' end;');
  14036. Add(' with obj do begin');
  14037. Add(' i:=int;');
  14038. Add(' int:=i;');
  14039. Add(' i:=size;');
  14040. Add(' size:=i;');
  14041. Add(' end;');
  14042. ConvertProgram;
  14043. CheckSource('TestClass_WithClassInstDoProperty',
  14044. LinesToStr([ // statements
  14045. 'rtl.createClass(this, "TObject", null, function () {',
  14046. ' this.$init = function () {',
  14047. ' this.FInt = 0;',
  14048. ' };',
  14049. ' this.$final = function () {',
  14050. ' };',
  14051. ' this.Create = function () {',
  14052. ' return this;',
  14053. ' };',
  14054. ' this.GetSize = function () {',
  14055. ' var Result = 0;',
  14056. ' return Result;',
  14057. ' };',
  14058. ' this.SetSize = function (Value) {',
  14059. ' };',
  14060. '});',
  14061. 'this.Obj = null;',
  14062. 'this.i = 0;'
  14063. ]),
  14064. LinesToStr([ // $mod.$main
  14065. 'var $with = $mod.TObject.$create("Create");',
  14066. '$mod.i = $with.FInt;',
  14067. '$with.FInt = $mod.i;',
  14068. '$mod.i = $with.GetSize();',
  14069. '$with.SetSize($mod.i);',
  14070. 'var $with1 = $mod.Obj;',
  14071. '$mod.i = $with1.FInt;',
  14072. '$with1.FInt = $mod.i;',
  14073. '$mod.i = $with1.GetSize();',
  14074. '$with1.SetSize($mod.i);',
  14075. '']));
  14076. end;
  14077. procedure TTestModule.TestClass_WithClassInstDoPropertyWithParams;
  14078. begin
  14079. StartProgram(false);
  14080. Add('type');
  14081. Add(' TObject = class');
  14082. Add(' constructor Create;');
  14083. Add(' function GetItems(Index: longint): longint;');
  14084. Add(' procedure SetItems(Index, Value: longint);');
  14085. Add(' property Items[Index: longint]: longint read GetItems write SetItems;');
  14086. Add(' end;');
  14087. Add('constructor TObject.Create; begin end;');
  14088. Add('function tobject.getitems(index: longint): longint; begin; end;');
  14089. Add('procedure tobject.setitems(index, value: longint); begin; end;');
  14090. Add('var');
  14091. Add(' Obj: tobject;');
  14092. Add(' i: longint;');
  14093. Add('begin');
  14094. Add(' with TObject.Create do begin');
  14095. Add(' i:=Items[1];');
  14096. Add(' Items[2]:=i;');
  14097. Add(' end;');
  14098. Add(' with obj do begin');
  14099. Add(' i:=Items[3];');
  14100. Add(' Items[4]:=i;');
  14101. Add(' end;');
  14102. ConvertProgram;
  14103. CheckSource('TestClass_WithClassInstDoPropertyWithParams',
  14104. LinesToStr([ // statements
  14105. 'rtl.createClass(this, "TObject", null, function () {',
  14106. ' this.$init = function () {',
  14107. ' };',
  14108. ' this.$final = function () {',
  14109. ' };',
  14110. ' this.Create = function () {',
  14111. ' return this;',
  14112. ' };',
  14113. ' this.GetItems = function (Index) {',
  14114. ' var Result = 0;',
  14115. ' return Result;',
  14116. ' };',
  14117. ' this.SetItems = function (Index, Value) {',
  14118. ' };',
  14119. '});',
  14120. 'this.Obj = null;',
  14121. 'this.i = 0;'
  14122. ]),
  14123. LinesToStr([ // $mod.$main
  14124. 'var $with = $mod.TObject.$create("Create");',
  14125. '$mod.i = $with.GetItems(1);',
  14126. '$with.SetItems(2, $mod.i);',
  14127. 'var $with1 = $mod.Obj;',
  14128. '$mod.i = $with1.GetItems(3);',
  14129. '$with1.SetItems(4, $mod.i);',
  14130. '']));
  14131. end;
  14132. procedure TTestModule.TestClass_WithClassInstDoFunc;
  14133. begin
  14134. StartProgram(false);
  14135. Add('type');
  14136. Add(' TObject = class');
  14137. Add(' constructor Create;');
  14138. Add(' function GetSize: longint;');
  14139. Add(' procedure SetSize(Value: longint);');
  14140. Add(' end;');
  14141. Add('constructor TObject.Create; begin end;');
  14142. Add('function TObject.GetSize: longint; begin; end;');
  14143. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  14144. Add('var');
  14145. Add(' Obj: tobject;');
  14146. Add(' i: longint;');
  14147. Add('begin');
  14148. Add(' with TObject.Create do begin');
  14149. Add(' i:=GetSize;');
  14150. Add(' i:=GetSize();');
  14151. Add(' SetSize(i);');
  14152. Add(' end;');
  14153. Add(' with obj do begin');
  14154. Add(' i:=GetSize;');
  14155. Add(' i:=GetSize();');
  14156. Add(' SetSize(i);');
  14157. Add(' end;');
  14158. ConvertProgram;
  14159. CheckSource('TestClass_WithClassInstDoFunc',
  14160. LinesToStr([ // statements
  14161. 'rtl.createClass(this, "TObject", null, function () {',
  14162. ' this.$init = function () {',
  14163. ' };',
  14164. ' this.$final = function () {',
  14165. ' };',
  14166. ' this.Create = function () {',
  14167. ' return this;',
  14168. ' };',
  14169. ' this.GetSize = function () {',
  14170. ' var Result = 0;',
  14171. ' return Result;',
  14172. ' };',
  14173. ' this.SetSize = function (Value) {',
  14174. ' };',
  14175. '});',
  14176. 'this.Obj = null;',
  14177. 'this.i = 0;'
  14178. ]),
  14179. LinesToStr([ // $mod.$main
  14180. 'var $with = $mod.TObject.$create("Create");',
  14181. '$mod.i = $with.GetSize();',
  14182. '$mod.i = $with.GetSize();',
  14183. '$with.SetSize($mod.i);',
  14184. 'var $with1 = $mod.Obj;',
  14185. '$mod.i = $with1.GetSize();',
  14186. '$mod.i = $with1.GetSize();',
  14187. '$with1.SetSize($mod.i);',
  14188. '']));
  14189. end;
  14190. procedure TTestModule.TestClass_TypeCast;
  14191. begin
  14192. StartProgram(false);
  14193. Add('type');
  14194. Add(' TObject = class');
  14195. Add(' Next: TObject;');
  14196. Add(' constructor Create;');
  14197. Add(' end;');
  14198. Add(' TControl = class(TObject)');
  14199. Add(' Arr: array of TObject;');
  14200. Add(' function GetIt(vI: longint = 0): TObject;');
  14201. Add(' end;');
  14202. Add('constructor tobject.create; begin end;');
  14203. Add('function tcontrol.getit(vi: longint = 0): tobject; begin end;');
  14204. Add('var');
  14205. Add(' Obj: tobject;');
  14206. Add('begin');
  14207. Add(' obj:=tcontrol(obj).next;');
  14208. Add(' tcontrol(obj):=nil;');
  14209. Add(' obj:=tcontrol(obj);');
  14210. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit);');
  14211. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit());');
  14212. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit(1));');
  14213. Add(' tcontrol(obj):=tcontrol(tcontrol(tcontrol(obj).getit).arr[2]);');
  14214. Add(' obj:=tcontrol(nil);');
  14215. ConvertProgram;
  14216. CheckSource('TestClass_TypeCast',
  14217. LinesToStr([ // statements
  14218. 'rtl.createClass(this, "TObject", null, function () {',
  14219. ' this.$init = function () {',
  14220. ' this.Next = null;',
  14221. ' };',
  14222. ' this.$final = function () {',
  14223. ' this.Next = undefined;',
  14224. ' };',
  14225. ' this.Create = function () {',
  14226. ' return this;',
  14227. ' };',
  14228. '});',
  14229. 'rtl.createClass(this, "TControl", this.TObject, function () {',
  14230. ' this.$init = function () {',
  14231. ' $mod.TObject.$init.call(this);',
  14232. ' this.Arr = [];',
  14233. ' };',
  14234. ' this.$final = function () {',
  14235. ' this.Arr = undefined;',
  14236. ' $mod.TObject.$final.call(this);',
  14237. ' };',
  14238. ' this.GetIt = function (vI) {',
  14239. ' var Result = null;',
  14240. ' return Result;',
  14241. ' };',
  14242. '});',
  14243. 'this.Obj = null;'
  14244. ]),
  14245. LinesToStr([ // $mod.$main
  14246. '$mod.Obj = $mod.Obj.Next;',
  14247. '$mod.Obj = null;',
  14248. '$mod.Obj = $mod.Obj;',
  14249. '$mod.Obj = $mod.Obj.GetIt(0);',
  14250. '$mod.Obj = $mod.Obj.GetIt(0);',
  14251. '$mod.Obj = $mod.Obj.GetIt(1);',
  14252. '$mod.Obj = $mod.Obj.GetIt(0).Arr[2];',
  14253. '$mod.Obj = null;',
  14254. '']));
  14255. end;
  14256. procedure TTestModule.TestClass_TypeCastUntypedParam;
  14257. begin
  14258. StartProgram(false);
  14259. Add('type');
  14260. Add(' TObject = class end;');
  14261. Add('procedure ProcA(var A);');
  14262. Add('begin');
  14263. Add(' TObject(A):=nil;');
  14264. Add(' TObject(A):=TObject(A);');
  14265. Add(' if TObject(A)=nil then ;');
  14266. Add(' if nil=TObject(A) then ;');
  14267. Add('end;');
  14268. Add('procedure ProcB(out A);');
  14269. Add('begin');
  14270. Add(' TObject(A):=nil;');
  14271. Add(' TObject(A):=TObject(A);');
  14272. Add(' if TObject(A)=nil then ;');
  14273. Add(' if nil=TObject(A) then ;');
  14274. Add('end;');
  14275. Add('procedure ProcC(const A);');
  14276. Add('begin');
  14277. Add(' if TObject(A)=nil then ;');
  14278. Add(' if nil=TObject(A) then ;');
  14279. Add('end;');
  14280. Add('var o: TObject;');
  14281. Add('begin');
  14282. Add(' ProcA(o);');
  14283. Add(' ProcB(o);');
  14284. Add(' ProcC(o);');
  14285. ConvertProgram;
  14286. CheckSource('TestClass_TypeCastUntypedParam',
  14287. LinesToStr([ // statements
  14288. 'rtl.createClass(this, "TObject", null, function () {',
  14289. ' this.$init = function () {',
  14290. ' };',
  14291. ' this.$final = function () {',
  14292. ' };',
  14293. '});',
  14294. 'this.ProcA = function (A) {',
  14295. ' A.set(null);',
  14296. ' A.set(A.get());',
  14297. ' if (A.get() === null);',
  14298. ' if (null === A.get());',
  14299. '};',
  14300. 'this.ProcB = function (A) {',
  14301. ' A.set(null);',
  14302. ' A.set(A.get());',
  14303. ' if (A.get() === null);',
  14304. ' if (null === A.get());',
  14305. '};',
  14306. 'this.ProcC = function (A) {',
  14307. ' if (A === null);',
  14308. ' if (null === A);',
  14309. '};',
  14310. 'this.o = null;',
  14311. '']),
  14312. LinesToStr([ // $mod.$main
  14313. '$mod.ProcA({',
  14314. ' p: $mod,',
  14315. ' get: function () {',
  14316. ' return this.p.o;',
  14317. ' },',
  14318. ' set: function (v) {',
  14319. ' this.p.o = v;',
  14320. ' }',
  14321. '});',
  14322. '$mod.ProcB({',
  14323. ' p: $mod,',
  14324. ' get: function () {',
  14325. ' return this.p.o;',
  14326. ' },',
  14327. ' set: function (v) {',
  14328. ' this.p.o = v;',
  14329. ' }',
  14330. '});',
  14331. '$mod.ProcC($mod.o);',
  14332. '']));
  14333. end;
  14334. procedure TTestModule.TestClass_Overloads;
  14335. begin
  14336. StartProgram(false);
  14337. Add('type');
  14338. Add(' TObject = class');
  14339. Add(' procedure DoIt;');
  14340. Add(' procedure DoIt(vI: longint);');
  14341. Add(' end;');
  14342. Add('procedure TObject.DoIt;');
  14343. Add('begin');
  14344. Add(' DoIt;');
  14345. Add(' DoIt(1);');
  14346. Add('end;');
  14347. Add('procedure TObject.DoIt(vI: longint); begin end;');
  14348. Add('begin');
  14349. ConvertProgram;
  14350. CheckSource('TestClass_Overloads',
  14351. LinesToStr([ // statements
  14352. 'rtl.createClass(this, "TObject", null, function () {',
  14353. ' this.$init = function () {',
  14354. ' };',
  14355. ' this.$final = function () {',
  14356. ' };',
  14357. ' this.DoIt = function () {',
  14358. ' this.DoIt();',
  14359. ' this.DoIt$1(1);',
  14360. ' };',
  14361. ' this.DoIt$1 = function (vI) {',
  14362. ' };',
  14363. '});',
  14364. '']),
  14365. LinesToStr([ // $mod.$main
  14366. '']));
  14367. end;
  14368. procedure TTestModule.TestClass_OverloadsAncestor;
  14369. begin
  14370. StartProgram(false);
  14371. Add('type');
  14372. Add(' TObject = class;');
  14373. Add(' TObject = class');
  14374. Add(' procedure DoIt(vA: longint);');
  14375. Add(' procedure DoIt(vA, vB: longint);');
  14376. Add(' end;');
  14377. Add(' TCar = class;');
  14378. Add(' TCar = class');
  14379. Add(' procedure DoIt(vA: longint);');
  14380. Add(' procedure DoIt(vA, vB: longint);');
  14381. Add(' end;');
  14382. Add('procedure tobject.doit(va: longint);');
  14383. Add('begin');
  14384. Add(' doit(1);');
  14385. Add(' doit(1,2);');
  14386. Add('end;');
  14387. Add('procedure tobject.doit(va, vb: longint); begin end;');
  14388. Add('procedure tcar.doit(va: longint);');
  14389. Add('begin');
  14390. Add(' doit(1);');
  14391. Add(' doit(1,2);');
  14392. Add(' inherited doit(1);');
  14393. Add(' inherited doit(1,2);');
  14394. Add('end;');
  14395. Add('procedure tcar.doit(va, vb: longint); begin end;');
  14396. Add('begin');
  14397. ConvertProgram;
  14398. CheckSource('TestClass_OverloadsAncestor',
  14399. LinesToStr([ // statements
  14400. 'rtl.createClass(this, "TObject", null, function () {',
  14401. ' this.$init = function () {',
  14402. ' };',
  14403. ' this.$final = function () {',
  14404. ' };',
  14405. ' this.DoIt = function (vA) {',
  14406. ' this.DoIt(1);',
  14407. ' this.DoIt$1(1,2);',
  14408. ' };',
  14409. ' this.DoIt$1 = function (vA, vB) {',
  14410. ' };',
  14411. '});',
  14412. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  14413. ' this.DoIt$2 = function (vA) {',
  14414. ' this.DoIt$2(1);',
  14415. ' this.DoIt$3(1, 2);',
  14416. ' $mod.TObject.DoIt.call(this, 1);',
  14417. ' $mod.TObject.DoIt$1.call(this, 1, 2);',
  14418. ' };',
  14419. ' this.DoIt$3 = function (vA, vB) {',
  14420. ' };',
  14421. '});',
  14422. '']),
  14423. LinesToStr([ // $mod.$main
  14424. '']));
  14425. end;
  14426. procedure TTestModule.TestClass_OverloadConstructor;
  14427. begin
  14428. StartProgram(false);
  14429. Add('type');
  14430. Add(' TObject = class');
  14431. Add(' constructor Create(vA: longint);');
  14432. Add(' constructor Create(vA, vB: longint);');
  14433. Add(' end;');
  14434. Add(' TCar = class');
  14435. Add(' constructor Create(vA: longint);');
  14436. Add(' constructor Create(vA, vB: longint);');
  14437. Add(' end;');
  14438. Add('constructor tobject.create(va: longint);');
  14439. Add('begin');
  14440. Add(' create(1);');
  14441. Add(' create(1,2);');
  14442. Add('end;');
  14443. Add('constructor tobject.create(va, vb: longint); begin end;');
  14444. Add('constructor tcar.create(va: longint);');
  14445. Add('begin');
  14446. Add(' create(1);');
  14447. Add(' create(1,2);');
  14448. Add(' inherited create(1);');
  14449. Add(' inherited create(1,2);');
  14450. Add('end;');
  14451. Add('constructor tcar.create(va, vb: longint); begin end;');
  14452. Add('begin');
  14453. Add(' tobject.create(1);');
  14454. Add(' tobject.create(1,2);');
  14455. Add(' tcar.create(1);');
  14456. Add(' tcar.create(1,2);');
  14457. ConvertProgram;
  14458. CheckSource('TestClass_OverloadConstructor',
  14459. LinesToStr([ // statements
  14460. 'rtl.createClass(this, "TObject", null, function () {',
  14461. ' this.$init = function () {',
  14462. ' };',
  14463. ' this.$final = function () {',
  14464. ' };',
  14465. ' this.Create = function (vA) {',
  14466. ' this.Create(1);',
  14467. ' this.Create$1(1,2);',
  14468. ' return this;',
  14469. ' };',
  14470. ' this.Create$1 = function (vA, vB) {',
  14471. ' return this;',
  14472. ' };',
  14473. '});',
  14474. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  14475. ' this.Create$2 = function (vA) {',
  14476. ' this.Create$2(1);',
  14477. ' this.Create$3(1, 2);',
  14478. ' $mod.TObject.Create.call(this, 1);',
  14479. ' $mod.TObject.Create$1.call(this, 1, 2);',
  14480. ' return this;',
  14481. ' };',
  14482. ' this.Create$3 = function (vA, vB) {',
  14483. ' return this;',
  14484. ' };',
  14485. '});',
  14486. '']),
  14487. LinesToStr([ // $mod.$main
  14488. '$mod.TObject.$create("Create", [1]);',
  14489. '$mod.TObject.$create("Create$1", [1, 2]);',
  14490. '$mod.TCar.$create("Create$2", [1]);',
  14491. '$mod.TCar.$create("Create$3", [1, 2]);',
  14492. '']));
  14493. end;
  14494. procedure TTestModule.TestClass_OverloadDelphiOverride;
  14495. begin
  14496. StartProgram(false);
  14497. Add([
  14498. '{$mode delphi}',
  14499. 'type',
  14500. ' TObject = class end;',
  14501. ' TBird = class',
  14502. ' function {#a}GetValue: longint; overload; virtual;',
  14503. ' function {#b}GetValue(AValue: longint): longint; overload; virtual;',
  14504. ' end;',
  14505. ' TEagle = class(TBird)',
  14506. ' function {#c}GetValue: longint; overload; override;',
  14507. ' function {#d}GetValue(AValue: longint): longint; overload; override;',
  14508. ' end;',
  14509. 'function TBird.GetValue: longint;',
  14510. 'begin',
  14511. ' if 3={@a}GetValue then ;',
  14512. ' if 4={@b}GetValue(5) then ;',
  14513. 'end;',
  14514. 'function TBird.GetValue(AValue: longint): longint;',
  14515. 'begin',
  14516. 'end;',
  14517. 'function TEagle.GetValue: longint;',
  14518. 'begin',
  14519. ' if 13={@c}GetValue then ;',
  14520. ' if 14={@d}GetValue(15) then ;',
  14521. ' if 15=inherited {@a}GetValue then ;',
  14522. ' if 16=inherited {@b}GetValue(17) then ;',
  14523. 'end;',
  14524. 'function TEagle.GetValue(AValue: longint): longint;',
  14525. 'begin',
  14526. 'end;',
  14527. 'var',
  14528. ' e: TEagle;',
  14529. 'begin',
  14530. ' if 23=e.{@c}GetValue then ;',
  14531. ' if 24=e.{@d}GetValue(25) then ;']);
  14532. ConvertProgram;
  14533. CheckSource('TestClass_OverloadDelphiOverride',
  14534. LinesToStr([ // statements
  14535. 'rtl.createClass(this, "TObject", null, function () {',
  14536. ' this.$init = function () {',
  14537. ' };',
  14538. ' this.$final = function () {',
  14539. ' };',
  14540. '});',
  14541. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  14542. ' this.GetValue = function () {',
  14543. ' var Result = 0;',
  14544. ' if (3 === this.GetValue()) ;',
  14545. ' if (4 === this.GetValue$1(5)) ;',
  14546. ' return Result;',
  14547. ' };',
  14548. ' this.GetValue$1 = function (AValue) {',
  14549. ' var Result = 0;',
  14550. ' return Result;',
  14551. ' };',
  14552. '});',
  14553. 'rtl.createClass(this, "TEagle", this.TBird, function () {',
  14554. ' this.GetValue = function () {',
  14555. ' var Result = 0;',
  14556. ' if (13 === this.GetValue()) ;',
  14557. ' if (14 === this.GetValue$1(15)) ;',
  14558. ' if (15 === $mod.TBird.GetValue.call(this)) ;',
  14559. ' if (16 === $mod.TBird.GetValue$1.call(this, 17)) ;',
  14560. ' return Result;',
  14561. ' };',
  14562. ' this.GetValue$1 = function (AValue) {',
  14563. ' var Result = 0;',
  14564. ' return Result;',
  14565. ' };',
  14566. '});',
  14567. 'this.e = null;',
  14568. '']),
  14569. LinesToStr([ // $mod.$main
  14570. 'if (23 === $mod.e.GetValue()) ;',
  14571. 'if (24 === $mod.e.GetValue$1(25)) ;',
  14572. '']));
  14573. end;
  14574. procedure TTestModule.TestClass_ReintroduceVarDelphi;
  14575. begin
  14576. StartProgram(false);
  14577. Add([
  14578. '{$mode delphi}',
  14579. 'type',
  14580. ' TObject = class end;',
  14581. ' TAnimal = class',
  14582. ' public',
  14583. ' {#animal_a}A: longint;',
  14584. ' function {#animal_b}B: longint;',
  14585. ' end;',
  14586. ' TBird = class(TAnimal)',
  14587. ' public',
  14588. ' {#bird_a}A: double;',
  14589. ' {#bird_b}B: boolean;',
  14590. ' end;',
  14591. ' TEagle = class(TBird)',
  14592. ' public',
  14593. ' function {#eagle_a}A: boolean;',
  14594. ' {#eagle_b}B: double;',
  14595. ' end;',
  14596. 'function TAnimal.B: longint;',
  14597. 'begin',
  14598. 'end;',
  14599. 'function TEagle.A: boolean;',
  14600. 'begin',
  14601. ' {@eagle_b}B:=3.3;',
  14602. ' {@eagle_a}A();',
  14603. ' TBird(Self).{@bird_b}B:=true;',
  14604. ' TAnimal(Self).{@animal_a}A:=17;',
  14605. ' inherited {@bird_b}B:=inherited {bird_a}A>1;', // Delphi allows only inherited <functionname>
  14606. 'end;',
  14607. 'var',
  14608. ' e: TEagle;',
  14609. 'begin',
  14610. ' e.{@eagle_b}B:=5.3;',
  14611. ' if e.{@eagle_a}A then ;',
  14612. '']);
  14613. ConvertProgram;
  14614. CheckSource('TestClass_ReintroduceVarDelphi',
  14615. LinesToStr([ // statements
  14616. 'rtl.createClass(this, "TObject", null, function () {',
  14617. ' this.$init = function () {',
  14618. ' };',
  14619. ' this.$final = function () {',
  14620. ' };',
  14621. '});',
  14622. 'rtl.createClass(this, "TAnimal", this.TObject, function () {',
  14623. ' this.$init = function () {',
  14624. ' $mod.TObject.$init.call(this);',
  14625. ' this.A = 0;',
  14626. ' };',
  14627. ' this.B = function () {',
  14628. ' var Result = 0;',
  14629. ' return Result;',
  14630. ' };',
  14631. '});',
  14632. 'rtl.createClass(this, "TBird", this.TAnimal, function () {',
  14633. ' this.$init = function () {',
  14634. ' $mod.TAnimal.$init.call(this);',
  14635. ' this.A$1 = 0.0;',
  14636. ' this.B$1 = false;',
  14637. ' };',
  14638. '});',
  14639. 'rtl.createClass(this, "TEagle", this.TBird, function () {',
  14640. ' this.$init = function () {',
  14641. ' $mod.TBird.$init.call(this);',
  14642. ' this.B$2 = 0.0;',
  14643. ' };',
  14644. ' this.A$2 = function () {',
  14645. ' var Result = false;',
  14646. ' this.B$2 = 3.3;',
  14647. ' this.A$2();',
  14648. ' this.B$1 = true;',
  14649. ' this.A = 17;',
  14650. ' this.B$1 = this.A$1 > 1;',
  14651. ' return Result;',
  14652. ' };',
  14653. '});',
  14654. 'this.e = null;',
  14655. '']),
  14656. LinesToStr([ // $mod.$main
  14657. '$mod.e.B$2 = 5.3;',
  14658. 'if ($mod.e.A$2()) ;',
  14659. '']));
  14660. end;
  14661. procedure TTestModule.TestClass_ReintroducedVar;
  14662. begin
  14663. StartProgram(false);
  14664. Add('type');
  14665. Add(' TObject = class');
  14666. Add(' strict private');
  14667. Add(' Some: longint;');
  14668. Add(' end;');
  14669. Add(' TMobile = class');
  14670. Add(' strict private');
  14671. Add(' Some: string;');
  14672. Add(' end;');
  14673. Add(' TCar = class(tmobile)');
  14674. Add(' procedure Some;');
  14675. Add(' procedure Some(vA: longint);');
  14676. Add(' end;');
  14677. Add('procedure tcar.some;');
  14678. Add('begin');
  14679. Add(' Some;');
  14680. Add(' Some(1);');
  14681. Add('end;');
  14682. Add('procedure tcar.some(va: longint); begin end;');
  14683. Add('begin');
  14684. ConvertProgram;
  14685. CheckSource('TestClass_ReintroducedVar',
  14686. LinesToStr([ // statements
  14687. 'rtl.createClass(this, "TObject", null, function () {',
  14688. ' this.$init = function () {',
  14689. ' this.Some = 0;',
  14690. ' };',
  14691. ' this.$final = function () {',
  14692. ' };',
  14693. '});',
  14694. 'rtl.createClass(this, "TMobile", this.TObject, function () {',
  14695. ' this.$init = function () {',
  14696. ' $mod.TObject.$init.call(this);',
  14697. ' this.Some$1 = "";',
  14698. ' };',
  14699. '});',
  14700. 'rtl.createClass(this, "TCar", this.TMobile, function () {',
  14701. ' this.Some$2 = function () {',
  14702. ' this.Some$2();',
  14703. ' this.Some$3(1);',
  14704. ' };',
  14705. ' this.Some$3 = function (vA) {',
  14706. ' };',
  14707. '});',
  14708. '']),
  14709. LinesToStr([ // $mod.$main
  14710. '']));
  14711. end;
  14712. procedure TTestModule.TestClass_RaiseDescendant;
  14713. begin
  14714. StartProgram(false);
  14715. Add([
  14716. 'type',
  14717. ' TObject = class',
  14718. ' constructor Create(Msg: string);',
  14719. ' end;',
  14720. ' Exception = class',
  14721. ' end;',
  14722. ' EConvertError = class(Exception)',
  14723. ' end;',
  14724. 'constructor TObject.Create(Msg: string); begin end;',
  14725. 'function AssertConv(Msg: string = ''def''): EConvertError; begin end;',
  14726. 'begin',
  14727. ' raise Exception.Create(''Bar1'');',
  14728. ' raise EConvertError.Create(''Bar2'');',
  14729. ' raise AssertConv(''Bar2'');',
  14730. ' raise AssertConv;',
  14731. '']);
  14732. ConvertProgram;
  14733. CheckSource('TestClass_RaiseDescendant',
  14734. LinesToStr([ // statements
  14735. 'rtl.createClass(this, "TObject", null, function () {',
  14736. ' this.$init = function () {',
  14737. ' };',
  14738. ' this.$final = function () {',
  14739. ' };',
  14740. ' this.Create = function (Msg) {',
  14741. ' return this;',
  14742. ' };',
  14743. '});',
  14744. 'rtl.createClass(this, "Exception", this.TObject, function () {',
  14745. '});',
  14746. 'rtl.createClass(this, "EConvertError", this.Exception, function () {',
  14747. '});',
  14748. 'this.AssertConv = function (Msg) {',
  14749. ' var Result = null;',
  14750. ' return Result;',
  14751. '};',
  14752. '']),
  14753. LinesToStr([ // $mod.$main
  14754. 'throw $mod.Exception.$create("Create",["Bar1"]);',
  14755. 'throw $mod.EConvertError.$create("Create",["Bar2"]);',
  14756. 'throw $mod.AssertConv("Bar2");',
  14757. 'throw $mod.AssertConv("def");',
  14758. '']));
  14759. end;
  14760. procedure TTestModule.TestClass_ExternalMethod;
  14761. begin
  14762. AddModuleWithIntfImplSrc('unit2.pas',
  14763. LinesToStr([
  14764. 'type',
  14765. ' TObject = class',
  14766. ' public',
  14767. ' procedure Intern; external name ''$DoIntern'';',
  14768. ' end;',
  14769. '']),
  14770. LinesToStr([
  14771. '']));
  14772. StartUnit(true);
  14773. Add('interface');
  14774. Add('uses unit2;');
  14775. Add('type');
  14776. Add(' TCar = class(TObject)');
  14777. Add(' public');
  14778. Add(' procedure Intern2; external name ''$DoIntern2'';');
  14779. Add(' procedure DoIt;');
  14780. Add(' end;');
  14781. Add('implementation');
  14782. Add('procedure tcar.doit;');
  14783. Add('begin');
  14784. Add(' Intern;');
  14785. Add(' Intern();');
  14786. Add(' Intern2;');
  14787. Add(' Intern2();');
  14788. Add('end;');
  14789. Add('var Obj: TCar;');
  14790. Add('begin');
  14791. Add(' obj.intern;');
  14792. Add(' obj.intern();');
  14793. Add(' obj.intern2;');
  14794. Add(' obj.intern2();');
  14795. Add(' obj.doit;');
  14796. Add(' obj.doit();');
  14797. Add(' with obj do begin');
  14798. Add(' Intern;');
  14799. Add(' Intern();');
  14800. Add(' Intern2;');
  14801. Add(' Intern2();');
  14802. Add(' end;');
  14803. ConvertUnit;
  14804. CheckSource('TestClass_ExternalMethod',
  14805. LinesToStr([
  14806. 'var $impl = $mod.$impl;',
  14807. 'rtl.createClass(this, "TCar", pas.unit2.TObject, function () {',
  14808. ' this.DoIt = function () {',
  14809. ' this.$DoIntern();',
  14810. ' this.$DoIntern();',
  14811. ' this.$DoIntern2();',
  14812. ' this.$DoIntern2();',
  14813. ' };',
  14814. ' });',
  14815. '']),
  14816. LinesToStr([ // this.$init
  14817. '$impl.Obj.$DoIntern();',
  14818. '$impl.Obj.$DoIntern();',
  14819. '$impl.Obj.$DoIntern2();',
  14820. '$impl.Obj.$DoIntern2();',
  14821. '$impl.Obj.DoIt();',
  14822. '$impl.Obj.DoIt();',
  14823. 'var $with = $impl.Obj;',
  14824. '$with.$DoIntern();',
  14825. '$with.$DoIntern();',
  14826. '$with.$DoIntern2();',
  14827. '$with.$DoIntern2();',
  14828. '']),
  14829. LinesToStr([ // implementation
  14830. '$impl.Obj = null;',
  14831. '']) );
  14832. end;
  14833. procedure TTestModule.TestClass_ExternalVirtualNameMismatchFail;
  14834. begin
  14835. StartProgram(false);
  14836. Add('type');
  14837. Add(' TObject = class');
  14838. Add(' procedure DoIt; virtual; external name ''Foo'';');
  14839. Add(' end;');
  14840. Add('begin');
  14841. SetExpectedPasResolverError('Virtual method name must match external',
  14842. nVirtualMethodNameMustMatchExternal);
  14843. ConvertProgram;
  14844. end;
  14845. procedure TTestModule.TestClass_ExternalOverrideFail;
  14846. begin
  14847. StartProgram(false);
  14848. Add('type');
  14849. Add(' TObject = class');
  14850. Add(' procedure DoIt; virtual; external name ''DoIt'';');
  14851. Add(' end;');
  14852. Add(' TCar = class');
  14853. Add(' procedure DoIt; override; external name ''DoIt'';');
  14854. Add(' end;');
  14855. Add('begin');
  14856. SetExpectedPasResolverError('Invalid procedure modifier override,external',
  14857. nInvalidXModifierY);
  14858. ConvertProgram;
  14859. end;
  14860. procedure TTestModule.TestClass_ExternalVar;
  14861. begin
  14862. AddModuleWithIntfImplSrc('unit2.pas',
  14863. LinesToStr([
  14864. '{$modeswitch externalclass}',
  14865. 'type',
  14866. ' TObject = class',
  14867. ' public',
  14868. ' Intern: longint external name ''$Intern'';',
  14869. ' Bracket: longint external name ''["A B"]'';',
  14870. ' end;',
  14871. '']),
  14872. LinesToStr([
  14873. '']));
  14874. StartUnit(true);
  14875. Add([
  14876. 'interface',
  14877. 'uses unit2;',
  14878. '{$modeswitch externalclass}',
  14879. 'type',
  14880. ' TCar = class(tobject)',
  14881. ' public',
  14882. ' Intern2: longint external name ''$Intern2'';',
  14883. ' procedure DoIt;',
  14884. ' end;',
  14885. 'implementation',
  14886. 'procedure tcar.doit;',
  14887. 'begin',
  14888. ' Intern:=Intern+1;',
  14889. ' Intern2:=Intern2+2;',
  14890. ' Bracket:=Bracket+3;',
  14891. 'end;',
  14892. 'var Obj: TCar;',
  14893. 'begin',
  14894. ' obj.intern:=obj.intern+1;',
  14895. ' obj.intern2:=obj.intern2+2;',
  14896. ' obj.Bracket:=obj.Bracket+3;',
  14897. ' with obj do begin',
  14898. ' intern:=intern+1;',
  14899. ' intern2:=intern2+2;',
  14900. ' Bracket:=Bracket+3;',
  14901. ' end;']);
  14902. ConvertUnit;
  14903. CheckSource('TestClass_ExternalVar',
  14904. LinesToStr([
  14905. 'var $impl = $mod.$impl;',
  14906. 'rtl.createClass(this, "TCar", pas.unit2.TObject, function () {',
  14907. ' this.DoIt = function () {',
  14908. ' this.$Intern = this.$Intern + 1;',
  14909. ' this.$Intern2 = this.$Intern2 + 2;',
  14910. ' this["A B"] = this["A B"] + 3;',
  14911. ' };',
  14912. ' });',
  14913. '']),
  14914. LinesToStr([
  14915. '$impl.Obj.$Intern = $impl.Obj.$Intern + 1;',
  14916. '$impl.Obj.$Intern2 = $impl.Obj.$Intern2 + 2;',
  14917. '$impl.Obj["A B"] = $impl.Obj["A B"] + 3;',
  14918. 'var $with = $impl.Obj;',
  14919. '$with.$Intern = $with.$Intern + 1;',
  14920. '$with.$Intern2 = $with.$Intern2 + 2;',
  14921. '$with["A B"] = $with["A B"] + 3;',
  14922. '']),
  14923. LinesToStr([ // implementation
  14924. '$impl.Obj = null;',
  14925. '']));
  14926. end;
  14927. procedure TTestModule.TestClass_Const;
  14928. begin
  14929. StartProgram(false);
  14930. Add([
  14931. 'type',
  14932. ' integer = longint;',
  14933. ' TClass = class of TObject;',
  14934. ' TObject = class',
  14935. ' public',
  14936. ' const cI: integer = 3;',
  14937. ' procedure DoIt;',
  14938. ' class procedure DoMore;',
  14939. ' end;',
  14940. 'procedure tobject.doit;',
  14941. 'begin',
  14942. ' if cI=4 then;',
  14943. ' if 5=cI then;',
  14944. ' if Self.cI=6 then;',
  14945. ' if 7=Self.cI then;',
  14946. ' with Self do begin',
  14947. ' if cI=11 then;',
  14948. ' if 12=cI then;',
  14949. ' end;',
  14950. 'end;',
  14951. 'class procedure tobject.domore;',
  14952. 'begin',
  14953. ' if cI=8 then;',
  14954. ' if Self.cI=9 then;',
  14955. ' if 10=cI then;',
  14956. ' if 11=Self.cI then;',
  14957. ' with Self do begin',
  14958. ' if cI=13 then;',
  14959. ' if 14=cI then;',
  14960. ' end;',
  14961. 'end;',
  14962. 'var',
  14963. ' Obj: TObject;',
  14964. ' Cla: TClass;',
  14965. 'begin',
  14966. ' if TObject.cI=21 then ;',
  14967. ' if Obj.cI=22 then ;',
  14968. ' if Cla.cI=23 then ;',
  14969. ' with obj do if ci=24 then;',
  14970. ' with TObject do if ci=25 then;',
  14971. ' with Cla do if ci=26 then;']);
  14972. ConvertProgram;
  14973. CheckSource('TestClass_Const',
  14974. LinesToStr([
  14975. 'rtl.createClass(this, "TObject", null, function () {',
  14976. ' this.cI = 3;',
  14977. ' this.$init = function () {',
  14978. ' };',
  14979. ' this.$final = function () {',
  14980. ' };',
  14981. ' this.DoIt = function () {',
  14982. ' if (this.cI === 4) ;',
  14983. ' if (5 === this.cI) ;',
  14984. ' if (this.cI === 6) ;',
  14985. ' if (7 === this.cI) ;',
  14986. ' if (this.cI === 11) ;',
  14987. ' if (12 === this.cI) ;',
  14988. ' };',
  14989. ' this.DoMore = function () {',
  14990. ' if (this.cI === 8) ;',
  14991. ' if (this.cI === 9) ;',
  14992. ' if (10 === this.cI) ;',
  14993. ' if (11 === this.cI) ;',
  14994. ' if (this.cI === 13) ;',
  14995. ' if (14 === this.cI) ;',
  14996. ' };',
  14997. '});',
  14998. 'this.Obj = null;',
  14999. 'this.Cla = null;',
  15000. '']),
  15001. LinesToStr([
  15002. 'if ($mod.TObject.cI === 21) ;',
  15003. 'if ($mod.Obj.cI === 22) ;',
  15004. 'if ($mod.Cla.cI === 23) ;',
  15005. 'var $with = $mod.Obj;',
  15006. 'if ($with.cI === 24) ;',
  15007. 'var $with1 = $mod.TObject;',
  15008. 'if ($with1.cI === 25) ;',
  15009. 'var $with2 = $mod.Cla;',
  15010. 'if ($with2.cI === 26) ;',
  15011. '']));
  15012. end;
  15013. procedure TTestModule.TestClass_ConstEnum;
  15014. begin
  15015. StartProgram(false);
  15016. Add([
  15017. 'type',
  15018. ' TEnum = (red,blue);',
  15019. ' TObject = class',
  15020. ' end;',
  15021. ' TAnimal = class',
  15022. ' public',
  15023. ' type TSubEnum = (light,dark);',
  15024. ' const a = high(TEnum);',
  15025. ' const b = high(TSubEnum);',
  15026. ' end;',
  15027. ' TBird = class(TAnimal)',
  15028. ' public',
  15029. ' const c = high(TEnum);',
  15030. ' const d = high(TSubEnum);',
  15031. ' end;',
  15032. ' TAnt = class',
  15033. ' public',
  15034. ' const e = high(TEnum);',
  15035. ' const f = high(TBird.TSubEnum);',
  15036. ' end;',
  15037. 'begin',
  15038. '']);
  15039. ConvertProgram;
  15040. CheckSource('TestClass_ConstEnum',
  15041. LinesToStr([
  15042. 'this.TEnum = {',
  15043. ' "0": "red",',
  15044. ' red: 0,',
  15045. ' "1": "blue",',
  15046. ' blue: 1',
  15047. '};',
  15048. 'rtl.createClass(this, "TObject", null, function () {',
  15049. ' this.$init = function () {',
  15050. ' };',
  15051. ' this.$final = function () {',
  15052. ' };',
  15053. '});',
  15054. 'rtl.createClass(this, "TAnimal", this.TObject, function () {',
  15055. ' this.TSubEnum = {',
  15056. ' "0": "light",',
  15057. ' light: 0,',
  15058. ' "1": "dark",',
  15059. ' dark: 1',
  15060. ' };',
  15061. ' this.a = $mod.TEnum.blue;',
  15062. ' this.b = this.TSubEnum.dark;',
  15063. '});',
  15064. 'rtl.createClass(this, "TBird", this.TAnimal, function () {',
  15065. ' this.c = $mod.TEnum.blue;',
  15066. ' this.d = this.TSubEnum.dark;',
  15067. '});',
  15068. 'rtl.createClass(this, "TAnt", this.TObject, function () {',
  15069. ' this.e = $mod.TEnum.blue;',
  15070. ' this.f = $mod.TAnimal.TSubEnum.dark;',
  15071. '});',
  15072. '']),
  15073. LinesToStr([
  15074. '']));
  15075. end;
  15076. procedure TTestModule.TestClass_LocalConstDuplicate_Prg;
  15077. begin
  15078. StartProgram(false);
  15079. Add([
  15080. 'type',
  15081. ' TObject = class',
  15082. ' const cI: longint = 3;',
  15083. ' procedure Fly;',
  15084. ' procedure Run;',
  15085. ' end;',
  15086. ' TBird = class',
  15087. ' procedure Go;',
  15088. ' end;',
  15089. 'procedure tobject.fly;',
  15090. 'const cI: word = 4;',
  15091. 'begin',
  15092. ' if cI=Self.cI then ;',
  15093. 'end;',
  15094. 'procedure tobject.run;',
  15095. 'const cI: word = 5;',
  15096. 'begin',
  15097. ' if cI=Self.cI then ;',
  15098. 'end;',
  15099. 'procedure tbird.go;',
  15100. 'const cI: word = 6;',
  15101. 'begin',
  15102. ' if cI=Self.cI then ;',
  15103. 'end;',
  15104. 'begin',
  15105. '']);
  15106. ConvertProgram;
  15107. CheckSource('TestClass_LocalConstDuplicate_Prg',
  15108. LinesToStr([
  15109. 'rtl.createClass(this, "TObject", null, function () {',
  15110. ' this.cI = 3;',
  15111. ' this.$init = function () {',
  15112. ' };',
  15113. ' this.$final = function () {',
  15114. ' };',
  15115. ' var cI$1 = 4;',
  15116. ' this.Fly = function () {',
  15117. ' if (cI$1 === this.cI) ;',
  15118. ' };',
  15119. ' var cI$2 = 5;',
  15120. ' this.Run = function () {',
  15121. ' if (cI$2 === this.cI) ;',
  15122. ' };',
  15123. '});',
  15124. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  15125. ' var cI$3 = 6;',
  15126. ' this.Go = function () {',
  15127. ' if (cI$3 === this.cI) ;',
  15128. ' };',
  15129. '});',
  15130. '']),
  15131. LinesToStr([
  15132. '']));
  15133. end;
  15134. procedure TTestModule.TestClass_LocalConstDuplicate_Unit;
  15135. begin
  15136. StartUnit(false);
  15137. Add([
  15138. 'interface',
  15139. 'type',
  15140. ' TObject = class',
  15141. ' const cI: longint = 3;',
  15142. ' procedure Fly;',
  15143. ' procedure Run;',
  15144. ' end;',
  15145. ' TBird = class',
  15146. ' procedure Go;',
  15147. ' end;',
  15148. 'implementation',
  15149. 'procedure tobject.fly;',
  15150. 'const cI: word = 4;',
  15151. 'begin',
  15152. ' if cI=Self.cI then ;',
  15153. 'end;',
  15154. 'procedure tobject.run;',
  15155. 'const cI: word = 5;',
  15156. 'begin',
  15157. ' if cI=Self.cI then ;',
  15158. 'end;',
  15159. 'procedure tbird.go;',
  15160. 'const cI: word = 6;',
  15161. 'begin',
  15162. ' if cI=Self.cI then ;',
  15163. 'end;',
  15164. '']);
  15165. ConvertUnit;
  15166. CheckSource('TestClass_LocalConstDuplicate_Unit',
  15167. LinesToStr([
  15168. 'rtl.createClass(this, "TObject", null, function () {',
  15169. ' this.cI = 3;',
  15170. ' this.$init = function () {',
  15171. ' };',
  15172. ' this.$final = function () {',
  15173. ' };',
  15174. ' var cI$1 = 4;',
  15175. ' this.Fly = function () {',
  15176. ' if (cI$1 === this.cI) ;',
  15177. ' };',
  15178. ' var cI$2 = 5;',
  15179. ' this.Run = function () {',
  15180. ' if (cI$2 === this.cI) ;',
  15181. ' };',
  15182. '});',
  15183. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  15184. ' var cI$3 = 6;',
  15185. ' this.Go = function () {',
  15186. ' if (cI$3 === this.cI) ;',
  15187. ' };',
  15188. '});',
  15189. '']),
  15190. '',
  15191. '');
  15192. end;
  15193. procedure TTestModule.TestClass_LocalVarSelfFail;
  15194. begin
  15195. StartProgram(false);
  15196. Add([
  15197. 'type',
  15198. ' TObject = class',
  15199. ' constructor Create;',
  15200. ' end;',
  15201. 'constructor tobject.create;',
  15202. 'var self: longint;',
  15203. 'begin',
  15204. 'end',
  15205. 'begin',
  15206. '']);
  15207. SetExpectedPasResolverError('Duplicate identifier "self" at (0)',nDuplicateIdentifier);
  15208. ConvertProgram;
  15209. end;
  15210. procedure TTestModule.TestClass_ArgSelfFail;
  15211. begin
  15212. StartProgram(false);
  15213. Add([
  15214. 'type',
  15215. ' TObject = class',
  15216. ' procedure DoIt(Self: longint);',
  15217. ' end;',
  15218. 'procedure tobject.doit(self: longint);',
  15219. 'begin',
  15220. 'end',
  15221. 'begin',
  15222. '']);
  15223. SetExpectedPasResolverError('Duplicate identifier "Self" at test1.pp(5,24)',nDuplicateIdentifier);
  15224. ConvertProgram;
  15225. end;
  15226. procedure TTestModule.TestClass_NestedProcSelf;
  15227. begin
  15228. StartProgram(false);
  15229. Add([
  15230. 'type',
  15231. ' TObject = class',
  15232. ' Key: longint;',
  15233. ' class var State: longint;',
  15234. ' procedure DoIt;',
  15235. ' function GetSize: longint; virtual; abstract;',
  15236. ' procedure SetSize(Value: longint); virtual; abstract;',
  15237. ' property Size: longint read GetSize write SetSize;',
  15238. ' end;',
  15239. 'procedure tobject.doit;',
  15240. ' procedure Sub;',
  15241. ' begin',
  15242. ' key:=key+2;',
  15243. ' self.key:=self.key+3;',
  15244. ' state:=state+4;',
  15245. ' self.state:=self.state+5;',
  15246. ' tobject.state:=tobject.state+6;',
  15247. ' size:=size+7;',
  15248. ' self.size:=self.size+8;',
  15249. ' end;',
  15250. 'begin',
  15251. ' sub;',
  15252. ' key:=key+12;',
  15253. ' self.key:=self.key+13;',
  15254. ' state:=state+14;',
  15255. ' self.state:=self.state+15;',
  15256. ' tobject.state:=tobject.state+16;',
  15257. ' size:=size+17;',
  15258. ' self.size:=self.size+18;',
  15259. 'end;',
  15260. 'begin',
  15261. '']);
  15262. ConvertProgram;
  15263. CheckSource('TestClass_NestedProcSelf',
  15264. LinesToStr([ // statements
  15265. 'rtl.createClass(this, "TObject", null, function () {',
  15266. ' this.State = 0;',
  15267. ' this.$init = function () {',
  15268. ' this.Key = 0;',
  15269. ' };',
  15270. ' this.$final = function () {',
  15271. ' };',
  15272. ' this.DoIt = function () {',
  15273. ' var $Self = this;',
  15274. ' function Sub() {',
  15275. ' $Self.Key = $Self.Key + 2;',
  15276. ' $Self.Key = $Self.Key + 3;',
  15277. ' $mod.TObject.State = $Self.State + 4;',
  15278. ' $mod.TObject.State = $Self.State + 5;',
  15279. ' $mod.TObject.State = $mod.TObject.State + 6;',
  15280. ' $Self.SetSize($Self.GetSize() + 7);',
  15281. ' $Self.SetSize($Self.GetSize() + 8);',
  15282. ' };',
  15283. ' Sub();',
  15284. ' this.Key = this.Key + 12;',
  15285. ' $Self.Key = $Self.Key + 13;',
  15286. ' $mod.TObject.State = this.State + 14;',
  15287. ' $mod.TObject.State = $Self.State + 15;',
  15288. ' $mod.TObject.State = $mod.TObject.State + 16;',
  15289. ' this.SetSize(this.GetSize() + 17);',
  15290. ' $Self.SetSize($Self.GetSize() + 18);',
  15291. ' };',
  15292. '});',
  15293. '']),
  15294. LinesToStr([ // $mod.$main
  15295. '']));
  15296. end;
  15297. procedure TTestModule.TestClass_NestedProcSelf2;
  15298. begin
  15299. StartProgram(false);
  15300. Add([
  15301. 'type',
  15302. ' TObject = class',
  15303. ' Key: longint;',
  15304. ' class var State: longint;',
  15305. ' function GetSize: longint; virtual; abstract;',
  15306. ' procedure SetSize(Value: longint); virtual; abstract;',
  15307. ' property Size: longint read GetSize write SetSize;',
  15308. ' end;',
  15309. ' TBird = class',
  15310. ' procedure DoIt;',
  15311. ' end;',
  15312. 'procedure tbird.doit;',
  15313. ' procedure Sub;',
  15314. ' begin',
  15315. ' key:=key+2;',
  15316. ' self.key:=self.key+3;',
  15317. ' state:=state+4;',
  15318. ' self.state:=self.state+5;',
  15319. ' tobject.state:=tobject.state+6;',
  15320. ' size:=size+7;',
  15321. ' self.size:=self.size+8;',
  15322. ' end;',
  15323. 'begin',
  15324. ' sub;',
  15325. ' key:=key+12;',
  15326. ' self.key:=self.key+13;',
  15327. ' state:=state+14;',
  15328. ' self.state:=self.state+15;',
  15329. ' tobject.state:=tobject.state+16;',
  15330. ' size:=size+17;',
  15331. ' self.size:=self.size+18;',
  15332. 'end;',
  15333. 'begin',
  15334. '']);
  15335. ConvertProgram;
  15336. CheckSource('TestClass_NestedProcSelf2',
  15337. LinesToStr([ // statements
  15338. 'rtl.createClass(this, "TObject", null, function () {',
  15339. ' this.State = 0;',
  15340. ' this.$init = function () {',
  15341. ' this.Key = 0;',
  15342. ' };',
  15343. ' this.$final = function () {',
  15344. ' };',
  15345. '});',
  15346. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  15347. ' this.DoIt = function () {',
  15348. ' var $Self = this;',
  15349. ' function Sub() {',
  15350. ' $Self.Key = $Self.Key + 2;',
  15351. ' $Self.Key = $Self.Key + 3;',
  15352. ' $mod.TObject.State = $Self.State + 4;',
  15353. ' $mod.TObject.State = $Self.State + 5;',
  15354. ' $mod.TObject.State = $mod.TObject.State + 6;',
  15355. ' $Self.SetSize($Self.GetSize() + 7);',
  15356. ' $Self.SetSize($Self.GetSize() + 8);',
  15357. ' };',
  15358. ' Sub();',
  15359. ' this.Key = this.Key + 12;',
  15360. ' $Self.Key = $Self.Key + 13;',
  15361. ' $mod.TObject.State = this.State + 14;',
  15362. ' $mod.TObject.State = $Self.State + 15;',
  15363. ' $mod.TObject.State = $mod.TObject.State + 16;',
  15364. ' this.SetSize(this.GetSize() + 17);',
  15365. ' $Self.SetSize($Self.GetSize() + 18);',
  15366. ' };',
  15367. '});',
  15368. '']),
  15369. LinesToStr([ // $mod.$main
  15370. '']));
  15371. end;
  15372. procedure TTestModule.TestClass_NestedProcClassSelf;
  15373. begin
  15374. StartProgram(false);
  15375. Add([
  15376. 'type',
  15377. ' TObject = class',
  15378. ' class var State: longint;',
  15379. ' class procedure DoIt;',
  15380. ' class function GetSize: longint; virtual; abstract;',
  15381. ' class procedure SetSize(Value: longint); virtual; abstract;',
  15382. ' class property Size: longint read GetSize write SetSize;',
  15383. ' end;',
  15384. 'class procedure tobject.doit;',
  15385. ' procedure Sub;',
  15386. ' begin',
  15387. ' state:=state+2;',
  15388. ' self.state:=self.state+3;',
  15389. ' tobject.state:=tobject.state+4;',
  15390. ' size:=size+5;',
  15391. ' self.size:=self.size+6;',
  15392. ' tobject.size:=tobject.size+7;',
  15393. ' end;',
  15394. 'begin',
  15395. ' sub;',
  15396. ' state:=state+12;',
  15397. ' self.state:=self.state+13;',
  15398. ' tobject.state:=tobject.state+14;',
  15399. ' size:=size+15;',
  15400. ' self.size:=self.size+16;',
  15401. ' tobject.size:=tobject.size+17;',
  15402. 'end;',
  15403. 'begin',
  15404. '']);
  15405. ConvertProgram;
  15406. CheckSource('TestClass_NestedProcClassSelf',
  15407. LinesToStr([ // statements
  15408. 'rtl.createClass(this, "TObject", null, function () {',
  15409. ' this.State = 0;',
  15410. ' this.$init = function () {',
  15411. ' };',
  15412. ' this.$final = function () {',
  15413. ' };',
  15414. ' this.DoIt = function () {',
  15415. ' var $Self = this;',
  15416. ' function Sub() {',
  15417. ' $mod.TObject.State = $Self.State + 2;',
  15418. ' $mod.TObject.State = $Self.State + 3;',
  15419. ' $mod.TObject.State = $mod.TObject.State + 4;',
  15420. ' $Self.SetSize($Self.GetSize() + 5);',
  15421. ' $Self.SetSize($Self.GetSize() + 6);',
  15422. ' $mod.TObject.SetSize($mod.TObject.GetSize() + 7);',
  15423. ' };',
  15424. ' Sub();',
  15425. ' $mod.TObject.State = this.State + 12;',
  15426. ' $mod.TObject.State = $Self.State + 13;',
  15427. ' $mod.TObject.State = $mod.TObject.State + 14;',
  15428. ' this.SetSize(this.GetSize() + 15);',
  15429. ' $Self.SetSize($Self.GetSize() + 16);',
  15430. ' $mod.TObject.SetSize($mod.TObject.GetSize() + 17);',
  15431. ' };',
  15432. '});',
  15433. '']),
  15434. LinesToStr([ // $mod.$main
  15435. '']));
  15436. end;
  15437. procedure TTestModule.TestClass_NestedProcCallInherited;
  15438. begin
  15439. StartProgram(false);
  15440. Add([
  15441. 'type',
  15442. ' TObject = class',
  15443. ' function DoIt(k: boolean): longint; virtual;',
  15444. ' end;',
  15445. ' TBird = class',
  15446. ' function DoIt(k: boolean): longint; override;',
  15447. ' end;',
  15448. 'function tobject.doit(k: boolean): longint;',
  15449. 'begin',
  15450. 'end;',
  15451. 'function tbird.doit(k: boolean): longint;',
  15452. ' procedure Sub;',
  15453. ' begin',
  15454. ' inherited DoIt(true);',
  15455. //' if inherited DoIt(false)=4 then ;',
  15456. ' end;',
  15457. 'begin',
  15458. ' Sub;',
  15459. ' inherited;',
  15460. ' inherited DoIt(true);',
  15461. //' if inherited DoIt(false)=14 then ;',
  15462. 'end;',
  15463. 'begin',
  15464. '']);
  15465. ConvertProgram;
  15466. CheckSource('TestClass_NestedProcCallInherited',
  15467. LinesToStr([ // statements
  15468. 'rtl.createClass(this, "TObject", null, function () {',
  15469. ' this.$init = function () {',
  15470. ' };',
  15471. ' this.$final = function () {',
  15472. ' };',
  15473. ' this.DoIt = function (k) {',
  15474. ' var Result = 0;',
  15475. ' return Result;',
  15476. ' };',
  15477. '});',
  15478. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  15479. ' this.DoIt = function (k) {',
  15480. ' var $Self = this;',
  15481. ' var Result = 0;',
  15482. ' function Sub() {',
  15483. ' $mod.TObject.DoIt.call($Self, true);',
  15484. ' };',
  15485. ' Sub();',
  15486. ' $mod.TObject.DoIt.apply(this, arguments);',
  15487. ' $mod.TObject.DoIt.call(this, true);',
  15488. ' return Result;',
  15489. ' };',
  15490. '});',
  15491. '']),
  15492. LinesToStr([ // $mod.$main
  15493. '']));
  15494. end;
  15495. procedure TTestModule.TestClass_TObjectFree;
  15496. begin
  15497. StartProgram(false);
  15498. Add([
  15499. 'type',
  15500. ' TObject = class',
  15501. ' Obj: tobject;',
  15502. ' procedure Free;',
  15503. ' procedure Release;',
  15504. ' end;',
  15505. 'procedure tobject.free;',
  15506. 'begin',
  15507. 'end;',
  15508. 'procedure tobject.release;',
  15509. 'begin',
  15510. ' free;',
  15511. ' if true then free;',
  15512. 'end;',
  15513. 'function DoIt(o: tobject): tobject;',
  15514. 'var l: tobject;',
  15515. 'begin',
  15516. ' o.free;',
  15517. ' o.free();',
  15518. ' l.free;',
  15519. ' l.free();',
  15520. ' o.obj.free;',
  15521. ' o.obj.free();',
  15522. ' with o do obj.free;',
  15523. ' with o do obj.free();',
  15524. ' result.Free;',
  15525. ' result.Free();',
  15526. 'end;',
  15527. 'var o: tobject;',
  15528. ' a: array of tobject;',
  15529. 'begin',
  15530. ' o.free;',
  15531. ' o.obj.free;',
  15532. ' a[1+2].free;',
  15533. '']);
  15534. ConvertProgram;
  15535. CheckSource('TestClass_TObjectFree',
  15536. LinesToStr([ // statements
  15537. 'rtl.createClass(this, "TObject", null, function () {',
  15538. ' this.$init = function () {',
  15539. ' this.Obj = null;',
  15540. ' };',
  15541. ' this.$final = function () {',
  15542. ' this.Obj = undefined;',
  15543. ' };',
  15544. ' this.Free = function () {',
  15545. ' };',
  15546. ' this.Release = function () {',
  15547. ' this.Free();',
  15548. ' if (true) this.Free();',
  15549. ' };',
  15550. '});',
  15551. 'this.DoIt = function (o) {',
  15552. ' var Result = null;',
  15553. ' var l = null;',
  15554. ' o = rtl.freeLoc(o);',
  15555. ' o = rtl.freeLoc(o);',
  15556. ' l = rtl.freeLoc(l);',
  15557. ' l = rtl.freeLoc(l);',
  15558. ' rtl.free(o, "Obj");',
  15559. ' rtl.free(o, "Obj");',
  15560. ' rtl.free(o, "Obj");',
  15561. ' rtl.free(o, "Obj");',
  15562. ' Result = rtl.freeLoc(Result);',
  15563. ' Result = rtl.freeLoc(Result);',
  15564. ' return Result;',
  15565. '};',
  15566. 'this.o = null;',
  15567. 'this.a = [];',
  15568. '']),
  15569. LinesToStr([ // $mod.$main
  15570. 'rtl.free($mod, "o");',
  15571. 'rtl.free($mod.o, "Obj");',
  15572. 'rtl.free($mod.a, 1 + 2);',
  15573. '']));
  15574. end;
  15575. procedure TTestModule.TestClass_TObjectFree_VarArg;
  15576. begin
  15577. StartProgram(false);
  15578. Add([
  15579. 'type',
  15580. ' TObject = class',
  15581. ' Obj: tobject;',
  15582. ' procedure Free;',
  15583. ' end;',
  15584. 'procedure tobject.free;',
  15585. 'begin',
  15586. 'end;',
  15587. 'procedure DoIt(var o: tobject);',
  15588. 'begin',
  15589. ' o.free;',
  15590. ' o.free();',
  15591. 'end;',
  15592. 'begin',
  15593. '']);
  15594. ConvertProgram;
  15595. CheckSource('TestClass_TObjectFree_VarArg',
  15596. LinesToStr([ // statements
  15597. 'rtl.createClass(this, "TObject", null, function () {',
  15598. ' this.$init = function () {',
  15599. ' this.Obj = null;',
  15600. ' };',
  15601. ' this.$final = function () {',
  15602. ' this.Obj = undefined;',
  15603. ' };',
  15604. ' this.Free = function () {',
  15605. ' };',
  15606. '});',
  15607. 'this.DoIt = function (o) {',
  15608. ' o.set(rtl.freeLoc(o.get()));',
  15609. ' o.set(rtl.freeLoc(o.get()));',
  15610. '};',
  15611. '']),
  15612. LinesToStr([ // $mod.$main
  15613. '']));
  15614. end;
  15615. procedure TTestModule.TestClass_TObjectFreeNewInstance;
  15616. begin
  15617. StartProgram(false);
  15618. Add([
  15619. 'type',
  15620. ' TObject = class',
  15621. ' constructor Create;',
  15622. ' procedure Free;',
  15623. ' end;',
  15624. 'constructor TObject.Create; begin end;',
  15625. 'procedure tobject.free; begin end;',
  15626. 'begin',
  15627. ' with tobject.create do free;',
  15628. '']);
  15629. ConvertProgram;
  15630. CheckSource('TestClass_TObjectFreeNewInstance',
  15631. LinesToStr([ // statements
  15632. 'rtl.createClass(this, "TObject", null, function () {',
  15633. ' this.$init = function () {',
  15634. ' };',
  15635. ' this.$final = function () {',
  15636. ' };',
  15637. ' this.Create = function () {',
  15638. ' return this;',
  15639. ' };',
  15640. ' this.Free = function () {',
  15641. ' };',
  15642. '});',
  15643. '']),
  15644. LinesToStr([ // $mod.$main
  15645. 'var $with = $mod.TObject.$create("Create");',
  15646. '$with=rtl.freeLoc($with);',
  15647. '']));
  15648. end;
  15649. procedure TTestModule.TestClass_TObjectFreeLowerCase;
  15650. begin
  15651. StartProgram(false);
  15652. Add([
  15653. 'type',
  15654. ' TObject = class',
  15655. ' destructor Destroy;',
  15656. ' procedure Free;',
  15657. ' end;',
  15658. 'destructor TObject.Destroy; begin end;',
  15659. 'procedure tobject.free; begin end;',
  15660. 'var o: tobject;',
  15661. 'begin',
  15662. ' o.free;',
  15663. '']);
  15664. Converter.UseLowerCase:=true;
  15665. ConvertProgram;
  15666. CheckSource('TestClass_TObjectFreeLowerCase',
  15667. LinesToStr([ // statements
  15668. 'rtl.createClass(this, "tobject", null, function () {',
  15669. ' this.$init = function () {',
  15670. ' };',
  15671. ' this.$final = function () {',
  15672. ' };',
  15673. ' rtl.tObjectDestroy = "destroy";',
  15674. ' this.destroy = function () {',
  15675. ' };',
  15676. ' this.free = function () {',
  15677. ' };',
  15678. '});',
  15679. 'this.o = null;',
  15680. '']),
  15681. LinesToStr([ // $mod.$main
  15682. 'rtl.free($mod, "o");',
  15683. '']));
  15684. end;
  15685. procedure TTestModule.TestClass_TObjectFreeFunctionFail;
  15686. begin
  15687. StartProgram(false);
  15688. Add([
  15689. 'type',
  15690. ' TObject = class',
  15691. ' procedure Free;',
  15692. ' function GetObj: tobject; virtual; abstract;',
  15693. ' end;',
  15694. 'procedure tobject.free;',
  15695. 'begin',
  15696. 'end;',
  15697. 'var o: tobject;',
  15698. 'begin',
  15699. ' o.getobj.free;',
  15700. '']);
  15701. SetExpectedPasResolverError(sFreeNeedsVar,nFreeNeedsVar);
  15702. ConvertProgram;
  15703. end;
  15704. procedure TTestModule.TestClass_TObjectFreePropertyFail;
  15705. begin
  15706. StartProgram(false);
  15707. Add([
  15708. 'type',
  15709. ' TObject = class',
  15710. ' procedure Free;',
  15711. ' FObj: TObject;',
  15712. ' property Obj: tobject read FObj write FObj;',
  15713. ' end;',
  15714. 'procedure tobject.free;',
  15715. 'begin',
  15716. 'end;',
  15717. 'var o: tobject;',
  15718. 'begin',
  15719. ' o.obj.free;',
  15720. '']);
  15721. SetExpectedPasResolverError(sFreeNeedsVar,nFreeNeedsVar);
  15722. ConvertProgram;
  15723. end;
  15724. procedure TTestModule.TestClass_ForIn;
  15725. begin
  15726. StartProgram(false);
  15727. Add([
  15728. 'type',
  15729. ' TObject = class end;',
  15730. ' TItem = TObject;',
  15731. ' TEnumerator = class',
  15732. ' FCurrent: TItem;',
  15733. ' property Current: TItem read FCurrent;',
  15734. ' function MoveNext: boolean;',
  15735. ' end;',
  15736. ' TBird = class',
  15737. ' function GetEnumerator: TEnumerator;',
  15738. ' end;',
  15739. 'function TEnumerator.MoveNext: boolean;',
  15740. 'begin',
  15741. 'end;',
  15742. 'function TBird.GetEnumerator: TEnumerator;',
  15743. 'begin',
  15744. 'end;',
  15745. 'var',
  15746. ' b: TBird;',
  15747. ' i, i2: TItem;',
  15748. 'begin',
  15749. ' for i in b do i2:=i;']);
  15750. ConvertProgram;
  15751. CheckSource('TestClass_ForIn',
  15752. LinesToStr([ // statements
  15753. 'rtl.createClass(this, "TObject", null, function () {',
  15754. ' this.$init = function () {',
  15755. ' };',
  15756. ' this.$final = function () {',
  15757. ' };',
  15758. '});',
  15759. 'rtl.createClass(this, "TEnumerator", this.TObject, function () {',
  15760. ' this.$init = function () {',
  15761. ' $mod.TObject.$init.call(this);',
  15762. ' this.FCurrent = null;',
  15763. ' };',
  15764. ' this.$final = function () {',
  15765. ' this.FCurrent = undefined;',
  15766. ' $mod.TObject.$final.call(this);',
  15767. ' };',
  15768. ' this.MoveNext = function () {',
  15769. ' var Result = false;',
  15770. ' return Result;',
  15771. ' };',
  15772. '});',
  15773. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  15774. ' this.GetEnumerator = function () {',
  15775. ' var Result = null;',
  15776. ' return Result;',
  15777. ' };',
  15778. '});',
  15779. 'this.b = null;',
  15780. 'this.i = null;',
  15781. 'this.i2 = null;'
  15782. ]),
  15783. LinesToStr([ // $mod.$main
  15784. 'var $in = $mod.b.GetEnumerator();',
  15785. 'try {',
  15786. ' while ($in.MoveNext()){',
  15787. ' $mod.i = $in.FCurrent;',
  15788. ' $mod.i2 = $mod.i;',
  15789. ' }',
  15790. '} finally {',
  15791. ' $in = rtl.freeLoc($in)',
  15792. '};',
  15793. '']));
  15794. end;
  15795. procedure TTestModule.TestClass_DispatchMessage;
  15796. begin
  15797. StartProgram(false);
  15798. Add([
  15799. 'type',
  15800. ' TObject = class',
  15801. ' {$DispatchField DispInt}',
  15802. ' procedure Dispatch(var Msg); virtual; abstract;',
  15803. ' {$DispatchStrField DispStr}',
  15804. ' procedure DispatchStr(var Msg); virtual; abstract;',
  15805. ' end;',
  15806. ' THopMsg = record',
  15807. ' DispInt: longint;',
  15808. ' end;',
  15809. ' TPutMsg = record',
  15810. ' DispStr: string;',
  15811. ' end;',
  15812. ' TBird = class',
  15813. ' procedure Fly(var Msg); virtual; abstract; message 2;',
  15814. ' procedure Run; overload; virtual; abstract;',
  15815. ' procedure Run(var Msg); overload; message ''Fast'';',
  15816. ' procedure Hop(var Msg: THopMsg); virtual; abstract; message 3;',
  15817. ' procedure Put(var Msg: TPutMsg); virtual; abstract; message ''foo'';',
  15818. ' end;',
  15819. 'procedure TBird.Run(var Msg);',
  15820. 'begin',
  15821. 'end;',
  15822. 'begin',
  15823. '']);
  15824. ConvertProgram;
  15825. CheckSource('TestClass_Message',
  15826. LinesToStr([ // statements
  15827. 'rtl.createClass(this, "TObject", null, function () {',
  15828. ' this.$init = function () {',
  15829. ' };',
  15830. ' this.$final = function () {',
  15831. ' };',
  15832. '});',
  15833. 'rtl.recNewT(this, "THopMsg", function () {',
  15834. ' this.DispInt = 0;',
  15835. ' this.$eq = function (b) {',
  15836. ' return this.DispInt === b.DispInt;',
  15837. ' };',
  15838. ' this.$assign = function (s) {',
  15839. ' this.DispInt = s.DispInt;',
  15840. ' return this;',
  15841. ' };',
  15842. '});',
  15843. 'rtl.recNewT(this, "TPutMsg", function () {',
  15844. ' this.DispStr = "";',
  15845. ' this.$eq = function (b) {',
  15846. ' return this.DispStr === b.DispStr;',
  15847. ' };',
  15848. ' this.$assign = function (s) {',
  15849. ' this.DispStr = s.DispStr;',
  15850. ' return this;',
  15851. ' };',
  15852. '});',
  15853. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  15854. ' this.Run$1 = function (Msg) {',
  15855. ' };',
  15856. ' this.$msgint = {',
  15857. ' "2": "Fly",',
  15858. ' "3": "Hop"',
  15859. ' };',
  15860. ' this.$msgstr = {',
  15861. ' Fast: "Run$1",',
  15862. ' foo: "Put"',
  15863. ' };',
  15864. '});',
  15865. '']),
  15866. LinesToStr([ // $mod.$main
  15867. '']));
  15868. end;
  15869. procedure TTestModule.TestClass_Message_DuplicateIntFail;
  15870. begin
  15871. StartProgram(false);
  15872. Add([
  15873. 'type',
  15874. ' TObject = class',
  15875. ' procedure Fly(var Msg); virtual; abstract; message 3;',
  15876. ' procedure Run(var Msg); virtual; abstract; message 1+2;',
  15877. ' end;',
  15878. 'begin',
  15879. '']);
  15880. SetExpectedPasResolverError('Duplicate message id "3" at test1.pp(5,56)',nDuplicateMessageIdXAtY);
  15881. ConvertProgram;
  15882. end;
  15883. procedure TTestModule.TestClass_DispatchMessage_WrongFieldNameFail;
  15884. begin
  15885. StartProgram(false);
  15886. Add([
  15887. 'type',
  15888. ' TObject = class',
  15889. ' {$dispatchfield Msg}',
  15890. ' procedure Dispatch(var Msg); virtual; abstract;',
  15891. ' end;',
  15892. ' TFlyMsg = record',
  15893. ' FlyId: longint;',
  15894. ' end;',
  15895. ' TBird = class',
  15896. ' procedure Fly(var Msg: TFlyMsg); virtual; abstract; message 3;',
  15897. ' end;',
  15898. 'begin',
  15899. '']);
  15900. ConvertProgram;
  15901. CheckHint(mtWarning,nDispatchRequiresX,'Dispatch requires record field "Msg"');
  15902. end;
  15903. procedure TTestModule.TestClassOf_Create;
  15904. begin
  15905. StartProgram(false);
  15906. Add('type');
  15907. Add(' TObject = class');
  15908. Add(' constructor Create;');
  15909. Add(' end;');
  15910. Add(' TClass = class of TObject;');
  15911. Add('constructor tobject.create; begin end;');
  15912. Add('var');
  15913. Add(' Obj: tobject;');
  15914. Add(' C: tclass;');
  15915. Add('begin');
  15916. Add(' obj:=C.create;');
  15917. Add(' with c do obj:=create;');
  15918. ConvertProgram;
  15919. CheckSource('TestClassOf_Create',
  15920. LinesToStr([ // statements
  15921. 'rtl.createClass(this, "TObject", null, function () {',
  15922. ' this.$init = function () {',
  15923. ' };',
  15924. ' this.$final = function () {',
  15925. ' };',
  15926. ' this.Create = function () {',
  15927. ' return this;',
  15928. ' };',
  15929. '});',
  15930. 'this.Obj = null;',
  15931. 'this.C = null;'
  15932. ]),
  15933. LinesToStr([ // $mod.$main
  15934. '$mod.Obj = $mod.C.$create("Create");',
  15935. 'var $with = $mod.C;',
  15936. '$mod.Obj = $with.$create("Create");',
  15937. '']));
  15938. end;
  15939. procedure TTestModule.TestClassOf_Call;
  15940. begin
  15941. StartProgram(false);
  15942. Add('type');
  15943. Add(' TObject = class');
  15944. Add(' class procedure DoIt;');
  15945. Add(' end;');
  15946. Add(' TClass = class of TObject;');
  15947. Add('class procedure tobject.doit; begin end;');
  15948. Add('var');
  15949. Add(' C: tclass;');
  15950. Add('begin');
  15951. Add(' c.doit;');
  15952. Add(' with c do doit;');
  15953. ConvertProgram;
  15954. CheckSource('TestClassOf_Call',
  15955. LinesToStr([ // statements
  15956. 'rtl.createClass(this, "TObject", null, function () {',
  15957. ' this.$init = function () {',
  15958. ' };',
  15959. ' this.$final = function () {',
  15960. ' };',
  15961. ' this.DoIt = function () {',
  15962. ' };',
  15963. '});',
  15964. 'this.C = null;'
  15965. ]),
  15966. LinesToStr([ // $mod.$main
  15967. '$mod.C.DoIt();',
  15968. 'var $with = $mod.C;',
  15969. '$with.DoIt();',
  15970. '']));
  15971. end;
  15972. procedure TTestModule.TestClassOf_Assign;
  15973. begin
  15974. StartProgram(false);
  15975. Add('type');
  15976. Add(' TClass = class of TObject;');
  15977. Add(' TObject = class');
  15978. Add(' ClassType: TClass; ');
  15979. Add(' end;');
  15980. Add('var');
  15981. Add(' Obj: tobject;');
  15982. Add(' C: tclass;');
  15983. Add('begin');
  15984. Add(' c:=nil;');
  15985. Add(' c:=obj.classtype;');
  15986. ConvertProgram;
  15987. CheckSource('TestClassOf_Assign',
  15988. LinesToStr([ // statements
  15989. 'rtl.createClass(this, "TObject", null, function () {',
  15990. ' this.$init = function () {',
  15991. ' this.ClassType = null;',
  15992. ' };',
  15993. ' this.$final = function () {',
  15994. ' this.ClassType = undefined;',
  15995. ' };',
  15996. '});',
  15997. 'this.Obj = null;',
  15998. 'this.C = null;'
  15999. ]),
  16000. LinesToStr([ // $mod.$main
  16001. '$mod.C = null;',
  16002. '$mod.C = $mod.Obj.ClassType;',
  16003. '']));
  16004. end;
  16005. procedure TTestModule.TestClassOf_Is;
  16006. begin
  16007. StartProgram(false);
  16008. Add('type');
  16009. Add(' TClass = class of TObject;');
  16010. Add(' TObject = class');
  16011. Add(' end;');
  16012. Add(' TCar = class');
  16013. Add(' end;');
  16014. Add(' TCars = class of TCar;');
  16015. Add('var');
  16016. Add(' Obj: tobject;');
  16017. Add(' C: tclass;');
  16018. Add(' Cars: tcars;');
  16019. Add('begin');
  16020. Add(' if c is tcar then ;');
  16021. Add(' if c is tcars then ;');
  16022. ConvertProgram;
  16023. CheckSource('TestClassOf_Is',
  16024. LinesToStr([ // statements
  16025. 'rtl.createClass(this, "TObject", null, function () {',
  16026. ' this.$init = function () {',
  16027. ' };',
  16028. ' this.$final = function () {',
  16029. ' };',
  16030. '});',
  16031. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  16032. '});',
  16033. 'this.Obj = null;',
  16034. 'this.C = null;',
  16035. 'this.Cars = null;'
  16036. ]),
  16037. LinesToStr([ // $mod.$main
  16038. 'if(rtl.is($mod.C,$mod.TCar));',
  16039. 'if(rtl.is($mod.C,$mod.TCar));',
  16040. '']));
  16041. end;
  16042. procedure TTestModule.TestClassOf_Compare;
  16043. begin
  16044. StartProgram(false);
  16045. Add('type');
  16046. Add(' TClass = class of TObject;');
  16047. Add(' TObject = class');
  16048. Add(' ClassType: TClass; ');
  16049. Add(' end;');
  16050. Add('var');
  16051. Add(' b: boolean;');
  16052. Add(' Obj: tobject;');
  16053. Add(' C: tclass;');
  16054. Add('begin');
  16055. Add(' b:=c=nil;');
  16056. Add(' b:=nil=c;');
  16057. Add(' b:=c=obj.classtype;');
  16058. Add(' b:=obj.classtype=c;');
  16059. Add(' b:=c=TObject;');
  16060. Add(' b:=TObject=c;');
  16061. Add(' b:=c<>nil;');
  16062. Add(' b:=nil<>c;');
  16063. Add(' b:=c<>obj.classtype;');
  16064. Add(' b:=obj.classtype<>c;');
  16065. Add(' b:=c<>TObject;');
  16066. Add(' b:=TObject<>c;');
  16067. ConvertProgram;
  16068. CheckSource('TestClassOf_Compare',
  16069. LinesToStr([ // statements
  16070. 'rtl.createClass(this, "TObject", null, function () {',
  16071. ' this.$init = function () {',
  16072. ' this.ClassType = null;',
  16073. ' };',
  16074. ' this.$final = function () {',
  16075. ' this.ClassType = undefined;',
  16076. ' };',
  16077. '});',
  16078. 'this.b = false;',
  16079. 'this.Obj = null;',
  16080. 'this.C = null;'
  16081. ]),
  16082. LinesToStr([ // $mod.$main
  16083. '$mod.b = $mod.C === null;',
  16084. '$mod.b = null === $mod.C;',
  16085. '$mod.b = $mod.C === $mod.Obj.ClassType;',
  16086. '$mod.b = $mod.Obj.ClassType === $mod.C;',
  16087. '$mod.b = $mod.C === $mod.TObject;',
  16088. '$mod.b = $mod.TObject === $mod.C;',
  16089. '$mod.b = $mod.C !== null;',
  16090. '$mod.b = null !== $mod.C;',
  16091. '$mod.b = $mod.C !== $mod.Obj.ClassType;',
  16092. '$mod.b = $mod.Obj.ClassType !== $mod.C;',
  16093. '$mod.b = $mod.C !== $mod.TObject;',
  16094. '$mod.b = $mod.TObject !== $mod.C;',
  16095. '']));
  16096. end;
  16097. procedure TTestModule.TestClassOf_ClassVar;
  16098. begin
  16099. StartProgram(false);
  16100. Add('type');
  16101. Add(' TObject = class');
  16102. Add(' class var id: longint;');
  16103. Add(' end;');
  16104. Add(' TClass = class of TObject;');
  16105. Add('var');
  16106. Add(' C: tclass;');
  16107. Add('begin');
  16108. Add(' C.id:=C.id;');
  16109. ConvertProgram;
  16110. CheckSource('TestClassOf_ClassVar',
  16111. LinesToStr([ // statements
  16112. 'rtl.createClass(this, "TObject", null, function () {',
  16113. ' this.id = 0;',
  16114. ' this.$init = function () {',
  16115. ' };',
  16116. ' this.$final = function () {',
  16117. ' };',
  16118. '});',
  16119. 'this.C = null;'
  16120. ]),
  16121. LinesToStr([ // $mod.$main
  16122. '$mod.TObject.id = $mod.C.id;',
  16123. '']));
  16124. end;
  16125. procedure TTestModule.TestClassOf_ClassMethod;
  16126. begin
  16127. StartProgram(false);
  16128. Add('type');
  16129. Add(' TObject = class');
  16130. Add(' class function DoIt(i: longint = 0): longint;');
  16131. Add(' end;');
  16132. Add(' TClass = class of TObject;');
  16133. Add('class function tobject.doit(i: longint = 0): longint; begin end;');
  16134. Add('var');
  16135. Add(' i: longint;');
  16136. Add(' C: tclass;');
  16137. Add('begin');
  16138. Add(' C.DoIt;');
  16139. Add(' C.DoIt();');
  16140. Add(' i:=C.DoIt;');
  16141. Add(' i:=C.DoIt();');
  16142. ConvertProgram;
  16143. CheckSource('TestClassOf_ClassMethod',
  16144. LinesToStr([ // statements
  16145. 'rtl.createClass(this, "TObject", null, function () {',
  16146. ' this.$init = function () {',
  16147. ' };',
  16148. ' this.$final = function () {',
  16149. ' };',
  16150. ' this.DoIt = function (i) {',
  16151. ' var Result = 0;',
  16152. ' return Result;',
  16153. ' };',
  16154. '});',
  16155. 'this.i = 0;',
  16156. 'this.C = null;'
  16157. ]),
  16158. LinesToStr([ // $mod.$main
  16159. '$mod.C.DoIt(0);',
  16160. '$mod.C.DoIt(0);',
  16161. '$mod.i = $mod.C.DoIt(0);',
  16162. '$mod.i = $mod.C.DoIt(0);',
  16163. '']));
  16164. end;
  16165. procedure TTestModule.TestClassOf_ClassProperty;
  16166. begin
  16167. StartProgram(false);
  16168. Add([
  16169. 'type',
  16170. ' TObject = class',
  16171. ' class var FA: longint;',
  16172. ' class function GetA: longint;',
  16173. ' class procedure SetA(Value: longint);',
  16174. ' class property pA: longint read fa write fa;',
  16175. ' class property pB: longint read geta write seta;',
  16176. ' end;',
  16177. ' TObjectClass = class of tobject;',
  16178. 'class function tobject.geta: longint; begin end;',
  16179. 'class procedure tobject.seta(value: longint); begin end;',
  16180. 'var',
  16181. ' b: boolean;',
  16182. ' Obj: tobject;',
  16183. ' Cla: tobjectclass;',
  16184. 'begin',
  16185. ' obj.pa:=obj.pa;',
  16186. ' obj.pb:=obj.pb;',
  16187. ' b:=obj.pa=4;',
  16188. ' b:=obj.pb=obj.pb;',
  16189. ' b:=5=obj.pa;',
  16190. ' cla.pa:=6;',
  16191. ' cla.pa:=cla.pa;',
  16192. ' cla.pb:=cla.pb;',
  16193. ' b:=cla.pa=7;',
  16194. ' b:=cla.pb=cla.pb;',
  16195. ' b:=8=cla.pa;',
  16196. ' tobject.pa:=9;',
  16197. ' tobject.pb:=tobject.pb;',
  16198. ' b:=tobject.pa=10;',
  16199. ' b:=11=tobject.pa;',
  16200. '']);
  16201. ConvertProgram;
  16202. CheckSource('TestClassOf_ClassProperty',
  16203. LinesToStr([ // statements
  16204. 'rtl.createClass(this, "TObject", null, function () {',
  16205. ' this.FA = 0;',
  16206. ' this.$init = function () {',
  16207. ' };',
  16208. ' this.$final = function () {',
  16209. ' };',
  16210. ' this.GetA = function () {',
  16211. ' var Result = 0;',
  16212. ' return Result;',
  16213. ' };',
  16214. ' this.SetA = function (Value) {',
  16215. ' };',
  16216. '});',
  16217. 'this.b = false;',
  16218. 'this.Obj = null;',
  16219. 'this.Cla = null;'
  16220. ]),
  16221. LinesToStr([ // $mod.$main
  16222. '$mod.TObject.FA = $mod.Obj.FA;',
  16223. '$mod.Obj.$class.SetA($mod.Obj.$class.GetA());',
  16224. '$mod.b = $mod.Obj.FA === 4;',
  16225. '$mod.b = $mod.Obj.$class.GetA() === $mod.Obj.$class.GetA();',
  16226. '$mod.b = 5 === $mod.Obj.FA;',
  16227. '$mod.TObject.FA = 6;',
  16228. '$mod.TObject.FA = $mod.Cla.FA;',
  16229. '$mod.Cla.SetA($mod.Cla.GetA());',
  16230. '$mod.b = $mod.Cla.FA === 7;',
  16231. '$mod.b = $mod.Cla.GetA() === $mod.Cla.GetA();',
  16232. '$mod.b = 8 === $mod.Cla.FA;',
  16233. '$mod.TObject.FA = 9;',
  16234. '$mod.TObject.SetA($mod.TObject.GetA());',
  16235. '$mod.b = $mod.TObject.FA === 10;',
  16236. '$mod.b = 11 === $mod.TObject.FA;',
  16237. '']));
  16238. end;
  16239. procedure TTestModule.TestClassOf_ClassMethodSelf;
  16240. begin
  16241. StartProgram(false);
  16242. Add('type');
  16243. Add(' TObject = class');
  16244. Add(' class var GlobalId: longint;');
  16245. Add(' class procedure ProcA;');
  16246. Add(' end;');
  16247. Add('class procedure tobject.proca;');
  16248. Add('var b: boolean;');
  16249. Add('begin');
  16250. Add(' b:=self=nil;');
  16251. Add(' b:=self.globalid=3;');
  16252. Add(' b:=4=self.globalid;');
  16253. Add(' self.globalid:=5;');
  16254. Add(' self.proca;');
  16255. Add('end;');
  16256. Add('begin');
  16257. ConvertProgram;
  16258. CheckSource('TestClassOf_ClassMethodSelf',
  16259. LinesToStr([ // statements
  16260. 'rtl.createClass(this, "TObject", null, function () {',
  16261. ' this.GlobalId = 0;',
  16262. ' this.$init = function () {',
  16263. ' };',
  16264. ' this.$final = function () {',
  16265. ' };',
  16266. ' this.ProcA = function () {',
  16267. ' var b = false;',
  16268. ' b = this === null;',
  16269. ' b = this.GlobalId === 3;',
  16270. ' b = 4 === this.GlobalId;',
  16271. ' $mod.TObject.GlobalId = 5;',
  16272. ' this.ProcA();',
  16273. ' };',
  16274. '});'
  16275. ]),
  16276. LinesToStr([ // $mod.$main
  16277. '']));
  16278. end;
  16279. procedure TTestModule.TestClassOf_TypeCast;
  16280. begin
  16281. StartProgram(false);
  16282. Add('type');
  16283. Add(' TObject = class');
  16284. Add(' class procedure {#TObject_DoIt}DoIt;');
  16285. Add(' end;');
  16286. Add(' TClass = class of TObject;');
  16287. Add(' TMobile = class');
  16288. Add(' class procedure {#TMobile_DoIt}DoIt;');
  16289. Add(' end;');
  16290. Add(' TMobileClass = class of TMobile;');
  16291. Add(' TCar = class(TMobile)');
  16292. Add(' class procedure {#TCar_DoIt}DoIt;');
  16293. Add(' end;');
  16294. Add(' TCarClass = class of TCar;');
  16295. Add('class procedure TObject.DoIt;');
  16296. Add('begin');
  16297. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  16298. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  16299. Add('end;');
  16300. Add('class procedure TMobile.DoIt;');
  16301. Add('begin');
  16302. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  16303. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  16304. Add(' TCarClass(Self).{@TCar_DoIt}DoIt;');
  16305. Add('end;');
  16306. Add('class procedure TCar.DoIt; begin end;');
  16307. Add('var');
  16308. Add(' ObjC: TClass;');
  16309. Add(' MobileC: TMobileClass;');
  16310. Add(' CarC: TCarClass;');
  16311. Add('begin');
  16312. Add(' ObjC.{@TObject_DoIt}DoIt;');
  16313. Add(' MobileC.{@TMobile_DoIt}DoIt;');
  16314. Add(' CarC.{@TCar_DoIt}DoIt;');
  16315. Add(' TClass(ObjC).{@TObject_DoIt}DoIt;');
  16316. Add(' TMobileClass(ObjC).{@TMobile_DoIt}DoIt;');
  16317. Add(' TCarClass(ObjC).{@TCar_DoIt}DoIt;');
  16318. Add(' TClass(MobileC).{@TObject_DoIt}DoIt;');
  16319. Add(' TMobileClass(MobileC).{@TMobile_DoIt}DoIt;');
  16320. Add(' TCarClass(MobileC).{@TCar_DoIt}DoIt;');
  16321. Add(' TClass(CarC).{@TObject_DoIt}DoIt;');
  16322. Add(' TMobileClass(CarC).{@TMobile_DoIt}DoIt;');
  16323. Add(' TCarClass(CarC).{@TCar_DoIt}DoIt;');
  16324. ConvertProgram;
  16325. CheckSource('TestClassOf_TypeCast',
  16326. LinesToStr([ // statements
  16327. 'rtl.createClass(this, "TObject", null, function () {',
  16328. ' this.$init = function () {',
  16329. ' };',
  16330. ' this.$final = function () {',
  16331. ' };',
  16332. ' this.DoIt = function () {',
  16333. ' this.DoIt();',
  16334. ' this.DoIt$1();',
  16335. ' };',
  16336. '});',
  16337. 'rtl.createClass(this, "TMobile", this.TObject, function () {',
  16338. ' this.DoIt$1 = function () {',
  16339. ' this.DoIt();',
  16340. ' this.DoIt$1();',
  16341. ' this.DoIt$2();',
  16342. ' };',
  16343. '});',
  16344. 'rtl.createClass(this, "TCar", this.TMobile, function () {',
  16345. ' this.DoIt$2 = function () {',
  16346. ' };',
  16347. '});',
  16348. 'this.ObjC = null;',
  16349. 'this.MobileC = null;',
  16350. 'this.CarC = null;',
  16351. '']),
  16352. LinesToStr([ // $mod.$main
  16353. '$mod.ObjC.DoIt();',
  16354. '$mod.MobileC.DoIt$1();',
  16355. '$mod.CarC.DoIt$2();',
  16356. '$mod.ObjC.DoIt();',
  16357. '$mod.ObjC.DoIt$1();',
  16358. '$mod.ObjC.DoIt$2();',
  16359. '$mod.MobileC.DoIt();',
  16360. '$mod.MobileC.DoIt$1();',
  16361. '$mod.MobileC.DoIt$2();',
  16362. '$mod.CarC.DoIt();',
  16363. '$mod.CarC.DoIt$1();',
  16364. '$mod.CarC.DoIt$2();',
  16365. '']));
  16366. end;
  16367. procedure TTestModule.TestClassOf_ImplicitFunctionCall;
  16368. begin
  16369. StartProgram(false);
  16370. Add('type');
  16371. Add(' TObject = class');
  16372. Add(' function CurNow: longint; ');
  16373. Add(' class function Now: longint; ');
  16374. Add(' end;');
  16375. Add('function TObject.CurNow: longint; begin end;');
  16376. Add('class function TObject.Now: longint; begin end;');
  16377. Add('var');
  16378. Add(' Obj: tobject;');
  16379. Add(' vI: longint;');
  16380. Add('begin');
  16381. Add(' obj.curnow;');
  16382. Add(' vi:=obj.curnow;');
  16383. Add(' tobject.now;');
  16384. Add(' vi:=tobject.now;');
  16385. ConvertProgram;
  16386. CheckSource('TestClassOf_ImplicitFunctionCall',
  16387. LinesToStr([ // statements
  16388. 'rtl.createClass(this, "TObject", null, function () {',
  16389. ' this.$init = function () {',
  16390. ' };',
  16391. ' this.$final = function () {',
  16392. ' };',
  16393. ' this.CurNow = function () {',
  16394. ' var Result = 0;',
  16395. ' return Result;',
  16396. ' };',
  16397. ' this.Now = function () {',
  16398. ' var Result = 0;',
  16399. ' return Result;',
  16400. ' };',
  16401. '});',
  16402. 'this.Obj = null;',
  16403. 'this.vI = 0;',
  16404. '']),
  16405. LinesToStr([ // $mod.$main
  16406. '$mod.Obj.CurNow();',
  16407. '$mod.vI = $mod.Obj.CurNow();',
  16408. '$mod.TObject.Now();',
  16409. '$mod.vI = $mod.TObject.Now();',
  16410. '']));
  16411. end;
  16412. procedure TTestModule.TestClassOf_Const;
  16413. begin
  16414. StartProgram(false);
  16415. Add([
  16416. 'type',
  16417. ' TObject = class',
  16418. ' end;',
  16419. ' TBird = TObject;',
  16420. ' TBirds = class of TBird;',
  16421. ' TEagles = TBirds;',
  16422. ' THawk = class(TBird);',
  16423. 'const',
  16424. ' Hawk: TEagles = THawk;',
  16425. ' DefaultBirdClasses : Array [1..2] of TEagles = (',
  16426. ' TBird,',
  16427. ' THawk',
  16428. ' );',
  16429. 'begin']);
  16430. ConvertProgram;
  16431. CheckSource('TestClassOf_Const',
  16432. LinesToStr([ // statements
  16433. 'rtl.createClass(this, "TObject", null, function () {',
  16434. ' this.$init = function () {',
  16435. ' };',
  16436. ' this.$final = function () {',
  16437. ' };',
  16438. '});',
  16439. 'rtl.createClass(this, "THawk", this.TObject, function () {',
  16440. '});',
  16441. 'this.Hawk = this.THawk;',
  16442. 'this.DefaultBirdClasses = [this.TObject, this.THawk];',
  16443. '']),
  16444. LinesToStr([ // $mod.$main
  16445. '']));
  16446. end;
  16447. procedure TTestModule.TestNestedClass_Alias;
  16448. begin
  16449. WithTypeInfo:=true;
  16450. StartProgram(false);
  16451. Add([
  16452. 'type',
  16453. ' TObject = class',
  16454. ' type TNested = type longint;',
  16455. ' end;',
  16456. 'type TAlias = type tobject.tnested;',
  16457. 'var i: tobject.tnested = 3;',
  16458. 'var j: TAlias = 4;',
  16459. 'begin',
  16460. ' if typeinfo(TAlias)=nil then ;',
  16461. ' if typeinfo(tobject.tnested)=nil then ;',
  16462. '']);
  16463. ConvertProgram;
  16464. CheckSource('TestNestedClass_Alias',
  16465. LinesToStr([ // statements
  16466. 'rtl.createClass(this, "TObject", null, function () {',
  16467. ' $mod.$rtti.$inherited("TObject.TNested", rtl.longint, {});',
  16468. ' this.$init = function () {',
  16469. ' };',
  16470. ' this.$final = function () {',
  16471. ' };',
  16472. '});',
  16473. 'this.$rtti.$inherited("TAlias", this.$rtti["TObject.TNested"], {});',
  16474. 'this.i = 3;',
  16475. 'this.j = 4;',
  16476. '']),
  16477. LinesToStr([ // $mod.$main
  16478. 'if ($mod.$rtti["TAlias"] === null) ;',
  16479. 'if ($mod.$rtti["TObject.TNested"] === null) ;',
  16480. '']));
  16481. end;
  16482. procedure TTestModule.TestNestedClass_Record;
  16483. begin
  16484. WithTypeInfo:=true;
  16485. StartProgram(false);
  16486. Add([
  16487. 'type',
  16488. ' TObject = class',
  16489. ' type TPoint = record',
  16490. ' x,y: byte;',
  16491. ' end;',
  16492. ' procedure DoIt(t: TPoint);',
  16493. ' end;',
  16494. 'procedure tobject.DoIt(t: TPoint);',
  16495. 'var p: TPoint;',
  16496. 'begin',
  16497. ' t.x:=t.y;',
  16498. ' p:=t;',
  16499. 'end;',
  16500. 'var',
  16501. ' p: tobject.tpoint = (x:2; y:4);',
  16502. ' o: TObject;',
  16503. 'begin',
  16504. ' p:=p;',
  16505. ' o.doit(p);',
  16506. '']);
  16507. ConvertProgram;
  16508. CheckSource('TestNestedClass_Record',
  16509. LinesToStr([ // statements
  16510. 'rtl.createClass(this, "TObject", null, function () {',
  16511. ' rtl.recNewT(this, "TPoint", function () {',
  16512. ' this.x = 0;',
  16513. ' this.y = 0;',
  16514. ' this.$eq = function (b) {',
  16515. ' return (this.x === b.x) && (this.y === b.y);',
  16516. ' };',
  16517. ' this.$assign = function (s) {',
  16518. ' this.x = s.x;',
  16519. ' this.y = s.y;',
  16520. ' return this;',
  16521. ' };',
  16522. ' var $r = $mod.$rtti.$Record("TObject.TPoint", {});',
  16523. ' $r.addField("x", rtl.byte);',
  16524. ' $r.addField("y", rtl.byte);',
  16525. ' });',
  16526. ' this.$init = function () {',
  16527. ' };',
  16528. ' this.$final = function () {',
  16529. ' };',
  16530. ' this.DoIt = function (t) {',
  16531. ' var p = this.TPoint.$new();',
  16532. ' t.x = t.y;',
  16533. ' p.$assign(t);',
  16534. ' };',
  16535. '});',
  16536. 'this.p = this.TObject.TPoint.$clone({',
  16537. ' x: 2,',
  16538. ' y: 4',
  16539. '});',
  16540. 'this.o = null;',
  16541. '']),
  16542. LinesToStr([ // $mod.$main
  16543. '$mod.p.$assign($mod.p);',
  16544. '$mod.o.DoIt($mod.TObject.TPoint.$clone($mod.p));',
  16545. '']));
  16546. end;
  16547. procedure TTestModule.TestNestedClass_Class;
  16548. begin
  16549. WithTypeInfo:=true;
  16550. StartProgram(false);
  16551. Add([
  16552. 'type',
  16553. ' TObject = class end;',
  16554. ' TBird = class',
  16555. ' type TLeg = class',
  16556. ' FId: longint;',
  16557. ' constructor Create;',
  16558. ' function Create(i: longint): TLeg;',
  16559. ' end;',
  16560. ' function DoIt(b: TBird): Tleg;',
  16561. ' end;',
  16562. 'constructor tbird.tleg.create;',
  16563. 'begin',
  16564. ' FId:=3;',
  16565. 'end;',
  16566. 'function tbird.tleg.Create(i: longint): TLeg;',
  16567. 'begin',
  16568. ' Create;',
  16569. ' Result:=TLeg.Create;',
  16570. ' Result:=TBird.TLeg.Create;',
  16571. ' Result:=Create(3);',
  16572. ' FId:=i;',
  16573. 'end;',
  16574. 'function tbird.DoIt(b: tbird): tleg;',
  16575. 'begin',
  16576. ' Result.Create;',
  16577. ' Result:=TLeg.Create;',
  16578. ' Result:=TBird.TLeg.Create;',
  16579. ' Result:=Result.Create(3);',
  16580. 'end;',
  16581. 'var',
  16582. ' b: Tbird.tleg;',
  16583. 'begin',
  16584. ' b.Create;',
  16585. ' b:=TBird.TLeg.Create;',
  16586. ' b:=b.Create(3);',
  16587. '']);
  16588. ConvertProgram;
  16589. CheckSource('TestNestedClass_Class',
  16590. LinesToStr([ // statements
  16591. 'rtl.createClass(this, "TObject", null, function () {',
  16592. ' this.$init = function () {',
  16593. ' };',
  16594. ' this.$final = function () {',
  16595. ' };',
  16596. '});',
  16597. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  16598. ' rtl.createClass(this, "TLeg", $mod.TObject, function () {',
  16599. ' this.$init = function () {',
  16600. ' $mod.TObject.$init.call(this);',
  16601. ' this.FId = 0;',
  16602. ' };',
  16603. ' this.Create = function () {',
  16604. ' this.FId = 3;',
  16605. ' return this;',
  16606. ' };',
  16607. ' this.Create$1 = function (i) {',
  16608. ' var Result = null;',
  16609. ' this.Create();',
  16610. ' Result = $mod.TBird.TLeg.$create("Create");',
  16611. ' Result = $mod.TBird.TLeg.$create("Create");',
  16612. ' Result = this.Create$1(3);',
  16613. ' this.FId = i;',
  16614. ' return Result;',
  16615. ' };',
  16616. ' }, "TBird.TLeg");',
  16617. ' this.DoIt = function (b) {',
  16618. ' var Result = null;',
  16619. ' Result.Create();',
  16620. ' Result = this.TLeg.$create("Create");',
  16621. ' Result = $mod.TBird.TLeg.$create("Create");',
  16622. ' Result = Result.Create$1(3);',
  16623. ' return Result;',
  16624. ' };',
  16625. '});',
  16626. 'this.b = null;',
  16627. '']),
  16628. LinesToStr([ // $mod.$main
  16629. '$mod.b.Create();',
  16630. '$mod.b = $mod.TBird.TLeg.$create("Create");',
  16631. '$mod.b = $mod.b.Create$1(3);',
  16632. '']));
  16633. end;
  16634. procedure TTestModule.TestExternalClass_Var;
  16635. begin
  16636. StartProgram(false);
  16637. Add([
  16638. '{$modeswitch externalclass}',
  16639. 'type',
  16640. ' TExtA = class external name ''ExtObj''',
  16641. ' Id: longint external name ''$Id'';',
  16642. ' B: longint;',
  16643. ' end;',
  16644. 'var Obj: TExtA;',
  16645. 'begin',
  16646. ' obj.id:=obj.id+1;',
  16647. ' obj.B:=obj.B+1;']);
  16648. ConvertProgram;
  16649. CheckSource('TestExternalClass_Var',
  16650. LinesToStr([ // statements
  16651. 'this.Obj = null;',
  16652. '']),
  16653. LinesToStr([ // $mod.$main
  16654. '$mod.Obj.$Id = $mod.Obj.$Id + 1;',
  16655. '$mod.Obj.B = $mod.Obj.B + 1;',
  16656. '']));
  16657. end;
  16658. procedure TTestModule.TestExternalClass_Const;
  16659. begin
  16660. StartProgram(false);
  16661. Add([
  16662. '{$modeswitch externalclass}',
  16663. 'type',
  16664. ' TExtA = class external name ''ExtObj''',
  16665. ' const Two: longint = 2;',
  16666. ' const Three = 3;',
  16667. ' const Id: longint;',
  16668. ' end;',
  16669. ' TExtB = class external name ''ExtB''',
  16670. ' A: TExtA;',
  16671. ' end;',
  16672. 'var',
  16673. ' A: texta;',
  16674. ' B: textb;',
  16675. ' i: longint;',
  16676. 'begin',
  16677. ' i:=a.two;',
  16678. ' i:=texta.two;',
  16679. ' i:=a.three;',
  16680. ' i:=texta.three;',
  16681. ' i:=a.id;',
  16682. ' i:=texta.id;',
  16683. '']);
  16684. ConvertProgram;
  16685. CheckSource('TestExternalClass_Const',
  16686. LinesToStr([ // statements
  16687. 'this.A = null;',
  16688. 'this.B = null;',
  16689. 'this.i = 0;',
  16690. '']),
  16691. LinesToStr([ // $mod.$main
  16692. '$mod.i = 2;',
  16693. '$mod.i = 2;',
  16694. '$mod.i = 3;',
  16695. '$mod.i = 3;',
  16696. '$mod.i = $mod.A.Id;',
  16697. '$mod.i = ExtObj.Id;',
  16698. '']));
  16699. end;
  16700. procedure TTestModule.TestExternalClass_Dollar;
  16701. begin
  16702. StartProgram(false);
  16703. Add([
  16704. '{$modeswitch externalclass}',
  16705. 'type',
  16706. ' TExtA = class external name ''$''',
  16707. ' Id: longint external name ''$'';',
  16708. ' function Bla(i: longint): longint; external name ''$'';',
  16709. ' end;',
  16710. 'function dollar(k: longint): longint; external name ''$'';',
  16711. 'var Obj: TExtA;',
  16712. 'begin',
  16713. ' dollar(1);',
  16714. ' obj.id:=obj.id+2;',
  16715. ' obj.Bla(3);',
  16716. '']);
  16717. ConvertProgram;
  16718. CheckSource('TestExternalClass_Dollar',
  16719. LinesToStr([ // statements
  16720. 'this.Obj = null;',
  16721. '']),
  16722. LinesToStr([ // $mod.$main
  16723. '$(1);',
  16724. '$mod.Obj.$ = $mod.Obj.$ + 2;',
  16725. '$mod.Obj.$(3);',
  16726. '']));
  16727. end;
  16728. procedure TTestModule.TestExternalClass_DuplicateVarFail;
  16729. begin
  16730. StartProgram(false);
  16731. Add('{$modeswitch externalclass}');
  16732. Add('type');
  16733. Add(' TExtA = class external name ''ExtA''');
  16734. Add(' Id: longint external name ''$Id'';');
  16735. Add(' end;');
  16736. Add(' TExtB = class external ''lib'' name ''ExtB''(TExtA)');
  16737. Add(' Id: longint;');
  16738. Add(' end;');
  16739. Add('begin');
  16740. SetExpectedPasResolverError('Duplicate identifier "Id" at test1.pp(6,5)',nDuplicateIdentifier);
  16741. ConvertProgram;
  16742. end;
  16743. procedure TTestModule.TestExternalClass_Method;
  16744. begin
  16745. StartProgram(false);
  16746. Add(['{$modeswitch externalclass}',
  16747. 'type',
  16748. ' TExtA = class external name ''ExtObj''',
  16749. ' procedure DoIt(Id: longint = 1); external name ''$Execute'';',
  16750. ' procedure DoSome(Id: longint = 1);',
  16751. ' end;',
  16752. 'var Obj: texta;',
  16753. 'begin',
  16754. ' obj.doit;',
  16755. ' obj.doit();',
  16756. ' obj.doit(2);',
  16757. ' with obj do begin',
  16758. ' doit;',
  16759. ' doit();',
  16760. ' doit(3);',
  16761. ' end;']);
  16762. ConvertProgram;
  16763. CheckSource('TestExternalClass_Method',
  16764. LinesToStr([ // statements
  16765. 'this.Obj = null;',
  16766. '']),
  16767. LinesToStr([ // $mod.$main
  16768. '$mod.Obj.$Execute(1);',
  16769. '$mod.Obj.$Execute(1);',
  16770. '$mod.Obj.$Execute(2);',
  16771. 'var $with = $mod.Obj;',
  16772. '$with.$Execute(1);',
  16773. '$with.$Execute(1);',
  16774. '$with.$Execute(3);',
  16775. '']));
  16776. end;
  16777. procedure TTestModule.TestExternalClass_ClassMethod;
  16778. begin
  16779. StartProgram(false);
  16780. Add([
  16781. '{$modeswitch externalclass}',
  16782. 'type',
  16783. ' TExtA = class external name ''ExtObj''',
  16784. ' class procedure DoIt(Id: longint = 1); external name ''$Execute'';',
  16785. ' end;',
  16786. ' TExtB = TExtA;',
  16787. 'var p: Pointer;',
  16788. 'begin',
  16789. ' texta.doit;',
  16790. ' texta.doit();',
  16791. ' texta.doit(2);',
  16792. ' p:[email protected];',
  16793. ' with texta do begin',
  16794. ' doit;',
  16795. ' doit();',
  16796. ' doit(3);',
  16797. ' p:=@DoIt;',
  16798. ' end;',
  16799. ' textb.doit;',
  16800. ' textb.doit();',
  16801. ' textb.doit(4);',
  16802. ' with textb do begin',
  16803. ' doit;',
  16804. ' doit();',
  16805. ' doit(5);',
  16806. ' end;',
  16807. '']);
  16808. ConvertProgram;
  16809. CheckSource('TestExternalClass_ClassMethod',
  16810. LinesToStr([ // statements
  16811. 'this.p = null;',
  16812. '']),
  16813. LinesToStr([ // $mod.$main
  16814. 'ExtObj.$Execute(1);',
  16815. 'ExtObj.$Execute(1);',
  16816. 'ExtObj.$Execute(2);',
  16817. '$mod.p = rtl.createCallback(ExtObj, "$Execute");',
  16818. 'ExtObj.$Execute(1);',
  16819. 'ExtObj.$Execute(1);',
  16820. 'ExtObj.$Execute(3);',
  16821. '$mod.p = rtl.createCallback(ExtObj, "$Execute");',
  16822. 'ExtObj.$Execute(1);',
  16823. 'ExtObj.$Execute(1);',
  16824. 'ExtObj.$Execute(4);',
  16825. 'ExtObj.$Execute(1);',
  16826. 'ExtObj.$Execute(1);',
  16827. 'ExtObj.$Execute(5);',
  16828. '']));
  16829. end;
  16830. procedure TTestModule.TestExternalClass_ClassMethodStatic;
  16831. begin
  16832. StartProgram(false);
  16833. Add([
  16834. '{$modeswitch externalclass}',
  16835. 'type',
  16836. ' TExtA = class external name ''ExtObj''',
  16837. ' class procedure DoIt(Id: longint = 1); static;',
  16838. ' end;',
  16839. 'var p: Pointer;',
  16840. 'begin',
  16841. ' texta.doit;',
  16842. ' texta.doit();',
  16843. ' texta.doit(2);',
  16844. ' p:[email protected];',
  16845. ' with texta do begin',
  16846. ' doit;',
  16847. ' doit();',
  16848. ' doit(3);',
  16849. ' p:=@DoIt;',
  16850. ' end;',
  16851. '']);
  16852. ConvertProgram;
  16853. CheckSource('TestExternalClass_ClassMethodStatic',
  16854. LinesToStr([ // statements
  16855. 'this.p = null;',
  16856. '']),
  16857. LinesToStr([ // $mod.$main
  16858. 'ExtObj.DoIt(1);',
  16859. 'ExtObj.DoIt(1);',
  16860. 'ExtObj.DoIt(2);',
  16861. '$mod.p = ExtObj.DoIt;',
  16862. 'ExtObj.DoIt(1);',
  16863. 'ExtObj.DoIt(1);',
  16864. 'ExtObj.DoIt(3);',
  16865. '$mod.p = ExtObj.DoIt;',
  16866. '']));
  16867. end;
  16868. procedure TTestModule.TestExternalClass_FunctionResultInTypeCast;
  16869. begin
  16870. StartProgram(false);
  16871. Add([
  16872. '{$modeswitch externalclass}',
  16873. 'type',
  16874. ' TBird = class external name ''Array''',
  16875. ' end;',
  16876. 'function GetPtr: Pointer;',
  16877. 'begin',
  16878. 'end;',
  16879. 'procedure Write(const p);',
  16880. 'begin',
  16881. 'end;',
  16882. 'procedure WriteLn; varargs;',
  16883. 'begin',
  16884. 'end;',
  16885. 'begin',
  16886. ' if TBird(GetPtr)=nil then ;',
  16887. ' Write(GetPtr);',
  16888. ' WriteLn(GetPtr);',
  16889. ' Write(TBird(GetPtr));',
  16890. ' WriteLn(TBird(GetPtr));',
  16891. '']);
  16892. ConvertProgram;
  16893. CheckSource('TestFunctionResultInTypeCast',
  16894. LinesToStr([ // statements
  16895. 'this.GetPtr = function () {',
  16896. ' var Result = null;',
  16897. ' return Result;',
  16898. '};',
  16899. 'this.Write = function (p) {',
  16900. '};',
  16901. 'this.WriteLn = function () {',
  16902. '};',
  16903. '']),
  16904. LinesToStr([
  16905. 'if ($mod.GetPtr() === null) ;',
  16906. '$mod.Write($mod.GetPtr());',
  16907. '$mod.WriteLn($mod.GetPtr());',
  16908. '$mod.Write($mod.GetPtr());',
  16909. '$mod.WriteLn($mod.GetPtr());',
  16910. '']));
  16911. end;
  16912. procedure TTestModule.TestExternalClass_NonExternalOverride;
  16913. begin
  16914. StartProgram(false);
  16915. Add([
  16916. '{$modeswitch externalclass}',
  16917. 'type',
  16918. ' TExtA = class external name ''ExtObjA''',
  16919. ' procedure ProcA; virtual;',
  16920. ' procedure ProcB; virtual;',
  16921. ' end;',
  16922. ' TExtB = class external name ''ExtObjB'' (TExtA)',
  16923. ' end;',
  16924. ' TExtC = class (TExtB)',
  16925. ' procedure ProcA; override;',
  16926. ' end;',
  16927. 'procedure TExtC.ProcA;',
  16928. 'begin',
  16929. ' ProcA;',
  16930. ' Self.ProcA;',
  16931. ' ProcB;',
  16932. ' Self.ProcB;',
  16933. 'end;',
  16934. 'var',
  16935. ' A: texta;',
  16936. ' B: textb;',
  16937. ' C: textc;',
  16938. 'begin',
  16939. ' a.proca;',
  16940. ' b.proca;',
  16941. ' c.proca;']);
  16942. ConvertProgram;
  16943. CheckSource('TestExternalClass_NonExternalOverride',
  16944. LinesToStr([ // statements
  16945. 'rtl.createClassExt(this, "TExtC", ExtObjB, "", function () {',
  16946. ' this.$init = function () {',
  16947. ' };',
  16948. ' this.$final = function () {',
  16949. ' };',
  16950. ' this.ProcA = function () {',
  16951. ' this.ProcA();',
  16952. ' this.ProcA();',
  16953. ' this.ProcB();',
  16954. ' this.ProcB();',
  16955. ' };',
  16956. '});',
  16957. 'this.A = null;',
  16958. 'this.B = null;',
  16959. 'this.C = null;',
  16960. '']),
  16961. LinesToStr([ // $mod.$main
  16962. '$mod.A.ProcA();',
  16963. '$mod.B.ProcA();',
  16964. '$mod.C.ProcA();',
  16965. '']));
  16966. end;
  16967. procedure TTestModule.TestExternalClass_OverloadHint;
  16968. begin
  16969. StartProgram(false);
  16970. Add([
  16971. '{$modeswitch externalclass}',
  16972. 'type',
  16973. ' TExtA = class external name ''ExtObjA''',
  16974. ' procedure DoIt;',
  16975. ' procedure DoIt(i: longint);',
  16976. ' end;',
  16977. 'begin',
  16978. '']);
  16979. ConvertProgram;
  16980. CheckResolverUnexpectedHints(true);
  16981. CheckSource('TestExternalClass_OverloadHint',
  16982. LinesToStr([ // statements
  16983. '']),
  16984. LinesToStr([ // $mod.$main
  16985. '']));
  16986. end;
  16987. procedure TTestModule.TestExternalClass_SameNamePublishedProperty;
  16988. begin
  16989. WithTypeInfo:=true;
  16990. StartProgram(false);
  16991. Add([
  16992. '{$modeswitch externalclass}',
  16993. 'type',
  16994. ' JSwiper = class external name ''Swiper''',
  16995. ' constructor New;',
  16996. ' end;',
  16997. ' TObject = class',
  16998. ' private',
  16999. ' FSwiper: JSwiper;',
  17000. ' published',
  17001. ' property Swiper: JSwiper read FSwiper write FSwiper;',
  17002. ' end;',
  17003. 'begin',
  17004. ' JSwiper.new;',
  17005. '']);
  17006. ConvertProgram;
  17007. CheckSource('TestExternalClass_SameNamePublishedProperty',
  17008. LinesToStr([ // statements
  17009. 'this.$rtti.$ExtClass("JSwiper", {',
  17010. ' jsclass: "Swiper"',
  17011. '});',
  17012. 'rtl.createClass(this, "TObject", null, function () {',
  17013. ' this.$init = function () {',
  17014. ' this.FSwiper = null;',
  17015. ' };',
  17016. ' this.$final = function () {',
  17017. ' this.FSwiper = undefined;',
  17018. ' };',
  17019. ' var $r = this.$rtti;',
  17020. ' $r.addProperty("Swiper", 0, $mod.$rtti["JSwiper"], "FSwiper", "FSwiper");',
  17021. '});',
  17022. '']),
  17023. LinesToStr([ // $mod.$main
  17024. 'new Swiper();',
  17025. '']));
  17026. end;
  17027. procedure TTestModule.TestExternalClass_Property;
  17028. begin
  17029. StartProgram(false);
  17030. Add([
  17031. '{$modeswitch externalclass}',
  17032. 'type',
  17033. ' TExtA = class external name ''ExtA''',
  17034. ' function getYear: longint;',
  17035. ' procedure setYear(Value: longint);',
  17036. ' property Year: longint read getyear write setyear;',
  17037. ' end;',
  17038. ' TExtB = class (TExtA)',
  17039. ' procedure OtherSetYear(Value: longint);',
  17040. ' property year write othersetyear;',
  17041. ' end;',
  17042. 'procedure textb.othersetyear(value: longint);',
  17043. 'begin',
  17044. ' setYear(Value+4);',
  17045. 'end;',
  17046. 'var',
  17047. ' A: texta;',
  17048. ' B: textb;',
  17049. 'begin',
  17050. ' a.year:=a.year+1;',
  17051. ' b.year:=b.year+2;']);
  17052. ConvertProgram;
  17053. CheckSource('TestExternalClass_NonExternalOverride',
  17054. LinesToStr([ // statements
  17055. 'rtl.createClassExt(this, "TExtB", ExtA, "", function () {',
  17056. ' this.$init = function () {',
  17057. ' };',
  17058. ' this.$final = function () {',
  17059. ' };',
  17060. ' this.OtherSetYear = function (Value) {',
  17061. ' this.setYear(Value+4);',
  17062. ' };',
  17063. '});',
  17064. 'this.A = null;',
  17065. 'this.B = null;',
  17066. '']),
  17067. LinesToStr([ // $mod.$main
  17068. '$mod.A.setYear($mod.A.getYear()+1);',
  17069. '$mod.B.OtherSetYear($mod.B.getYear()+2);',
  17070. '']));
  17071. end;
  17072. procedure TTestModule.TestExternalClass_PropertyDate;
  17073. begin
  17074. StartProgram(false);
  17075. Add([
  17076. '{$modeswitch externalclass}',
  17077. 'type',
  17078. ' TExtA = class external name ''ExtA''',
  17079. ' end;',
  17080. ' TExtB = class (TExtA)',
  17081. ' FDate: string;',
  17082. ' property Date: string read FDate write FDate;',
  17083. ' property ExtA: string read FDate write FDate;',
  17084. ' end;',
  17085. ' {$M+}',
  17086. ' TObject = class',
  17087. ' FDate: string;',
  17088. ' published',
  17089. ' property Date: string read FDate write FDate;',
  17090. ' property ExtA: string read FDate write FDate;',
  17091. ' end;',
  17092. 'var',
  17093. ' B: textb;',
  17094. ' o: TObject;',
  17095. 'begin',
  17096. ' b.date:=b.exta;',
  17097. ' o.date:=o.exta;']);
  17098. ConvertProgram;
  17099. CheckSource('TestExternalClass_PropertyDate',
  17100. LinesToStr([ // statements
  17101. 'rtl.createClassExt(this, "TExtB", ExtA, "", function () {',
  17102. ' this.$init = function () {',
  17103. ' this.FDate = "";',
  17104. ' };',
  17105. ' this.$final = function () {',
  17106. ' };',
  17107. '});',
  17108. 'rtl.createClass(this, "TObject", null, function () {',
  17109. ' this.$init = function () {',
  17110. ' this.FDate = "";',
  17111. ' };',
  17112. ' this.$final = function () {',
  17113. ' };',
  17114. ' var $r = this.$rtti;',
  17115. ' $r.addField("FDate", rtl.string);',
  17116. ' $r.addProperty("Date", 0, rtl.string, "FDate", "FDate");',
  17117. ' $r.addProperty("ExtA", 0, rtl.string, "FDate", "FDate");',
  17118. '});',
  17119. 'this.B = null;',
  17120. 'this.o = null;',
  17121. '']),
  17122. LinesToStr([ // $mod.$main
  17123. '$mod.B.FDate = $mod.B.FDate;',
  17124. '$mod.o.FDate = $mod.o.FDate;',
  17125. '']));
  17126. end;
  17127. procedure TTestModule.TestExternalClass_ClassProperty;
  17128. begin
  17129. StartProgram(false);
  17130. Add('{$modeswitch externalclass}');
  17131. Add('type');
  17132. Add(' TExtA = class external name ''ExtA''');
  17133. Add(' class function getYear: longint;');
  17134. Add(' class procedure setYear(Value: longint);');
  17135. Add(' class property Year: longint read getyear write setyear;');
  17136. Add(' end;');
  17137. Add(' TExtB = class (TExtA)');
  17138. Add(' class function GetCentury: longint;');
  17139. Add(' class procedure SetCentury(Value: longint);');
  17140. Add(' class property Century: longint read getcentury write setcentury;');
  17141. Add(' end;');
  17142. Add('class function textb.getcentury: longint;');
  17143. Add('begin');
  17144. Add('end;');
  17145. Add('class procedure textb.setcentury(value: longint);');
  17146. Add('begin');
  17147. Add(' setyear(value+11);');
  17148. Add(' texta.year:=texta.year+12;');
  17149. Add(' year:=year+13;');
  17150. Add(' textb.century:=textb.century+14;');
  17151. Add(' century:=century+15;');
  17152. Add('end;');
  17153. Add('var');
  17154. Add(' A: texta;');
  17155. Add(' B: textb;');
  17156. Add('begin');
  17157. Add(' texta.year:=texta.year+1;');
  17158. Add(' textb.year:=textb.year+2;');
  17159. Add(' TextA.year:=TextA.year+3;');
  17160. Add(' b.year:=b.year+4;');
  17161. Add(' textb.century:=textb.century+5;');
  17162. Add(' b.century:=b.century+6;');
  17163. ConvertProgram;
  17164. CheckSource('TestExternalClass_ClassProperty',
  17165. LinesToStr([ // statements
  17166. 'rtl.createClassExt(this, "TExtB", ExtA, "", function () {',
  17167. ' this.$init = function () {',
  17168. ' };',
  17169. ' this.$final = function () {',
  17170. ' };',
  17171. ' this.GetCentury = function () {',
  17172. ' var Result = 0;',
  17173. ' return Result;',
  17174. ' };',
  17175. ' this.SetCentury = function (Value) {',
  17176. ' this.setYear(Value + 11);',
  17177. ' ExtA.setYear(ExtA.getYear() + 12);',
  17178. ' this.setYear(this.getYear() + 13);',
  17179. ' $mod.TExtB.SetCentury($mod.TExtB.GetCentury() + 14);',
  17180. ' this.SetCentury(this.GetCentury() + 15);',
  17181. ' };',
  17182. '});',
  17183. 'this.A = null;',
  17184. 'this.B = null;',
  17185. '']),
  17186. LinesToStr([ // $mod.$main
  17187. 'ExtA.setYear(ExtA.getYear() + 1);',
  17188. '$mod.TExtB.setYear($mod.TExtB.getYear() + 2);',
  17189. 'ExtA.setYear(ExtA.getYear() + 3);',
  17190. '$mod.B.setYear($mod.B.getYear() + 4);',
  17191. '$mod.TExtB.SetCentury($mod.TExtB.GetCentury() + 5);',
  17192. '$mod.B.$class.SetCentury($mod.B.$class.GetCentury() + 6);',
  17193. '']));
  17194. end;
  17195. procedure TTestModule.TestExternalClass_ClassOf;
  17196. begin
  17197. StartProgram(false);
  17198. Add('{$modeswitch externalclass}');
  17199. Add('type');
  17200. Add(' TExtA = class external name ''ExtA''');
  17201. Add(' procedure ProcA; virtual;');
  17202. Add(' procedure ProcB; virtual;');
  17203. Add(' end;');
  17204. Add(' TExtAClass = class of TExtA;');
  17205. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  17206. Add(' end;');
  17207. Add(' TExtBClass = class of TExtB;');
  17208. Add(' TExtC = class (TExtB)');
  17209. Add(' procedure ProcA; override;');
  17210. Add(' end;');
  17211. Add(' TExtCClass = class of TExtC;');
  17212. Add('procedure TExtC.ProcA; begin end;');
  17213. Add('var');
  17214. Add(' A: texta; ClA: TExtAClass;');
  17215. Add(' B: textb; ClB: TExtBClass;');
  17216. Add(' C: textc; ClC: TExtCClass;');
  17217. Add('begin');
  17218. Add(' ClA:=texta;');
  17219. Add(' ClA:=textb;');
  17220. Add(' ClA:=textc;');
  17221. Add(' ClB:=textb;');
  17222. Add(' ClB:=textc;');
  17223. Add(' ClC:=textc;');
  17224. ConvertProgram;
  17225. CheckSource('TestExternalClass_ClassOf',
  17226. LinesToStr([ // statements
  17227. 'rtl.createClassExt(this, "TExtC", ExtB, "", function () {',
  17228. ' this.$init = function () {',
  17229. ' };',
  17230. ' this.$final = function () {',
  17231. ' };',
  17232. ' this.ProcA = function () {',
  17233. ' };',
  17234. '});',
  17235. 'this.A = null;',
  17236. 'this.ClA = null;',
  17237. 'this.B = null;',
  17238. 'this.ClB = null;',
  17239. 'this.C = null;',
  17240. 'this.ClC = null;',
  17241. '']),
  17242. LinesToStr([ // $mod.$main
  17243. '$mod.ClA = ExtA;',
  17244. '$mod.ClA = ExtB;',
  17245. '$mod.ClA = $mod.TExtC;',
  17246. '$mod.ClB = ExtB;',
  17247. '$mod.ClB = $mod.TExtC;',
  17248. '$mod.ClC = $mod.TExtC;',
  17249. '']));
  17250. end;
  17251. procedure TTestModule.TestExternalClass_ClassOtherUnit;
  17252. begin
  17253. AddModuleWithIntfImplSrc('unit2.pas',
  17254. LinesToStr([
  17255. '{$modeswitch externalclass}',
  17256. 'type',
  17257. ' TExtA = class external name ''ExtA''',
  17258. ' class var Id: longint;',
  17259. ' end;',
  17260. '']),
  17261. '');
  17262. StartUnit(true);
  17263. Add('interface');
  17264. Add('uses unit2;');
  17265. Add('implementation');
  17266. Add('begin');
  17267. Add(' unit2.texta.id:=unit2.texta.id+1;');
  17268. ConvertUnit;
  17269. CheckSource('TestExternalClass_ClassOtherUnit',
  17270. LinesToStr([
  17271. '']),
  17272. LinesToStr([
  17273. 'ExtA.Id = ExtA.Id + 1;',
  17274. '']));
  17275. end;
  17276. procedure TTestModule.TestExternalClass_Is;
  17277. begin
  17278. StartProgram(false);
  17279. Add([
  17280. '{$modeswitch externalclass}',
  17281. 'type',
  17282. ' TExtA = class external name ''ExtA''',
  17283. ' end;',
  17284. ' TExtAClass = class of TExtA;',
  17285. ' TExtB = class external name ''ExtB'' (TExtA)',
  17286. ' end;',
  17287. ' TExtBClass = class of TExtB;',
  17288. ' TExtC = class (TExtB)',
  17289. ' end;',
  17290. ' TExtCClass = class of TExtC;',
  17291. 'var',
  17292. ' A: texta; ClA: TExtAClass;',
  17293. ' B: textb; ClB: TExtBClass;',
  17294. ' C: textc; ClC: TExtCClass;',
  17295. 'begin',
  17296. ' if a is textb then ;',
  17297. ' if a is textc then ;',
  17298. ' if b is textc then ;',
  17299. ' if cla is textb then ;',
  17300. ' if cla is textc then ;',
  17301. ' if clb is textc then ;',
  17302. ' try',
  17303. ' except',
  17304. ' on TExtA do ;',
  17305. ' on e: TExtB do ;',
  17306. ' end;',
  17307. '']);
  17308. ConvertProgram;
  17309. CheckSource('TestExternalClass_Is',
  17310. LinesToStr([ // statements
  17311. 'rtl.createClassExt(this, "TExtC", ExtB, "", function () {',
  17312. ' this.$init = function () {',
  17313. ' };',
  17314. ' this.$final = function () {',
  17315. ' };',
  17316. '});',
  17317. 'this.A = null;',
  17318. 'this.ClA = null;',
  17319. 'this.B = null;',
  17320. 'this.ClB = null;',
  17321. 'this.C = null;',
  17322. 'this.ClC = null;',
  17323. '']),
  17324. LinesToStr([ // $mod.$main
  17325. 'if (rtl.isExt($mod.A, ExtB)) ;',
  17326. 'if ($mod.TExtC.isPrototypeOf($mod.A)) ;',
  17327. 'if ($mod.TExtC.isPrototypeOf($mod.B)) ;',
  17328. 'if (rtl.isExt($mod.ClA, ExtB)) ;',
  17329. 'if (rtl.is($mod.ClA, $mod.TExtC)) ;',
  17330. 'if (rtl.is($mod.ClB, $mod.TExtC)) ;',
  17331. 'try {} catch ($e) {',
  17332. ' if (rtl.isExt($e,ExtA)) {}',
  17333. ' else if (rtl.isExt($e,ExtB)) {',
  17334. ' var e = $e;',
  17335. ' } else throw $e',
  17336. '};',
  17337. '']));
  17338. end;
  17339. procedure TTestModule.TestExternalClass_As;
  17340. begin
  17341. StartProgram(false);
  17342. Add('{$modeswitch externalclass}');
  17343. Add('type');
  17344. Add(' TExtA = class external name ''ExtA''');
  17345. Add(' end;');
  17346. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  17347. Add(' end;');
  17348. Add(' TExtC = class (TExtB)');
  17349. Add(' end;');
  17350. Add('var');
  17351. Add(' A: texta;');
  17352. Add(' B: textb;');
  17353. Add(' C: textc;');
  17354. Add('begin');
  17355. Add(' b:=a as textb;');
  17356. Add(' c:=a as textc;');
  17357. Add(' c:=b as textc;');
  17358. ConvertProgram;
  17359. CheckSource('TestExternalClass_Is',
  17360. LinesToStr([ // statements
  17361. 'rtl.createClassExt(this, "TExtC", ExtB, "", function () {',
  17362. ' this.$init = function () {',
  17363. ' };',
  17364. ' this.$final = function () {',
  17365. ' };',
  17366. '});',
  17367. 'this.A = null;',
  17368. 'this.B = null;',
  17369. 'this.C = null;',
  17370. '']),
  17371. LinesToStr([ // $mod.$main
  17372. '$mod.B = rtl.asExt($mod.A, ExtB);',
  17373. '$mod.C = rtl.as($mod.A, $mod.TExtC);',
  17374. '$mod.C = rtl.as($mod.B, $mod.TExtC);',
  17375. '']));
  17376. end;
  17377. procedure TTestModule.TestExternalClass_DestructorFail;
  17378. begin
  17379. StartProgram(false);
  17380. Add('{$modeswitch externalclass}');
  17381. Add('type');
  17382. Add(' TExtA = class external name ''ExtA''');
  17383. Add(' destructor Free;');
  17384. Add(' end;');
  17385. SetExpectedPasResolverError('Pascal element not supported: destructor',
  17386. nPasElementNotSupported);
  17387. ConvertProgram;
  17388. end;
  17389. procedure TTestModule.TestExternalClass_New;
  17390. begin
  17391. StartProgram(false);
  17392. Add([
  17393. '{$modeswitch externalclass}',
  17394. 'type',
  17395. ' TExtA = class external name ''ExtA''',
  17396. ' constructor New;',
  17397. ' constructor New(i: longint; j: longint = 2);',
  17398. ' end;',
  17399. 'var',
  17400. ' A: texta;',
  17401. 'begin',
  17402. ' a:=texta.new;',
  17403. ' a:=texta(texta.new);',
  17404. ' a:=texta.new();',
  17405. ' a:=texta.new(1);',
  17406. ' with texta do begin',
  17407. ' a:=new;',
  17408. ' a:=new();',
  17409. ' a:=new(2);',
  17410. ' end;',
  17411. ' a:=test1.texta.new;',
  17412. ' a:=test1.texta.new();',
  17413. ' a:=test1.texta.new(3);',
  17414. '']);
  17415. ConvertProgram;
  17416. CheckSource('TestExternalClass_New',
  17417. LinesToStr([ // statements
  17418. 'this.A = null;',
  17419. '']),
  17420. LinesToStr([ // $mod.$main
  17421. '$mod.A = new ExtA();',
  17422. '$mod.A = new ExtA();',
  17423. '$mod.A = new ExtA();',
  17424. '$mod.A = new ExtA(1,2);',
  17425. '$mod.A = new ExtA();',
  17426. '$mod.A = new ExtA();',
  17427. '$mod.A = new ExtA(2,2);',
  17428. '$mod.A = new ExtA();',
  17429. '$mod.A = new ExtA();',
  17430. '$mod.A = new ExtA(3,2);',
  17431. '']));
  17432. end;
  17433. procedure TTestModule.TestExternalClass_ClassOf_New;
  17434. begin
  17435. StartProgram(false);
  17436. Add('{$modeswitch externalclass}');
  17437. Add('type');
  17438. Add(' TExtAClass = class of TExtA;');
  17439. Add(' TExtA = class external name ''ExtA''');
  17440. Add(' C: TExtAClass;');
  17441. Add(' constructor New;');
  17442. Add(' end;');
  17443. Add('var');
  17444. Add(' A: texta;');
  17445. Add(' C: textaclass;');
  17446. Add('begin');
  17447. Add(' a:=c.new;');
  17448. Add(' a:=c.new();');
  17449. Add(' with C do begin');
  17450. Add(' a:=new;');
  17451. Add(' a:=new();');
  17452. Add(' end;');
  17453. Add(' a:=test1.c.new;');
  17454. Add(' a:=test1.c.new();');
  17455. Add(' a:=A.c.new();');
  17456. ConvertProgram;
  17457. CheckSource('TestExternalClass_ClassOf_New',
  17458. LinesToStr([ // statements
  17459. 'this.A = null;',
  17460. 'this.C = null;',
  17461. '']),
  17462. LinesToStr([ // $mod.$main
  17463. '$mod.A = new $mod.C();',
  17464. '$mod.A = new $mod.C();',
  17465. 'var $with = $mod.C;',
  17466. '$mod.A = new $with();',
  17467. '$mod.A = new $with();',
  17468. '$mod.A = new $mod.C();',
  17469. '$mod.A = new $mod.C();',
  17470. '$mod.A = new $mod.A.C();',
  17471. '']));
  17472. end;
  17473. procedure TTestModule.TestExternalClass_FuncClassOf_New;
  17474. begin
  17475. StartProgram(false);
  17476. Add([
  17477. '{$modeswitch externalclass}',
  17478. 'type',
  17479. ' TExtAClass = class of TExtA;',
  17480. ' TExtA = class external name ''ExtA''',
  17481. ' constructor New;',
  17482. ' end;',
  17483. 'function GetCreator: TExtAClass;',
  17484. 'begin',
  17485. ' Result:=TExtA;',
  17486. 'end;',
  17487. 'var',
  17488. ' A: texta;',
  17489. 'begin',
  17490. ' a:=getcreator.new;',
  17491. ' a:=getcreator().new;',
  17492. ' a:=getcreator().new();',
  17493. ' a:=getcreator.new();',
  17494. ' with getcreator do begin',
  17495. ' a:=new;',
  17496. ' a:=new();',
  17497. ' end;']);
  17498. ConvertProgram;
  17499. CheckSource('TestExternalClass_FuncClassOf_New',
  17500. LinesToStr([ // statements
  17501. 'this.GetCreator = function () {',
  17502. ' var Result = null;',
  17503. ' Result = ExtA;',
  17504. ' return Result;',
  17505. '};',
  17506. 'this.A = null;',
  17507. '']),
  17508. LinesToStr([ // $mod.$main
  17509. '$mod.A = new ($mod.GetCreator())();',
  17510. '$mod.A = new ($mod.GetCreator())();',
  17511. '$mod.A = new ($mod.GetCreator())();',
  17512. '$mod.A = new ($mod.GetCreator())();',
  17513. 'var $with = $mod.GetCreator();',
  17514. '$mod.A = new $with();',
  17515. '$mod.A = new $with();',
  17516. '']));
  17517. end;
  17518. procedure TTestModule.TestExternalClass_New_PasClassFail;
  17519. begin
  17520. StartProgram(false);
  17521. Add([
  17522. '{$modeswitch externalclass}',
  17523. 'type',
  17524. ' TExtA = class external name ''ExtA''',
  17525. ' constructor New;',
  17526. ' end;',
  17527. ' TBird = class(TExtA)',
  17528. ' end;',
  17529. 'begin',
  17530. ' TBird.new;',
  17531. '']);
  17532. SetExpectedPasResolverError(sJSNewNotSupported,nJSNewNotSupported);
  17533. ConvertProgram;
  17534. end;
  17535. procedure TTestModule.TestExternalClass_New_PasClassBracketsFail;
  17536. begin
  17537. StartProgram(false);
  17538. Add([
  17539. '{$modeswitch externalclass}',
  17540. 'type',
  17541. ' TExtA = class external name ''ExtA''',
  17542. ' constructor New;',
  17543. ' end;',
  17544. ' TBird = class(TExtA)',
  17545. ' end;',
  17546. 'begin',
  17547. ' TBird.new();',
  17548. '']);
  17549. SetExpectedPasResolverError(sJSNewNotSupported,nJSNewNotSupported);
  17550. ConvertProgram;
  17551. end;
  17552. procedure TTestModule.TestExternalClass_NewExtName;
  17553. begin
  17554. StartProgram(false);
  17555. Add([
  17556. '{$modeswitch externalclass}',
  17557. 'type',
  17558. ' TExtA = class external name ''ExtA''',
  17559. ' constructor New; external name ''Other'';',
  17560. ' constructor New(i: longint; j: longint = 2); external name ''A.B'';',
  17561. ' end;',
  17562. 'var',
  17563. ' A: texta;',
  17564. 'begin',
  17565. ' a:=texta.new;',
  17566. ' a:=texta(texta.new);',
  17567. ' a:=texta.new();',
  17568. ' a:=texta.new(1);',
  17569. ' with texta do begin',
  17570. ' a:=new;',
  17571. ' a:=new();',
  17572. ' a:=new(2);',
  17573. ' end;',
  17574. ' a:=test1.texta.new;',
  17575. ' a:=test1.texta.new();',
  17576. ' a:=test1.texta.new(3);',
  17577. '']);
  17578. ConvertProgram;
  17579. CheckSource('TestExternalClass_NewExtName',
  17580. LinesToStr([ // statements
  17581. 'this.A = null;',
  17582. '']),
  17583. LinesToStr([ // $mod.$main
  17584. '$mod.A = new Other();',
  17585. '$mod.A = new Other();',
  17586. '$mod.A = new Other();',
  17587. '$mod.A = new A.B(1,2);',
  17588. '$mod.A = new Other();',
  17589. '$mod.A = new Other();',
  17590. '$mod.A = new A.B(2,2);',
  17591. '$mod.A = new Other();',
  17592. '$mod.A = new Other();',
  17593. '$mod.A = new A.B(3,2);',
  17594. '']));
  17595. end;
  17596. procedure TTestModule.TestExternalClass_Constructor;
  17597. begin
  17598. StartProgram(false);
  17599. Add([
  17600. '{$modeswitch externalclass}',
  17601. 'type',
  17602. ' TExtA = class external name ''ExtA''',
  17603. ' public type',
  17604. ' TExtB = class external name ''ExtB''',
  17605. ' public type',
  17606. ' TExtC = class external name ''ExtC''',
  17607. ' constructor New;',
  17608. ' constructor New(i: word);',
  17609. ' end;',
  17610. ' end;',
  17611. ' constructor Create;',
  17612. ' constructor Create(i: longint; j: longint = 2);',
  17613. ' end;',
  17614. 'var',
  17615. ' A: texta;',
  17616. ' C: texta.textb.textc;',
  17617. 'begin',
  17618. ' a:=texta.create;',
  17619. ' a:=texta(texta.create);',
  17620. ' a:=texta.create();',
  17621. ' a:=texta.create(1);',
  17622. ' with texta do begin',
  17623. ' a:=create;',
  17624. ' a:=create();',
  17625. ' a:=create(2);',
  17626. ' end;',
  17627. ' a:=test1.texta.create;',
  17628. ' a:=test1.texta.create();',
  17629. ' a:=test1.texta.create(3);',
  17630. ' c:=texta.textb.textc.new;',
  17631. ' c:=texta.textb.textc.new();',
  17632. ' c:=texta.textb.textc.new(4);',
  17633. '']);
  17634. ConvertProgram;
  17635. CheckSource('TestExternalClass_Constructor',
  17636. LinesToStr([ // statements
  17637. 'this.A = null;',
  17638. 'this.C = null;',
  17639. '']),
  17640. LinesToStr([ // $mod.$main
  17641. '$mod.A = new ExtA.Create();',
  17642. '$mod.A = new ExtA.Create();',
  17643. '$mod.A = new ExtA.Create();',
  17644. '$mod.A = new ExtA.Create(1,2);',
  17645. '$mod.A = new ExtA.Create();',
  17646. '$mod.A = new ExtA.Create();',
  17647. '$mod.A = new ExtA.Create(2,2);',
  17648. '$mod.A = new ExtA.Create();',
  17649. '$mod.A = new ExtA.Create();',
  17650. '$mod.A = new ExtA.Create(3,2);',
  17651. '$mod.C = new ExtA.ExtB.ExtC();',
  17652. '$mod.C = new ExtA.ExtB.ExtC();',
  17653. '$mod.C = new ExtA.ExtB.ExtC(4);',
  17654. '']));
  17655. end;
  17656. procedure TTestModule.TestExternalClass_ConstructorBrackets;
  17657. begin
  17658. StartProgram(false);
  17659. Add([
  17660. '{$modeswitch externalclass}',
  17661. 'type',
  17662. ' TExtA = class external name ''ExtA''',
  17663. ' constructor Create; external name ''{}'';',
  17664. ' end;',
  17665. 'var',
  17666. ' A: texta;',
  17667. 'begin',
  17668. ' a:=texta.create;',
  17669. ' a:=texta(texta.create);',
  17670. ' a:=texta.create();',
  17671. ' with texta do begin',
  17672. ' a:=create;',
  17673. ' a:=create();',
  17674. ' end;',
  17675. ' a:=test1.texta.create;',
  17676. ' a:=test1.texta.create();',
  17677. '']);
  17678. ConvertProgram;
  17679. CheckSource('TestExternalClass_ConstructorBrackets',
  17680. LinesToStr([ // statements
  17681. 'this.A = null;',
  17682. '']),
  17683. LinesToStr([ // $mod.$main
  17684. '$mod.A = {};',
  17685. '$mod.A = {};',
  17686. '$mod.A = {};',
  17687. '$mod.A = {};',
  17688. '$mod.A = {};',
  17689. '$mod.A = {};',
  17690. '$mod.A = {};',
  17691. '']));
  17692. end;
  17693. procedure TTestModule.TestExternalClass_LocalConstSameName;
  17694. begin
  17695. StartProgram(false);
  17696. Add('{$modeswitch externalclass}');
  17697. Add('type');
  17698. Add(' TExtA = class external name ''ExtA''');
  17699. Add(' constructor New;');
  17700. Add(' end;');
  17701. Add('function DoIt: longint;');
  17702. Add('const ExtA: longint = 3;');
  17703. Add('begin');
  17704. Add(' Result:=ExtA;');
  17705. Add('end;');
  17706. Add('var');
  17707. Add(' A: texta;');
  17708. Add('begin');
  17709. Add(' a:=texta.new;');
  17710. ConvertProgram;
  17711. CheckSource('TestExternalClass_LocalConstSameName',
  17712. LinesToStr([ // statements
  17713. 'var ExtA$1 = 3;',
  17714. 'this.DoIt = function () {',
  17715. ' var Result = 0;',
  17716. ' Result = ExtA$1;',
  17717. ' return Result;',
  17718. '};',
  17719. 'this.A = null;',
  17720. '']),
  17721. LinesToStr([ // $mod.$main
  17722. '$mod.A = new ExtA();',
  17723. '']));
  17724. end;
  17725. procedure TTestModule.TestExternalClass_ReintroduceOverload;
  17726. begin
  17727. StartProgram(false);
  17728. Add('{$modeswitch externalclass}');
  17729. Add('type');
  17730. Add(' TExtA = class external name ''ExtA''');
  17731. Add(' procedure DoIt;');
  17732. Add(' end;');
  17733. Add(' TMyA = class(TExtA)');
  17734. Add(' procedure DoIt;');
  17735. Add(' end;');
  17736. Add('procedure TMyA.DoIt; begin end;');
  17737. Add('begin');
  17738. ConvertProgram;
  17739. CheckSource('TestExternalClass_ReintroduceOverload',
  17740. LinesToStr([ // statements
  17741. 'rtl.createClassExt(this, "TMyA", ExtA, "", function () {',
  17742. ' this.$init = function () {',
  17743. ' };',
  17744. ' this.$final = function () {',
  17745. ' };',
  17746. ' this.DoIt$1 = function () {',
  17747. ' };',
  17748. '});',
  17749. '']),
  17750. LinesToStr([ // $mod.$main
  17751. '']));
  17752. end;
  17753. procedure TTestModule.TestExternalClass_Inherited;
  17754. begin
  17755. StartProgram(false);
  17756. Add('{$modeswitch externalclass}');
  17757. Add('type');
  17758. Add(' TExtA = class external name ''ExtA''');
  17759. Add(' procedure DoIt(i: longint = 1); virtual;');
  17760. Add(' procedure DoSome(j: longint = 2);');
  17761. Add(' end;');
  17762. Add(' TExtB = class external name ''ExtB''(TExtA)');
  17763. Add(' end;');
  17764. Add(' TMyC = class(TExtB)');
  17765. Add(' procedure DoIt(i: longint = 1); override;');
  17766. Add(' procedure DoSome(j: longint = 2); reintroduce;');
  17767. Add(' end;');
  17768. Add('procedure TMyC.DoIt(i: longint);');
  17769. Add('begin');
  17770. Add(' inherited;');
  17771. Add(' inherited DoIt;');
  17772. Add(' inherited DoIt();');
  17773. Add(' inherited DoIt(3);');
  17774. Add(' inherited DoSome;');
  17775. Add(' inherited DoSome();');
  17776. Add(' inherited DoSome(4);');
  17777. Add('end;');
  17778. Add('procedure TMyC.DoSome(j: longint);');
  17779. Add('begin');
  17780. Add(' inherited;');
  17781. Add('end;');
  17782. Add('begin');
  17783. ConvertProgram;
  17784. CheckSource('TestExternalClass_ReintroduceOverload',
  17785. LinesToStr([ // statements
  17786. 'rtl.createClassExt(this, "TMyC", ExtB, "", function () {',
  17787. ' this.$init = function () {',
  17788. ' };',
  17789. ' this.$final = function () {',
  17790. ' };',
  17791. ' this.DoIt = function (i) {',
  17792. ' ExtB.DoIt.apply(this, arguments);',
  17793. ' ExtB.DoIt.call(this, 1);',
  17794. ' ExtB.DoIt.call(this, 1);',
  17795. ' ExtB.DoIt.call(this, 3);',
  17796. ' ExtB.DoSome.call(this, 2);',
  17797. ' ExtB.DoSome.call(this, 2);',
  17798. ' ExtB.DoSome.call(this, 4);',
  17799. ' };',
  17800. ' this.DoSome$1 = function (j) {',
  17801. ' ExtB.DoSome.apply(this, arguments);',
  17802. ' };',
  17803. '});',
  17804. '']),
  17805. LinesToStr([ // $mod.$main
  17806. '']));
  17807. end;
  17808. procedure TTestModule.TestExternalClass_PascalAncestorFail;
  17809. begin
  17810. StartProgram(false);
  17811. Add('{$modeswitch externalclass}');
  17812. Add('type');
  17813. Add(' TObject = class');
  17814. Add(' end;');
  17815. Add(' TExtA = class external name ''ExtA''(TObject)');
  17816. Add(' end;');
  17817. Add('begin');
  17818. SetExpectedPasResolverError('Ancestor "TObject" is not external',nAncestorIsNotExternal);
  17819. ConvertProgram;
  17820. end;
  17821. procedure TTestModule.TestExternalClass_NewInstance;
  17822. begin
  17823. StartProgram(false);
  17824. Add('{$modeswitch externalclass}');
  17825. Add('type');
  17826. Add(' TExtA = class external name ''ExtA''');
  17827. Add(' end;');
  17828. Add(' TMyB = class(TExtA)');
  17829. Add(' protected');
  17830. Add(' class function NewInstance(fnname: string; const paramarray): TMyB; virtual;');
  17831. Add(' end;');
  17832. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  17833. Add('begin end;');
  17834. Add('begin');
  17835. ConvertProgram;
  17836. CheckSource('TestExternalClass_NewInstance',
  17837. LinesToStr([ // statements
  17838. 'rtl.createClassExt(this, "TMyB", ExtA, "NewInstance", function () {',
  17839. ' this.$init = function () {',
  17840. ' };',
  17841. ' this.$final = function () {',
  17842. ' };',
  17843. ' this.NewInstance = function (fnname, paramarray) {',
  17844. ' var Result = null;',
  17845. ' return Result;',
  17846. ' };',
  17847. '});',
  17848. '']),
  17849. LinesToStr([ // $mod.$main
  17850. '']));
  17851. end;
  17852. procedure TTestModule.TestExternalClass_NewInstance_NonVirtualFail;
  17853. begin
  17854. StartProgram(false);
  17855. Add('{$modeswitch externalclass}');
  17856. Add('type');
  17857. Add(' TExtA = class external name ''ExtA''');
  17858. Add(' end;');
  17859. Add(' TMyB = class(TExtA)');
  17860. Add(' protected');
  17861. Add(' class function NewInstance(fnname: string; const paramarray): TMyB;');
  17862. Add(' end;');
  17863. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  17864. Add('begin end;');
  17865. Add('begin');
  17866. SetExpectedPasResolverError(sNewInstanceFunctionMustBeVirtual,nNewInstanceFunctionMustBeVirtual);
  17867. ConvertProgram;
  17868. end;
  17869. procedure TTestModule.TestExternalClass_NewInstance_FirstParamNotString_Fail;
  17870. begin
  17871. StartProgram(false);
  17872. Add('{$modeswitch externalclass}');
  17873. Add('type');
  17874. Add(' TExtA = class external name ''ExtA''');
  17875. Add(' end;');
  17876. Add(' TMyB = class(TExtA)');
  17877. Add(' protected');
  17878. Add(' class function NewInstance(fnname: longint; const paramarray): TMyB; virtual;');
  17879. Add(' end;');
  17880. Add('class function TMyB.NewInstance(fnname: longint; const paramarray): TMyB;');
  17881. Add('begin end;');
  17882. Add('begin');
  17883. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Longint", expected "String"',
  17884. nIncompatibleTypeArgNo);
  17885. ConvertProgram;
  17886. end;
  17887. procedure TTestModule.TestExternalClass_NewInstance_SecondParamTyped_Fail;
  17888. begin
  17889. StartProgram(false);
  17890. Add('{$modeswitch externalclass}');
  17891. Add('type');
  17892. Add(' TExtA = class external name ''ExtA''');
  17893. Add(' end;');
  17894. Add(' TMyB = class(TExtA)');
  17895. Add(' protected');
  17896. Add(' class function NewInstance(fnname: string; const paramarray: string): TMyB; virtual;');
  17897. Add(' end;');
  17898. Add('class function TMyB.NewInstance(fnname: string; const paramarray: string): TMyB;');
  17899. Add('begin end;');
  17900. Add('begin');
  17901. SetExpectedPasResolverError('Incompatible type arg no. 2: Got "type", expected "untyped"',
  17902. nIncompatibleTypeArgNo);
  17903. ConvertProgram;
  17904. end;
  17905. procedure TTestModule.TestExternalClass_JSFunctionPasDescendant;
  17906. begin
  17907. StartProgram(false);
  17908. Add([
  17909. '{$modeswitch externalclass}',
  17910. 'type',
  17911. ' TJSFunction = class external name ''Function''',
  17912. ' end;',
  17913. ' TExtA = class external name ''ExtA''(TJSFunction)',
  17914. ' constructor New(w: word);',
  17915. ' end;',
  17916. ' TBird = class (TExtA)',
  17917. ' public',
  17918. ' Size: word;',
  17919. ' class var Legs: word;',
  17920. ' constructor Create(a: word);',
  17921. ' end;',
  17922. ' TEagle = class (TBird)',
  17923. ' public',
  17924. ' constructor Create(b: word); reintroduce;',
  17925. ' end;',
  17926. 'constructor TBird.Create(a: word);',
  17927. 'begin',
  17928. ' inherited;', // silently ignored
  17929. ' inherited New(a);', // this.$func(a)
  17930. 'end;',
  17931. 'constructor TEagle.Create(b: word);',
  17932. 'begin',
  17933. ' inherited Create(b);',
  17934. 'end;',
  17935. 'var',
  17936. ' Bird: TBird;',
  17937. ' Eagle: TEagle;',
  17938. 'begin',
  17939. ' Bird:=TBird.Create(3);',
  17940. ' Eagle:=TEagle.Create(4);',
  17941. ' Bird.Size:=Bird.Size+5;',
  17942. ' Bird.Legs:=Bird.Legs+6;',
  17943. ' Eagle.Size:=Eagle.Size+5;',
  17944. ' Eagle.Legs:=Eagle.Legs+6;',
  17945. '']);
  17946. ConvertProgram;
  17947. CheckSource('TestExternalClass_JSFunctionPasDescendant',
  17948. LinesToStr([ // statements
  17949. 'rtl.createClassExt(this, "TBird", ExtA, "", function () {',
  17950. ' this.Legs = 0;',
  17951. ' this.$init = function () {',
  17952. ' this.Size = 0;',
  17953. ' };',
  17954. ' this.$final = function () {',
  17955. ' };',
  17956. ' this.Create = function (a) {',
  17957. ' this.$ancestorfunc(a);',
  17958. ' return this;',
  17959. ' };',
  17960. '});',
  17961. 'rtl.createClassExt(this, "TEagle", this.TBird, "", function () {',
  17962. ' this.Create$1 = function (b) {',
  17963. ' $mod.TBird.Create.call(this, b);',
  17964. ' return this;',
  17965. ' };',
  17966. '});',
  17967. 'this.Bird = null;',
  17968. 'this.Eagle = null;',
  17969. '']),
  17970. LinesToStr([ // $mod.$main
  17971. '$mod.Bird = $mod.TBird.$create("Create", [3]);',
  17972. '$mod.Eagle = $mod.TEagle.$create("Create$1", [4]);',
  17973. '$mod.Bird.Size = $mod.Bird.Size + 5;',
  17974. '$mod.TBird.Legs = $mod.Bird.Legs + 6;',
  17975. '$mod.Eagle.Size = $mod.Eagle.Size + 5;',
  17976. '$mod.TBird.Legs = $mod.Eagle.Legs + 6;',
  17977. '']));
  17978. end;
  17979. procedure TTestModule.TestExternalClass_PascalProperty;
  17980. begin
  17981. StartProgram(false);
  17982. Add('{$modeswitch externalclass}');
  17983. Add('type');
  17984. Add(' TJSElement = class;');
  17985. Add(' TJSNotifyEvent = procedure(Sender: TJSElement) of object;');
  17986. Add(' TJSElement = class external name ''ExtA''');
  17987. Add(' end;');
  17988. Add(' TControl = class(TJSElement)');
  17989. Add(' private');
  17990. Add(' FOnClick: TJSNotifyEvent;');
  17991. Add(' property OnClick: TJSNotifyEvent read FOnClick write FOnClick;');
  17992. Add(' procedure Click(Sender: TJSElement);');
  17993. Add(' end;');
  17994. Add('procedure TControl.Click(Sender: TJSElement);');
  17995. Add('begin');
  17996. Add(' OnClick(Self);');
  17997. Add('end;');
  17998. Add('var');
  17999. Add(' Ctrl: TControl;');
  18000. Add('begin');
  18001. Add(' Ctrl.OnClick:[email protected];');
  18002. Add(' Ctrl.OnClick(Ctrl);');
  18003. ConvertProgram;
  18004. CheckSource('TestExternalClass_PascalProperty',
  18005. LinesToStr([ // statements
  18006. 'rtl.createClassExt(this, "TControl", ExtA, "", function () {',
  18007. ' this.$init = function () {',
  18008. ' this.FOnClick = null;',
  18009. ' };',
  18010. ' this.$final = function () {',
  18011. ' this.FOnClick = undefined;',
  18012. ' };',
  18013. ' this.Click = function (Sender) {',
  18014. ' this.FOnClick(this);',
  18015. ' };',
  18016. '});',
  18017. 'this.Ctrl = null;',
  18018. '']),
  18019. LinesToStr([ // $mod.$main
  18020. '$mod.Ctrl.FOnClick = rtl.createCallback($mod.Ctrl, "Click");',
  18021. '$mod.Ctrl.FOnClick($mod.Ctrl);',
  18022. '']));
  18023. end;
  18024. procedure TTestModule.TestExternalClass_TypeCastToRootClass;
  18025. begin
  18026. StartProgram(false);
  18027. Add([
  18028. '{$modeswitch externalclass}',
  18029. 'type',
  18030. ' IUnknown = interface end;',
  18031. ' TObject = class',
  18032. ' end;',
  18033. ' TChild = class',
  18034. ' end;',
  18035. ' TExtRootA = class external name ''ExtRootA''',
  18036. ' end;',
  18037. ' TExtChildA = class external name ''ExtChildA''(TExtRootA)',
  18038. ' end;',
  18039. ' TExtRootB = class external name ''ExtRootB''',
  18040. ' end;',
  18041. ' TExtChildB = class external name ''ExtChildB''(TExtRootB)',
  18042. ' end;',
  18043. ' TExtString = class external name ''String''',
  18044. ' function charAt(aIndex : NativeInt) : string;',
  18045. ' end;',
  18046. 'var',
  18047. ' Obj: TObject;',
  18048. ' Child: TChild;',
  18049. ' RootA: TExtRootA;',
  18050. ' ChildA: TExtChildA;',
  18051. ' RootB: TExtRootB;',
  18052. ' ChildB: TExtChildB;',
  18053. ' i: IUnknown;',
  18054. ' s: string;',
  18055. ' v: jsvalue;',
  18056. 'begin',
  18057. ' obj:=tobject(roota);',
  18058. ' obj:=tobject(childa);',
  18059. ' child:=tchild(tobject(roota));',
  18060. ' roota:=textroota(obj);',
  18061. ' roota:=textroota(child);',
  18062. ' roota:=textroota(rootb);',
  18063. ' roota:=textroota(childb);',
  18064. ' childa:=textchilda(textroota(obj));',
  18065. ' roota:=TExtRootA(i);',
  18066. ' s:=TExtString(s).charAt(7);',
  18067. ' s:=TExtString(v).charAt(8);',
  18068. '']);
  18069. ConvertProgram;
  18070. CheckSource('TestExternalClass_TypeCastToRootClass',
  18071. LinesToStr([ // statements
  18072. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  18073. 'rtl.createClass(this, "TObject", null, function () {',
  18074. ' this.$init = function () {',
  18075. ' };',
  18076. ' this.$final = function () {',
  18077. ' };',
  18078. '});',
  18079. 'rtl.createClass(this, "TChild", this.TObject, function () {',
  18080. '});',
  18081. 'this.Obj = null;',
  18082. 'this.Child = null;',
  18083. 'this.RootA = null;',
  18084. 'this.ChildA = null;',
  18085. 'this.RootB = null;',
  18086. 'this.ChildB = null;',
  18087. 'this.i = null;',
  18088. 'this.s = "";',
  18089. 'this.v = undefined;',
  18090. '']),
  18091. LinesToStr([ // $mod.$main
  18092. '$mod.Obj = $mod.RootA;',
  18093. '$mod.Obj = $mod.ChildA;',
  18094. '$mod.Child = $mod.RootA;',
  18095. '$mod.RootA = $mod.Obj;',
  18096. '$mod.RootA = $mod.Child;',
  18097. '$mod.RootA = $mod.RootB;',
  18098. '$mod.RootA = $mod.ChildB;',
  18099. '$mod.ChildA = $mod.Obj;',
  18100. '$mod.RootA = $mod.i;',
  18101. '$mod.s = $mod.s.charAt(7);',
  18102. '$mod.s = $mod.v.charAt(8);',
  18103. '']));
  18104. end;
  18105. procedure TTestModule.TestExternalClass_TypeCastToJSObject;
  18106. begin
  18107. StartProgram(false);
  18108. Add([
  18109. '{$modeswitch externalclass}',
  18110. 'type',
  18111. ' IUnknown = interface end;',
  18112. ' IBird = interface(IUnknown) end;',
  18113. ' TClass = class of TObject;',
  18114. ' TObject = class',
  18115. ' end;',
  18116. ' TChild = class',
  18117. ' end;',
  18118. ' TJSObject = class external name ''Object''',
  18119. ' end;',
  18120. ' TRec = record end;',
  18121. 'var',
  18122. ' Obj: TObject;',
  18123. ' Child: TChild;',
  18124. ' i: IUnknown;',
  18125. ' Bird: IBird;',
  18126. ' j: TJSObject;',
  18127. ' r: TRec;',
  18128. ' c: TClass;',
  18129. 'begin',
  18130. ' j:=tjsobject(IUnknown);',
  18131. ' j:=tjsobject(IBird);',
  18132. ' j:=tjsobject(TObject);',
  18133. ' j:=tjsobject(TChild);',
  18134. ' j:=tjsobject(TRec);',
  18135. ' j:=tjsobject(Obj);',
  18136. ' j:=tjsobject(Child);',
  18137. ' j:=tjsobject(i);',
  18138. ' j:=tjsobject(Bird);',
  18139. ' j:=tjsobject(r);',
  18140. ' j:=tjsobject(c);',
  18141. '']);
  18142. ConvertProgram;
  18143. CheckSource('TestExternalClass_TypeCastToJSObject',
  18144. LinesToStr([ // statements
  18145. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  18146. 'rtl.createInterface(this, "IBird", "{4B0D080B-C0F6-396E-AE88-000B87785074}", [], this.IUnknown);',
  18147. 'rtl.createClass(this, "TObject", null, function () {',
  18148. ' this.$init = function () {',
  18149. ' };',
  18150. ' this.$final = function () {',
  18151. ' };',
  18152. '});',
  18153. 'rtl.createClass(this, "TChild", this.TObject, function () {',
  18154. '});',
  18155. 'rtl.recNewT(this, "TRec", function () {',
  18156. ' this.$eq = function (b) {',
  18157. ' return true;',
  18158. ' };',
  18159. ' this.$assign = function (s) {',
  18160. ' return this;',
  18161. ' };',
  18162. '});',
  18163. 'this.Obj = null;',
  18164. 'this.Child = null;',
  18165. 'this.i = null;',
  18166. 'this.Bird = null;',
  18167. 'this.j = null;',
  18168. 'this.r = this.TRec.$new();',
  18169. 'this.c = null;',
  18170. '']),
  18171. LinesToStr([ // $mod.$main
  18172. '$mod.j = $mod.IUnknown;',
  18173. '$mod.j = $mod.IBird;',
  18174. '$mod.j = $mod.TObject;',
  18175. '$mod.j = $mod.TChild;',
  18176. '$mod.j = $mod.TRec;',
  18177. '$mod.j = $mod.Obj;',
  18178. '$mod.j = $mod.Child;',
  18179. '$mod.j = $mod.i;',
  18180. '$mod.j = $mod.Bird;',
  18181. '$mod.j = $mod.r;',
  18182. '$mod.j = $mod.c;',
  18183. '']));
  18184. end;
  18185. procedure TTestModule.TestExternalClass_TypeCastStringToExternalString;
  18186. begin
  18187. StartProgram(false);
  18188. Add('{$modeswitch externalclass}');
  18189. Add('type');
  18190. Add(' TJSString = class external name ''String''');
  18191. Add(' class function fromCharCode() : string; varargs;');
  18192. Add(' function anchor(const aName : string) : string;');
  18193. Add(' end;');
  18194. Add('var');
  18195. Add(' s: string;');
  18196. Add('begin');
  18197. Add(' s:=TJSString.fromCharCode(65,66);');
  18198. Add(' s:=TJSString(s).anchor(s);');
  18199. Add(' s:=TJSString(''foo'').anchor(s);');
  18200. ConvertProgram;
  18201. CheckSource('TestExternalClass_TypeCastStringToExternalString',
  18202. LinesToStr([ // statements
  18203. 'this.s = "";',
  18204. '']),
  18205. LinesToStr([ // $mod.$main
  18206. '$mod.s = String.fromCharCode(65, 66);',
  18207. '$mod.s = $mod.s.anchor($mod.s);',
  18208. '$mod.s = "foo".anchor($mod.s);',
  18209. '']));
  18210. end;
  18211. procedure TTestModule.TestExternalClass_TypeCastToJSFunction;
  18212. begin
  18213. StartProgram(false);
  18214. Add([
  18215. '{$modeswitch externalclass}',
  18216. 'type',
  18217. ' TJSObject = class external name ''Object'' end;',
  18218. ' TJSFunction = class external name ''Function''',
  18219. ' function bind(thisArg: TJSObject): TJSFunction; varargs;',
  18220. ' function call(thisArg: TJSObject): JSValue; varargs;',
  18221. ' end;',
  18222. ' TObject = class',
  18223. ' procedure DoIt(i: longint);',
  18224. ' end;',
  18225. ' TFuncInt = function(o: TObject): longint;',
  18226. 'function GetIt(o: TObject): longint;',
  18227. ' procedure Sub; begin end;',
  18228. 'var',
  18229. ' f: TJSFunction;',
  18230. ' fi: TFuncInt;',
  18231. 'begin',
  18232. ' fi:=TFuncInt(f);',
  18233. ' f:=TJSFunction(fi);',
  18234. ' f:=TJSFunction(@GetIt);',
  18235. ' f:=TJSFunction(@GetIt).bind(nil,3);',
  18236. ' f:=TJSFunction(@Sub);',
  18237. ' f:=TJSFunction(@o.doit);',
  18238. ' f:=TJSFunction(fi).bind(nil,4)',
  18239. 'end;',
  18240. 'procedure TObject.DoIt(i: longint);',
  18241. ' procedure Sub; begin end;',
  18242. 'var f: TJSFunction;',
  18243. 'begin',
  18244. ' f:=TJSFunction(@DoIt);',
  18245. ' f:=TJSFunction(@DoIt).bind(nil,13);',
  18246. ' f:=TJSFunction(@Sub);',
  18247. ' f:=TJSFunction(@GetIt);',
  18248. 'end;',
  18249. 'begin']);
  18250. ConvertProgram;
  18251. CheckSource('TestExternalClass_TypeCastToJSFunction',
  18252. LinesToStr([ // statements
  18253. 'rtl.createClass(this, "TObject", null, function () {',
  18254. ' this.$init = function () {',
  18255. ' };',
  18256. ' this.$final = function () {',
  18257. ' };',
  18258. ' this.DoIt = function (i) {',
  18259. ' var $Self = this;',
  18260. ' function Sub() {',
  18261. ' };',
  18262. ' var f = null;',
  18263. ' f = this.DoIt;',
  18264. ' f = this.DoIt.bind(null, 13);',
  18265. ' f = Sub;',
  18266. ' f = $mod.GetIt;',
  18267. ' };',
  18268. '});',
  18269. 'this.GetIt = function (o) {',
  18270. ' var Result = 0;',
  18271. ' function Sub() {',
  18272. ' };',
  18273. ' var f = null;',
  18274. ' var fi = null;',
  18275. ' fi = f;',
  18276. ' f = fi;',
  18277. ' f = $mod.GetIt;',
  18278. ' f = $mod.GetIt.bind(null, 3);',
  18279. ' f = Sub;',
  18280. ' f = $mod.TObject.DoIt;',
  18281. ' f = fi.bind(null, 4);',
  18282. ' return Result;',
  18283. '};',
  18284. '']),
  18285. LinesToStr([ // $mod.$main
  18286. '']));
  18287. end;
  18288. procedure TTestModule.TestExternalClass_TypeCastDelphiUnrelated;
  18289. begin
  18290. StartProgram(false);
  18291. Add([
  18292. '{$mode delphi}',
  18293. '{$modeswitch externalclass}',
  18294. 'type',
  18295. ' TJSObject = class external name ''Object'' end;',
  18296. ' TJSWindow = class external name ''Window''(TJSObject)',
  18297. ' procedure Open;',
  18298. ' end;',
  18299. ' TJSEventTarget = class external name ''Event''(TJSObject)',
  18300. ' procedure Execute;',
  18301. ' end;',
  18302. 'procedure Fly;',
  18303. 'var',
  18304. ' w: TJSWindow;',
  18305. ' e: TJSEventTarget;',
  18306. 'begin',
  18307. ' w:=TJSWindow(e);',
  18308. ' e:=TJSEventTarget(w);',
  18309. 'end;',
  18310. 'begin']);
  18311. ConvertProgram;
  18312. CheckSource('TestExternalClass_TypeCastDelphiUnrelated',
  18313. LinesToStr([ // statements
  18314. 'this.Fly = function () {',
  18315. ' var w = null;',
  18316. ' var e = null;',
  18317. ' w = e;',
  18318. ' e = w;',
  18319. '};',
  18320. '']),
  18321. LinesToStr([ // $mod.$main
  18322. '']));
  18323. end;
  18324. procedure TTestModule.TestExternalClass_CallClassFunctionOfInstanceFail;
  18325. begin
  18326. StartProgram(false);
  18327. Add('{$modeswitch externalclass}');
  18328. Add('type');
  18329. Add(' TJSString = class external name ''String''');
  18330. Add(' class function fromCharCode() : string; varargs;');
  18331. Add(' end;');
  18332. Add('var');
  18333. Add(' s: string;');
  18334. Add(' sObj: TJSString;');
  18335. Add('begin');
  18336. Add(' s:=sObj.fromCharCode(65,66);');
  18337. SetExpectedPasResolverError('External class instance cannot access static class function fromCharCode',
  18338. nExternalClassInstanceCannotAccessStaticX);
  18339. ConvertProgram;
  18340. end;
  18341. procedure TTestModule.TestExternalClass_BracketAccessor;
  18342. begin
  18343. StartProgram(false);
  18344. Add([
  18345. '{$modeswitch externalclass}',
  18346. 'type',
  18347. ' TJSArray = class external name ''Array2''',
  18348. ' function GetItems(Index: longint): jsvalue; external name ''[]'';',
  18349. ' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';',
  18350. ' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;',
  18351. ' end;',
  18352. 'procedure DoIt(vI: JSValue; const vJ: jsvalue; var vK: jsvalue; out vL: jsvalue);',
  18353. 'begin end;',
  18354. 'var',
  18355. ' Arr: tjsarray;',
  18356. ' s: string;',
  18357. ' i: longint;',
  18358. ' v: jsvalue;',
  18359. 'begin',
  18360. ' v:=arr[0];',
  18361. ' v:=arr.items[1];',
  18362. ' arr[2]:=s;',
  18363. ' arr.items[3]:=s;',
  18364. ' arr[4]:=i;',
  18365. ' arr[5]:=arr[6];',
  18366. ' arr.items[7]:=arr.items[8];',
  18367. ' with arr do items[9]:=items[10];',
  18368. ' doit(arr[7],arr[8],arr[9],arr[10]);',
  18369. ' with arr do begin',
  18370. ' v:=GetItems(14);',
  18371. ' setitems(15,16);',
  18372. ' end;',
  18373. ' v:=test1.arr.items[17];',
  18374. ' test1.arr.items[18]:=v;',
  18375. '']);
  18376. ConvertProgram;
  18377. CheckSource('TestExternalClass_BracketAccessor',
  18378. LinesToStr([ // statements
  18379. 'this.DoIt = function (vI, vJ, vK, vL) {',
  18380. '};',
  18381. 'this.Arr = null;',
  18382. 'this.s = "";',
  18383. 'this.i = 0;',
  18384. 'this.v = undefined;',
  18385. '']),
  18386. LinesToStr([ // $mod.$main
  18387. '$mod.v = $mod.Arr[0];',
  18388. '$mod.v = $mod.Arr[1];',
  18389. '$mod.Arr[2] = $mod.s;',
  18390. '$mod.Arr[3] = $mod.s;',
  18391. '$mod.Arr[4] = $mod.i;',
  18392. '$mod.Arr[5] = $mod.Arr[6];',
  18393. '$mod.Arr[7] = $mod.Arr[8];',
  18394. 'var $with = $mod.Arr;',
  18395. '$with[9] = $with[10];',
  18396. '$mod.DoIt($mod.Arr[7], $mod.Arr[8], {',
  18397. ' a: 9,',
  18398. ' p: $mod.Arr,',
  18399. ' get: function () {',
  18400. ' return this.p[this.a];',
  18401. ' },',
  18402. ' set: function (v) {',
  18403. ' this.p[this.a] = v;',
  18404. ' }',
  18405. '}, {',
  18406. ' a: 10,',
  18407. ' p: $mod.Arr,',
  18408. ' get: function () {',
  18409. ' return this.p[this.a];',
  18410. ' },',
  18411. ' set: function (v) {',
  18412. ' this.p[this.a] = v;',
  18413. ' }',
  18414. '});',
  18415. 'var $with1 = $mod.Arr;',
  18416. '$mod.v = $with1[14];',
  18417. '$with1[15] = 16;',
  18418. '$mod.v = $mod.Arr[17];',
  18419. '$mod.Arr[18] = $mod.v;',
  18420. '']));
  18421. end;
  18422. procedure TTestModule.TestExternalClass_BracketAccessor_Call;
  18423. begin
  18424. StartProgram(false);
  18425. Add([
  18426. '{$modeswitch externalclass}',
  18427. 'type',
  18428. ' TJSArray = class external name ''Array2''',
  18429. ' function GetItems(Index: longint): jsvalue; external name ''[]'';',
  18430. ' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';',
  18431. ' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;',
  18432. ' end;',
  18433. ' TMyArr = class(TJSArray)',
  18434. ' procedure DoIt;',
  18435. ' end;',
  18436. 'procedure tmyarr.DoIt;',
  18437. 'begin',
  18438. ' Items[1]:=Items[2];',
  18439. ' SetItems(3,getItems(4));',
  18440. 'end;',
  18441. 'var',
  18442. ' Arr: tmyarr;',
  18443. ' s: string;',
  18444. ' i: longint;',
  18445. ' v: jsvalue;',
  18446. 'begin',
  18447. ' v:=arr[0];',
  18448. ' v:=arr.items[1];',
  18449. ' arr[2]:=s;',
  18450. ' arr.items[3]:=s;',
  18451. ' arr[4]:=i;',
  18452. ' arr[5]:=arr[6];',
  18453. ' arr.items[7]:=arr.items[8];',
  18454. ' with arr do items[9]:=items[10];',
  18455. ' with arr do begin',
  18456. ' v:=GetItems(14);',
  18457. ' setitems(15,16);',
  18458. ' end;',
  18459. '']);
  18460. ConvertProgram;
  18461. CheckSource('TestExternalClass_BracketAccessor_Call',
  18462. LinesToStr([ // statements
  18463. 'rtl.createClassExt(this, "TMyArr", Array2, "", function () {',
  18464. ' this.$init = function () {',
  18465. ' };',
  18466. ' this.$final = function () {',
  18467. ' };',
  18468. ' this.DoIt = function () {',
  18469. ' this[1] = this[2];',
  18470. ' this[3] = this[4];',
  18471. ' };',
  18472. '});',
  18473. 'this.Arr = null;',
  18474. 'this.s = "";',
  18475. 'this.i = 0;',
  18476. 'this.v = undefined;',
  18477. '']),
  18478. LinesToStr([ // $mod.$main
  18479. '$mod.v = $mod.Arr[0];',
  18480. '$mod.v = $mod.Arr[1];',
  18481. '$mod.Arr[2] = $mod.s;',
  18482. '$mod.Arr[3] = $mod.s;',
  18483. '$mod.Arr[4] = $mod.i;',
  18484. '$mod.Arr[5] = $mod.Arr[6];',
  18485. '$mod.Arr[7] = $mod.Arr[8];',
  18486. 'var $with = $mod.Arr;',
  18487. '$with[9] = $with[10];',
  18488. 'var $with1 = $mod.Arr;',
  18489. '$mod.v = $with1[14];',
  18490. '$with1[15] = 16;',
  18491. '']));
  18492. end;
  18493. procedure TTestModule.TestExternalClass_BracketAccessor_2ParamsFail;
  18494. begin
  18495. StartProgram(false);
  18496. Add('{$modeswitch externalclass}');
  18497. Add('type');
  18498. Add(' TJSArray = class external name ''Array2''');
  18499. Add(' function GetItems(Index1, Index2: longint): jsvalue; external name ''[]'';');
  18500. Add(' procedure SetItems(Index1, Index2: longint; Value: jsvalue); external name ''[]'';');
  18501. Add(' property Items[Index1, Index2: longint]: jsvalue read GetItems write SetItems; default;');
  18502. Add(' end;');
  18503. Add('begin');
  18504. SetExpectedPasResolverError(sBracketAccessorOfExternalClassMustHaveOneParameter,
  18505. nBracketAccessorOfExternalClassMustHaveOneParameter);
  18506. ConvertProgram;
  18507. end;
  18508. procedure TTestModule.TestExternalClass_BracketAccessor_ReadOnly;
  18509. begin
  18510. StartProgram(false);
  18511. Add('{$modeswitch externalclass}');
  18512. Add('type');
  18513. Add(' TJSArray = class external name ''Array2''');
  18514. Add(' function GetItems(Index: longint): jsvalue; external name ''[]'';');
  18515. Add(' property Items[Index: longint]: jsvalue read GetItems; default;');
  18516. Add(' end;');
  18517. Add('procedure DoIt(vI: JSValue; const vJ: jsvalue);');
  18518. Add('begin end;');
  18519. Add('var');
  18520. Add(' Arr: tjsarray;');
  18521. Add(' v: jsvalue;');
  18522. Add('begin');
  18523. Add(' v:=arr[0];');
  18524. Add(' v:=arr.items[1];');
  18525. Add(' with arr do v:=items[2];');
  18526. Add(' doit(arr[3],arr[4]);');
  18527. ConvertProgram;
  18528. CheckSource('TestExternalClass_BracketAccessor_ReadOnly',
  18529. LinesToStr([ // statements
  18530. 'this.DoIt = function (vI, vJ) {',
  18531. '};',
  18532. 'this.Arr = null;',
  18533. 'this.v = undefined;',
  18534. '']),
  18535. LinesToStr([ // $mod.$main
  18536. '$mod.v = $mod.Arr[0];',
  18537. '$mod.v = $mod.Arr[1];',
  18538. 'var $with = $mod.Arr;',
  18539. '$mod.v = $with[2];',
  18540. '$mod.DoIt($mod.Arr[3], $mod.Arr[4]);',
  18541. '']));
  18542. end;
  18543. procedure TTestModule.TestExternalClass_BracketAccessor_WriteOnly;
  18544. begin
  18545. StartProgram(false);
  18546. Add('{$modeswitch externalclass}');
  18547. Add('type');
  18548. Add(' TJSArray = class external name ''Array2''');
  18549. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  18550. Add(' property Items[Index: longint]: jsvalue write SetItems; default;');
  18551. Add(' end;');
  18552. Add('var');
  18553. Add(' Arr: tjsarray;');
  18554. Add(' s: string;');
  18555. Add(' i: longint;');
  18556. Add(' v: jsvalue;');
  18557. Add('begin');
  18558. Add(' arr[2]:=s;');
  18559. Add(' arr.items[3]:=s;');
  18560. Add(' arr[4]:=i;');
  18561. Add(' with arr do items[5]:=i;');
  18562. ConvertProgram;
  18563. CheckSource('TestExternalClass_BracketAccessor_WriteOnly',
  18564. LinesToStr([ // statements
  18565. 'this.Arr = null;',
  18566. 'this.s = "";',
  18567. 'this.i = 0;',
  18568. 'this.v = undefined;',
  18569. '']),
  18570. LinesToStr([ // $mod.$main
  18571. '$mod.Arr[2] = $mod.s;',
  18572. '$mod.Arr[3] = $mod.s;',
  18573. '$mod.Arr[4] = $mod.i;',
  18574. 'var $with = $mod.Arr;',
  18575. '$with[5] = $mod.i;',
  18576. '']));
  18577. end;
  18578. procedure TTestModule.TestExternalClass_BracketAccessor_MultiType;
  18579. begin
  18580. StartProgram(false);
  18581. Add('{$modeswitch externalclass}');
  18582. Add('type');
  18583. Add(' TJSArray = class external name ''Array2''');
  18584. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  18585. Add(' property Items[Index: longint]: jsvalue write SetItems; default;');
  18586. Add(' procedure SetNumbers(Index: longint; Value: longint); external name ''[]'';');
  18587. Add(' property Numbers[Index: longint]: longint write SetNumbers;');
  18588. Add(' end;');
  18589. Add('var');
  18590. Add(' Arr: tjsarray;');
  18591. Add(' s: string;');
  18592. Add(' i: longint;');
  18593. Add(' v: jsvalue;');
  18594. Add('begin');
  18595. Add(' arr[2]:=s;');
  18596. Add(' arr.items[3]:=s;');
  18597. Add(' arr.numbers[4]:=i;');
  18598. Add(' with arr do items[5]:=i;');
  18599. Add(' with arr do numbers[6]:=i;');
  18600. ConvertProgram;
  18601. CheckSource('TestExternalClass_BracketAccessor_MultiType',
  18602. LinesToStr([ // statements
  18603. 'this.Arr = null;',
  18604. 'this.s = "";',
  18605. 'this.i = 0;',
  18606. 'this.v = undefined;',
  18607. '']),
  18608. LinesToStr([ // $mod.$main
  18609. '$mod.Arr[2] = $mod.s;',
  18610. '$mod.Arr[3] = $mod.s;',
  18611. '$mod.Arr[4] = $mod.i;',
  18612. 'var $with = $mod.Arr;',
  18613. '$with[5] = $mod.i;',
  18614. 'var $with1 = $mod.Arr;',
  18615. '$with1[6] = $mod.i;',
  18616. '']));
  18617. end;
  18618. procedure TTestModule.TestExternalClass_BracketAccessor_Index;
  18619. begin
  18620. StartProgram(false);
  18621. Add('{$modeswitch externalclass}');
  18622. Add('type');
  18623. Add(' TJSArray = class external name ''Array2''');
  18624. Add(' function GetItems(Index: longint): jsvalue; external name ''[]'';');
  18625. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  18626. Add(' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;');
  18627. Add(' end;');
  18628. Add('var');
  18629. Add(' Arr: tjsarray;');
  18630. Add(' i: longint;');
  18631. Add(' IntArr: array of longint;');
  18632. Add(' v: jsvalue;');
  18633. Add('begin');
  18634. Add(' v:=arr.items[i];');
  18635. Add(' arr[longint(v)]:=arr.items[intarr[0]];');
  18636. Add(' arr.items[intarr[1]]:=arr[IntArr[2]];');
  18637. ConvertProgram;
  18638. CheckSource('TestExternalClass_BracketAccessor_Index',
  18639. LinesToStr([ // statements
  18640. 'this.Arr = null;',
  18641. 'this.i = 0;',
  18642. 'this.IntArr = [];',
  18643. 'this.v = undefined;',
  18644. '']),
  18645. LinesToStr([ // $mod.$main
  18646. '$mod.v = $mod.Arr[$mod.i];',
  18647. '$mod.Arr[rtl.trunc($mod.v)] = $mod.Arr[$mod.IntArr[0]];',
  18648. '$mod.Arr[$mod.IntArr[1]] = $mod.Arr[$mod.IntArr[2]];',
  18649. '']));
  18650. end;
  18651. procedure TTestModule.TestExternalClass_ForInJSObject;
  18652. begin
  18653. StartProgram(false);
  18654. Add([
  18655. '{$modeswitch externalclass}',
  18656. 'type',
  18657. ' TJSObject = class external name ''Object''',
  18658. ' end;',
  18659. 'var',
  18660. ' o: TJSObject;',
  18661. ' key: string;',
  18662. 'begin',
  18663. ' for key in o do',
  18664. ' if key=''abc'' then ;',
  18665. '']);
  18666. ConvertProgram;
  18667. CheckSource('TestExternalClass_ForInJSObject',
  18668. LinesToStr([ // statements
  18669. 'this.o = null;',
  18670. 'this.key = "";',
  18671. '']),
  18672. LinesToStr([ // $mod.$main
  18673. 'for ($mod.key in $mod.o) if ($mod.key === "abc") ;',
  18674. '']));
  18675. end;
  18676. procedure TTestModule.TestExternalClass_ForInJSArray;
  18677. begin
  18678. StartProgram(false);
  18679. Add([
  18680. '{$modeswitch externalclass}',
  18681. 'type',
  18682. ' TJSInt8Array = class external name ''Int8Array''',
  18683. ' private',
  18684. ' flength: NativeInt external name ''length'';',
  18685. ' function getValue(Index: NativeInt): shortint; external name ''[]'';',
  18686. ' public',
  18687. ' property values[Index: NativeInt]: Shortint Read getValue; default;',
  18688. ' property Length: NativeInt read flength;',
  18689. ' end;',
  18690. 'var',
  18691. ' a: TJSInt8Array;',
  18692. ' value: shortint;',
  18693. 'begin',
  18694. ' for value in a do',
  18695. ' if value=3 then ;',
  18696. '']);
  18697. ConvertProgram;
  18698. CheckSource('TestExternalClass_ForInJSArray',
  18699. LinesToStr([ // statements
  18700. 'this.a = null;',
  18701. 'this.value = 0;',
  18702. '']),
  18703. LinesToStr([ // $mod.$main
  18704. 'for (var $in = $mod.a, $l = 0, $end = rtl.length($in) - 1; $l <= $end; $l++) {',
  18705. ' $mod.value = $in[$l];',
  18706. ' if ($mod.value === 3) ;',
  18707. '};',
  18708. '']));
  18709. end;
  18710. procedure TTestModule.TestExternalClass_IncompatibleArgDuplicateIdentifier;
  18711. begin
  18712. AddModuleWithIntfImplSrc('unit2.pas',
  18713. LinesToStr([
  18714. '{$modeswitch externalclass}',
  18715. 'type',
  18716. ' TJSBufferSource = class external name ''BufferSource''',
  18717. ' end;',
  18718. 'procedure DoIt(s: TJSBufferSource); external name ''DoIt'';',
  18719. '']),
  18720. '');
  18721. AddModuleWithIntfImplSrc('unit3.pas',
  18722. LinesToStr([
  18723. '{$modeswitch externalclass}',
  18724. 'type',
  18725. ' TJSBufferSource = class external name ''BufferSource''',
  18726. ' end;',
  18727. '']),
  18728. '');
  18729. StartUnit(true);
  18730. Add([
  18731. 'interface',
  18732. 'uses unit2, unit3;',
  18733. 'procedure DoSome(s: TJSBufferSource);',
  18734. 'implementation',
  18735. 'procedure DoSome(s: TJSBufferSource);',
  18736. 'begin',
  18737. ' DoIt(s);',
  18738. 'end;',
  18739. '']);
  18740. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "unit3.TJSBufferSource", expected "unit2.TJSBufferSource"',
  18741. nIncompatibleTypeArgNo);
  18742. ConvertUnit;
  18743. end;
  18744. procedure TTestModule.TestClassInterface_Corba;
  18745. begin
  18746. StartProgram(false);
  18747. Add([
  18748. '{$interfaces corba}',
  18749. 'type',
  18750. ' IUnknown = interface;',
  18751. ' IUnknown = interface',
  18752. ' [''{00000000-0000-0000-C000-000000000046}'']',
  18753. ' end;',
  18754. ' IInterface = IUnknown;',
  18755. ' IBird = interface(IInterface)',
  18756. ' function GetSize: longint;',
  18757. ' procedure SetSize(i: longint);',
  18758. ' property Size: longint read GetSize write SetSize;',
  18759. ' procedure DoIt(i: longint);',
  18760. ' end;',
  18761. ' TObject = class',
  18762. ' end;',
  18763. ' TBird = class(TObject,IBird)',
  18764. ' function GetSize: longint; virtual; abstract;',
  18765. ' procedure SetSize(i: longint); virtual; abstract;',
  18766. ' procedure DoIt(i: longint); virtual; abstract;',
  18767. ' end;',
  18768. 'var',
  18769. ' BirdIntf: IBird;',
  18770. 'begin',
  18771. ' BirdIntf.Size:=BirdIntf.Size;',
  18772. '']);
  18773. ConvertProgram;
  18774. CheckSource('TestClassInterface_Corba',
  18775. LinesToStr([ // statements
  18776. 'rtl.createInterface(this, "IUnknown", "{00000000-0000-0000-C000-000000000046}", [], null);',
  18777. 'rtl.createInterface(this, "IBird", "{5BD1A53B-69BB-37EE-AF32-BEFB86D85B03}", ["GetSize", "SetSize", "DoIt"], this.IUnknown);',
  18778. 'rtl.createClass(this, "TObject", null, function () {',
  18779. ' this.$init = function () {',
  18780. ' };',
  18781. ' this.$final = function () {',
  18782. ' };',
  18783. '});',
  18784. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  18785. ' rtl.addIntf(this, $mod.IBird);',
  18786. '});',
  18787. 'this.BirdIntf = null;',
  18788. '']),
  18789. LinesToStr([ // $mod.$main
  18790. ' $mod.BirdIntf.SetSize($mod.BirdIntf.GetSize());',
  18791. '']));
  18792. end;
  18793. procedure TTestModule.TestClassInterface_ProcExternalFail;
  18794. begin
  18795. StartProgram(false);
  18796. Add([
  18797. '{$interfaces corba}',
  18798. 'type',
  18799. ' IUnknown = interface',
  18800. ' procedure DoIt; external name ''foo'';',
  18801. ' end;',
  18802. 'begin']);
  18803. SetExpectedParserError(
  18804. 'Fields are not allowed in interface at token "Identifier external" in file test1.pp at line 6 column 21',
  18805. nParserNoFieldsAllowed);
  18806. ConvertProgram;
  18807. end;
  18808. procedure TTestModule.TestClassInterface_Overloads;
  18809. begin
  18810. StartProgram(false);
  18811. Add([
  18812. '{$interfaces corba}',
  18813. 'type',
  18814. ' integer = longint;',
  18815. ' IUnknown = interface',
  18816. ' procedure DoIt(i: integer);',
  18817. ' procedure DoIt(s: string);',
  18818. ' end;',
  18819. ' IBird = interface(IUnknown)',
  18820. ' procedure DoIt(b: boolean); overload;',
  18821. ' end;',
  18822. ' TObject = class',
  18823. ' end;',
  18824. ' TBird = class(TObject,IBird)',
  18825. ' procedure DoIt(o: TObject);',
  18826. ' procedure DoIt(s: string);',
  18827. ' procedure DoIt(i: integer);',
  18828. ' procedure DoIt(b: boolean);',
  18829. ' end;',
  18830. 'procedure TBird.DoIt(o: TObject); begin end;',
  18831. 'procedure TBird.DoIt(s: string); begin end;',
  18832. 'procedure TBird.DoIt(i: integer); begin end;',
  18833. 'procedure TBird.DoIt(b: boolean); begin end;',
  18834. 'var',
  18835. ' BirdIntf: IBird;',
  18836. 'begin',
  18837. ' BirdIntf.DoIt(3);',
  18838. ' BirdIntf.DoIt(''abc'');',
  18839. ' BirdIntf.DoIt(true);',
  18840. '']);
  18841. ConvertProgram;
  18842. CheckSource('TestClassInterface_Overloads',
  18843. LinesToStr([ // statements
  18844. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-BDC4-8A2AE2C59400}", ["DoIt", "DoIt$1"], null);',
  18845. 'rtl.createInterface(this, "IBird", "{8285DD5E-EA3E-396E-AE88-000B86AABF05}", ["DoIt$2"], this.IUnknown);',
  18846. 'rtl.createClass(this, "TObject", null, function () {',
  18847. ' this.$init = function () {',
  18848. ' };',
  18849. ' this.$final = function () {',
  18850. ' };',
  18851. '});',
  18852. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  18853. ' this.DoIt = function (o) {',
  18854. ' };',
  18855. ' this.DoIt$1 = function (s) {',
  18856. ' };',
  18857. ' this.DoIt$2 = function (i) {',
  18858. ' };',
  18859. ' this.DoIt$3 = function (b) {',
  18860. ' };',
  18861. ' rtl.addIntf(this, $mod.IBird, {',
  18862. ' DoIt$2: "DoIt$3",',
  18863. ' DoIt: "DoIt$2"',
  18864. ' });',
  18865. '});',
  18866. 'this.BirdIntf = null;',
  18867. '']),
  18868. LinesToStr([ // $mod.$main
  18869. '$mod.BirdIntf.DoIt(3);',
  18870. '$mod.BirdIntf.DoIt$1("abc");',
  18871. '$mod.BirdIntf.DoIt$2(true);',
  18872. '']));
  18873. end;
  18874. procedure TTestModule.TestClassInterface_DuplicateGUIInIntfListFail;
  18875. begin
  18876. StartProgram(false);
  18877. Add([
  18878. '{$interfaces corba}',
  18879. 'type',
  18880. ' IBird = interface',
  18881. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  18882. ' end;',
  18883. ' IDog = interface',
  18884. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  18885. ' end;',
  18886. ' TObject = class(IBird,IDog)',
  18887. ' end;',
  18888. 'begin']);
  18889. SetExpectedPasResolverError('Duplicate GUID {4B3BA825-E0EC-4799-A19C-55F714A07959} in IDog and IBird',
  18890. nDuplicateGUIDXInYZ);
  18891. ConvertProgram;
  18892. end;
  18893. procedure TTestModule.TestClassInterface_DuplicateGUIInAncestorFail;
  18894. begin
  18895. StartProgram(false);
  18896. Add([
  18897. '{$interfaces corba}',
  18898. 'type',
  18899. ' IAnimal = interface',
  18900. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  18901. ' end;',
  18902. ' IBird = interface(IAnimal)',
  18903. ' end;',
  18904. ' IHawk = interface(IBird)',
  18905. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  18906. ' end;',
  18907. 'begin']);
  18908. SetExpectedPasResolverError('Duplicate GUID {4B3BA825-E0EC-4799-A19C-55F714A07959} in IHawk and IAnimal',
  18909. nDuplicateGUIDXInYZ);
  18910. ConvertProgram;
  18911. end;
  18912. procedure TTestModule.TestClassInterface_AncestorImpl;
  18913. begin
  18914. StartProgram(false);
  18915. Add([
  18916. '{$interfaces corba}',
  18917. 'type',
  18918. ' integer = longint;',
  18919. ' IUnknown = interface',
  18920. ' procedure DoIt(i: integer);',
  18921. ' end;',
  18922. ' IBird = interface',
  18923. ' procedure Fly(i: integer);',
  18924. ' end;',
  18925. ' TObject = class(IUnknown)',
  18926. ' procedure DoIt(i: integer);',
  18927. ' end;',
  18928. ' TBird = class(IBird)',
  18929. ' procedure Fly(i: integer);',
  18930. ' end;',
  18931. 'procedure TObject.DoIt(i: integer); begin end;',
  18932. 'procedure TBird.Fly(i: integer); begin end;',
  18933. 'begin',
  18934. '']);
  18935. ConvertProgram;
  18936. CheckSource('TestClassInterface_AncestorIntf',
  18937. LinesToStr([ // statements
  18938. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-BDC4-8A2800000000}", ["DoIt"], null);',
  18939. 'rtl.createInterface(this, "IBird", "{B92D5841-6264-3AE3-BF20-000000000000}", ["Fly"], null);',
  18940. 'rtl.createClass(this, "TObject", null, function () {',
  18941. ' this.$init = function () {',
  18942. ' };',
  18943. ' this.$final = function () {',
  18944. ' };',
  18945. ' this.DoIt = function (i) {',
  18946. ' };',
  18947. ' rtl.addIntf(this, $mod.IUnknown);',
  18948. '});',
  18949. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  18950. ' this.Fly = function (i) {',
  18951. ' };',
  18952. ' rtl.addIntf(this, $mod.IBird);',
  18953. ' rtl.addIntf(this, $mod.IUnknown);',
  18954. '});',
  18955. '']),
  18956. LinesToStr([ // $mod.$main
  18957. '']));
  18958. end;
  18959. procedure TTestModule.TestClassInterface_ImplReintroduce;
  18960. begin
  18961. StartProgram(false);
  18962. Add([
  18963. '{$interfaces corba}',
  18964. 'type',
  18965. ' integer = longint;',
  18966. ' IBird = interface',
  18967. ' procedure DoIt(i: integer);',
  18968. ' end;',
  18969. ' TObject = class',
  18970. ' procedure DoIt(i: integer);',
  18971. ' end;',
  18972. ' TBird = class(IBird)',
  18973. ' procedure DoIt(i: integer); virtual; reintroduce;',
  18974. ' end;',
  18975. 'procedure TObject.DoIt(i: integer); begin end;',
  18976. 'procedure TBird.DoIt(i: integer); begin end;',
  18977. 'begin',
  18978. '']);
  18979. ConvertProgram;
  18980. CheckSource('TestClassInterface_ImplReintroduce',
  18981. LinesToStr([ // statements
  18982. 'rtl.createInterface(this, "IBird", "{B92D5841-6264-3AE2-8594-000000000000}", ["DoIt"], null);',
  18983. 'rtl.createClass(this, "TObject", null, function () {',
  18984. ' this.$init = function () {',
  18985. ' };',
  18986. ' this.$final = function () {',
  18987. ' };',
  18988. ' this.DoIt = function (i) {',
  18989. ' };',
  18990. '});',
  18991. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  18992. ' this.DoIt$1 = function (i) {',
  18993. ' };',
  18994. ' rtl.addIntf(this, $mod.IBird, {',
  18995. ' DoIt: "DoIt$1"',
  18996. ' });',
  18997. '});',
  18998. '']),
  18999. LinesToStr([ // $mod.$main
  19000. '']));
  19001. end;
  19002. procedure TTestModule.TestClassInterface_MethodResolution;
  19003. begin
  19004. StartProgram(false);
  19005. Add([
  19006. '{$interfaces corba}',
  19007. 'type',
  19008. ' IUnknown = interface',
  19009. ' procedure Walk(i: longint);',
  19010. ' end;',
  19011. ' IBird = interface(IUnknown)',
  19012. ' procedure Walk(b: boolean); overload;',
  19013. ' procedure Fly(s: string);',
  19014. ' end;',
  19015. ' TObject = class',
  19016. ' end;',
  19017. ' TBird = class(TObject,IBird)',
  19018. ' procedure IBird.Fly = Move;',
  19019. ' procedure IBird.Walk = Hop;',
  19020. ' procedure Hop(i: longint);',
  19021. ' procedure Move(s: string);',
  19022. ' procedure Hop(b: boolean);',
  19023. ' end;',
  19024. 'procedure TBird.Move(s: string); begin end;',
  19025. 'procedure TBird.Hop(i: longint); begin end;',
  19026. 'procedure TBird.Hop(b: boolean); begin end;',
  19027. 'var',
  19028. ' BirdIntf: IBird;',
  19029. 'begin',
  19030. ' BirdIntf.Walk(3);',
  19031. ' BirdIntf.Walk(true);',
  19032. ' BirdIntf.Fly(''abc'');',
  19033. '']);
  19034. ConvertProgram;
  19035. CheckSource('TestClassInterface_MethodResolution',
  19036. LinesToStr([ // statements
  19037. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-BDD7-23D600000000}", ["Walk"], null);',
  19038. 'rtl.createInterface(this, "IBird", "{CF8A4986-80F6-396E-AE88-000B86AAE208}", ["Walk$1", "Fly"], this.IUnknown);',
  19039. 'rtl.createClass(this, "TObject", null, function () {',
  19040. ' this.$init = function () {',
  19041. ' };',
  19042. ' this.$final = function () {',
  19043. ' };',
  19044. '});',
  19045. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19046. ' this.Hop = function (i) {',
  19047. ' };',
  19048. ' this.Move = function (s) {',
  19049. ' };',
  19050. ' this.Hop$1 = function (b) {',
  19051. ' };',
  19052. ' rtl.addIntf(this, $mod.IBird, {',
  19053. ' Walk$1: "Hop$1",',
  19054. ' Fly: "Move",',
  19055. ' Walk: "Hop"',
  19056. ' });',
  19057. '});',
  19058. 'this.BirdIntf = null;',
  19059. '']),
  19060. LinesToStr([ // $mod.$main
  19061. '$mod.BirdIntf.Walk(3);',
  19062. '$mod.BirdIntf.Walk$1(true);',
  19063. '$mod.BirdIntf.Fly("abc");',
  19064. '']));
  19065. end;
  19066. procedure TTestModule.TestClassInterface_AncestorMoreInterfaces;
  19067. begin
  19068. StartProgram(false);
  19069. Add([
  19070. '{$interfaces com}',
  19071. 'type',
  19072. ' IUnknown = interface',
  19073. ' function _AddRef: longint;',
  19074. ' procedure Walk;',
  19075. ' end;',
  19076. ' IBird = interface end;',
  19077. ' IDog = interface end;',
  19078. ' TObject = class(IBird,IDog)',
  19079. ' function _AddRef: longint; virtual; abstract;',
  19080. ' procedure Walk; virtual; abstract;',
  19081. ' end;',
  19082. ' TBird = class(IUnknown)',
  19083. ' end;',
  19084. 'begin',
  19085. '']);
  19086. ConvertProgram;
  19087. CheckSource('TestClassInterface_COM_AncestorLess',
  19088. LinesToStr([ // statements
  19089. 'rtl.createInterface(this, "IUnknown", "{8F2D5841-758A-322B-BDDF-21CD521DD723}", ["_AddRef", "Walk"], null);',
  19090. 'rtl.createInterface(this, "IBird", "{CCE11D4C-6504-3AEE-AE88-000B86AAE675}", [], this.IUnknown);',
  19091. 'rtl.createInterface(this, "IDog", "{CCE11D4C-6504-3AEE-AE88-000B8E5FC675}", [], this.IUnknown);',
  19092. 'rtl.createClass(this, "TObject", null, function () {',
  19093. ' this.$init = function () {',
  19094. ' };',
  19095. ' this.$final = function () {',
  19096. ' };',
  19097. ' rtl.addIntf(this, $mod.IBird);',
  19098. ' rtl.addIntf(this, $mod.IDog);',
  19099. '});',
  19100. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19101. ' rtl.addIntf(this, $mod.IUnknown);',
  19102. ' rtl.addIntf(this, $mod.IBird);',
  19103. ' rtl.addIntf(this, $mod.IDog);',
  19104. '});',
  19105. '']),
  19106. LinesToStr([ // $mod.$main
  19107. '']));
  19108. end;
  19109. procedure TTestModule.TestClassInterface_MethodOverride;
  19110. begin
  19111. StartProgram(false);
  19112. Add([
  19113. '{$interfaces corba}',
  19114. 'type',
  19115. ' IUnknown = interface',
  19116. ' [''{D6D98E5B-8A10-4FEC-856A-7BFC847FE74B}'']',
  19117. ' procedure Go;',
  19118. ' end;',
  19119. ' TObject = class(IUnknown)',
  19120. ' procedure Go; virtual; abstract;',
  19121. ' end;',
  19122. ' TBird = class',
  19123. ' procedure Go; override;',
  19124. ' end;',
  19125. ' TCat = class(TObject)',
  19126. ' procedure Go; override;',
  19127. ' end;',
  19128. ' TDog = class(TObject, IUnknown)',
  19129. ' procedure Go; override;',
  19130. ' end;',
  19131. 'procedure TBird.Go; begin end;',
  19132. 'procedure TCat.Go; begin end;',
  19133. 'procedure TDog.Go; begin end;',
  19134. 'begin',
  19135. '']);
  19136. ConvertProgram;
  19137. CheckSource('TestClassInterface_MethodOverride',
  19138. LinesToStr([ // statements
  19139. 'rtl.createInterface(this, "IUnknown", "{D6D98E5B-8A10-4FEC-856A-7BFC847FE74B}", ["Go"], null);',
  19140. 'rtl.createClass(this, "TObject", null, function () {',
  19141. ' this.$init = function () {',
  19142. ' };',
  19143. ' this.$final = function () {',
  19144. ' };',
  19145. ' rtl.addIntf(this, $mod.IUnknown);',
  19146. '});',
  19147. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19148. ' this.Go = function () {',
  19149. ' };',
  19150. ' rtl.addIntf(this, $mod.IUnknown);',
  19151. '});',
  19152. 'rtl.createClass(this, "TCat", this.TObject, function () {',
  19153. ' this.Go = function () {',
  19154. ' };',
  19155. ' rtl.addIntf(this, $mod.IUnknown);',
  19156. '});',
  19157. 'rtl.createClass(this, "TDog", this.TObject, function () {',
  19158. ' this.Go = function () {',
  19159. ' };',
  19160. ' rtl.addIntf(this, $mod.IUnknown);',
  19161. '});',
  19162. '']),
  19163. LinesToStr([ // $mod.$main
  19164. '']));
  19165. end;
  19166. procedure TTestModule.TestClassInterface_Corba_Delegation;
  19167. begin
  19168. StartProgram(false);
  19169. Add([
  19170. '{$interfaces corba}',
  19171. 'type',
  19172. ' IUnknown = interface',
  19173. ' end;',
  19174. ' IBird = interface(IUnknown)',
  19175. ' procedure Fly(s: string);',
  19176. ' end;',
  19177. ' IEagle = interface(IBird)',
  19178. ' end;',
  19179. ' IDove = interface(IBird)',
  19180. ' end;',
  19181. ' ISwallow = interface(IBird)',
  19182. ' end;',
  19183. ' TObject = class',
  19184. ' end;',
  19185. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  19186. ' procedure Fly(s: string); virtual; abstract;',
  19187. ' end;',
  19188. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  19189. ' FBirdIntf: IBird;',
  19190. ' property BirdIntf: IBird read FBirdIntf implements IBird;',
  19191. ' function GetEagleIntf: IEagle; virtual; abstract;',
  19192. ' property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  19193. ' FDoveObj: TBird;',
  19194. ' property DoveObj: TBird read FDoveObj implements IDove;',
  19195. ' function GetSwallowObj: TBird; virtual; abstract;',
  19196. ' property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  19197. ' end;',
  19198. 'begin',
  19199. '']);
  19200. ConvertProgram;
  19201. CheckSource('TestClassInterface_Corba_Delegation',
  19202. LinesToStr([ // statements
  19203. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  19204. 'rtl.createInterface(this, "IBird", "{478D080B-C0F6-396E-AE88-000B87785B07}", ["Fly"], this.IUnknown);',
  19205. 'rtl.createInterface(this, "IEagle", "{489289DE-FDE2-34A6-8288-39119022B1B4}", [], this.IBird);',
  19206. 'rtl.createInterface(this, "IDove", "{489289DE-FDE2-34A6-8288-39118EF16074}", [], this.IBird);',
  19207. 'rtl.createInterface(this, "ISwallow", "{B89289DE-FDE2-34A6-8288-3911CBDCB359}", [], this.IBird);',
  19208. 'rtl.createClass(this, "TObject", null, function () {',
  19209. ' this.$init = function () {',
  19210. ' };',
  19211. ' this.$final = function () {',
  19212. ' };',
  19213. '});',
  19214. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19215. ' rtl.addIntf(this, $mod.IBird);',
  19216. ' rtl.addIntf(this, $mod.IEagle);',
  19217. ' rtl.addIntf(this, $mod.IDove);',
  19218. ' rtl.addIntf(this, $mod.ISwallow);',
  19219. '});',
  19220. 'rtl.createClass(this, "TBat", this.TObject, function () {',
  19221. ' this.$init = function () {',
  19222. ' $mod.TObject.$init.call(this);',
  19223. ' this.FBirdIntf = null;',
  19224. ' this.FDoveObj = null;',
  19225. ' };',
  19226. ' this.$final = function () {',
  19227. ' this.FBirdIntf = undefined;',
  19228. ' this.FDoveObj = undefined;',
  19229. ' $mod.TObject.$final.call(this);',
  19230. ' };',
  19231. ' this.$intfmaps = {',
  19232. ' "{478D080B-C0F6-396E-AE88-000B87785B07}": function () {',
  19233. ' return this.FBirdIntf;',
  19234. ' },',
  19235. ' "{489289DE-FDE2-34A6-8288-39119022B1B4}": function () {',
  19236. ' return this.GetEagleIntf();',
  19237. ' },',
  19238. ' "{489289DE-FDE2-34A6-8288-39118EF16074}": function () {',
  19239. ' return rtl.getIntfT(this.FDoveObj, $mod.IDove);',
  19240. ' },',
  19241. ' "{B89289DE-FDE2-34A6-8288-3911CBDCB359}": function () {',
  19242. ' return rtl.getIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  19243. ' }',
  19244. ' };',
  19245. '});',
  19246. '']),
  19247. LinesToStr([ // $mod.$main
  19248. '']));
  19249. end;
  19250. procedure TTestModule.TestClassInterface_Corba_DelegationStatic;
  19251. begin
  19252. StartProgram(false);
  19253. Add([
  19254. '{$interfaces corba}',
  19255. 'type',
  19256. ' IUnknown = interface',
  19257. ' end;',
  19258. ' IBird = interface(IUnknown)',
  19259. ' procedure Fly(s: string);',
  19260. ' end;',
  19261. ' IEagle = interface(IBird)',
  19262. ' end;',
  19263. ' IDove = interface(IBird)',
  19264. ' end;',
  19265. ' ISwallow = interface(IBird)',
  19266. ' end;',
  19267. ' TObject = class',
  19268. ' end;',
  19269. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  19270. ' procedure Fly(s: string); virtual; abstract;',
  19271. ' end;',
  19272. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  19273. ' private',
  19274. ' class var FBirdIntf: IBird;',
  19275. ' class var FDoveObj: TBird;',
  19276. ' class function GetEagleIntf: IEagle; virtual; abstract;',
  19277. ' class function GetSwallowObj: TBird; virtual; abstract;',
  19278. ' protected',
  19279. ' class property BirdIntf: IBird read FBirdIntf implements IBird;',
  19280. ' class property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  19281. ' class property DoveObj: TBird read FDoveObj implements IDove;',
  19282. ' class property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  19283. ' end;',
  19284. 'begin',
  19285. '']);
  19286. ConvertProgram;
  19287. CheckSource('TestClassInterface_Corba_DelegationStatic',
  19288. LinesToStr([ // statements
  19289. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  19290. 'rtl.createInterface(this, "IBird", "{478D080B-C0F6-396E-AE88-000B87785B07}", ["Fly"], this.IUnknown);',
  19291. 'rtl.createInterface(this, "IEagle", "{489289DE-FDE2-34A6-8288-39119022B1B4}", [], this.IBird);',
  19292. 'rtl.createInterface(this, "IDove", "{489289DE-FDE2-34A6-8288-39118EF16074}", [], this.IBird);',
  19293. 'rtl.createInterface(this, "ISwallow", "{B89289DE-FDE2-34A6-8288-3911CBDCB359}", [], this.IBird);',
  19294. 'rtl.createClass(this, "TObject", null, function () {',
  19295. ' this.$init = function () {',
  19296. ' };',
  19297. ' this.$final = function () {',
  19298. ' };',
  19299. '});',
  19300. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19301. ' rtl.addIntf(this, $mod.IBird);',
  19302. ' rtl.addIntf(this, $mod.IEagle);',
  19303. ' rtl.addIntf(this, $mod.IDove);',
  19304. ' rtl.addIntf(this, $mod.ISwallow);',
  19305. '});',
  19306. 'rtl.createClass(this, "TBat", this.TObject, function () {',
  19307. ' this.FBirdIntf = null;',
  19308. ' this.FDoveObj = null;',
  19309. ' this.$intfmaps = {',
  19310. ' "{478D080B-C0F6-396E-AE88-000B87785B07}": function () {',
  19311. ' return this.FBirdIntf;',
  19312. ' },',
  19313. ' "{489289DE-FDE2-34A6-8288-39119022B1B4}": function () {',
  19314. ' return this.GetEagleIntf();',
  19315. ' },',
  19316. ' "{489289DE-FDE2-34A6-8288-39118EF16074}": function () {',
  19317. ' return rtl.getIntfT(this.FDoveObj, $mod.IDove);',
  19318. ' },',
  19319. ' "{B89289DE-FDE2-34A6-8288-3911CBDCB359}": function () {',
  19320. ' return rtl.getIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  19321. ' }',
  19322. ' };',
  19323. '});',
  19324. '']),
  19325. LinesToStr([ // $mod.$main
  19326. '']));
  19327. end;
  19328. procedure TTestModule.TestClassInterface_Corba_Operators;
  19329. begin
  19330. StartProgram(false);
  19331. Add([
  19332. '{$interfaces corba}',
  19333. 'type',
  19334. ' IUnknown = interface',
  19335. ' end;',
  19336. ' IBird = interface(IUnknown)',
  19337. ' function GetItems(Index: longint): longint;',
  19338. ' procedure SetItems(Index: longint; Value: longint);',
  19339. ' property Items[Index: longint]: longint read GetItems write SetItems; default;',
  19340. ' end;',
  19341. ' TObject = class',
  19342. ' end;',
  19343. ' TBird = class(TObject,IBird)',
  19344. ' function GetItems(Index: longint): longint; virtual; abstract;',
  19345. ' procedure SetItems(Index: longint; Value: longint); virtual; abstract;',
  19346. ' end;',
  19347. 'var',
  19348. ' IntfVar: IBird = nil;',
  19349. ' IntfVar2: IBird;',
  19350. ' ObjVar: TBird;',
  19351. ' v: JSValue;',
  19352. 'begin',
  19353. ' IntfVar:=nil;',
  19354. ' IntfVar[3]:=IntfVar[4];',
  19355. ' if Assigned(IntfVar) then ;',
  19356. ' IntfVar:=IntfVar2;',
  19357. ' IntfVar:=ObjVar;',
  19358. ' if IntfVar=IntfVar2 then ;',
  19359. ' if IntfVar<>IntfVar2 then ;',
  19360. ' if IntfVar is IBird then ;',
  19361. ' if IntfVar is TBird then ;',
  19362. ' if ObjVar is IBird then ;',
  19363. ' IntfVar:=IntfVar2 as IBird;',
  19364. ' ObjVar:=IntfVar2 as TBird;',
  19365. ' IntfVar:=ObjVar as IBird;',
  19366. ' IntfVar:=IBird(IntfVar2);',
  19367. ' ObjVar:=TBird(IntfVar);',
  19368. ' IntfVar:=IBird(ObjVar);',
  19369. ' v:=IntfVar;',
  19370. ' IntfVar:=IBird(v);',
  19371. ' if v is IBird then ;',
  19372. ' v:=JSValue(IntfVar);',
  19373. ' v:=IBird;',
  19374. '']);
  19375. ConvertProgram;
  19376. CheckSource('TestClassInterface_Corba_Operators',
  19377. LinesToStr([ // statements
  19378. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  19379. 'rtl.createInterface(this, "IBird", "{D53FED90-DE59-3202-B1AE-000B87785B08}", ["GetItems", "SetItems"], this.IUnknown);',
  19380. 'rtl.createClass(this, "TObject", null, function () {',
  19381. ' this.$init = function () {',
  19382. ' };',
  19383. ' this.$final = function () {',
  19384. ' };',
  19385. '});',
  19386. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19387. ' rtl.addIntf(this, $mod.IBird);',
  19388. '});',
  19389. 'this.IntfVar = null;',
  19390. 'this.IntfVar2 = null;',
  19391. 'this.ObjVar = null;',
  19392. 'this.v = undefined;',
  19393. '']),
  19394. LinesToStr([ // $mod.$main
  19395. '$mod.IntfVar = null;',
  19396. '$mod.IntfVar.SetItems(3, $mod.IntfVar.GetItems(4));',
  19397. 'if ($mod.IntfVar != null) ;',
  19398. '$mod.IntfVar = $mod.IntfVar2;',
  19399. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar,$mod.IBird);',
  19400. 'if ($mod.IntfVar === $mod.IntfVar2) ;',
  19401. 'if ($mod.IntfVar !== $mod.IntfVar2) ;',
  19402. 'if ($mod.IBird.isPrototypeOf($mod.IntfVar)) ;',
  19403. 'if (rtl.intfIsClass($mod.IntfVar, $mod.TBird)) ;',
  19404. 'if (rtl.getIntfT($mod.ObjVar, $mod.IBird) !== null) ;',
  19405. '$mod.IntfVar = rtl.as($mod.IntfVar2, $mod.IBird);',
  19406. '$mod.ObjVar = rtl.intfAsClass($mod.IntfVar2, $mod.TBird);',
  19407. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar, $mod.IBird);',
  19408. '$mod.IntfVar = $mod.IntfVar2;',
  19409. '$mod.ObjVar = rtl.intfToClass($mod.IntfVar, $mod.TBird);',
  19410. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar, $mod.IBird);',
  19411. '$mod.v = $mod.IntfVar;',
  19412. '$mod.IntfVar = rtl.getObject($mod.v);',
  19413. 'if (rtl.isExt($mod.v, $mod.IBird, 1)) ;',
  19414. '$mod.v = $mod.IntfVar;',
  19415. '$mod.v = $mod.IBird;',
  19416. '']));
  19417. end;
  19418. procedure TTestModule.TestClassInterface_Corba_Args;
  19419. begin
  19420. StartProgram(false);
  19421. Add([
  19422. '{$interfaces corba}',
  19423. 'type',
  19424. ' IUnknown = interface',
  19425. ' end;',
  19426. ' IBird = interface(IUnknown)',
  19427. ' end;',
  19428. ' TObject = class',
  19429. ' end;',
  19430. ' TBird = class(TObject,IBird)',
  19431. ' end;',
  19432. 'procedure DoIt(var u; i: IBird; const j: IBird);',
  19433. 'begin',
  19434. ' DoIt(i,i,i);',
  19435. 'end;',
  19436. 'procedure Change(var i: IBird; out j: IBird);',
  19437. 'begin',
  19438. ' DoIt(i,i,i);',
  19439. ' Change(i,i);',
  19440. 'end;',
  19441. 'var',
  19442. ' i: IBird;',
  19443. ' o: TBird;',
  19444. 'begin',
  19445. ' DoIt(i,i,i);',
  19446. ' Change(i,i);',
  19447. ' DoIt(o,o,o);',
  19448. '']);
  19449. ConvertProgram;
  19450. CheckSource('TestClassInterface_Corba_Args',
  19451. LinesToStr([ // statements
  19452. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  19453. 'rtl.createInterface(this, "IBird", "{4B0D080B-C0F6-396E-AE88-000B87785074}", [], this.IUnknown);',
  19454. 'rtl.createClass(this, "TObject", null, function () {',
  19455. ' this.$init = function () {',
  19456. ' };',
  19457. ' this.$final = function () {',
  19458. ' };',
  19459. '});',
  19460. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  19461. ' rtl.addIntf(this, $mod.IBird);',
  19462. '});',
  19463. 'this.DoIt = function (u, i, j) {',
  19464. ' $mod.DoIt({',
  19465. ' get: function () {',
  19466. ' return i;',
  19467. ' },',
  19468. ' set: function (v) {',
  19469. ' i = v;',
  19470. ' }',
  19471. ' }, i, i);',
  19472. '};',
  19473. 'this.Change = function (i, j) {',
  19474. ' $mod.DoIt(i, i.get(), i.get());',
  19475. ' $mod.Change(i, i);',
  19476. '};',
  19477. 'this.i = null;',
  19478. 'this.o = null;',
  19479. '']),
  19480. LinesToStr([ // $mod.$main
  19481. '$mod.DoIt({',
  19482. ' p: $mod,',
  19483. ' get: function () {',
  19484. ' return this.p.i;',
  19485. ' },',
  19486. ' set: function (v) {',
  19487. ' this.p.i = v;',
  19488. ' }',
  19489. '}, $mod.i, $mod.i);',
  19490. '$mod.Change({',
  19491. ' p: $mod,',
  19492. ' get: function () {',
  19493. ' return this.p.i;',
  19494. ' },',
  19495. ' set: function (v) {',
  19496. ' this.p.i = v;',
  19497. ' }',
  19498. '}, {',
  19499. ' p: $mod,',
  19500. ' get: function () {',
  19501. ' return this.p.i;',
  19502. ' },',
  19503. ' set: function (v) {',
  19504. ' this.p.i = v;',
  19505. ' }',
  19506. '});',
  19507. '$mod.DoIt({',
  19508. ' p: $mod,',
  19509. ' get: function () {',
  19510. ' return this.p.o;',
  19511. ' },',
  19512. ' set: function (v) {',
  19513. ' this.p.o = v;',
  19514. ' }',
  19515. '}, rtl.getIntfT($mod.o, $mod.IBird), rtl.getIntfT($mod.o, $mod.IBird));',
  19516. '']));
  19517. end;
  19518. procedure TTestModule.TestClassInterface_Corba_ForIn;
  19519. begin
  19520. StartProgram(false);
  19521. Add([
  19522. '{$interfaces corba}',
  19523. 'type',
  19524. ' IUnknown = interface end;',
  19525. ' TObject = class',
  19526. ' Id: longint;',
  19527. ' end;',
  19528. ' IEnumerator = interface(IUnknown)',
  19529. ' function GetCurrent: TObject;',
  19530. ' function MoveNext: Boolean;',
  19531. ' property Current: TObject read GetCurrent;',
  19532. ' end;',
  19533. ' IEnumerable = interface(IUnknown)',
  19534. ' function GetEnumerator: IEnumerator;',
  19535. ' end;',
  19536. 'var',
  19537. ' o: TObject;',
  19538. ' i: IEnumerable;',
  19539. 'begin',
  19540. ' for o in i do o.Id:=3;',
  19541. '']);
  19542. ConvertProgram;
  19543. CheckSource('TestClassInterface_Corba_ForIn',
  19544. LinesToStr([ // statements
  19545. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  19546. 'rtl.createClass(this, "TObject", null, function () {',
  19547. ' this.$init = function () {',
  19548. ' this.Id = 0;',
  19549. ' };',
  19550. ' this.$final = function () {',
  19551. ' };',
  19552. '});',
  19553. 'rtl.createInterface(this, "IEnumerator", "{95D7745D-ED61-3F13-BBE4-07708161999E}", ["GetCurrent", "MoveNext"], this.IUnknown);',
  19554. 'rtl.createInterface(this, "IEnumerable", "{8CC9D45D-ED7D-3B73-96B6-290B931BB19E}", ["GetEnumerator"], this.IUnknown);',
  19555. 'this.o = null;',
  19556. 'this.i = null;',
  19557. '']),
  19558. LinesToStr([ // $mod.$main
  19559. 'var $in = $mod.i.GetEnumerator();',
  19560. 'while ($in.MoveNext()) {',
  19561. ' $mod.o = $in.GetCurrent();',
  19562. ' $mod.o.Id = 3;',
  19563. '};',
  19564. '']));
  19565. end;
  19566. procedure TTestModule.TestClassInterface_COM_AssignVar;
  19567. begin
  19568. StartProgram(false);
  19569. Add([
  19570. '{$interfaces com}',
  19571. 'type',
  19572. ' IUnknown = interface',
  19573. ' function _AddRef: longint;',
  19574. ' function _Release: longint;',
  19575. ' end;',
  19576. ' TObject = class(IUnknown)',
  19577. ' function _AddRef: longint; virtual; abstract;',
  19578. ' function _Release: longint; virtual; abstract;',
  19579. ' end;',
  19580. 'var',
  19581. ' i: IUnknown;',
  19582. 'procedure DoGlobal(o: TObject);',
  19583. 'begin',
  19584. ' i:=nil;',
  19585. ' i:=o;',
  19586. ' i:=i;',
  19587. 'end;',
  19588. 'procedure DoLocal(o: TObject);',
  19589. 'const k: IUnknown = nil;',
  19590. 'var j: IUnknown;',
  19591. 'begin',
  19592. ' k:=o;',
  19593. ' k:=i;',
  19594. ' j:=o;',
  19595. ' j:=i;',
  19596. 'end;',
  19597. 'var o: TObject;',
  19598. 'begin',
  19599. ' i:=nil;',
  19600. ' i:=o;',
  19601. '']);
  19602. ConvertProgram;
  19603. CheckSource('TestClassInterface_COM_AssignVar',
  19604. LinesToStr([ // statements
  19605. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  19606. 'rtl.createClass(this, "TObject", null, function () {',
  19607. ' this.$init = function () {',
  19608. ' };',
  19609. ' this.$final = function () {',
  19610. ' };',
  19611. ' rtl.addIntf(this, $mod.IUnknown);',
  19612. '});',
  19613. 'this.i = null;',
  19614. 'this.DoGlobal = function (o) {',
  19615. ' rtl.setIntfP($mod, "i", null);',
  19616. ' rtl.setIntfP($mod, "i", rtl.queryIntfT(o, $mod.IUnknown), true);',
  19617. ' rtl.setIntfP($mod, "i", $mod.i);',
  19618. '};',
  19619. 'var k = null;',
  19620. 'this.DoLocal = function (o) {',
  19621. ' var j = null;',
  19622. ' try{',
  19623. ' k = rtl.setIntfL(k, rtl.queryIntfT(o, $mod.IUnknown), true);',
  19624. ' k = rtl.setIntfL(k, $mod.i);',
  19625. ' j = rtl.setIntfL(j, rtl.queryIntfT(o, $mod.IUnknown), true);',
  19626. ' j = rtl.setIntfL(j, $mod.i);',
  19627. ' }finally{',
  19628. ' rtl._Release(j);',
  19629. ' };',
  19630. '};',
  19631. 'this.o = null;',
  19632. '']),
  19633. LinesToStr([ // $mod.$main
  19634. 'rtl.setIntfP($mod, "i", null);',
  19635. 'rtl.setIntfP($mod, "i", rtl.queryIntfT($mod.o, $mod.IUnknown), true);',
  19636. '']));
  19637. end;
  19638. procedure TTestModule.TestClassInterface_COM_AssignArg;
  19639. begin
  19640. StartProgram(false);
  19641. Add([
  19642. '{$interfaces com}',
  19643. 'type',
  19644. ' IUnknown = interface',
  19645. ' function _AddRef: longint;',
  19646. ' function _Release: longint;',
  19647. ' end;',
  19648. ' TObject = class(IUnknown)',
  19649. ' function _AddRef: longint; virtual; abstract;',
  19650. ' function _Release: longint; virtual; abstract;',
  19651. ' end;',
  19652. 'procedure DoDefault(i, j: IUnknown);',
  19653. 'begin',
  19654. ' i:=nil;',
  19655. ' i:=j;',
  19656. 'end;',
  19657. 'begin',
  19658. '']);
  19659. ConvertProgram;
  19660. CheckSource('TestClassInterface_COM_AssignArg',
  19661. LinesToStr([ // statements
  19662. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  19663. 'rtl.createClass(this, "TObject", null, function () {',
  19664. ' this.$init = function () {',
  19665. ' };',
  19666. ' this.$final = function () {',
  19667. ' };',
  19668. ' rtl.addIntf(this, $mod.IUnknown);',
  19669. '});',
  19670. 'this.DoDefault = function (i, j) {',
  19671. ' rtl._AddRef(i);',
  19672. ' try {',
  19673. ' i = rtl.setIntfL(i, null);',
  19674. ' i = rtl.setIntfL(i, j);',
  19675. ' } finally {',
  19676. ' rtl._Release(i);',
  19677. ' };',
  19678. '};',
  19679. '']),
  19680. LinesToStr([ // $mod.$main
  19681. '']));
  19682. end;
  19683. procedure TTestModule.TestClassInterface_COM_FunctionResult;
  19684. begin
  19685. StartProgram(false);
  19686. Add([
  19687. '{$interfaces com}',
  19688. 'type',
  19689. ' IUnknown = interface',
  19690. ' function _AddRef: longint;',
  19691. ' function _Release: longint;',
  19692. ' end;',
  19693. ' TObject = class(IUnknown)',
  19694. ' function _AddRef: longint; virtual; abstract;',
  19695. ' function _Release: longint; virtual; abstract;',
  19696. ' end;',
  19697. 'function DoDefault(i: IUnknown): IUnknown;',
  19698. 'begin',
  19699. ' Result:=i;',
  19700. ' if Result<>nil then exit;',
  19701. 'end;',
  19702. 'begin',
  19703. '']);
  19704. ConvertProgram;
  19705. CheckSource('TestClassInterface_COM_FunctionResult',
  19706. LinesToStr([ // statements
  19707. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  19708. 'rtl.createClass(this, "TObject", null, function () {',
  19709. ' this.$init = function () {',
  19710. ' };',
  19711. ' this.$final = function () {',
  19712. ' };',
  19713. ' rtl.addIntf(this, $mod.IUnknown);',
  19714. '});',
  19715. 'this.DoDefault = function (i) {',
  19716. ' var Result = null;',
  19717. ' var $ok = false;',
  19718. ' try {',
  19719. ' Result = rtl.setIntfL(Result, i);',
  19720. ' if(Result !== null){',
  19721. ' $ok = true;',
  19722. ' return Result;',
  19723. ' };',
  19724. ' $ok = true;',
  19725. ' } finally {',
  19726. ' if(!$ok) rtl._Release(Result);',
  19727. ' };',
  19728. ' return Result;',
  19729. '};',
  19730. '']),
  19731. LinesToStr([ // $mod.$main
  19732. '']));
  19733. end;
  19734. procedure TTestModule.TestClassInterface_COM_InheritedFuncResult;
  19735. begin
  19736. StartProgram(false);
  19737. Add([
  19738. '{$interfaces com}',
  19739. 'type',
  19740. ' IUnknown = interface',
  19741. ' function _AddRef: longint;',
  19742. ' function _Release: longint;',
  19743. ' end;',
  19744. ' TObject = class(IUnknown)',
  19745. ' function _AddRef: longint; virtual; abstract;',
  19746. ' function _Release: longint; virtual; abstract;',
  19747. ' function GetIntf: IUnknown; virtual;',
  19748. ' end;',
  19749. ' TMouse = class',
  19750. ' function GetIntf: IUnknown; override;',
  19751. ' end;',
  19752. 'function TObject.GetIntf: IUnknown; begin end;',
  19753. 'function TMouse.GetIntf: IUnknown;',
  19754. 'var i: IUnknown;',
  19755. 'begin',
  19756. ' inherited;',
  19757. ' inherited GetIntf;',
  19758. ' inherited GetIntf();',
  19759. ' Result:=inherited GetIntf;',
  19760. ' Result:=inherited GetIntf();',
  19761. ' i:=inherited GetIntf;',
  19762. ' i:=inherited GetIntf();',
  19763. 'end;',
  19764. 'begin',
  19765. '']);
  19766. ConvertProgram;
  19767. CheckSource('TestClassInterface_COM_InheritedFuncResult',
  19768. LinesToStr([ // statements
  19769. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  19770. 'rtl.createClass(this, "TObject", null, function () {',
  19771. ' this.$init = function () {',
  19772. ' };',
  19773. ' this.$final = function () {',
  19774. ' };',
  19775. ' this.GetIntf = function () {',
  19776. ' var Result = null;',
  19777. ' return Result;',
  19778. ' };',
  19779. ' rtl.addIntf(this, $mod.IUnknown);',
  19780. '});',
  19781. 'rtl.createClass(this, "TMouse", this.TObject, function () {',
  19782. ' this.GetIntf = function () {',
  19783. ' var Result = null;',
  19784. ' var i = null;',
  19785. ' var $ir = rtl.createIntfRefs();',
  19786. ' var $ok = false;',
  19787. ' try {',
  19788. ' $ir.ref(1, $mod.TObject.GetIntf.call(this));',
  19789. ' $ir.ref(2, $mod.TObject.GetIntf.call(this));',
  19790. ' $ir.ref(3, $mod.TObject.GetIntf.call(this));',
  19791. ' Result = rtl.setIntfL(Result, $mod.TObject.GetIntf.call(this), true);',
  19792. ' Result = rtl.setIntfL(Result, $mod.TObject.GetIntf.call(this), true);',
  19793. ' i = rtl.setIntfL(i, $mod.TObject.GetIntf.call(this), true);',
  19794. ' i = rtl.setIntfL(i, $mod.TObject.GetIntf.call(this), true);',
  19795. ' $ok = true;',
  19796. ' } finally {',
  19797. ' $ir.free();',
  19798. ' rtl._Release(i);',
  19799. ' if (!$ok) rtl._Release(Result);',
  19800. ' };',
  19801. ' return Result;',
  19802. ' };',
  19803. ' rtl.addIntf(this, $mod.IUnknown);',
  19804. '});',
  19805. '']),
  19806. LinesToStr([ // $mod.$main
  19807. '']));
  19808. end;
  19809. procedure TTestModule.TestClassInterface_COM_IsAsTypeCasts;
  19810. begin
  19811. StartProgram(false);
  19812. Add([
  19813. '{$interfaces com}',
  19814. 'type',
  19815. ' IUnknown = interface',
  19816. ' function _AddRef: longint;',
  19817. ' function _Release: longint;',
  19818. ' end;',
  19819. ' TObject = class(IUnknown)',
  19820. ' function _AddRef: longint; virtual; abstract;',
  19821. ' function _Release: longint; virtual; abstract;',
  19822. ' end;',
  19823. 'procedure DoDefault(i, j: IUnknown; o: TObject);',
  19824. 'begin',
  19825. ' if i is IUnknown then ;',
  19826. ' if o is IUnknown then ;',
  19827. ' if i is TObject then ;',
  19828. ' i:=j as IUnknown;',
  19829. ' i:=o as IUnknown;',
  19830. ' o:=j as TObject;',
  19831. ' i:=IUnknown(j);',
  19832. ' i:=IUnknown(o);',
  19833. ' o:=TObject(i);',
  19834. 'end;',
  19835. 'begin',
  19836. '']);
  19837. ConvertProgram;
  19838. CheckSource('TestClassInterface_COM_IsAsTypeCasts',
  19839. LinesToStr([ // statements
  19840. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  19841. 'rtl.createClass(this, "TObject", null, function () {',
  19842. ' this.$init = function () {',
  19843. ' };',
  19844. ' this.$final = function () {',
  19845. ' };',
  19846. ' rtl.addIntf(this, $mod.IUnknown);',
  19847. '});',
  19848. 'this.DoDefault = function (i, j, o) {',
  19849. ' rtl._AddRef(i);',
  19850. ' try {',
  19851. ' if (rtl.intfIsIntfT(i, $mod.IUnknown)) ;',
  19852. ' if (rtl.queryIntfIsT(o, $mod.IUnknown)) ;',
  19853. ' if (rtl.intfIsClass(i, $mod.TObject)) ;',
  19854. ' i = rtl.setIntfL(i, rtl.intfAsIntfT(j, $mod.IUnknown));',
  19855. ' i = rtl.setIntfL(i, rtl.queryIntfT(o, $mod.IUnknown), true);',
  19856. ' o = rtl.intfAsClass(j, $mod.TObject);',
  19857. ' i = rtl.setIntfL(i, j);',
  19858. ' i = rtl.setIntfL(i, rtl.queryIntfT(o, $mod.IUnknown), true);',
  19859. ' o = rtl.intfToClass(i, $mod.TObject);',
  19860. ' } finally {',
  19861. ' rtl._Release(i);',
  19862. ' };',
  19863. '};',
  19864. '']),
  19865. LinesToStr([ // $mod.$main
  19866. '']));
  19867. end;
  19868. procedure TTestModule.TestClassInterface_COM_PassAsArg;
  19869. begin
  19870. StartProgram(false);
  19871. Add([
  19872. '{$interfaces com}',
  19873. 'type',
  19874. ' IUnknown = interface',
  19875. ' function _AddRef: longint;',
  19876. ' function _Release: longint;',
  19877. ' end;',
  19878. ' TObject = class(IUnknown)',
  19879. ' function _AddRef: longint; virtual; abstract;',
  19880. ' function _Release: longint; virtual; abstract;',
  19881. ' end;',
  19882. 'procedure DoIt(v: IUnknown; const j: IUnknown; var k: IUnknown; out l: IUnknown);',
  19883. 'var o: TObject;',
  19884. 'begin',
  19885. ' DoIt(v,v,v,v);',
  19886. ' DoIt(o,o,k,k);',
  19887. 'end;',
  19888. 'procedure DoSome;',
  19889. 'var v: IUnknown;',
  19890. 'begin',
  19891. ' DoIt(v,v,v,v);',
  19892. 'end;',
  19893. 'var i: IUnknown;',
  19894. 'begin',
  19895. ' DoIt(i,i,i,i);',
  19896. '']);
  19897. ConvertProgram;
  19898. CheckSource('TestClassInterface_COM_PassAsArg',
  19899. LinesToStr([ // statements
  19900. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  19901. 'rtl.createClass(this, "TObject", null, function () {',
  19902. ' this.$init = function () {',
  19903. ' };',
  19904. ' this.$final = function () {',
  19905. ' };',
  19906. ' rtl.addIntf(this, $mod.IUnknown);',
  19907. '});',
  19908. 'this.DoIt = function (v, j, k, l) {',
  19909. ' var o = null;',
  19910. ' var $ir = rtl.createIntfRefs();',
  19911. ' rtl._AddRef(v);',
  19912. ' try {',
  19913. ' $mod.DoIt(v, v, {',
  19914. ' get: function () {',
  19915. ' return v;',
  19916. ' },',
  19917. ' set: function (w) {',
  19918. ' v = rtl.setIntfL(v, w);',
  19919. ' }',
  19920. ' }, {',
  19921. ' get: function () {',
  19922. ' return v;',
  19923. ' },',
  19924. ' set: function (w) {',
  19925. ' v = rtl.setIntfL(v, w);',
  19926. ' }',
  19927. ' });',
  19928. ' $mod.DoIt($ir.ref(1, rtl.queryIntfT(o, $mod.IUnknown)), $ir.ref(2, rtl.queryIntfT(o, $mod.IUnknown)), k, k);',
  19929. ' } finally {',
  19930. ' $ir.free();',
  19931. ' rtl._Release(v);',
  19932. ' };',
  19933. '};',
  19934. 'this.DoSome = function () {',
  19935. ' var v = null;',
  19936. ' try {',
  19937. ' $mod.DoIt(v, v, {',
  19938. ' get: function () {',
  19939. ' return v;',
  19940. ' },',
  19941. ' set: function (w) {',
  19942. ' v = rtl.setIntfL(v, w);',
  19943. ' }',
  19944. ' }, {',
  19945. ' get: function () {',
  19946. ' return v;',
  19947. ' },',
  19948. ' set: function (w) {',
  19949. ' v = rtl.setIntfL(v, w);',
  19950. ' }',
  19951. ' });',
  19952. ' } finally {',
  19953. ' rtl._Release(v);',
  19954. ' };',
  19955. '};',
  19956. 'this.i = null;',
  19957. '']),
  19958. LinesToStr([ // $mod.$main
  19959. '$mod.DoIt($mod.i, $mod.i, {',
  19960. ' p: $mod,',
  19961. ' get: function () {',
  19962. ' return this.p.i;',
  19963. ' },',
  19964. ' set: function (v) {',
  19965. ' rtl.setIntfP(this.p, "i", v);',
  19966. ' }',
  19967. '}, {',
  19968. ' p: $mod,',
  19969. ' get: function () {',
  19970. ' return this.p.i;',
  19971. ' },',
  19972. ' set: function (v) {',
  19973. ' rtl.setIntfP(this.p, "i", v);',
  19974. ' }',
  19975. '});',
  19976. '']));
  19977. end;
  19978. procedure TTestModule.TestClassInterface_COM_PassToUntypedParam;
  19979. begin
  19980. StartProgram(false);
  19981. Add([
  19982. '{$interfaces com}',
  19983. 'type',
  19984. ' IUnknown = interface',
  19985. ' function _AddRef: longint;',
  19986. ' function _Release: longint;',
  19987. ' end;',
  19988. ' TObject = class(IUnknown)',
  19989. ' function _AddRef: longint; virtual; abstract;',
  19990. ' function _Release: longint; virtual; abstract;',
  19991. ' end;',
  19992. 'procedure DoIt(out i);',
  19993. 'begin end;',
  19994. 'procedure DoSome;',
  19995. 'var v: IUnknown;',
  19996. 'begin',
  19997. ' DoIt(v);',
  19998. 'end;',
  19999. 'function GetIt: IUnknown;',
  20000. 'begin',
  20001. ' DoIt(Result);',
  20002. 'end;',
  20003. 'var i: IUnknown;',
  20004. 'begin',
  20005. ' DoIt(i);',
  20006. '']);
  20007. ConvertProgram;
  20008. CheckSource('TestClassInterface_COM_PassToUntypedParam',
  20009. LinesToStr([ // statements
  20010. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  20011. 'rtl.createClass(this, "TObject", null, function () {',
  20012. ' this.$init = function () {',
  20013. ' };',
  20014. ' this.$final = function () {',
  20015. ' };',
  20016. ' rtl.addIntf(this, $mod.IUnknown);',
  20017. '});',
  20018. 'this.DoIt = function (i) {',
  20019. '};',
  20020. 'this.DoSome = function () {',
  20021. ' var v = null;',
  20022. ' try {',
  20023. ' $mod.DoIt({',
  20024. ' get: function () {',
  20025. ' return v;',
  20026. ' },',
  20027. ' set: function (w) {',
  20028. ' v = w;',
  20029. ' }',
  20030. ' });',
  20031. ' } finally {',
  20032. ' rtl._Release(v);',
  20033. ' };',
  20034. '};',
  20035. 'this.GetIt = function () {',
  20036. ' var Result = null;',
  20037. ' var $ok = false;',
  20038. ' try {',
  20039. ' $mod.DoIt({',
  20040. ' get: function () {',
  20041. ' return Result;',
  20042. ' },',
  20043. ' set: function (v) {',
  20044. ' Result = v;',
  20045. ' }',
  20046. ' });',
  20047. ' $ok = true;',
  20048. ' } finally {',
  20049. ' if (!$ok) rtl._Release(Result);',
  20050. ' };',
  20051. ' return Result;',
  20052. '};',
  20053. 'this.i = null;',
  20054. '']),
  20055. LinesToStr([ // $mod.$main
  20056. 'try {',
  20057. ' $mod.DoIt({',
  20058. ' p: $mod,',
  20059. ' get: function () {',
  20060. ' return this.p.i;',
  20061. ' },',
  20062. ' set: function (v) {',
  20063. ' this.p.i = v;',
  20064. ' }',
  20065. ' });',
  20066. '} finally {',
  20067. ' rtl._Release($mod.i);',
  20068. '};',
  20069. '']));
  20070. end;
  20071. procedure TTestModule.TestClassInterface_COM_FunctionInExpr;
  20072. begin
  20073. StartProgram(false);
  20074. Add([
  20075. '{$interfaces com}',
  20076. 'type',
  20077. ' IUnknown = interface',
  20078. ' function _AddRef: longint;',
  20079. ' function _Release: longint;',
  20080. ' end;',
  20081. ' TObject = class(IUnknown)',
  20082. ' function _AddRef: longint; virtual; abstract;',
  20083. ' function _Release: longint; virtual; abstract;',
  20084. ' end;',
  20085. 'function GetIt: IUnknown;',
  20086. 'begin',
  20087. 'end;',
  20088. 'procedure DoSome;',
  20089. 'var v: IUnknown;',
  20090. ' i: longint;',
  20091. 'begin',
  20092. ' v:=GetIt;',
  20093. ' v:=GetIt();',
  20094. ' GetIt()._AddRef;',
  20095. ' i:=GetIt()._AddRef;',
  20096. 'end;',
  20097. 'var v: IUnknown;',
  20098. ' i: longint;',
  20099. 'begin',
  20100. ' v:=GetIt;',
  20101. ' v:=GetIt();',
  20102. ' GetIt()._AddRef;',
  20103. ' i:=GetIt()._AddRef;',
  20104. '']);
  20105. ConvertProgram;
  20106. CheckSource('TestClassInterface_COM_FunctionInExpr',
  20107. LinesToStr([ // statements
  20108. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  20109. 'rtl.createClass(this, "TObject", null, function () {',
  20110. ' this.$init = function () {',
  20111. ' };',
  20112. ' this.$final = function () {',
  20113. ' };',
  20114. ' rtl.addIntf(this, $mod.IUnknown);',
  20115. '});',
  20116. 'this.GetIt = function () {',
  20117. ' var Result = null;',
  20118. ' return Result;',
  20119. '};',
  20120. 'this.DoSome = function () {',
  20121. ' var v = null;',
  20122. ' var i = 0;',
  20123. ' var $ir = rtl.createIntfRefs();',
  20124. ' try {',
  20125. ' v = rtl.setIntfL(v, $mod.GetIt(), true);',
  20126. ' v = rtl.setIntfL(v, $mod.GetIt(), true);',
  20127. ' $ir.ref(1, $mod.GetIt())._AddRef();',
  20128. ' i = $ir.ref(2, $mod.GetIt())._AddRef();',
  20129. ' } finally {',
  20130. ' $ir.free();',
  20131. ' rtl._Release(v);',
  20132. ' };',
  20133. '};',
  20134. 'this.v = null;',
  20135. 'this.i = 0;',
  20136. '']),
  20137. LinesToStr([ // $mod.$main
  20138. 'var $ir = rtl.createIntfRefs();',
  20139. 'try {',
  20140. ' rtl.setIntfP($mod, "v", $mod.GetIt(), true);',
  20141. ' rtl.setIntfP($mod, "v", $mod.GetIt(), true);',
  20142. ' $ir.ref(1, $mod.GetIt())._AddRef();',
  20143. ' $mod.i = $ir.ref(2, $mod.GetIt())._AddRef();',
  20144. '} finally {',
  20145. ' $ir.free();',
  20146. '};',
  20147. '']));
  20148. end;
  20149. procedure TTestModule.TestClassInterface_COM_Property;
  20150. begin
  20151. StartProgram(false);
  20152. Add([
  20153. '{$interfaces com}',
  20154. 'type',
  20155. ' IUnknown = interface',
  20156. ' function _AddRef: longint;',
  20157. ' function _Release: longint;',
  20158. ' end;',
  20159. ' TObject = class(IUnknown)',
  20160. ' FAnt: IUnknown;',
  20161. ' function _AddRef: longint; virtual; abstract;',
  20162. ' function _Release: longint; virtual; abstract;',
  20163. ' function GetBird: IUnknown; virtual; abstract;',
  20164. ' procedure SetBird(Value: IUnknown); virtual; abstract;',
  20165. ' function GetItems(Index: longint): IUnknown; virtual; abstract;',
  20166. ' procedure SetItems(Index: longint; Value: IUnknown); virtual; abstract;',
  20167. ' property Ant: IUnknown read FAnt write FAnt;',
  20168. ' property Bird: IUnknown read GetBird write SetBird;',
  20169. ' property Items[Index: longint]: IUnknown read GetItems write SetItems; default;',
  20170. ' end;',
  20171. 'procedure DoIt;',
  20172. 'var',
  20173. ' o: TObject;',
  20174. ' v: IUnknown;',
  20175. 'begin',
  20176. ' v:=o.Ant;',
  20177. ' o.Ant:=v;',
  20178. ' o.Ant:=o.Ant;',
  20179. ' v:=o.Bird;',
  20180. ' o.Bird:=v;',
  20181. ' o.Bird:=o.Bird;',
  20182. ' v:=o.Items[1];',
  20183. ' o.Items[2]:=v;',
  20184. ' o.Items[3]:=o.Items[4];',
  20185. ' v:=o[5];',
  20186. ' o[6]:=v;',
  20187. ' o[7]:=o[8];',
  20188. 'end;',
  20189. 'begin',
  20190. '']);
  20191. ConvertProgram;
  20192. CheckSource('TestClassInterface_COM_Property',
  20193. LinesToStr([ // statements
  20194. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  20195. 'rtl.createClass(this, "TObject", null, function () {',
  20196. ' this.$init = function () {',
  20197. ' this.FAnt = null;',
  20198. ' };',
  20199. ' this.$final = function () {',
  20200. ' this.FAnt = undefined;',
  20201. ' };',
  20202. ' rtl.addIntf(this, $mod.IUnknown);',
  20203. '});',
  20204. 'this.DoIt = function () {',
  20205. ' var o = null;',
  20206. ' var v = null;',
  20207. ' var $ir = rtl.createIntfRefs();',
  20208. ' try {',
  20209. ' v = rtl.setIntfL(v, o.FAnt);',
  20210. ' rtl.setIntfP(o, "FAnt", v);',
  20211. ' rtl.setIntfP(o, "FAnt", o.FAnt);',
  20212. ' v = rtl.setIntfL(v, o.GetBird(), true);',
  20213. ' o.SetBird(v);',
  20214. ' o.SetBird($ir.ref(1, o.GetBird()));',
  20215. ' v = rtl.setIntfL(v, o.GetItems(1), true);',
  20216. ' o.SetItems(2, v);',
  20217. ' o.SetItems(3, $ir.ref(2, o.GetItems(4)));',
  20218. ' v = rtl.setIntfL(v, o.GetItems(5), true);',
  20219. ' o.SetItems(6, v);',
  20220. ' o.SetItems(7, $ir.ref(3, o.GetItems(8)));',
  20221. ' } finally {',
  20222. ' $ir.free();',
  20223. ' rtl._Release(v);',
  20224. ' };',
  20225. '};',
  20226. '']),
  20227. LinesToStr([ // $mod.$main
  20228. '']));
  20229. end;
  20230. procedure TTestModule.TestClassInterface_COM_IntfProperty;
  20231. begin
  20232. StartProgram(false);
  20233. Add([
  20234. '{$interfaces com}',
  20235. 'type',
  20236. ' IUnknown = interface',
  20237. ' function _AddRef: longint;',
  20238. ' function _Release: longint;',
  20239. ' function GetBird: IUnknown;',
  20240. ' procedure SetBird(Value: IUnknown);',
  20241. ' function GetItems(Index: longint): IUnknown;',
  20242. ' procedure SetItems(Index: longint; Value: IUnknown);',
  20243. ' property Bird: IUnknown read GetBird write SetBird;',
  20244. ' property Items[Index: longint]: IUnknown read GetItems write SetItems; default;',
  20245. ' end;',
  20246. ' TObject = class(IUnknown)',
  20247. ' function _AddRef: longint; virtual; abstract;',
  20248. ' function _Release: longint; virtual; abstract;',
  20249. ' function GetBird: IUnknown; virtual; abstract;',
  20250. ' procedure SetBird(Value: IUnknown); virtual; abstract;',
  20251. ' function GetItems(Index: longint): IUnknown; virtual; abstract;',
  20252. ' procedure SetItems(Index: longint; Value: IUnknown); virtual; abstract;',
  20253. ' end;',
  20254. 'procedure DoIt;',
  20255. 'var',
  20256. ' o: TObject;',
  20257. ' v: IUnknown;',
  20258. 'begin',
  20259. ' v:=v.Items[1];',
  20260. ' v.Items[2]:=v;',
  20261. ' v.Items[3]:=v.Items[4];',
  20262. ' v:=v[5];',
  20263. ' v[6]:=v;',
  20264. ' v[7]:=v[8];',
  20265. ' v[9].Bird.Bird:=v;',
  20266. ' v:=v.Bird[10].Bird',
  20267. 'end;',
  20268. 'begin',
  20269. '']);
  20270. ConvertProgram;
  20271. CheckSource('TestClassInterface_COM_IntfProperty',
  20272. LinesToStr([ // statements
  20273. 'rtl.createInterface(this, "IUnknown", "{385F5482-571B-338C-8130-4E97F330543B}", [',
  20274. ' "_AddRef",',
  20275. ' "_Release",',
  20276. ' "GetBird",',
  20277. ' "SetBird",',
  20278. ' "GetItems",',
  20279. ' "SetItems"',
  20280. '], null);',
  20281. 'rtl.createClass(this, "TObject", null, function () {',
  20282. ' this.$init = function () {',
  20283. ' };',
  20284. ' this.$final = function () {',
  20285. ' };',
  20286. ' rtl.addIntf(this, $mod.IUnknown);',
  20287. '});',
  20288. 'this.DoIt = function () {',
  20289. ' var o = null;',
  20290. ' var v = null;',
  20291. ' var $ir = rtl.createIntfRefs();',
  20292. ' try {',
  20293. ' v = rtl.setIntfL(v, v.GetItems(1), true);',
  20294. ' v.SetItems(2, v);',
  20295. ' v.SetItems(3, $ir.ref(1, v.GetItems(4)));',
  20296. ' v = rtl.setIntfL(v, v.GetItems(5), true);',
  20297. ' v.SetItems(6, v);',
  20298. ' v.SetItems(7, $ir.ref(2, v.GetItems(8)));',
  20299. ' $ir.ref(4, $ir.ref(3, v.GetItems(9)).GetBird()).SetBird(v);',
  20300. ' v = rtl.setIntfL(v, $ir.ref(6, $ir.ref(5, v.GetBird()).GetItems(10)).GetBird(), true);',
  20301. ' } finally {',
  20302. ' $ir.free();',
  20303. ' rtl._Release(v);',
  20304. ' };',
  20305. '};',
  20306. '']),
  20307. LinesToStr([ // $mod.$main
  20308. '']));
  20309. end;
  20310. procedure TTestModule.TestClassInterface_COM_Delegation;
  20311. begin
  20312. StartProgram(false);
  20313. Add([
  20314. '{$interfaces com}',
  20315. 'type',
  20316. ' IUnknown = interface',
  20317. ' function _AddRef: longint;',
  20318. ' function _Release: longint;',
  20319. ' end;',
  20320. ' IBird = interface(IUnknown)',
  20321. ' procedure Fly(s: string);',
  20322. ' end;',
  20323. ' IEagle = interface(IBird) end;',
  20324. ' IDove = interface(IBird) end;',
  20325. ' ISwallow = interface(IBird) end;',
  20326. ' TObject = class',
  20327. ' end;',
  20328. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  20329. ' function _AddRef: longint; virtual; abstract;',
  20330. ' function _Release: longint; virtual; abstract;',
  20331. ' procedure Fly(s: string); virtual; abstract;',
  20332. ' end;',
  20333. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  20334. ' function _AddRef: longint; virtual; abstract;',
  20335. ' function _Release: longint; virtual; abstract;',
  20336. ' FBirdIntf: IBird;',
  20337. ' property BirdIntf: IBird read FBirdIntf implements IBird;',
  20338. ' function GetEagleIntf: IEagle; virtual; abstract;',
  20339. ' property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  20340. ' FDoveObj: TBird;',
  20341. ' property DoveObj: TBird read FDoveObj implements IDove;',
  20342. ' function GetSwallowObj: TBird; virtual; abstract;',
  20343. ' property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  20344. ' end;',
  20345. 'begin',
  20346. '']);
  20347. ConvertProgram;
  20348. CheckSource('TestClassInterface_COM_Delegation',
  20349. LinesToStr([ // statements
  20350. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  20351. 'rtl.createInterface(this, "IBird", "{CC440C7F-7623-3DEE-AE88-000B86AAF108}", ["Fly"], this.IUnknown);',
  20352. 'rtl.createInterface(this, "IEagle", "{4B6A41C9-B020-3D7C-B688-96D19022B1B4}", [], this.IBird);',
  20353. 'rtl.createInterface(this, "IDove", "{4B6A41C9-B020-3D7C-B688-96D18EF16074}", [], this.IBird);',
  20354. 'rtl.createInterface(this, "ISwallow", "{BB6A41C9-B020-3D7C-B688-96D1CBDCB359}", [], this.IBird);',
  20355. 'rtl.createClass(this, "TObject", null, function () {',
  20356. ' this.$init = function () {',
  20357. ' };',
  20358. ' this.$final = function () {',
  20359. ' };',
  20360. '});',
  20361. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  20362. ' rtl.addIntf(this, $mod.IBird);',
  20363. ' rtl.addIntf(this, $mod.IEagle);',
  20364. ' rtl.addIntf(this, $mod.IDove);',
  20365. ' rtl.addIntf(this, $mod.ISwallow);',
  20366. '});',
  20367. 'rtl.createClass(this, "TBat", this.TObject, function () {',
  20368. ' this.$init = function () {',
  20369. ' $mod.TObject.$init.call(this);',
  20370. ' this.FBirdIntf = null;',
  20371. ' this.FDoveObj = null;',
  20372. ' };',
  20373. ' this.$final = function () {',
  20374. ' this.FBirdIntf = undefined;',
  20375. ' this.FDoveObj = undefined;',
  20376. ' $mod.TObject.$final.call(this);',
  20377. ' };',
  20378. ' this.$intfmaps = {',
  20379. ' "{CC440C7F-7623-3DEE-AE88-000B86AAF108}": function () {',
  20380. ' return rtl._AddRef(this.FBirdIntf);',
  20381. ' },',
  20382. ' "{4B6A41C9-B020-3D7C-B688-96D19022B1B4}": function () {',
  20383. ' return this.GetEagleIntf();',
  20384. ' },',
  20385. ' "{4B6A41C9-B020-3D7C-B688-96D18EF16074}": function () {',
  20386. ' return rtl.queryIntfT(this.FDoveObj, $mod.IDove);',
  20387. ' },',
  20388. ' "{BB6A41C9-B020-3D7C-B688-96D1CBDCB359}": function () {',
  20389. ' return rtl.queryIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  20390. ' }',
  20391. ' };',
  20392. '});',
  20393. '']),
  20394. LinesToStr([ // $mod.$main
  20395. '']));
  20396. end;
  20397. procedure TTestModule.TestClassInterface_COM_With;
  20398. begin
  20399. StartProgram(false);
  20400. Add([
  20401. '{$interfaces com}',
  20402. 'type',
  20403. ' IUnknown = interface',
  20404. ' function _AddRef: longint;',
  20405. ' function _Release: longint;',
  20406. ' function GetAnt: IUnknown;',
  20407. ' property Ant: IUnknown read GetAnt;',
  20408. ' end;',
  20409. ' TObject = class(IUnknown)',
  20410. ' function _AddRef: longint; virtual; abstract;',
  20411. ' function _Release: longint; virtual; abstract;',
  20412. ' function GetAnt: IUnknown; virtual; abstract;',
  20413. ' property Ant: IUnknown read GetAnt;',
  20414. ' end;',
  20415. 'procedure DoIt;',
  20416. 'var',
  20417. ' i: IUnknown;',
  20418. 'begin',
  20419. ' with i do ',
  20420. ' GetAnt;',
  20421. ' with i.Ant, Ant do ',
  20422. ' GetAnt;',
  20423. 'end;',
  20424. 'begin',
  20425. '']);
  20426. ConvertProgram;
  20427. CheckSource('TestClassInterface_COM_With',
  20428. LinesToStr([ // statements
  20429. 'rtl.createInterface(this, "IUnknown", "{D7ADB00D-C6B6-39FB-BDDF-21CD521DDFA9}", ["_AddRef", "_Release", "GetAnt"], null);',
  20430. 'rtl.createClass(this, "TObject", null, function () {',
  20431. ' this.$init = function () {',
  20432. ' };',
  20433. ' this.$final = function () {',
  20434. ' };',
  20435. ' rtl.addIntf(this, $mod.IUnknown);',
  20436. '});',
  20437. 'this.DoIt = function () {',
  20438. ' var i = null;',
  20439. ' var $ir = rtl.createIntfRefs();',
  20440. ' try {',
  20441. ' $ir.ref(1, i.GetAnt());',
  20442. ' var $with = $ir.ref(2, i.GetAnt());',
  20443. ' var $with1 = $ir.ref(3, $with.GetAnt());',
  20444. ' $ir.ref(4, $with1.GetAnt());',
  20445. ' } finally {',
  20446. ' $ir.free();',
  20447. ' };',
  20448. '};',
  20449. '']),
  20450. LinesToStr([ // $mod.$main
  20451. '']));
  20452. end;
  20453. procedure TTestModule.TestClassInterface_COM_ForIn;
  20454. begin
  20455. StartProgram(false);
  20456. Add([
  20457. '{$interfaces com}',
  20458. 'type',
  20459. ' IUnknown = interface end;',
  20460. ' TObject = class',
  20461. ' Id: longint;',
  20462. ' end;',
  20463. ' IEnumerator = interface(IUnknown)',
  20464. ' function GetCurrent: TObject;',
  20465. ' function MoveNext: Boolean;',
  20466. ' property Current: TObject read GetCurrent;',
  20467. ' end;',
  20468. ' IEnumerable = interface(IUnknown)',
  20469. ' function GetEnumerator: IEnumerator;',
  20470. ' end;',
  20471. 'var',
  20472. ' o: TObject;',
  20473. ' i: IEnumerable;',
  20474. 'begin',
  20475. ' for o in i do o.Id:=3;',
  20476. '']);
  20477. ConvertProgram;
  20478. CheckSource('TestClassInterface_COM_ForIn',
  20479. LinesToStr([ // statements
  20480. 'rtl.createInterface(this, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  20481. 'rtl.createClass(this, "TObject", null, function () {',
  20482. ' this.$init = function () {',
  20483. ' this.Id = 0;',
  20484. ' };',
  20485. ' this.$final = function () {',
  20486. ' };',
  20487. '});',
  20488. 'rtl.createInterface(this, "IEnumerator", "{95D7745D-ED61-3F13-BBE4-07708161999E}", ["GetCurrent", "MoveNext"], this.IUnknown);',
  20489. 'rtl.createInterface(this, "IEnumerable", "{8CC9D45D-ED7D-3B73-96B6-290B931BB19E}", ["GetEnumerator"], this.IUnknown);',
  20490. 'this.o = null;',
  20491. 'this.i = null;',
  20492. '']),
  20493. LinesToStr([ // $mod.$main
  20494. 'var $in = $mod.i.GetEnumerator();',
  20495. 'try {',
  20496. ' while ($in.MoveNext()) {',
  20497. ' $mod.o = $in.GetCurrent();',
  20498. ' $mod.o.Id = 3;',
  20499. ' }',
  20500. '} finally {',
  20501. ' rtl._Release($in)',
  20502. '};',
  20503. '']));
  20504. end;
  20505. procedure TTestModule.TestClassInterface_COM_ArrayOfIntfFail;
  20506. begin
  20507. StartProgram(false);
  20508. Add([
  20509. '{$interfaces com}',
  20510. 'type',
  20511. ' IUnknown = interface',
  20512. ' function _AddRef: longint;',
  20513. ' function _Release: longint;',
  20514. ' end;',
  20515. ' TObject = class',
  20516. ' end;',
  20517. ' TArrOfIntf = array of IUnknown;',
  20518. 'begin',
  20519. '']);
  20520. SetExpectedPasResolverError('Not supported: array of COM-interface',nNotSupportedX);
  20521. ConvertProgram;
  20522. end;
  20523. procedure TTestModule.TestClassInterface_COM_RecordIntfFail;
  20524. begin
  20525. StartProgram(false);
  20526. Add([
  20527. '{$interfaces com}',
  20528. 'type',
  20529. ' IUnknown = interface',
  20530. ' function _AddRef: longint;',
  20531. ' function _Release: longint;',
  20532. ' end;',
  20533. ' TRec = record',
  20534. ' i: IUnknown;',
  20535. ' end;',
  20536. 'begin',
  20537. '']);
  20538. SetExpectedPasResolverError('Not supported: COM-interface as record member',nNotSupportedX);
  20539. ConvertProgram;
  20540. end;
  20541. procedure TTestModule.TestClassInterface_COM_UnitInitialization;
  20542. begin
  20543. StartUnit(false);
  20544. Add([
  20545. '{$interfaces com}',
  20546. 'interface',
  20547. 'implementation',
  20548. 'type',
  20549. ' IUnknown = interface',
  20550. ' function _AddRef: longint;',
  20551. ' end;',
  20552. ' TObject = class(IUnknown)',
  20553. ' function _AddRef: longint;',
  20554. ' end;',
  20555. 'function TObject._AddRef: longint; begin end;',
  20556. 'var i: IUnknown;',
  20557. ' o: TObject;',
  20558. 'initialization',
  20559. ' i:=nil;',
  20560. ' i:=i;',
  20561. ' i:=o;',
  20562. ' if (o as IUnknown)=nil then ;',
  20563. '']);
  20564. ConvertUnit;
  20565. CheckSource('TestClassInterface_COM_UnitInitialization',
  20566. LinesToStr([ // statements
  20567. 'var $impl = $mod.$impl;',
  20568. '']),
  20569. LinesToStr([ // this.$init
  20570. 'var $ir = rtl.createIntfRefs();',
  20571. 'try {',
  20572. ' rtl.setIntfP($impl, "i", null);',
  20573. ' rtl.setIntfP($impl, "i", $impl.i);',
  20574. ' rtl.setIntfP($impl, "i", rtl.queryIntfT($impl.o, $impl.IUnknown), true);',
  20575. ' if ($ir.ref(1, rtl.queryIntfT($impl.o, $impl.IUnknown)) === null) ;',
  20576. '} finally {',
  20577. ' $ir.free();',
  20578. '};',
  20579. '']),
  20580. LinesToStr([ // implementation
  20581. 'rtl.createInterface($impl, "IUnknown", "{B92D5841-758A-322B-BDDF-21CD52180000}", ["_AddRef"], null);',
  20582. 'rtl.createClass($impl, "TObject", null, function () {',
  20583. ' this.$init = function () {',
  20584. ' };',
  20585. ' this.$final = function () {',
  20586. ' };',
  20587. ' this._AddRef = function () {',
  20588. ' var Result = 0;',
  20589. ' return Result;',
  20590. ' };',
  20591. ' rtl.addIntf(this, $impl.IUnknown);',
  20592. '});',
  20593. '$impl.i = null;',
  20594. '$impl.o = null;',
  20595. ''])
  20596. );
  20597. end;
  20598. procedure TTestModule.TestClassInterface_GUID;
  20599. begin
  20600. StartProgram(false);
  20601. Add([
  20602. '{$interfaces corba}',
  20603. 'type',
  20604. ' IUnknown = interface',
  20605. ' [''{f31db68f-3010-D355-4EBA-CDD4EF4A737C}'']',
  20606. ' end;',
  20607. ' TObject = class end;',
  20608. ' TGUID = record D1, D2, D3, D4: word; end;',
  20609. ' TAliasGUID = TGUID;',
  20610. ' TGUIDString = type string;',
  20611. ' TAliasGUIDString = TGUIDString;',
  20612. 'procedure DoConstGUIDIt(const g: TAliasGUID); overload;',
  20613. 'begin end;',
  20614. 'procedure DoDefGUID(g: TAliasGUID); overload;',
  20615. 'begin end;',
  20616. 'procedure DoStr(const s: TAliasGUIDString); overload;',
  20617. 'begin end;',
  20618. 'var',
  20619. ' i: IUnknown;',
  20620. ' g: TAliasGUID = ''{d91c9af4-3C93-420F-A303-BF5BA82BFD23}'';',
  20621. ' s: TAliasGUIDString;',
  20622. 'begin',
  20623. ' DoConstGUIDIt(IUnknown);',
  20624. ' DoDefGUID(IUnknown);',
  20625. ' DoStr(IUnknown);',
  20626. ' DoConstGUIDIt(i);',
  20627. ' DoDefGUID(i);',
  20628. ' DoStr(i);',
  20629. ' DoConstGUIDIt(''{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}'');',
  20630. ' DoDefGUID(''{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}'');',
  20631. ' DoStr(g);',
  20632. ' g:=i;',
  20633. ' g:=IUnknown;',
  20634. ' g:=''{D91C9AF4-3C93-420F-A303-bf5ba82bfd23}'';',
  20635. ' s:=i;',
  20636. ' s:=IUnknown;',
  20637. ' s:=g;',
  20638. ' if g=i then ;',
  20639. ' if i=g then ;',
  20640. ' if g=IUnknown then ;',
  20641. ' if IUnknown=g then ;',
  20642. ' if s=i then ;',
  20643. ' if i=s then ;',
  20644. ' if s=IUnknown then ;',
  20645. ' if IUnknown=s then ;',
  20646. ' if s=g then ;',
  20647. ' if g=s then ;',
  20648. '']);
  20649. ConvertProgram;
  20650. CheckSource('TestClassInterface_GUID',
  20651. LinesToStr([ // statements
  20652. 'rtl.createInterface(this, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
  20653. 'rtl.createClass(this, "TObject", null, function () {',
  20654. ' this.$init = function () {',
  20655. ' };',
  20656. ' this.$final = function () {',
  20657. ' };',
  20658. '});',
  20659. 'rtl.recNewT(this, "TGUID", function () {',
  20660. ' this.D1 = 0;',
  20661. ' this.D2 = 0;',
  20662. ' this.D3 = 0;',
  20663. ' this.D4 = 0;',
  20664. ' this.$eq = function (b) {',
  20665. ' return (this.D1 === b.D1) && (this.D2 === b.D2) && (this.D3 === b.D3) && (this.D4 === b.D4);',
  20666. ' };',
  20667. ' this.$assign = function (s) {',
  20668. ' this.D1 = s.D1;',
  20669. ' this.D2 = s.D2;',
  20670. ' this.D3 = s.D3;',
  20671. ' this.D4 = s.D4;',
  20672. ' return this;',
  20673. ' };',
  20674. '});',
  20675. 'this.DoConstGUIDIt = function (g) {',
  20676. '};',
  20677. 'this.DoDefGUID = function (g) {',
  20678. '};',
  20679. 'this.DoStr = function (s) {',
  20680. '};',
  20681. 'this.i = null;',
  20682. 'this.g = this.TGUID.$clone({',
  20683. ' D1: 0xD91C9AF4,',
  20684. ' D2: 0x3C93,',
  20685. ' D3: 0x420F,',
  20686. ' D4: [',
  20687. ' 0xA3,',
  20688. ' 0x03,',
  20689. ' 0xBF,',
  20690. ' 0x5B,',
  20691. ' 0xA8,',
  20692. ' 0x2B,',
  20693. ' 0xFD,',
  20694. ' 0x23',
  20695. ' ]',
  20696. '});',
  20697. 'this.s = "";',
  20698. '']),
  20699. LinesToStr([ // $mod.$main
  20700. '$mod.DoConstGUIDIt(rtl.getIntfGUIDR($mod.IUnknown));',
  20701. '$mod.DoDefGUID($mod.TGUID.$clone(rtl.getIntfGUIDR($mod.IUnknown)));',
  20702. '$mod.DoStr($mod.IUnknown.$guid);',
  20703. '$mod.DoConstGUIDIt(rtl.getIntfGUIDR($mod.i));',
  20704. '$mod.DoDefGUID($mod.TGUID.$clone(rtl.getIntfGUIDR($mod.i)));',
  20705. '$mod.DoStr($mod.i.$guid);',
  20706. '$mod.DoConstGUIDIt(rtl.strToGUIDR("{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}"));',
  20707. '$mod.DoDefGUID(rtl.strToGUIDR("{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}"));',
  20708. '$mod.DoStr(rtl.guidrToStr($mod.g));',
  20709. '$mod.g.$assign(rtl.getIntfGUIDR($mod.i));',
  20710. '$mod.g.$assign(rtl.getIntfGUIDR($mod.IUnknown));',
  20711. '$mod.g.$assign({',
  20712. ' D1: 0xD91C9AF4,',
  20713. ' D2: 0x3C93,',
  20714. ' D3: 0x420F,',
  20715. ' D4: [',
  20716. ' 0xA3,',
  20717. ' 0x03,',
  20718. ' 0xBF,',
  20719. ' 0x5B,',
  20720. ' 0xA8,',
  20721. ' 0x2B,',
  20722. ' 0xFD,',
  20723. ' 0x23',
  20724. ' ]',
  20725. '});',
  20726. '$mod.s = $mod.i.$guid;',
  20727. '$mod.s = $mod.IUnknown.$guid;',
  20728. '$mod.s = rtl.guidrToStr($mod.g);',
  20729. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.i))) ;',
  20730. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.i))) ;',
  20731. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.IUnknown))) ;',
  20732. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.IUnknown))) ;',
  20733. 'if ($mod.s === $mod.i.$guid) ;',
  20734. 'if ($mod.i.$guid === $mod.s) ;',
  20735. 'if ($mod.s === $mod.IUnknown.$guid) ;',
  20736. 'if ($mod.IUnknown.$guid === $mod.s) ;',
  20737. 'if ($mod.g.$eq(rtl.createTGUID($mod.s))) ;',
  20738. 'if ($mod.g.$eq(rtl.createTGUID($mod.s))) ;',
  20739. '']));
  20740. end;
  20741. procedure TTestModule.TestClassInterface_GUIDProperty;
  20742. begin
  20743. StartProgram(false);
  20744. Add([
  20745. '{$interfaces corba}',
  20746. 'type',
  20747. ' IUnknown = interface',
  20748. ' [''{f31db68f-3010-D355-4EBA-CDD4EF4A737C}'']',
  20749. ' end;',
  20750. ' TGUID = record D1, D2, D3, D4: word; end;',
  20751. ' TAliasGUID = TGUID;',
  20752. ' TGUIDString = type string;',
  20753. ' TAliasGUIDString = TGUIDString;',
  20754. ' TObject = class',
  20755. ' function GetG: TAliasGUID; virtual; abstract;',
  20756. ' procedure SetG(const Value: TAliasGUID); virtual; abstract;',
  20757. ' function GetS: TAliasGUIDString; virtual; abstract;',
  20758. ' procedure SetS(const Value: TAliasGUIDString); virtual; abstract;',
  20759. ' property g: TAliasGUID read GetG write SetG;',
  20760. ' property s: TAliasGUIDString read GetS write SetS;',
  20761. ' end;',
  20762. 'var o: TObject;',
  20763. 'begin',
  20764. ' o.g:=IUnknown;',
  20765. ' o.g:=''{D91C9AF4-3C93-420F-A303-bf5ba82bfd23}'';',
  20766. ' o.s:=IUnknown;',
  20767. ' o.s:=o.g;',
  20768. '']);
  20769. ConvertProgram;
  20770. CheckSource('TestClassInterface_GUIDProperty',
  20771. LinesToStr([ // statements
  20772. 'rtl.createInterface(this, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
  20773. 'rtl.recNewT(this, "TGUID", function () {',
  20774. ' this.D1 = 0;',
  20775. ' this.D2 = 0;',
  20776. ' this.D3 = 0;',
  20777. ' this.D4 = 0;',
  20778. ' this.$eq = function (b) {',
  20779. ' return (this.D1 === b.D1) && (this.D2 === b.D2) && (this.D3 === b.D3) && (this.D4 === b.D4);',
  20780. ' };',
  20781. ' this.$assign = function (s) {',
  20782. ' this.D1 = s.D1;',
  20783. ' this.D2 = s.D2;',
  20784. ' this.D3 = s.D3;',
  20785. ' this.D4 = s.D4;',
  20786. ' return this;',
  20787. ' };',
  20788. '});',
  20789. 'rtl.createClass(this, "TObject", null, function () {',
  20790. ' this.$init = function () {',
  20791. ' };',
  20792. ' this.$final = function () {',
  20793. ' };',
  20794. '});',
  20795. 'this.o = null;',
  20796. '']),
  20797. LinesToStr([ // $mod.$main
  20798. '$mod.o.SetG(rtl.getIntfGUIDR($mod.IUnknown));',
  20799. '$mod.o.SetG({',
  20800. ' D1: 0xD91C9AF4,',
  20801. ' D2: 0x3C93,',
  20802. ' D3: 0x420F,',
  20803. ' D4: [',
  20804. ' 0xA3,',
  20805. ' 0x03,',
  20806. ' 0xBF,',
  20807. ' 0x5B,',
  20808. ' 0xA8,',
  20809. ' 0x2B,',
  20810. ' 0xFD,',
  20811. ' 0x23',
  20812. ' ]',
  20813. '});',
  20814. '$mod.o.SetS($mod.IUnknown.$guid);',
  20815. '$mod.o.SetS(rtl.guidrToStr($mod.o.GetG()));',
  20816. '']));
  20817. end;
  20818. procedure TTestModule.TestClassHelper_ClassVar;
  20819. begin
  20820. StartProgram(false);
  20821. Add([
  20822. 'type',
  20823. ' TObject = class',
  20824. ' end;',
  20825. ' THelper = class helper for TObject',
  20826. ' const',
  20827. ' One = 1;',
  20828. ' Two: word = 2;',
  20829. ' class var',
  20830. ' Glob: word;',
  20831. ' function Foo(w: word): word;',
  20832. ' class function Bar(w: word): word;',
  20833. ' end;',
  20834. 'function THelper.foo(w: word): word;',
  20835. 'begin',
  20836. ' Result:=w;',
  20837. ' Two:=One+w;',
  20838. ' Glob:=Glob;',
  20839. ' Result:=Self.Glob;',
  20840. ' Self.Glob:=Self.Glob;',
  20841. ' with Self do Glob:=Glob;',
  20842. 'end;',
  20843. 'class function THelper.bar(w: word): word;',
  20844. 'begin',
  20845. ' Result:=w;',
  20846. ' Two:=One;',
  20847. ' Glob:=Glob;',
  20848. ' Self.Glob:=Self.Glob;',
  20849. ' with Self do Glob:=Glob;',
  20850. 'end;',
  20851. 'var o: TObject;',
  20852. 'begin',
  20853. ' tobject.two:=tobject.one;',
  20854. ' tobject.Glob:=tobject.Glob;',
  20855. ' with tobject do begin',
  20856. ' two:=one;',
  20857. ' Glob:=Glob;',
  20858. ' end;',
  20859. ' o.two:=o.one;',
  20860. ' o.Glob:=o.Glob;',
  20861. ' with o do begin',
  20862. ' two:=one;',
  20863. ' Glob:=Glob;',
  20864. ' end;',
  20865. '']);
  20866. ConvertProgram;
  20867. CheckSource('TestClassHelper_ClassVar',
  20868. LinesToStr([ // statements
  20869. 'rtl.createClass(this, "TObject", null, function () {',
  20870. ' this.$init = function () {',
  20871. ' };',
  20872. ' this.$final = function () {',
  20873. ' };',
  20874. '});',
  20875. 'rtl.createHelper(this, "THelper", null, function () {',
  20876. ' this.One = 1;',
  20877. ' this.Two = 2;',
  20878. ' this.Glob = 0;',
  20879. ' this.Foo = function (w) {',
  20880. ' var Result = 0;',
  20881. ' Result = w;',
  20882. ' $mod.THelper.Two = 1 + w;',
  20883. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20884. ' Result = $mod.THelper.Glob;',
  20885. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20886. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20887. ' return Result;',
  20888. ' };',
  20889. ' this.Bar = function (w) {',
  20890. ' var Result = 0;',
  20891. ' Result = w;',
  20892. ' $mod.THelper.Two = 1;',
  20893. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20894. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20895. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20896. ' return Result;',
  20897. ' };',
  20898. '});',
  20899. 'this.o = null;',
  20900. '']),
  20901. LinesToStr([ // $mod.$main
  20902. '$mod.THelper.Two = 1;',
  20903. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20904. 'var $with = $mod.TObject;',
  20905. '$mod.THelper.Two = 1;',
  20906. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20907. '$mod.THelper.Two = 1;',
  20908. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20909. 'var $with1 = $mod.o;',
  20910. '$mod.THelper.Two = 1;',
  20911. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20912. '']));
  20913. end;
  20914. procedure TTestModule.TestClassHelper_Method_AccessInstanceFields;
  20915. begin
  20916. StartProgram(false);
  20917. Add([
  20918. 'type',
  20919. ' TObject = class',
  20920. ' FSize: word;',
  20921. ' property Size: word read FSize write FSize;',
  20922. ' end;',
  20923. ' THelper = class helper for TObject',
  20924. ' function Foo(w: word = 1): word;',
  20925. ' end;',
  20926. 'function THelper.foo(w: word): word;',
  20927. 'begin',
  20928. ' Result:=Size;',
  20929. ' Size:=Size+2;',
  20930. ' Self.Size:=Self.Size+3;',
  20931. ' FSize:=FSize+4;',
  20932. ' Self.FSize:=Self.FSize+5;',
  20933. ' with Self do begin',
  20934. ' Size:=Size+6;',
  20935. ' FSize:=FSize+7;',
  20936. ' FSize:=FSize+8;',
  20937. ' end;',
  20938. 'end;',
  20939. 'begin',
  20940. '']);
  20941. ConvertProgram;
  20942. CheckSource('TestClassHelper_Method_AccessInstanceFields',
  20943. LinesToStr([ // statements
  20944. 'rtl.createClass(this, "TObject", null, function () {',
  20945. ' this.$init = function () {',
  20946. ' this.FSize = 0;',
  20947. ' };',
  20948. ' this.$final = function () {',
  20949. ' };',
  20950. '});',
  20951. 'rtl.createHelper(this, "THelper", null, function () {',
  20952. ' this.Foo = function (w) {',
  20953. ' var Result = 0;',
  20954. ' Result = this.FSize;',
  20955. ' this.FSize = this.FSize + 2;',
  20956. ' this.FSize = this.FSize + 3;',
  20957. ' this.FSize = this.FSize + 4;',
  20958. ' this.FSize = this.FSize + 5;',
  20959. ' this.FSize = this.FSize + 6;',
  20960. ' this.FSize = this.FSize + 7;',
  20961. ' this.FSize = this.FSize + 8;',
  20962. ' return Result;',
  20963. ' };',
  20964. '});',
  20965. '']),
  20966. LinesToStr([ // $mod.$main
  20967. '']));
  20968. end;
  20969. procedure TTestModule.TestClassHelper_Method_Call;
  20970. begin
  20971. StartProgram(false);
  20972. Add([
  20973. 'type',
  20974. ' TObject = class',
  20975. ' procedure Run(w: word = 10);',
  20976. ' end;',
  20977. ' THelper = class helper for TObject',
  20978. ' function Foo(w: word = 1): word;',
  20979. ' end;',
  20980. 'procedure TObject.Run(w: word);',
  20981. 'var o: TObject;',
  20982. 'begin',
  20983. ' Foo;',
  20984. ' Foo();',
  20985. ' Foo(2);',
  20986. ' Self.Foo;',
  20987. ' Self.Foo();',
  20988. ' Self.Foo(3);',
  20989. ' with Self do begin',
  20990. ' Foo;',
  20991. ' Foo();',
  20992. ' Foo(4);',
  20993. ' end;',
  20994. ' with o do Foo(5);',
  20995. 'end;',
  20996. 'function THelper.foo(w: word): word;',
  20997. 'begin',
  20998. ' Run;',
  20999. ' Run();',
  21000. ' Run(11);',
  21001. ' Foo;',
  21002. ' Foo();',
  21003. ' Foo(12);',
  21004. ' Self.Foo;',
  21005. ' Self.Foo();',
  21006. ' Self.Foo(13);',
  21007. ' with Self do begin',
  21008. ' Foo;',
  21009. ' Foo();',
  21010. ' Foo(14);',
  21011. ' end;',
  21012. 'end;',
  21013. 'var Obj: TObject;',
  21014. 'begin',
  21015. ' obj.Foo;',
  21016. ' obj.Foo();',
  21017. ' obj.Foo(21);',
  21018. ' with obj do begin',
  21019. ' Foo;',
  21020. ' Foo();',
  21021. ' Foo(22);',
  21022. ' end;',
  21023. '']);
  21024. ConvertProgram;
  21025. CheckSource('TestClassHelper_Method_Call',
  21026. LinesToStr([ // statements
  21027. 'rtl.createClass(this, "TObject", null, function () {',
  21028. ' this.$init = function () {',
  21029. ' };',
  21030. ' this.$final = function () {',
  21031. ' };',
  21032. ' this.Run = function (w) {',
  21033. ' var o = null;',
  21034. ' $mod.THelper.Foo.call(this, 1);',
  21035. ' $mod.THelper.Foo.call(this, 1);',
  21036. ' $mod.THelper.Foo.call(this, 2);',
  21037. ' $mod.THelper.Foo.call(this, 1);',
  21038. ' $mod.THelper.Foo.call(this, 1);',
  21039. ' $mod.THelper.Foo.call(this, 3);',
  21040. ' $mod.THelper.Foo.call(this, 1);',
  21041. ' $mod.THelper.Foo.call(this, 1);',
  21042. ' $mod.THelper.Foo.call(this, 4);',
  21043. ' $mod.THelper.Foo.call(o, 5);',
  21044. ' };',
  21045. '});',
  21046. 'rtl.createHelper(this, "THelper", null, function () {',
  21047. ' this.Foo = function (w) {',
  21048. ' var Result = 0;',
  21049. ' this.Run(10);',
  21050. ' this.Run(10);',
  21051. ' this.Run(11);',
  21052. ' $mod.THelper.Foo.call(this, 1);',
  21053. ' $mod.THelper.Foo.call(this, 1);',
  21054. ' $mod.THelper.Foo.call(this, 12);',
  21055. ' $mod.THelper.Foo.call(this, 1);',
  21056. ' $mod.THelper.Foo.call(this, 1);',
  21057. ' $mod.THelper.Foo.call(this, 13);',
  21058. ' $mod.THelper.Foo.call(this, 1);',
  21059. ' $mod.THelper.Foo.call(this, 1);',
  21060. ' $mod.THelper.Foo.call(this, 14);',
  21061. ' return Result;',
  21062. ' };',
  21063. '});',
  21064. 'this.Obj = null;',
  21065. '']),
  21066. LinesToStr([ // $mod.$main
  21067. '$mod.THelper.Foo.call($mod.Obj, 1);',
  21068. '$mod.THelper.Foo.call($mod.Obj, 1);',
  21069. '$mod.THelper.Foo.call($mod.Obj, 21);',
  21070. 'var $with = $mod.Obj;',
  21071. '$mod.THelper.Foo.call($with, 1);',
  21072. '$mod.THelper.Foo.call($with, 1);',
  21073. '$mod.THelper.Foo.call($with, 22);',
  21074. '']));
  21075. end;
  21076. procedure TTestModule.TestClassHelper_Method_Nested_Call;
  21077. begin
  21078. StartProgram(false);
  21079. Add([
  21080. 'type',
  21081. ' TObject = class',
  21082. ' procedure Run(w: word = 10);',
  21083. ' end;',
  21084. ' THelper = class helper for TObject',
  21085. ' function Foo(w: word = 1): word;',
  21086. ' end;',
  21087. 'procedure TObject.Run(w: word);',
  21088. ' procedure Sub(Self: TObject);',
  21089. ' begin',
  21090. ' Foo;',
  21091. ' Foo();',
  21092. ' Self.Foo;',
  21093. ' Self.Foo();',
  21094. ' with Self do begin',
  21095. ' Foo;',
  21096. ' Foo();',
  21097. ' end;',
  21098. ' end;',
  21099. 'begin',
  21100. 'end;',
  21101. 'function THelper.foo(w: word): word;',
  21102. ' procedure Sub(Self: TObject);',
  21103. ' begin',
  21104. ' Run;',
  21105. ' Run();',
  21106. ' Foo;',
  21107. ' Foo();',
  21108. ' Self.Foo;',
  21109. ' Self.Foo();',
  21110. ' with Self do begin',
  21111. ' Foo;',
  21112. ' Foo();',
  21113. ' end;',
  21114. ' end;',
  21115. 'begin',
  21116. 'end;',
  21117. 'begin',
  21118. '']);
  21119. ConvertProgram;
  21120. CheckSource('TestClassHelper_Method_Nested_Call',
  21121. LinesToStr([ // statements
  21122. 'rtl.createClass(this, "TObject", null, function () {',
  21123. ' this.$init = function () {',
  21124. ' };',
  21125. ' this.$final = function () {',
  21126. ' };',
  21127. ' this.Run = function (w) {',
  21128. ' var $Self = this;',
  21129. ' function Sub(Self) {',
  21130. ' $mod.THelper.Foo.call($Self, 1);',
  21131. ' $mod.THelper.Foo.call($Self, 1);',
  21132. ' $mod.THelper.Foo.call(Self, 1);',
  21133. ' $mod.THelper.Foo.call(Self, 1);',
  21134. ' $mod.THelper.Foo.call(Self, 1);',
  21135. ' $mod.THelper.Foo.call(Self, 1);',
  21136. ' };',
  21137. ' };',
  21138. '});',
  21139. 'rtl.createHelper(this, "THelper", null, function () {',
  21140. ' this.Foo = function (w) {',
  21141. ' var $Self = this;',
  21142. ' var Result = 0;',
  21143. ' function Sub(Self) {',
  21144. ' $Self.Run(10);',
  21145. ' $Self.Run(10);',
  21146. ' $mod.THelper.Foo.call($Self, 1);',
  21147. ' $mod.THelper.Foo.call($Self, 1);',
  21148. ' $mod.THelper.Foo.call(Self, 1);',
  21149. ' $mod.THelper.Foo.call(Self, 1);',
  21150. ' $mod.THelper.Foo.call(Self, 1);',
  21151. ' $mod.THelper.Foo.call(Self, 1);',
  21152. ' };',
  21153. ' return Result;',
  21154. ' };',
  21155. '});',
  21156. '']),
  21157. LinesToStr([ // $mod.$main
  21158. '']));
  21159. end;
  21160. procedure TTestModule.TestClassHelper_ClassMethod_Call;
  21161. begin
  21162. StartProgram(false);
  21163. Add([
  21164. 'type',
  21165. ' TObject = class',
  21166. ' class procedure Run(w: word = 10);',
  21167. ' end;',
  21168. ' THelper = class helper for TObject',
  21169. ' class function Foo(w: word = 1): word;',
  21170. ' end;',
  21171. 'class procedure TObject.Run(w: word);',
  21172. 'begin',
  21173. ' Foo;',
  21174. ' Foo();',
  21175. ' Self.Foo;',
  21176. ' Self.Foo();',
  21177. ' with Self do begin',
  21178. ' Foo;',
  21179. ' Foo();',
  21180. ' end;',
  21181. 'end;',
  21182. 'class function THelper.foo(w: word): word;',
  21183. 'begin',
  21184. ' Run;',
  21185. ' Run();',
  21186. ' Foo;',
  21187. ' Foo();',
  21188. ' Self.Foo;',
  21189. ' Self.Foo();',
  21190. ' with Self do begin',
  21191. ' Foo;',
  21192. ' Foo();',
  21193. ' end;',
  21194. 'end;',
  21195. 'var',
  21196. ' Obj: TObject;',
  21197. 'begin',
  21198. ' obj.Foo;',
  21199. ' obj.Foo();',
  21200. ' with obj do begin',
  21201. ' Foo;',
  21202. ' Foo();',
  21203. ' end;',
  21204. ' tobject.Foo;',
  21205. ' tobject.Foo();',
  21206. ' with tobject do begin',
  21207. ' Foo;',
  21208. ' Foo();',
  21209. ' end;',
  21210. '']);
  21211. ConvertProgram;
  21212. CheckSource('TestClassHelper_ClassMethod_Call',
  21213. LinesToStr([ // statements
  21214. 'rtl.createClass(this, "TObject", null, function () {',
  21215. ' this.$init = function () {',
  21216. ' };',
  21217. ' this.$final = function () {',
  21218. ' };',
  21219. ' this.Run = function (w) {',
  21220. ' $mod.THelper.Foo.call(this, 1);',
  21221. ' $mod.THelper.Foo.call(this, 1);',
  21222. ' $mod.THelper.Foo.call(this, 1);',
  21223. ' $mod.THelper.Foo.call(this, 1);',
  21224. ' $mod.THelper.Foo.call(this, 1);',
  21225. ' $mod.THelper.Foo.call(this, 1);',
  21226. ' };',
  21227. '});',
  21228. 'rtl.createHelper(this, "THelper", null, function () {',
  21229. ' this.Foo = function (w) {',
  21230. ' var Result = 0;',
  21231. ' this.Run(10);',
  21232. ' this.Run(10);',
  21233. ' $mod.THelper.Foo.call(this, 1);',
  21234. ' $mod.THelper.Foo.call(this, 1);',
  21235. ' $mod.THelper.Foo.call(this, 1);',
  21236. ' $mod.THelper.Foo.call(this, 1);',
  21237. ' $mod.THelper.Foo.call(this, 1);',
  21238. ' $mod.THelper.Foo.call(this, 1);',
  21239. ' return Result;',
  21240. ' };',
  21241. '});',
  21242. 'this.Obj = null;',
  21243. '']),
  21244. LinesToStr([ // $mod.$main
  21245. '$mod.THelper.Foo.call($mod.Obj.$class, 1);',
  21246. '$mod.THelper.Foo.call($mod.Obj.$class, 1);',
  21247. 'var $with = $mod.Obj;',
  21248. '$mod.THelper.Foo.call($with.$class, 1);',
  21249. '$mod.THelper.Foo.call($with.$class, 1);',
  21250. '$mod.THelper.Foo.call($mod.TObject, 1);',
  21251. '$mod.THelper.Foo.call($mod.TObject, 1);',
  21252. 'var $with1 = $mod.TObject;',
  21253. '$mod.THelper.Foo.call($mod.TObject, 1);',
  21254. '$mod.THelper.Foo.call($mod.TObject, 1);',
  21255. '']));
  21256. end;
  21257. procedure TTestModule.TestClassHelper_ClassOf;
  21258. begin
  21259. StartProgram(false);
  21260. Add([
  21261. 'type',
  21262. ' TObject = class',
  21263. ' end;',
  21264. ' TClass = class of TObject;',
  21265. ' THelper = class helper for TObject',
  21266. ' class function Foo(w: word = 1): word;',
  21267. ' end;',
  21268. 'class function THelper.foo(w: word): word;',
  21269. 'begin',
  21270. 'end;',
  21271. 'var',
  21272. ' c: TClass;',
  21273. 'begin',
  21274. ' c.Foo;',
  21275. ' c.Foo();',
  21276. ' with c do begin',
  21277. ' Foo;',
  21278. ' Foo();',
  21279. ' end;',
  21280. '']);
  21281. ConvertProgram;
  21282. CheckSource('TestClassHelper_ClassOf',
  21283. LinesToStr([ // statements
  21284. 'rtl.createClass(this, "TObject", null, function () {',
  21285. ' this.$init = function () {',
  21286. ' };',
  21287. ' this.$final = function () {',
  21288. ' };',
  21289. '});',
  21290. 'rtl.createHelper(this, "THelper", null, function () {',
  21291. ' this.Foo = function (w) {',
  21292. ' var Result = 0;',
  21293. ' return Result;',
  21294. ' };',
  21295. '});',
  21296. 'this.c = null;',
  21297. '']),
  21298. LinesToStr([ // $mod.$main
  21299. '$mod.THelper.Foo.call($mod.c, 1);',
  21300. '$mod.THelper.Foo.call($mod.c, 1);',
  21301. 'var $with = $mod.c;',
  21302. '$mod.THelper.Foo.call($with, 1);',
  21303. '$mod.THelper.Foo.call($with, 1);',
  21304. '']));
  21305. end;
  21306. procedure TTestModule.TestClassHelper_MethodRefObjFPC;
  21307. begin
  21308. StartProgram(false);
  21309. Add([
  21310. '{$mode objfpc}',
  21311. 'type',
  21312. ' TObject = class',
  21313. ' procedure DoIt;',
  21314. ' end;',
  21315. ' THelper = class helper for TObject',
  21316. ' procedure Fly(w: word = 1);',
  21317. ' class procedure Glide(w: word = 1);',
  21318. ' class procedure Run(w: word = 1); static;',
  21319. ' end;',
  21320. ' TFly = procedure(w: word) of object;',
  21321. ' TGlide = TFly;',
  21322. ' TRun = procedure(w: word);',
  21323. 'var',
  21324. ' f: TFly;',
  21325. ' g: TGlide;',
  21326. ' r: TRun;',
  21327. 'procedure TObject.DoIt;',
  21328. 'begin',
  21329. ' f:=@fly;',
  21330. ' g:=@glide;',
  21331. ' r:=@run;',
  21332. ' f:[email protected];',
  21333. ' g:[email protected];',
  21334. ' r:[email protected];',
  21335. ' with self do begin',
  21336. ' f:=@fly;',
  21337. ' g:=@glide;',
  21338. ' r:=@run;',
  21339. ' end;',
  21340. 'end;',
  21341. 'procedure THelper.fly(w: word);',
  21342. 'begin',
  21343. ' f:=@fly;',
  21344. ' g:=@glide;',
  21345. ' r:=@run;',
  21346. 'end;',
  21347. 'class procedure THelper.glide(w: word);',
  21348. 'begin',
  21349. ' g:=@glide;',
  21350. ' r:=@run;',
  21351. 'end;',
  21352. 'class procedure THelper.run(w: word);',
  21353. 'begin',
  21354. ' g:=@glide;',
  21355. ' r:=@run;',
  21356. 'end;',
  21357. 'var',
  21358. ' Obj: TObject;',
  21359. 'begin',
  21360. ' f:[email protected];',
  21361. ' g:[email protected];',
  21362. ' r:[email protected];',
  21363. ' with obj do begin',
  21364. ' f:=@fly;',
  21365. ' g:=@glide;',
  21366. ' r:=@run;',
  21367. ' end;',
  21368. ' g:[email protected];',
  21369. ' r:[email protected];',
  21370. ' with tobject do begin',
  21371. ' g:=@glide;',
  21372. ' r:=@run;',
  21373. ' end;',
  21374. '']);
  21375. ConvertProgram;
  21376. CheckSource('TestClassHelper_MethodRefObjFPC',
  21377. LinesToStr([ // statements
  21378. 'rtl.createClass(this, "TObject", null, function () {',
  21379. ' this.$init = function () {',
  21380. ' };',
  21381. ' this.$final = function () {',
  21382. ' };',
  21383. ' this.DoIt = function () {',
  21384. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  21385. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  21386. ' $mod.r = $mod.THelper.Run;',
  21387. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  21388. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  21389. ' $mod.r = $mod.THelper.Run;',
  21390. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  21391. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  21392. ' $mod.r = $mod.THelper.Run;',
  21393. ' };',
  21394. '});',
  21395. 'rtl.createHelper(this, "THelper", null, function () {',
  21396. ' this.Fly = function (w) {',
  21397. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  21398. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  21399. ' $mod.r = $mod.THelper.Run;',
  21400. ' };',
  21401. ' this.Glide = function (w) {',
  21402. ' $mod.g = rtl.createCallback(this, $mod.THelper.Glide);',
  21403. ' $mod.r = $mod.THelper.Run;',
  21404. ' };',
  21405. ' this.Run = function (w) {',
  21406. ' $mod.g = rtl.createCallback($mod.THelper, $mod.THelper.Glide);',
  21407. ' $mod.r = $mod.THelper.Run;',
  21408. ' };',
  21409. '});',
  21410. 'this.f = null;',
  21411. 'this.g = null;',
  21412. 'this.r = null;',
  21413. 'this.Obj = null;',
  21414. '']),
  21415. LinesToStr([ // $mod.$main
  21416. '$mod.f = rtl.createCallback($mod.Obj, $mod.THelper.Fly);',
  21417. '$mod.g = rtl.createCallback($mod.Obj.$class, $mod.THelper.Glide);',
  21418. '$mod.r = $mod.THelper.Run;',
  21419. 'var $with = $mod.Obj;',
  21420. '$mod.f = rtl.createCallback($with, $mod.THelper.Fly);',
  21421. '$mod.g = rtl.createCallback($with.$class, $mod.THelper.Glide);',
  21422. '$mod.r = $mod.THelper.Run;',
  21423. '$mod.g = rtl.createCallback($mod.TObject, $mod.THelper.Glide);',
  21424. '$mod.r = $mod.THelper.Run;',
  21425. 'var $with1 = $mod.TObject;',
  21426. '$mod.g = rtl.createCallback($with1, $mod.THelper.Glide);',
  21427. '$mod.r = $mod.THelper.Run;',
  21428. '']));
  21429. end;
  21430. procedure TTestModule.TestClassHelper_Constructor;
  21431. begin
  21432. StartProgram(false);
  21433. Add([
  21434. 'type',
  21435. ' TObject = class',
  21436. ' constructor Create;',
  21437. ' end;',
  21438. ' TClass = class of TObject;',
  21439. ' THelper = class helper for TObject',
  21440. ' constructor NewHlp(w: word);',
  21441. ' end;',
  21442. 'var',
  21443. ' obj: TObject;',
  21444. ' c: TClass;',
  21445. 'constructor TObject.Create;',
  21446. 'begin',
  21447. ' NewHlp(2);', // normal call
  21448. ' tobject.NewHlp(3);', // new instance
  21449. ' c.newhlp(4);', // new instance
  21450. 'end;',
  21451. 'constructor THelper.NewHlp(w: word);',
  21452. 'begin',
  21453. ' create;', // normal call
  21454. ' tobject.create;', // new instance
  21455. ' NewHlp(2);', // normal call
  21456. ' tobject.NewHlp(3);', // new instance
  21457. ' c.newhlp(4);', // new instance
  21458. 'end;',
  21459. 'begin',
  21460. ' obj.newhlp(2);', // normal call
  21461. ' with Obj do newhlp(12);', // normal call
  21462. ' tobject.newhlp(3);', // new instance
  21463. ' with tobject do newhlp(13);', // new instance
  21464. ' c.newhlp(4);', // new instance
  21465. ' with c do newhlp(14);', // new instance
  21466. '']);
  21467. ConvertProgram;
  21468. CheckSource('TestClassHelper_Constructor',
  21469. LinesToStr([ // statements
  21470. 'rtl.createClass(this, "TObject", null, function () {',
  21471. ' this.$init = function () {',
  21472. ' };',
  21473. ' this.$final = function () {',
  21474. ' };',
  21475. ' this.Create = function () {',
  21476. ' $mod.THelper.NewHlp.call(this, 2);',
  21477. ' $mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  21478. ' $mod.c.$create($mod.THelper.NewHlp, [4]);',
  21479. ' return this;',
  21480. ' };',
  21481. '});',
  21482. 'rtl.createHelper(this, "THelper", null, function () {',
  21483. ' this.NewHlp = function (w) {',
  21484. ' this.Create();',
  21485. ' $mod.TObject.$create("Create");',
  21486. ' $mod.THelper.NewHlp.call(this, 2);',
  21487. ' $mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  21488. ' $mod.c.$create($mod.THelper.NewHlp, [4]);',
  21489. ' return this;',
  21490. ' };',
  21491. '});',
  21492. 'this.obj = null;',
  21493. 'this.c = null;',
  21494. '']),
  21495. LinesToStr([ // $mod.$main
  21496. '$mod.THelper.NewHlp.call($mod.obj, 2);',
  21497. 'var $with = $mod.obj;',
  21498. '$mod.THelper.NewHlp.call($with, 12);',
  21499. '$mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  21500. 'var $with1 = $mod.TObject;',
  21501. '$with1.$create($mod.THelper.NewHlp, [13]);',
  21502. '$mod.c.$create($mod.THelper.NewHlp, [4]);',
  21503. 'var $with2 = $mod.c;',
  21504. '$with2.$create($mod.THelper.NewHlp, [14]);',
  21505. '']));
  21506. end;
  21507. procedure TTestModule.TestClassHelper_InheritedObjFPC;
  21508. begin
  21509. StartProgram(false);
  21510. Add([
  21511. 'type',
  21512. ' TObject = class',
  21513. ' procedure Fly;',
  21514. ' end;',
  21515. ' TObjHelper = class helper for TObject',
  21516. ' procedure Fly;',
  21517. ' end;',
  21518. ' TBird = class',
  21519. ' procedure Fly;',
  21520. ' end;',
  21521. ' TBirdHelper = class helper for TBird',
  21522. ' procedure Fly;',
  21523. ' procedure Walk(w: word);',
  21524. ' end;',
  21525. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  21526. ' procedure Fly;',
  21527. ' procedure Walk(w: word);',
  21528. ' end;',
  21529. 'procedure Tobject.fly;',
  21530. 'begin',
  21531. ' inherited;', // ignore
  21532. 'end;',
  21533. 'procedure Tobjhelper.fly;',
  21534. 'begin',
  21535. ' {@TObject_Fly}inherited;',
  21536. ' inherited {@TObject_Fly}Fly;',
  21537. 'end;',
  21538. 'procedure Tbird.fly;',
  21539. 'begin',
  21540. ' {@TObjHelper_Fly}inherited;',
  21541. ' inherited {@TObjHelper_Fly}Fly;',
  21542. 'end;',
  21543. 'procedure Tbirdhelper.fly;',
  21544. 'begin',
  21545. ' {@TBird_Fly}inherited;',
  21546. ' inherited {@TBird_Fly}Fly;',
  21547. 'end;',
  21548. 'procedure Tbirdhelper.walk(w: word);',
  21549. 'begin',
  21550. 'end;',
  21551. 'procedure teagleHelper.fly;',
  21552. 'begin',
  21553. ' {@TBird_Fly}inherited;',
  21554. ' inherited {@TBird_Fly}Fly;',
  21555. 'end;',
  21556. 'procedure teagleHelper.walk(w: word);',
  21557. 'begin',
  21558. ' {@TBirdHelper_Walk}inherited;',
  21559. ' inherited {@TBirdHelper_Walk}Walk(3);',
  21560. 'end;',
  21561. 'begin',
  21562. '']);
  21563. ConvertProgram;
  21564. CheckSource('TestClassHelper_InheritedObjFPC',
  21565. LinesToStr([ // statements
  21566. 'rtl.createClass(this, "TObject", null, function () {',
  21567. ' this.$init = function () {',
  21568. ' };',
  21569. ' this.$final = function () {',
  21570. ' };',
  21571. ' this.Fly = function () {',
  21572. ' };',
  21573. '});',
  21574. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  21575. ' this.Fly = function () {',
  21576. ' $mod.TObject.Fly.call(this);',
  21577. ' $mod.TObject.Fly.call(this);',
  21578. ' };',
  21579. '});',
  21580. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  21581. ' this.Fly$1 = function () {',
  21582. ' $mod.TObjHelper.Fly.call(this);',
  21583. ' $mod.TObjHelper.Fly.call(this);',
  21584. ' };',
  21585. '});',
  21586. 'rtl.createHelper(this, "TBirdHelper", null, function () {',
  21587. ' this.Fly = function () {',
  21588. ' $mod.TBird.Fly$1.call(this);',
  21589. ' $mod.TBird.Fly$1.call(this);',
  21590. ' };',
  21591. ' this.Walk = function (w) {',
  21592. ' };',
  21593. '});',
  21594. 'rtl.createHelper(this, "TEagleHelper", this.TBirdHelper, function () {',
  21595. ' this.Fly$1 = function () {',
  21596. ' $mod.TBird.Fly$1.call(this);',
  21597. ' $mod.TBird.Fly$1.call(this);',
  21598. ' };',
  21599. ' this.Walk$1 = function (w) {',
  21600. ' $mod.TBirdHelper.Walk.apply(this, arguments);',
  21601. ' $mod.TBirdHelper.Walk.call(this, 3);',
  21602. ' };',
  21603. '});',
  21604. '']),
  21605. LinesToStr([ // $mod.$main
  21606. '']));
  21607. end;
  21608. procedure TTestModule.TestClassHelper_Property;
  21609. begin
  21610. StartProgram(false);
  21611. Add([
  21612. 'type',
  21613. ' TObject = class',
  21614. ' FSize: word;',
  21615. ' function GetSpeed: word;',
  21616. ' procedure SetSpeed(Value: word);',
  21617. ' end;',
  21618. ' TObjHelper = class helper for TObject',
  21619. ' function GetLeft: word;',
  21620. ' procedure SetLeft(Value: word);',
  21621. ' property Size: word read FSize write FSize;',
  21622. ' property Speed: word read GetSpeed write SetSpeed;',
  21623. ' property Left: word read GetLeft write SetLeft;',
  21624. ' end;',
  21625. ' TBird = class',
  21626. ' property NotRight: word read GetLeft write SetLeft;',
  21627. ' procedure DoIt;',
  21628. ' end;',
  21629. 'var',
  21630. ' b: TBird;',
  21631. 'function Tobject.GetSpeed: word;',
  21632. 'begin',
  21633. ' Size:=Size+11;',
  21634. ' Speed:=Speed+12;',
  21635. ' Result:=Left+13;',
  21636. ' Left:=13;',
  21637. ' Left:=Left+13;',
  21638. ' Self.Size:=Self.Size+21;',
  21639. ' Self.Speed:=Self.Speed+22;',
  21640. ' Self.Left:=Self.Left+23;',
  21641. ' with Self do begin',
  21642. ' Size:=Size+31;',
  21643. ' Speed:=Speed+32;',
  21644. ' Left:=Left+33;',
  21645. ' end;',
  21646. 'end;',
  21647. 'procedure Tobject.SetSpeed(Value: word);',
  21648. 'begin',
  21649. 'end;',
  21650. 'function TObjHelper.GetLeft: word;',
  21651. 'begin',
  21652. ' Size:=Size+11;',
  21653. ' Speed:=Speed+12;',
  21654. ' Left:=Left+13;',
  21655. ' Self.Size:=Self.Size+21;',
  21656. ' Self.Speed:=Self.Speed+22;',
  21657. ' Self.Left:=Self.Left+23;',
  21658. ' with Self do begin',
  21659. ' Size:=Size+31;',
  21660. ' Speed:=Speed+32;',
  21661. ' Left:=Left+33;',
  21662. ' end;',
  21663. 'end;',
  21664. 'procedure TObjHelper.SetLeft(Value: word);',
  21665. 'begin',
  21666. 'end;',
  21667. 'procedure TBird.DoIt;',
  21668. 'begin',
  21669. ' NotRight:=NotRight+11;',
  21670. ' Self.NotRight:=Self.NotRight+21;',
  21671. ' with Self do begin',
  21672. ' NotRight:=NotRight+31;',
  21673. ' end;',
  21674. 'end;',
  21675. 'begin',
  21676. ' b.Size:=b.Size+11;',
  21677. ' b.Speed:=b.Speed+12;',
  21678. ' b.Left:=b.Left+13;',
  21679. ' b.NotRight:=b.NotRight+14;',
  21680. ' with b do begin',
  21681. ' Size:=Size+31;',
  21682. ' Speed:=Speed+32;',
  21683. ' Left:=Left+33;',
  21684. ' NotRight:=NotRight+34;',
  21685. ' end;',
  21686. '']);
  21687. ConvertProgram;
  21688. CheckSource('TestClassHelper_Property',
  21689. LinesToStr([ // statements
  21690. 'rtl.createClass(this, "TObject", null, function () {',
  21691. ' this.$init = function () {',
  21692. ' this.FSize = 0;',
  21693. ' };',
  21694. ' this.$final = function () {',
  21695. ' };',
  21696. ' this.GetSpeed = function () {',
  21697. ' var Result = 0;',
  21698. ' this.FSize = this.FSize + 11;',
  21699. ' this.SetSpeed(this.GetSpeed() + 12);',
  21700. ' Result = $mod.TObjHelper.GetLeft.call(this) + 13;',
  21701. ' $mod.TObjHelper.SetLeft.call(this, 13);',
  21702. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  21703. ' this.FSize = this.FSize + 21;',
  21704. ' this.SetSpeed(this.GetSpeed() + 22);',
  21705. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  21706. ' this.FSize = this.FSize + 31;',
  21707. ' this.SetSpeed(this.GetSpeed() + 32);',
  21708. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  21709. ' return Result;',
  21710. ' };',
  21711. ' this.SetSpeed = function (Value) {',
  21712. ' };',
  21713. '});',
  21714. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  21715. ' this.GetLeft = function () {',
  21716. ' var Result = 0;',
  21717. ' this.FSize = this.FSize + 11;',
  21718. ' this.SetSpeed(this.GetSpeed() + 12);',
  21719. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  21720. ' this.FSize = this.FSize + 21;',
  21721. ' this.SetSpeed(this.GetSpeed() + 22);',
  21722. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  21723. ' this.FSize = this.FSize + 31;',
  21724. ' this.SetSpeed(this.GetSpeed() + 32);',
  21725. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  21726. ' return Result;',
  21727. ' };',
  21728. ' this.SetLeft = function (Value) {',
  21729. ' };',
  21730. '});',
  21731. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  21732. ' this.DoIt = function () {',
  21733. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 11);',
  21734. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 21);',
  21735. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 31);',
  21736. ' };',
  21737. '});',
  21738. 'this.b = null;',
  21739. '']),
  21740. LinesToStr([ // $mod.$main
  21741. '$mod.b.FSize = $mod.b.FSize + 11;',
  21742. '$mod.b.SetSpeed($mod.b.GetSpeed() + 12);',
  21743. '$mod.TObjHelper.SetLeft.call($mod.b, $mod.TObjHelper.GetLeft.call($mod.b) + 13);',
  21744. '$mod.TObjHelper.SetLeft.call($mod.b, $mod.TObjHelper.GetLeft.call($mod.b) + 14);',
  21745. 'var $with = $mod.b;',
  21746. '$with.FSize = $with.FSize + 31;',
  21747. '$with.SetSpeed($with.GetSpeed() + 32);',
  21748. '$mod.TObjHelper.SetLeft.call($with, $mod.TObjHelper.GetLeft.call($with) + 33);',
  21749. '$mod.TObjHelper.SetLeft.call($with, $mod.TObjHelper.GetLeft.call($with) + 34);',
  21750. '']));
  21751. end;
  21752. procedure TTestModule.TestClassHelper_Property_Array;
  21753. begin
  21754. StartProgram(false);
  21755. Add([
  21756. 'type',
  21757. ' TObject = class',
  21758. ' function GetSpeed(Index: boolean): word;',
  21759. ' procedure SetSpeed(Index: boolean; Value: word);',
  21760. ' end;',
  21761. ' TObjHelper = class helper for TObject',
  21762. ' function GetSize(Index: boolean): word;',
  21763. ' procedure SetSize(Index: boolean; Value: word);',
  21764. ' property Size[Index: boolean]: word read GetSize write SetSize;',
  21765. ' property Speed[Index: boolean]: word read GetSpeed write SetSpeed;',
  21766. ' end;',
  21767. ' TBird = class',
  21768. ' property Items[Index: boolean]: word read GetSize write SetSize;',
  21769. ' procedure DoIt;',
  21770. ' end;',
  21771. 'var',
  21772. ' b: TBird;',
  21773. 'function Tobject.GetSpeed(Index: boolean): word;',
  21774. 'begin',
  21775. ' Result:=Size[false];',
  21776. ' Size[true]:=Size[false]+11;',
  21777. ' Speed[true]:=Speed[false]+12;',
  21778. ' Self.Size[true]:=Self.Size[false]+21;',
  21779. ' Self.Speed[true]:=Self.Speed[false]+22;',
  21780. ' with Self do begin',
  21781. ' Size[true]:=Size[false]+31;',
  21782. ' Speed[true]:=Speed[false]+32;',
  21783. ' end;',
  21784. 'end;',
  21785. 'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
  21786. 'begin',
  21787. 'end;',
  21788. 'function TObjHelper.GetSize(Index: boolean): word;',
  21789. 'begin',
  21790. ' Size[true]:=Size[false]+11;',
  21791. ' Speed[true]:=Speed[false]+12;',
  21792. ' Self.Size[true]:=Self.Size[false]+21;',
  21793. ' Self.Speed[true]:=Self.Speed[false]+22;',
  21794. ' with Self do begin',
  21795. ' Size[true]:=Size[false]+31;',
  21796. ' Speed[true]:=Speed[false]+32;',
  21797. ' end;',
  21798. 'end;',
  21799. 'procedure TObjHelper.SetSize(Index: boolean; Value: word);',
  21800. 'begin',
  21801. 'end;',
  21802. 'procedure TBird.DoIt;',
  21803. 'begin',
  21804. ' Items[true]:=Items[false]+11;',
  21805. ' Self.Items[true]:=Self.Items[false]+21;',
  21806. ' with Self do Items[true]:=Items[false]+31;',
  21807. 'end;',
  21808. 'begin',
  21809. ' b.Size[true]:=b.Size[false]+11;',
  21810. ' b.Speed[true]:=b.Speed[false]+12;',
  21811. ' b.Items[true]:=b.Items[false]+13;',
  21812. ' with b do begin',
  21813. ' Size[true]:=Size[false]+21;',
  21814. ' Speed[true]:=Speed[false]+22;',
  21815. ' Items[true]:=Items[false]+23;',
  21816. ' end;',
  21817. '']);
  21818. ConvertProgram;
  21819. CheckSource('TestClassHelper_Property_Array',
  21820. LinesToStr([ // statements
  21821. 'rtl.createClass(this, "TObject", null, function () {',
  21822. ' this.$init = function () {',
  21823. ' };',
  21824. ' this.$final = function () {',
  21825. ' };',
  21826. ' this.GetSpeed = function (Index) {',
  21827. ' var Result = 0;',
  21828. ' Result = $mod.TObjHelper.GetSize.call(this, false);',
  21829. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  21830. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  21831. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  21832. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  21833. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  21834. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  21835. ' return Result;',
  21836. ' };',
  21837. ' this.SetSpeed = function (Index, Value) {',
  21838. ' };',
  21839. '});',
  21840. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  21841. ' this.GetSize = function (Index) {',
  21842. ' var Result = 0;',
  21843. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  21844. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  21845. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  21846. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  21847. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  21848. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  21849. ' return Result;',
  21850. ' };',
  21851. ' this.SetSize = function (Index, Value) {',
  21852. ' };',
  21853. '});',
  21854. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  21855. ' this.DoIt = function () {',
  21856. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  21857. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  21858. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  21859. ' };',
  21860. '});',
  21861. 'this.b = null;',
  21862. '']),
  21863. LinesToStr([ // $mod.$main
  21864. '$mod.TObjHelper.SetSize.call($mod.b, true, $mod.TObjHelper.GetSize.call($mod.b, false) + 11);',
  21865. '$mod.b.SetSpeed(true, $mod.b.GetSpeed(false) + 12);',
  21866. '$mod.TObjHelper.SetSize.call($mod.b, true, $mod.TObjHelper.GetSize.call($mod.b, false) + 13);',
  21867. 'var $with = $mod.b;',
  21868. '$mod.TObjHelper.SetSize.call($with, true, $mod.TObjHelper.GetSize.call($with, false) + 21);',
  21869. '$with.SetSpeed(true, $with.GetSpeed(false) + 22);',
  21870. '$mod.TObjHelper.SetSize.call($with, true, $mod.TObjHelper.GetSize.call($with, false) + 23);',
  21871. '']));
  21872. end;
  21873. procedure TTestModule.TestClassHelper_Property_Array_Default;
  21874. begin
  21875. StartProgram(false);
  21876. Add([
  21877. 'type',
  21878. ' TObject = class',
  21879. ' function GetSpeed(Index: boolean): word;',
  21880. ' procedure SetSpeed(Index: boolean; Value: word);',
  21881. ' end;',
  21882. ' TObjHelper = class helper for TObject',
  21883. ' property Speed[Index: boolean]: word read GetSpeed write SetSpeed; default;',
  21884. ' end;',
  21885. ' TBird = class',
  21886. ' end;',
  21887. ' TBirdHelper = class helper for TBird',
  21888. ' function GetSize(Index: word): boolean;',
  21889. ' procedure SetSize(Index: word; Value: boolean);',
  21890. ' property Size[Index: word]: boolean read GetSize write SetSize; default;',
  21891. ' end;',
  21892. 'function Tobject.GetSpeed(Index: boolean): word;',
  21893. 'begin',
  21894. ' Self[true]:=Self[false]+1;',
  21895. 'end;',
  21896. 'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
  21897. 'begin',
  21898. 'end;',
  21899. 'function TBirdHelper.GetSize(Index: word): boolean;',
  21900. 'begin',
  21901. ' Self[1]:=not Self[2];',
  21902. 'end;',
  21903. 'procedure TBirdHelper.SetSize(Index: word; Value: boolean);',
  21904. 'begin',
  21905. 'end;',
  21906. 'var',
  21907. ' o: TObject;',
  21908. ' b: TBird;',
  21909. 'begin',
  21910. ' o[true]:=o[false]+1;',
  21911. ' b[3]:=not b[4];',
  21912. '']);
  21913. ConvertProgram;
  21914. CheckSource('TestClassHelper_Property_Array_Default',
  21915. LinesToStr([ // statements
  21916. 'rtl.createClass(this, "TObject", null, function () {',
  21917. ' this.$init = function () {',
  21918. ' };',
  21919. ' this.$final = function () {',
  21920. ' };',
  21921. ' this.GetSpeed = function (Index) {',
  21922. ' var Result = 0;',
  21923. ' this.SetSpeed(true, this.GetSpeed(false) + 1);',
  21924. ' return Result;',
  21925. ' };',
  21926. ' this.SetSpeed = function (Index, Value) {',
  21927. ' };',
  21928. '});',
  21929. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  21930. '});',
  21931. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  21932. '});',
  21933. 'rtl.createHelper(this, "TBirdHelper", null, function () {',
  21934. ' this.GetSize = function (Index) {',
  21935. ' var Result = false;',
  21936. ' $mod.TBirdHelper.SetSize.call(this, 1, !$mod.TBirdHelper.GetSize.call(this, 2));',
  21937. ' return Result;',
  21938. ' };',
  21939. ' this.SetSize = function (Index, Value) {',
  21940. ' };',
  21941. '});',
  21942. 'this.o = null;',
  21943. 'this.b = null;',
  21944. '']),
  21945. LinesToStr([ // $mod.$main
  21946. '$mod.o.SetSpeed(true, $mod.o.GetSpeed(false) + 1);',
  21947. '$mod.TBirdHelper.SetSize.call($mod.b, 3, !$mod.TBirdHelper.GetSize.call($mod.b, 4));',
  21948. '']));
  21949. end;
  21950. procedure TTestModule.TestClassHelper_Property_Array_DefaultDefault;
  21951. begin
  21952. StartProgram(false);
  21953. Add([
  21954. 'type',
  21955. ' TObject = class',
  21956. ' end;',
  21957. ' TObjHelper = class helper for TObject',
  21958. ' function GetItems(Index: word): TObject;',
  21959. ' procedure SetItems(Index: word; Value: TObject);',
  21960. ' property Items[Index: word]: TObject read GetItems write SetItems; default;',
  21961. ' end;',
  21962. 'function Tobjhelper.GetItems(Index: word): TObject;',
  21963. 'begin',
  21964. ' Self[1][2]:=Self[3][4];',
  21965. 'end;',
  21966. 'procedure Tobjhelper.SetItems(Index: word; Value: TObject);',
  21967. 'begin',
  21968. 'end;',
  21969. 'var',
  21970. ' o: TObject;',
  21971. 'begin',
  21972. ' o[1][2]:=o[3][4];',
  21973. '']);
  21974. ConvertProgram;
  21975. CheckSource('TestClassHelper_Property_Array_DefaultDefault',
  21976. LinesToStr([ // statements
  21977. 'rtl.createClass(this, "TObject", null, function () {',
  21978. ' this.$init = function () {',
  21979. ' };',
  21980. ' this.$final = function () {',
  21981. ' };',
  21982. '});',
  21983. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  21984. ' this.GetItems = function (Index) {',
  21985. ' var Result = null;',
  21986. ' $mod.TObjHelper.SetItems.call($mod.TObjHelper.GetItems.call(this, 1), 2, $mod.TObjHelper.GetItems.call($mod.TObjHelper.GetItems.call(this, 3), 4));',
  21987. ' return Result;',
  21988. ' };',
  21989. ' this.SetItems = function (Index, Value) {',
  21990. ' };',
  21991. '});',
  21992. 'this.o = null;',
  21993. '']),
  21994. LinesToStr([ // $mod.$main
  21995. '$mod.TObjHelper.SetItems.call($mod.TObjHelper.GetItems.call($mod.o, 1), 2, $mod.TObjHelper.GetItems.call($mod.TObjHelper.GetItems.call($mod.o, 3), 4));',
  21996. '']));
  21997. end;
  21998. procedure TTestModule.TestClassHelper_ClassProperty;
  21999. begin
  22000. StartProgram(false);
  22001. Add([
  22002. 'type',
  22003. ' TObject = class',
  22004. ' class var FSize: word;',
  22005. ' class function GetSpeed: word;',
  22006. ' class procedure SetSpeed(Value: word); virtual; abstract;',
  22007. ' end;',
  22008. ' TObjHelper = class helper for TObject',
  22009. ' class function GetLeft: word;',
  22010. ' class procedure SetLeft(Value: word);',
  22011. ' class property Size: word read FSize write FSize;',
  22012. ' class property Speed: word read GetSpeed write SetSpeed;',
  22013. ' class property Left: word read GetLeft write SetLeft;',
  22014. ' end;',
  22015. ' TBird = class',
  22016. ' class property NotRight: word read GetLeft write SetLeft;',
  22017. ' class procedure DoIt;',
  22018. ' end;',
  22019. ' TBirdClass = class of TBird;',
  22020. 'class function Tobject.GetSpeed: word;',
  22021. 'begin',
  22022. ' Size:=Size+11;',
  22023. ' Speed:=Speed+12;',
  22024. ' Left:=Left+13;',
  22025. ' Self.Size:=Self.Size+21;',
  22026. ' Self.Speed:=Self.Speed+22;',
  22027. ' Self.Left:=Self.Left+23;',
  22028. ' with Self do begin',
  22029. ' Size:=Size+31;',
  22030. ' Speed:=Speed+32;',
  22031. ' Left:=Left+33;',
  22032. ' end;',
  22033. 'end;',
  22034. 'class function TObjHelper.GetLeft: word;',
  22035. 'begin',
  22036. ' Size:=Size+11;',
  22037. ' Speed:=Speed+12;',
  22038. ' Left:=Left+13;',
  22039. ' Self.Size:=Self.Size+21;',
  22040. ' Self.Speed:=Self.Speed+22;',
  22041. ' Self.Left:=Self.Left+23;',
  22042. ' with Self do begin',
  22043. ' Size:=Size+31;',
  22044. ' Speed:=Speed+32;',
  22045. ' Left:=Left+33;',
  22046. ' end;',
  22047. 'end;',
  22048. 'class procedure TObjHelper.SetLeft(Value: word);',
  22049. 'begin',
  22050. 'end;',
  22051. 'class procedure TBird.DoIt;',
  22052. 'begin',
  22053. ' NotRight:=NotRight+11;',
  22054. ' Self.NotRight:=Self.NotRight+21;',
  22055. ' with Self do NotRight:=NotRight+31;',
  22056. 'end;',
  22057. 'var',
  22058. ' b: TBird;',
  22059. ' c: TBirdClass;',
  22060. 'begin',
  22061. ' b.Size:=b.Size+11;',
  22062. ' b.Speed:=b.Speed+12;',
  22063. ' b.Left:=b.Left+13;',
  22064. ' b.NotRight:=b.NotRight+14;',
  22065. ' with b do begin',
  22066. ' Size:=Size+31;',
  22067. ' Speed:=Speed+32;',
  22068. ' Left:=Left+33;',
  22069. ' NotRight:=NotRight+34;',
  22070. ' end;',
  22071. ' c.Size:=c.Size+11;',
  22072. ' c.Speed:=c.Speed+12;',
  22073. ' c.Left:=c.Left+13;',
  22074. ' c.NotRight:=c.NotRight+14;',
  22075. ' with c do begin',
  22076. ' Size:=Size+31;',
  22077. ' Speed:=Speed+32;',
  22078. ' Left:=Left+33;',
  22079. ' NotRight:=NotRight+34;',
  22080. ' end;',
  22081. ' tbird.Size:=tbird.Size+11;',
  22082. ' tbird.Speed:=tbird.Speed+12;',
  22083. ' tbird.Left:=tbird.Left+13;',
  22084. ' tbird.NotRight:=tbird.NotRight+14;',
  22085. ' with tbird do begin',
  22086. ' Size:=Size+31;',
  22087. ' Speed:=Speed+32;',
  22088. ' Left:=Left+33;',
  22089. ' NotRight:=NotRight+34;',
  22090. ' end;',
  22091. '']);
  22092. ConvertProgram;
  22093. CheckSource('TestClassHelper_ClassProperty',
  22094. LinesToStr([ // statements
  22095. 'rtl.createClass(this, "TObject", null, function () {',
  22096. ' this.FSize = 0;',
  22097. ' this.$init = function () {',
  22098. ' };',
  22099. ' this.$final = function () {',
  22100. ' };',
  22101. ' this.GetSpeed = function () {',
  22102. ' var Result = 0;',
  22103. ' $mod.TObject.FSize = this.FSize + 11;',
  22104. ' this.SetSpeed(this.GetSpeed() + 12);',
  22105. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  22106. ' $mod.TObject.FSize = this.FSize + 21;',
  22107. ' this.SetSpeed(this.GetSpeed() + 22);',
  22108. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  22109. ' $mod.TObject.FSize = this.FSize + 31;',
  22110. ' this.SetSpeed(this.GetSpeed() + 32);',
  22111. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  22112. ' return Result;',
  22113. ' };',
  22114. '});',
  22115. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  22116. ' this.GetLeft = function () {',
  22117. ' var Result = 0;',
  22118. ' $mod.TObject.FSize = this.FSize + 11;',
  22119. ' this.SetSpeed(this.GetSpeed() + 12);',
  22120. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  22121. ' $mod.TObject.FSize = this.FSize + 21;',
  22122. ' this.SetSpeed(this.GetSpeed() + 22);',
  22123. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  22124. ' $mod.TObject.FSize = this.FSize + 31;',
  22125. ' this.SetSpeed(this.GetSpeed() + 32);',
  22126. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  22127. ' return Result;',
  22128. ' };',
  22129. ' this.SetLeft = function (Value) {',
  22130. ' };',
  22131. '});',
  22132. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  22133. ' this.DoIt = function () {',
  22134. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 11);',
  22135. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 21);',
  22136. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 31);',
  22137. ' };',
  22138. '});',
  22139. 'this.b = null;',
  22140. 'this.c = null;',
  22141. '']),
  22142. LinesToStr([ // $mod.$main
  22143. '$mod.TObject.FSize = $mod.b.FSize + 11;',
  22144. '$mod.b.$class.SetSpeed($mod.b.$class.GetSpeed() + 12);',
  22145. '$mod.TObjHelper.SetLeft.call($mod.b.$class, $mod.TObjHelper.GetLeft.call($mod.b.$class) + 13);',
  22146. '$mod.TObjHelper.SetLeft.call($mod.b.$class, $mod.TObjHelper.GetLeft.call($mod.b.$class) + 14);',
  22147. 'var $with = $mod.b;',
  22148. '$mod.TObject.FSize = $with.FSize + 31;',
  22149. '$with.$class.SetSpeed($with.$class.GetSpeed() + 32);',
  22150. '$mod.TObjHelper.SetLeft.call($with.$class, $mod.TObjHelper.GetLeft.call($with.$class) + 33);',
  22151. '$mod.TObjHelper.SetLeft.call($with.$class, $mod.TObjHelper.GetLeft.call($with.$class) + 34);',
  22152. '$mod.TObject.FSize = $mod.c.FSize + 11;',
  22153. '$mod.c.SetSpeed($mod.c.GetSpeed() + 12);',
  22154. '$mod.TObjHelper.SetLeft.call($mod.c, $mod.TObjHelper.GetLeft.call($mod.c) + 13);',
  22155. '$mod.TObjHelper.SetLeft.call($mod.c, $mod.TObjHelper.GetLeft.call($mod.c) + 14);',
  22156. 'var $with1 = $mod.c;',
  22157. '$mod.TObject.FSize = $with1.FSize + 31;',
  22158. '$with1.SetSpeed($with1.GetSpeed() + 32);',
  22159. '$mod.TObjHelper.SetLeft.call($with1, $mod.TObjHelper.GetLeft.call($with1) + 33);',
  22160. '$mod.TObjHelper.SetLeft.call($with1, $mod.TObjHelper.GetLeft.call($with1) + 34);',
  22161. '$mod.TObject.FSize = $mod.TBird.FSize + 11;',
  22162. '$mod.TBird.SetSpeed($mod.TBird.GetSpeed() + 12);',
  22163. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 13);',
  22164. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 14);',
  22165. 'var $with2 = $mod.TBird;',
  22166. '$mod.TObject.FSize = $with2.FSize + 31;',
  22167. '$with2.SetSpeed($with2.GetSpeed() + 32);',
  22168. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 33);',
  22169. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 34);',
  22170. '']));
  22171. end;
  22172. procedure TTestModule.TestClassHelper_ClassPropertyStatic;
  22173. begin
  22174. StartProgram(false);
  22175. Add([
  22176. 'type',
  22177. ' TObject = class',
  22178. ' class function GetSpeed: word; static;',
  22179. ' class procedure SetSpeed(Value: word); static;',
  22180. ' end;',
  22181. ' TObjHelper = class helper for TObject',
  22182. ' class function GetLeft: word; static;',
  22183. ' class procedure SetLeft(Value: word); static;',
  22184. ' class property Speed: word read GetSpeed write SetSpeed;',
  22185. ' class property Left: word read GetLeft write SetLeft;',
  22186. ' end;',
  22187. ' TBird = class',
  22188. ' class property NotRight: word read GetLeft write SetLeft;',
  22189. ' class procedure DoIt; static;',
  22190. ' class procedure DoSome;',
  22191. ' end;',
  22192. ' TBirdClass = class of TBird;',
  22193. 'class function Tobject.GetSpeed: word;',
  22194. 'begin',
  22195. ' Speed:=Speed+12;',
  22196. ' Left:=Left+13;',
  22197. 'end;',
  22198. 'class procedure TObject.SetSpeed(Value: word);',
  22199. 'begin',
  22200. 'end;',
  22201. 'class function TObjHelper.GetLeft: word;',
  22202. 'begin',
  22203. ' Speed:=Speed+12;',
  22204. ' Left:=Left+13;',
  22205. 'end;',
  22206. 'class procedure TObjHelper.SetLeft(Value: word);',
  22207. 'begin',
  22208. 'end;',
  22209. 'class procedure TBird.DoIt;',
  22210. 'begin',
  22211. ' NotRight:=NotRight+11;',
  22212. 'end;',
  22213. 'class procedure TBird.DoSome;',
  22214. 'begin',
  22215. ' Speed:=Speed+12;',
  22216. ' Left:=Left+13;',
  22217. ' Self.Speed:=Self.Speed+22;',
  22218. ' Self.Left:=Self.Left+23;',
  22219. ' with Self do begin',
  22220. ' Speed:=Speed+32;',
  22221. ' Left:=Left+33;',
  22222. ' end;',
  22223. ' NotRight:=NotRight+11;',
  22224. ' Self.NotRight:=Self.NotRight+21;',
  22225. ' with Self do NotRight:=NotRight+31;',
  22226. 'end;',
  22227. 'var',
  22228. ' b: TBird;',
  22229. ' c: TBirdClass;',
  22230. 'begin',
  22231. ' b.Speed:=b.Speed+12;',
  22232. ' b.Left:=b.Left+13;',
  22233. ' b.NotRight:=b.NotRight+14;',
  22234. ' with b do begin',
  22235. ' Speed:=Speed+32;',
  22236. ' Left:=Left+33;',
  22237. ' NotRight:=NotRight+34;',
  22238. ' end;',
  22239. ' c.Speed:=c.Speed+12;',
  22240. ' c.Left:=c.Left+13;',
  22241. ' c.NotRight:=c.NotRight+14;',
  22242. ' with c do begin',
  22243. ' Speed:=Speed+32;',
  22244. ' Left:=Left+33;',
  22245. ' NotRight:=NotRight+34;',
  22246. ' end;',
  22247. ' tbird.Speed:=tbird.Speed+12;',
  22248. ' tbird.Left:=tbird.Left+13;',
  22249. ' tbird.NotRight:=tbird.NotRight+14;',
  22250. ' with tbird do begin',
  22251. ' Speed:=Speed+32;',
  22252. ' Left:=Left+33;',
  22253. ' NotRight:=NotRight+34;',
  22254. ' end;',
  22255. '']);
  22256. ConvertProgram;
  22257. CheckSource('TestClassHelper_ClassPropertyStatic',
  22258. LinesToStr([ // statements
  22259. 'rtl.createClass(this, "TObject", null, function () {',
  22260. ' this.$init = function () {',
  22261. ' };',
  22262. ' this.$final = function () {',
  22263. ' };',
  22264. ' this.GetSpeed = function () {',
  22265. ' var Result = 0;',
  22266. ' $mod.TObject.SetSpeed($mod.TObject.GetSpeed() + 12);',
  22267. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  22268. ' return Result;',
  22269. ' };',
  22270. ' this.SetSpeed = function (Value) {',
  22271. ' };',
  22272. '});',
  22273. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  22274. ' this.GetLeft = function () {',
  22275. ' var Result = 0;',
  22276. ' $mod.TObject.SetSpeed($mod.TObject.GetSpeed() + 12);',
  22277. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  22278. ' return Result;',
  22279. ' };',
  22280. ' this.SetLeft = function (Value) {',
  22281. ' };',
  22282. '});',
  22283. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  22284. ' this.DoIt = function () {',
  22285. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 11);',
  22286. ' };',
  22287. ' this.DoSome = function () {',
  22288. ' this.SetSpeed(this.GetSpeed() + 12);',
  22289. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  22290. ' this.SetSpeed(this.GetSpeed() + 22);',
  22291. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 23);',
  22292. ' this.SetSpeed(this.GetSpeed() + 32);',
  22293. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  22294. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 11);',
  22295. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 21);',
  22296. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 31);',
  22297. ' };',
  22298. '});',
  22299. 'this.b = null;',
  22300. 'this.c = null;',
  22301. '']),
  22302. LinesToStr([ // $mod.$main
  22303. '$mod.TObject.SetSpeed($mod.TObject.GetSpeed() + 12);',
  22304. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  22305. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  22306. 'var $with = $mod.b;',
  22307. '$with.SetSpeed($with.GetSpeed() + 32);',
  22308. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  22309. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  22310. '$mod.TObject.SetSpeed($mod.TObject.GetSpeed() + 12);',
  22311. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  22312. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  22313. 'var $with1 = $mod.c;',
  22314. '$with1.SetSpeed($with1.GetSpeed() + 32);',
  22315. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  22316. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  22317. '$mod.TObject.SetSpeed($mod.TObject.GetSpeed() + 12);',
  22318. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  22319. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  22320. 'var $with2 = $mod.TBird;',
  22321. '$with2.SetSpeed($with2.GetSpeed() + 32);',
  22322. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  22323. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  22324. '']));
  22325. end;
  22326. procedure TTestModule.TestClassHelper_ClassProperty_Array;
  22327. begin
  22328. StartProgram(false);
  22329. Add([
  22330. 'type',
  22331. ' TObject = class',
  22332. ' class function GetSpeed(Index: boolean): word;',
  22333. ' class procedure SetSpeed(Index: boolean; Value: word); virtual; abstract;',
  22334. ' end;',
  22335. ' TObjHelper = class helper for TObject',
  22336. ' class function GetSize(Index: boolean): word;',
  22337. ' class procedure SetSize(Index: boolean; Value: word);',
  22338. ' class property Size[Index: boolean]: word read GetSize write SetSize;',
  22339. ' class property Speed[Index: boolean]: word read GetSpeed write SetSpeed;',
  22340. ' end;',
  22341. ' TBird = class',
  22342. ' class property Items[Index: boolean]: word read GetSize write SetSize;',
  22343. ' class procedure DoIt;',
  22344. ' end;',
  22345. ' TBirdClass = class of TBird;',
  22346. 'class function Tobject.GetSpeed(Index: boolean): word;',
  22347. 'begin',
  22348. ' Size[true]:=Size[false]+11;',
  22349. ' Speed[true]:=Speed[false]+12;',
  22350. ' Self.Size[true]:=Self.Size[false]+21;',
  22351. ' Self.Speed[true]:=Self.Speed[false]+22;',
  22352. ' with Self do begin',
  22353. ' Size[true]:=Size[false]+31;',
  22354. ' Speed[true]:=Speed[false]+32;',
  22355. ' end;',
  22356. 'end;',
  22357. 'class function TObjHelper.GetSize(Index: boolean): word;',
  22358. 'begin',
  22359. ' Size[true]:=Size[false]+11;',
  22360. ' Speed[true]:=Speed[false]+12;',
  22361. ' Self.Size[true]:=Self.Size[false]+21;',
  22362. ' Self.Speed[true]:=Self.Speed[false]+22;',
  22363. ' with Self do begin',
  22364. ' Size[true]:=Size[false]+31;',
  22365. ' Speed[true]:=Speed[false]+32;',
  22366. ' end;',
  22367. 'end;',
  22368. 'class procedure TObjHelper.SetSize(Index: boolean; Value: word);',
  22369. 'begin',
  22370. 'end;',
  22371. 'class procedure TBird.DoIt;',
  22372. 'begin',
  22373. ' Items[true]:=Items[false]+11;',
  22374. ' Self.Items[true]:=Self.Items[false]+21;',
  22375. ' with Self do Items[true]:=Items[false]+31;',
  22376. 'end;',
  22377. 'var',
  22378. ' b: TBird;',
  22379. ' c: TBirdClass;',
  22380. 'begin',
  22381. ' b.Size[true]:=b.Size[false]+11;',
  22382. ' b.Speed[true]:=b.Speed[false]+12;',
  22383. ' b.Items[true]:=b.Items[false]+13;',
  22384. ' with b do begin',
  22385. ' Size[true]:=Size[false]+21;',
  22386. ' Speed[true]:=Speed[false]+22;',
  22387. ' Items[true]:=Items[false]+23;',
  22388. ' end;',
  22389. ' c.Size[true]:=c.Size[false]+11;',
  22390. ' c.Speed[true]:=c.Speed[false]+12;',
  22391. ' c.Items[true]:=c.Items[false]+13;',
  22392. ' with c do begin',
  22393. ' Size[true]:=Size[false]+21;',
  22394. ' Speed[true]:=Speed[false]+22;',
  22395. ' Items[true]:=Items[false]+23;',
  22396. ' end;',
  22397. ' TBird.Size[true]:=TBird.Size[false]+11;',
  22398. ' TBird.Speed[true]:=TBird.Speed[false]+12;',
  22399. ' TBird.Items[true]:=TBird.Items[false]+13;',
  22400. ' with TBird do begin',
  22401. ' Size[true]:=Size[false]+21;',
  22402. ' Speed[true]:=Speed[false]+22;',
  22403. ' Items[true]:=Items[false]+23;',
  22404. ' end;',
  22405. '']);
  22406. ConvertProgram;
  22407. CheckSource('TestClassHelper_ClassProperty_Array',
  22408. LinesToStr([ // statements
  22409. 'rtl.createClass(this, "TObject", null, function () {',
  22410. ' this.$init = function () {',
  22411. ' };',
  22412. ' this.$final = function () {',
  22413. ' };',
  22414. ' this.GetSpeed = function (Index) {',
  22415. ' var Result = 0;',
  22416. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  22417. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  22418. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  22419. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  22420. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  22421. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  22422. ' return Result;',
  22423. ' };',
  22424. '});',
  22425. 'rtl.createHelper(this, "TObjHelper", null, function () {',
  22426. ' this.GetSize = function (Index) {',
  22427. ' var Result = 0;',
  22428. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  22429. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  22430. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  22431. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  22432. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  22433. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  22434. ' return Result;',
  22435. ' };',
  22436. ' this.SetSize = function (Index, Value) {',
  22437. ' };',
  22438. '});',
  22439. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  22440. ' this.DoIt = function () {',
  22441. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  22442. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  22443. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  22444. ' };',
  22445. '});',
  22446. 'this.b = null;',
  22447. 'this.c = null;',
  22448. '']),
  22449. LinesToStr([ // $mod.$main
  22450. '$mod.TObjHelper.SetSize.call($mod.b.$class, true, $mod.TObjHelper.GetSize.call($mod.b.$class, false) + 11);',
  22451. '$mod.b.$class.SetSpeed(true, $mod.b.$class.GetSpeed(false) + 12);',
  22452. '$mod.TObjHelper.SetSize.call($mod.b.$class, true, $mod.TObjHelper.GetSize.call($mod.b.$class, false) + 13);',
  22453. 'var $with = $mod.b;',
  22454. '$mod.TObjHelper.SetSize.call($with.$class, true, $mod.TObjHelper.GetSize.call($with.$class, false) + 21);',
  22455. '$with.$class.SetSpeed(true, $with.$class.GetSpeed(false) + 22);',
  22456. '$mod.TObjHelper.SetSize.call($with.$class, true, $mod.TObjHelper.GetSize.call($with.$class, false) + 23);',
  22457. '$mod.TObjHelper.SetSize.call($mod.c, true, $mod.TObjHelper.GetSize.call($mod.c, false) + 11);',
  22458. '$mod.c.SetSpeed(true, $mod.c.GetSpeed(false) + 12);',
  22459. '$mod.TObjHelper.SetSize.call($mod.c, true, $mod.TObjHelper.GetSize.call($mod.c, false) + 13);',
  22460. 'var $with1 = $mod.c;',
  22461. '$mod.TObjHelper.SetSize.call($with1, true, $mod.TObjHelper.GetSize.call($with1, false) + 21);',
  22462. '$with1.SetSpeed(true, $with1.GetSpeed(false) + 22);',
  22463. '$mod.TObjHelper.SetSize.call($with1, true, $mod.TObjHelper.GetSize.call($with1, false) + 23);',
  22464. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 11);',
  22465. '$mod.TBird.SetSpeed(true, $mod.TBird.GetSpeed(false) + 12);',
  22466. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 13);',
  22467. 'var $with2 = $mod.TBird;',
  22468. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 21);',
  22469. '$with2.SetSpeed(true, $with2.GetSpeed(false) + 22);',
  22470. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 23);',
  22471. '']));
  22472. end;
  22473. procedure TTestModule.TestClassHelper_ForIn;
  22474. begin
  22475. StartProgram(false);
  22476. Add([
  22477. 'type',
  22478. ' TObject = class end;',
  22479. ' TItem = TObject;',
  22480. ' TEnumerator = class',
  22481. ' FCurrent: TItem;',
  22482. ' property Current: TItem read FCurrent;',
  22483. ' function MoveNext: boolean;',
  22484. ' end;',
  22485. ' TBird = class',
  22486. ' end;',
  22487. ' TBirdHelper = class helper for TBird',
  22488. ' function GetEnumerator: TEnumerator;',
  22489. ' end;',
  22490. 'function TEnumerator.MoveNext: boolean;',
  22491. 'begin',
  22492. 'end;',
  22493. 'function TBirdHelper.GetEnumerator: TEnumerator;',
  22494. 'begin',
  22495. 'end;',
  22496. 'var',
  22497. ' b: TBird;',
  22498. ' i, i2: TItem;',
  22499. 'begin',
  22500. ' for i in b do i2:=i;']);
  22501. ConvertProgram;
  22502. CheckSource('TestClassHelper_ForIn',
  22503. LinesToStr([ // statements
  22504. 'rtl.createClass(this, "TObject", null, function () {',
  22505. ' this.$init = function () {',
  22506. ' };',
  22507. ' this.$final = function () {',
  22508. ' };',
  22509. '});',
  22510. 'rtl.createClass(this, "TEnumerator", this.TObject, function () {',
  22511. ' this.$init = function () {',
  22512. ' $mod.TObject.$init.call(this);',
  22513. ' this.FCurrent = null;',
  22514. ' };',
  22515. ' this.$final = function () {',
  22516. ' this.FCurrent = undefined;',
  22517. ' $mod.TObject.$final.call(this);',
  22518. ' };',
  22519. ' this.MoveNext = function () {',
  22520. ' var Result = false;',
  22521. ' return Result;',
  22522. ' };',
  22523. '});',
  22524. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  22525. '});',
  22526. 'rtl.createHelper(this, "TBirdHelper", null, function () {',
  22527. ' this.GetEnumerator = function () {',
  22528. ' var Result = null;',
  22529. ' return Result;',
  22530. ' };',
  22531. '});',
  22532. 'this.b = null;',
  22533. 'this.i = null;',
  22534. 'this.i2 = null;'
  22535. ]),
  22536. LinesToStr([ // $mod.$main
  22537. 'var $in = $mod.TBirdHelper.GetEnumerator.call($mod.b);',
  22538. 'try {',
  22539. ' while ($in.MoveNext()){',
  22540. ' $mod.i = $in.FCurrent;',
  22541. ' $mod.i2 = $mod.i;',
  22542. ' }',
  22543. '} finally {',
  22544. ' $in = rtl.freeLoc($in)',
  22545. '};',
  22546. '']));
  22547. end;
  22548. procedure TTestModule.TestClassHelper_PassProperty;
  22549. begin
  22550. StartProgram(false);
  22551. Add([
  22552. 'type',
  22553. ' TObject = class',
  22554. ' FField: TObject;',
  22555. ' property Field: TObject read FField write FField;',
  22556. ' end;',
  22557. ' THelper = class helper for TObject',
  22558. ' procedure Fly;',
  22559. ' class procedure Run;',
  22560. ' class procedure Jump; static;',
  22561. ' end;',
  22562. 'procedure THelper.Fly;',
  22563. 'begin',
  22564. ' Field.Fly;',
  22565. ' Field.Run;',
  22566. ' Field.Jump;',
  22567. ' with Field do begin',
  22568. ' Fly;',
  22569. ' Run;',
  22570. ' Jump;',
  22571. ' end;',
  22572. 'end;',
  22573. 'class procedure THelper.Run;',
  22574. 'begin',
  22575. 'end;',
  22576. 'class procedure THelper.Jump;',
  22577. 'begin',
  22578. 'end;',
  22579. 'var',
  22580. ' b: TObject;',
  22581. 'begin',
  22582. ' b.Field.Fly;',
  22583. ' b.Field.Run;',
  22584. ' b.Field.Jump;',
  22585. ' with b do begin',
  22586. ' Field.Run;',
  22587. ' Field.Fly;',
  22588. ' Field.Jump;',
  22589. ' end;',
  22590. ' with b.Field do begin',
  22591. ' Run;',
  22592. ' Fly;',
  22593. ' Jump;',
  22594. ' end;',
  22595. '']);
  22596. ConvertProgram;
  22597. CheckSource('TestClassHelper_PassProperty',
  22598. LinesToStr([ // statements
  22599. 'rtl.createClass(this, "TObject", null, function () {',
  22600. ' this.$init = function () {',
  22601. ' this.FField = null;',
  22602. ' };',
  22603. ' this.$final = function () {',
  22604. ' this.FField = undefined;',
  22605. ' };',
  22606. '});',
  22607. 'rtl.createHelper(this, "THelper", null, function () {',
  22608. ' this.Fly = function () {',
  22609. ' $mod.THelper.Fly.call(this.FField);',
  22610. ' $mod.THelper.Run.call(this.FField.$class);',
  22611. ' $mod.THelper.Jump();',
  22612. ' var $with = this.FField;',
  22613. ' $mod.THelper.Fly.call($with);',
  22614. ' $mod.THelper.Run.call($with.$class);',
  22615. ' $mod.THelper.Jump();',
  22616. ' };',
  22617. ' this.Run = function () {',
  22618. ' };',
  22619. ' this.Jump = function () {',
  22620. ' };',
  22621. '});',
  22622. 'this.b = null;',
  22623. '']),
  22624. LinesToStr([ // $mod.$main
  22625. '$mod.THelper.Fly.call($mod.b.FField);',
  22626. '$mod.THelper.Run.call($mod.b.FField.$class);',
  22627. '$mod.THelper.Jump();',
  22628. 'var $with = $mod.b;',
  22629. '$mod.THelper.Run.call($with.FField.$class);',
  22630. '$mod.THelper.Fly.call($with.FField);',
  22631. '$mod.THelper.Jump();',
  22632. 'var $with1 = $mod.b.FField;',
  22633. '$mod.THelper.Run.call($with1.$class);',
  22634. '$mod.THelper.Fly.call($with1);',
  22635. '$mod.THelper.Jump();',
  22636. '']));
  22637. end;
  22638. procedure TTestModule.TestExtClassHelper_ClassVar;
  22639. begin
  22640. StartProgram(false);
  22641. Add([
  22642. '{$modeswitch externalclass}',
  22643. 'type',
  22644. ' TExtA = class external name ''ExtObj''',
  22645. ' end;',
  22646. ' THelper = class helper for TExtA',
  22647. ' const',
  22648. ' One = 1;',
  22649. ' Two: word = 2;',
  22650. ' class var',
  22651. ' Glob: word;',
  22652. ' function Foo(w: word): word;',
  22653. ' class function Bar(w: word): word; static;',
  22654. ' end;',
  22655. 'function THelper.foo(w: word): word;',
  22656. 'begin',
  22657. ' Result:=w;',
  22658. ' Two:=One+w;',
  22659. ' Glob:=Glob;',
  22660. ' Result:=Self.Glob;',
  22661. ' Self.Glob:=Self.Glob;',
  22662. ' with Self do Glob:=Glob;',
  22663. 'end;',
  22664. 'class function THelper.bar(w: word): word;',
  22665. 'begin',
  22666. ' Result:=w;',
  22667. ' Two:=One;',
  22668. ' Glob:=Glob;',
  22669. 'end;',
  22670. 'var o: TExtA;',
  22671. 'begin',
  22672. ' texta.two:=texta.one;',
  22673. ' texta.Glob:=texta.Glob;',
  22674. ' with texta do begin',
  22675. ' two:=one;',
  22676. ' Glob:=Glob;',
  22677. ' end;',
  22678. ' o.two:=o.one;',
  22679. ' o.Glob:=o.Glob;',
  22680. ' with o do begin',
  22681. ' two:=one;',
  22682. ' Glob:=Glob;',
  22683. ' end;',
  22684. '']);
  22685. ConvertProgram;
  22686. CheckSource('TestExtClassHelper_ClassVar',
  22687. LinesToStr([ // statements
  22688. 'rtl.createHelper(this, "THelper", null, function () {',
  22689. ' this.One = 1;',
  22690. ' this.Two = 2;',
  22691. ' this.Glob = 0;',
  22692. ' this.Foo = function (w) {',
  22693. ' var Result = 0;',
  22694. ' Result = w;',
  22695. ' $mod.THelper.Two = 1 + w;',
  22696. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22697. ' Result = $mod.THelper.Glob;',
  22698. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22699. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22700. ' return Result;',
  22701. ' };',
  22702. ' this.Bar = function (w) {',
  22703. ' var Result = 0;',
  22704. ' Result = w;',
  22705. ' $mod.THelper.Two = 1;',
  22706. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22707. ' return Result;',
  22708. ' };',
  22709. '});',
  22710. 'this.o = null;',
  22711. '']),
  22712. LinesToStr([ // $mod.$main
  22713. '$mod.THelper.Two = 1;',
  22714. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22715. '$mod.THelper.Two = 1;',
  22716. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22717. '$mod.THelper.Two = 1;',
  22718. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22719. 'var $with = $mod.o;',
  22720. '$mod.THelper.Two = 1;',
  22721. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22722. '']));
  22723. end;
  22724. procedure TTestModule.TestExtClassHelper_Method_Call;
  22725. begin
  22726. StartProgram(false);
  22727. Add([
  22728. '{$modeswitch externalclass}',
  22729. 'type',
  22730. ' TFly = function(w: word): word of object;',
  22731. ' TExtA = class external name ''ExtObj''',
  22732. ' procedure Run(w: word = 10);',
  22733. ' end;',
  22734. ' THelper = class helper for TExtA',
  22735. ' function Foo(w: word = 1): word;',
  22736. ' function Fly(w: word = 2): word; external name ''Fly'';',
  22737. ' end;',
  22738. 'var p: TFly;',
  22739. 'function THelper.foo(w: word): word;',
  22740. 'begin',
  22741. ' Run;',
  22742. ' Run();',
  22743. ' Run(11);',
  22744. ' Foo;',
  22745. ' Foo();',
  22746. ' Foo(12);',
  22747. ' Self.Foo;',
  22748. ' Self.Foo();',
  22749. ' Self.Foo(13);',
  22750. ' Fly;',
  22751. ' Fly();',
  22752. ' with Self do begin',
  22753. ' Foo;',
  22754. ' Foo();',
  22755. ' Foo(14);',
  22756. ' Fly;',
  22757. ' Fly();',
  22758. ' end;',
  22759. ' p:=@Fly;',
  22760. 'end;',
  22761. 'var Obj: TExtA;',
  22762. 'begin',
  22763. ' obj.Foo;',
  22764. ' obj.Foo();',
  22765. ' obj.Foo(21);',
  22766. ' obj.Fly;',
  22767. ' obj.Fly();',
  22768. ' with obj do begin',
  22769. ' Foo;',
  22770. ' Foo();',
  22771. ' Foo(22);',
  22772. ' Fly;',
  22773. ' Fly();',
  22774. ' end;',
  22775. ' p:[email protected];',
  22776. '']);
  22777. ConvertProgram;
  22778. CheckSource('TestExtClassHelper_Method_Call',
  22779. LinesToStr([ // statements
  22780. 'rtl.createHelper(this, "THelper", null, function () {',
  22781. ' this.Foo = function (w) {',
  22782. ' var Result = 0;',
  22783. ' this.Run(10);',
  22784. ' this.Run(10);',
  22785. ' this.Run(11);',
  22786. ' $mod.THelper.Foo.call(this, 1);',
  22787. ' $mod.THelper.Foo.call(this, 1);',
  22788. ' $mod.THelper.Foo.call(this, 12);',
  22789. ' $mod.THelper.Foo.call(this, 1);',
  22790. ' $mod.THelper.Foo.call(this, 1);',
  22791. ' $mod.THelper.Foo.call(this, 13);',
  22792. ' this.Fly(2);',
  22793. ' this.Fly(2);',
  22794. ' $mod.THelper.Foo.call(this, 1);',
  22795. ' $mod.THelper.Foo.call(this, 1);',
  22796. ' $mod.THelper.Foo.call(this, 14);',
  22797. ' this.Fly(2);',
  22798. ' this.Fly(2);',
  22799. ' $mod.p = rtl.createCallback(this, "Fly");',
  22800. ' return Result;',
  22801. ' };',
  22802. '});',
  22803. 'this.p = null;',
  22804. 'this.Obj = null;',
  22805. '']),
  22806. LinesToStr([ // $mod.$main
  22807. '$mod.THelper.Foo.call($mod.Obj, 1);',
  22808. '$mod.THelper.Foo.call($mod.Obj, 1);',
  22809. '$mod.THelper.Foo.call($mod.Obj, 21);',
  22810. '$mod.Obj.Fly(2);',
  22811. '$mod.Obj.Fly(2);',
  22812. 'var $with = $mod.Obj;',
  22813. '$mod.THelper.Foo.call($with, 1);',
  22814. '$mod.THelper.Foo.call($with, 1);',
  22815. '$mod.THelper.Foo.call($with, 22);',
  22816. '$with.Fly(2);',
  22817. '$with.Fly(2);',
  22818. '$mod.p = rtl.createCallback($mod.Obj, "Fly");',
  22819. '']));
  22820. end;
  22821. procedure TTestModule.TestExtClassHelper_ClassMethod_MissingStatic;
  22822. begin
  22823. StartProgram(false);
  22824. Add([
  22825. '{$modeswitch externalclass}',
  22826. 'type',
  22827. ' TExtA = class external name ''ExtObj''',
  22828. ' procedure Run(w: word = 10);',
  22829. ' end;',
  22830. ' THelper = class helper for TExtA',
  22831. ' class procedure Fly;',
  22832. ' end;',
  22833. 'class procedure THelper.Fly;',
  22834. 'begin end;',
  22835. 'begin',
  22836. '']);
  22837. SetExpectedPasResolverError(sHelperClassMethodForExtClassMustBeStatic,
  22838. nHelperClassMethodForExtClassMustBeStatic);
  22839. ConvertProgram;
  22840. end;
  22841. procedure TTestModule.TestRecordHelper_ClassVar;
  22842. begin
  22843. StartProgram(false);
  22844. Add([
  22845. 'type',
  22846. ' TRec = record',
  22847. ' end;',
  22848. ' THelper = record helper for TRec',
  22849. ' const',
  22850. ' One = 1;',
  22851. ' Two: word = 2;',
  22852. ' class var',
  22853. ' Glob: word;',
  22854. ' function Foo(w: word): word;',
  22855. ' class function Bar(w: word): word; static;',
  22856. ' end;',
  22857. 'function THelper.foo(w: word): word;',
  22858. 'begin',
  22859. ' Result:=w;',
  22860. ' Two:=One+w;',
  22861. ' Glob:=Glob;',
  22862. ' Result:=Self.Glob;',
  22863. ' Self.Glob:=Self.Glob;',
  22864. ' with Self do Glob:=Glob;',
  22865. ' Self:=Self;',
  22866. 'end;',
  22867. 'class function THelper.bar(w: word): word;',
  22868. 'begin',
  22869. ' Result:=w;',
  22870. ' Two:=One;',
  22871. ' Glob:=Glob;',
  22872. 'end;',
  22873. 'var r: TRec;',
  22874. 'begin',
  22875. ' trec.two:=trec.one;',
  22876. ' trec.Glob:=trec.Glob;',
  22877. ' with trec do begin',
  22878. ' two:=one;',
  22879. ' Glob:=Glob;',
  22880. ' end;',
  22881. ' r.two:=r.one;',
  22882. ' r.Glob:=r.Glob;',
  22883. ' with r do begin',
  22884. ' two:=one;',
  22885. ' Glob:=Glob;',
  22886. ' end;',
  22887. '']);
  22888. ConvertProgram;
  22889. CheckSource('TestRecordHelper_ClassVar',
  22890. LinesToStr([ // statements
  22891. 'rtl.recNewT(this, "TRec", function () {',
  22892. ' this.$eq = function (b) {',
  22893. ' return true;',
  22894. ' };',
  22895. ' this.$assign = function (s) {',
  22896. ' return this;',
  22897. ' };',
  22898. '});',
  22899. 'rtl.createHelper(this, "THelper", null, function () {',
  22900. ' this.One = 1;',
  22901. ' this.Two = 2;',
  22902. ' this.Glob = 0;',
  22903. ' this.Foo = function (w) {',
  22904. ' var Result = 0;',
  22905. ' Result = w;',
  22906. ' $mod.THelper.Two = 1 + w;',
  22907. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22908. ' Result = $mod.THelper.Glob;',
  22909. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22910. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22911. ' this.$assign(this);',
  22912. ' return Result;',
  22913. ' };',
  22914. ' this.Bar = function (w) {',
  22915. ' var Result = 0;',
  22916. ' Result = w;',
  22917. ' $mod.THelper.Two = 1;',
  22918. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  22919. ' return Result;',
  22920. ' };',
  22921. '});',
  22922. 'this.r = this.TRec.$new();',
  22923. '']),
  22924. LinesToStr([ // $mod.$main
  22925. '$mod.THelper.Two = 1;',
  22926. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22927. 'var $with = $mod.TRec;',
  22928. '$mod.THelper.Two = 1;',
  22929. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22930. '$mod.THelper.Two = 1;',
  22931. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22932. 'var $with1 = $mod.r;',
  22933. '$mod.THelper.Two = 1;',
  22934. '$mod.THelper.Glob = $mod.THelper.Glob;',
  22935. '']));
  22936. end;
  22937. procedure TTestModule.TestRecordHelper_Method_Call;
  22938. begin
  22939. StartProgram(false);
  22940. Add([
  22941. '{$modeswitch AdvancedRecords}',
  22942. 'type',
  22943. ' TRec = record',
  22944. ' procedure Run(w: word = 10);',
  22945. ' end;',
  22946. ' THelper = record helper for TRec',
  22947. ' function Foo(w: word = 1): word;',
  22948. ' end;',
  22949. 'procedure TRec.Run(w: word);',
  22950. 'begin',
  22951. ' Foo;',
  22952. ' Foo();',
  22953. ' Foo(2);',
  22954. ' Self.Foo;',
  22955. ' Self.Foo();',
  22956. ' Self.Foo(3);',
  22957. ' with Self do begin',
  22958. ' Foo;',
  22959. ' Foo();',
  22960. ' Foo(4);',
  22961. ' end;',
  22962. 'end;',
  22963. 'function THelper.foo(w: word): word;',
  22964. 'begin',
  22965. ' Run;',
  22966. ' Run();',
  22967. ' Run(11);',
  22968. ' Foo;',
  22969. ' Foo();',
  22970. ' Foo(12);',
  22971. ' Self.Foo;',
  22972. ' Self.Foo();',
  22973. ' Self.Foo(13);',
  22974. ' with Self do begin',
  22975. ' Foo;',
  22976. ' Foo();',
  22977. ' Foo(14);',
  22978. ' end;',
  22979. 'end;',
  22980. 'var Rec: TRec;',
  22981. 'begin',
  22982. ' Rec.Foo;',
  22983. ' Rec.Foo();',
  22984. ' Rec.Foo(21);',
  22985. ' with Rec do begin',
  22986. ' Foo;',
  22987. ' Foo();',
  22988. ' Foo(22);',
  22989. ' end;',
  22990. '']);
  22991. ConvertProgram;
  22992. CheckSource('TestRecordHelper_Method_Call',
  22993. LinesToStr([ // statements
  22994. 'rtl.recNewT(this, "TRec", function () {',
  22995. ' this.$eq = function (b) {',
  22996. ' return true;',
  22997. ' };',
  22998. ' this.$assign = function (s) {',
  22999. ' return this;',
  23000. ' };',
  23001. ' this.Run = function (w) {',
  23002. ' $mod.THelper.Foo.call(this, 1);',
  23003. ' $mod.THelper.Foo.call(this, 1);',
  23004. ' $mod.THelper.Foo.call(this, 2);',
  23005. ' $mod.THelper.Foo.call(this, 1);',
  23006. ' $mod.THelper.Foo.call(this, 1);',
  23007. ' $mod.THelper.Foo.call(this, 3);',
  23008. ' $mod.THelper.Foo.call(this, 1);',
  23009. ' $mod.THelper.Foo.call(this, 1);',
  23010. ' $mod.THelper.Foo.call(this, 4);',
  23011. ' };',
  23012. '});',
  23013. 'rtl.createHelper(this, "THelper", null, function () {',
  23014. ' this.Foo = function (w) {',
  23015. ' var Result = 0;',
  23016. ' this.Run(10);',
  23017. ' this.Run(10);',
  23018. ' this.Run(11);',
  23019. ' $mod.THelper.Foo.call(this, 1);',
  23020. ' $mod.THelper.Foo.call(this, 1);',
  23021. ' $mod.THelper.Foo.call(this, 12);',
  23022. ' $mod.THelper.Foo.call(this, 1);',
  23023. ' $mod.THelper.Foo.call(this, 1);',
  23024. ' $mod.THelper.Foo.call(this, 13);',
  23025. ' $mod.THelper.Foo.call(this, 1);',
  23026. ' $mod.THelper.Foo.call(this, 1);',
  23027. ' $mod.THelper.Foo.call(this, 14);',
  23028. ' return Result;',
  23029. ' };',
  23030. '});',
  23031. 'this.Rec = this.TRec.$new();',
  23032. '']),
  23033. LinesToStr([ // $mod.$main
  23034. '$mod.THelper.Foo.call($mod.Rec, 1);',
  23035. '$mod.THelper.Foo.call($mod.Rec, 1);',
  23036. '$mod.THelper.Foo.call($mod.Rec, 21);',
  23037. 'var $with = $mod.Rec;',
  23038. '$mod.THelper.Foo.call($with, 1);',
  23039. '$mod.THelper.Foo.call($with, 1);',
  23040. '$mod.THelper.Foo.call($with, 22);',
  23041. '']));
  23042. end;
  23043. procedure TTestModule.TestRecordHelper_Constructor;
  23044. begin
  23045. StartProgram(false);
  23046. Add([
  23047. '{$modeswitch AdvancedRecords}',
  23048. 'type',
  23049. ' TRec = record',
  23050. ' constructor Create(w: word);',
  23051. ' end;',
  23052. ' THelper = record helper for TRec',
  23053. ' constructor NewHlp(w: word);',
  23054. ' end;',
  23055. 'var',
  23056. ' Rec: TRec;',
  23057. 'constructor TRec.Create(w: word);',
  23058. 'begin',
  23059. ' NewHlp(2);', // normal call
  23060. ' trec.NewHlp(3);', // new instance
  23061. 'end;',
  23062. 'constructor THelper.NewHlp(w: word);',
  23063. 'begin',
  23064. ' create(2);', // normal call
  23065. ' trec.create(3);', // new instance
  23066. ' NewHlp(4);', // normal call
  23067. ' trec.NewHlp(5);', // new instance
  23068. 'end;',
  23069. 'begin',
  23070. ' rec.newhlp(2);', // normal call
  23071. ' with rec do newhlp(12);', // normal call
  23072. ' trec.newhlp(3);', // new instance
  23073. ' with trec do newhlp(13);', // new instance
  23074. '']);
  23075. ConvertProgram;
  23076. CheckSource('TestRecordHelper_Constructor',
  23077. LinesToStr([ // statements
  23078. 'rtl.recNewT(this, "TRec", function () {',
  23079. ' this.$eq = function (b) {',
  23080. ' return true;',
  23081. ' };',
  23082. ' this.$assign = function (s) {',
  23083. ' return this;',
  23084. ' };',
  23085. ' this.Create = function (w) {',
  23086. ' $mod.THelper.NewHlp.call(this, 2);',
  23087. ' $mod.THelper.$new("NewHlp", [3]);',
  23088. ' return this;',
  23089. ' };',
  23090. '});',
  23091. 'rtl.createHelper(this, "THelper", null, function () {',
  23092. ' this.NewHlp = function (w) {',
  23093. ' this.Create(2);',
  23094. ' $mod.TRec.$new().Create(3);',
  23095. ' $mod.THelper.NewHlp.call(this, 4);',
  23096. ' $mod.THelper.$new("NewHlp", [5]);',
  23097. ' return this;',
  23098. ' };',
  23099. ' this.$new = function (fn, args) {',
  23100. ' return this[fn].apply($mod.TRec.$new(), args);',
  23101. ' };',
  23102. '});',
  23103. 'this.Rec = this.TRec.$new();',
  23104. '']),
  23105. LinesToStr([ // $mod.$main
  23106. '$mod.THelper.NewHlp.call($mod.Rec, 2);',
  23107. 'var $with = $mod.Rec;',
  23108. '$mod.THelper.NewHlp.call($with, 12);',
  23109. '$mod.THelper.$new("NewHlp", [3]);',
  23110. 'var $with1 = $mod.TRec;',
  23111. '$mod.THelper.$new("NewHlp", [13]);',
  23112. '']));
  23113. end;
  23114. procedure TTestModule.TestTypeHelper_ClassVar;
  23115. begin
  23116. StartProgram(false);
  23117. Add([
  23118. '{$modeswitch typehelpers}',
  23119. 'type',
  23120. ' THelper = type helper for byte',
  23121. ' const',
  23122. ' One = 1;',
  23123. ' Two: word = 2;',
  23124. ' class var',
  23125. ' Glob: word;',
  23126. ' function Foo(w: word): word;',
  23127. ' class function Bar(w: word): word; static;',
  23128. ' end;',
  23129. 'function THelper.foo(w: word): word;',
  23130. 'begin',
  23131. ' Result:=w;',
  23132. ' Two:=One+w;',
  23133. ' Glob:=Glob;',
  23134. ' Result:=Self.Glob;',
  23135. ' Self.Glob:=Self.Glob;',
  23136. ' with Self do Glob:=Glob;',
  23137. 'end;',
  23138. 'class function THelper.bar(w: word): word;',
  23139. 'begin',
  23140. ' Result:=w;',
  23141. ' Two:=One;',
  23142. ' Glob:=Glob;',
  23143. 'end;',
  23144. 'var b: byte;',
  23145. 'begin',
  23146. ' byte.two:=byte.one;',
  23147. ' byte.Glob:=byte.Glob;',
  23148. ' with byte do begin',
  23149. ' two:=one;',
  23150. ' Glob:=Glob;',
  23151. ' end;',
  23152. ' b.two:=b.one;',
  23153. ' b.Glob:=b.Glob;',
  23154. ' with b do begin',
  23155. ' two:=one;',
  23156. ' Glob:=Glob;',
  23157. ' end;',
  23158. '']);
  23159. ConvertProgram;
  23160. CheckSource('TestTypeHelper_ClassVar',
  23161. LinesToStr([ // statements
  23162. 'rtl.createHelper(this, "THelper", null, function () {',
  23163. ' this.One = 1;',
  23164. ' this.Two = 2;',
  23165. ' this.Glob = 0;',
  23166. ' this.Foo = function (w) {',
  23167. ' var Result = 0;',
  23168. ' Result = w;',
  23169. ' $mod.THelper.Two = 1 + w;',
  23170. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  23171. ' Result = $mod.THelper.Glob;',
  23172. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  23173. ' var $with = this.get();',
  23174. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  23175. ' return Result;',
  23176. ' };',
  23177. ' this.Bar = function (w) {',
  23178. ' var Result = 0;',
  23179. ' Result = w;',
  23180. ' $mod.THelper.Two = 1;',
  23181. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  23182. ' return Result;',
  23183. ' };',
  23184. '});',
  23185. 'this.b = 0;',
  23186. '']),
  23187. LinesToStr([ // $mod.$main
  23188. '$mod.THelper.Two = 1;',
  23189. '$mod.THelper.Glob = $mod.THelper.Glob;',
  23190. '$mod.THelper.Two = 1;',
  23191. '$mod.THelper.Glob = $mod.THelper.Glob;',
  23192. '$mod.THelper.Two = 1;',
  23193. '$mod.THelper.Glob = $mod.THelper.Glob;',
  23194. 'var $with = $mod.b;',
  23195. '$mod.THelper.Two = 1;',
  23196. '$mod.THelper.Glob = $mod.THelper.Glob;',
  23197. '']));
  23198. end;
  23199. procedure TTestModule.TestTypeHelper_PassResultElement;
  23200. begin
  23201. StartProgram(false);
  23202. Add([
  23203. '{$modeswitch typehelpers}',
  23204. 'type',
  23205. ' THelper = type helper for word',
  23206. ' procedure DoIt(e: byte = 123);',
  23207. ' class procedure DoSome(e: byte = 456); static;',
  23208. ' end;',
  23209. 'procedure THelper.DoIt(e: byte);',
  23210. 'begin',
  23211. 'end;',
  23212. 'class procedure THelper.DoSome(e: byte);',
  23213. 'begin',
  23214. 'end;',
  23215. 'function Foo(w: word): word;',
  23216. 'begin',
  23217. ' Result.DoIt;',
  23218. ' Result.DoIt();',
  23219. ' Result.DoSome;',
  23220. ' Result.DoSome();',
  23221. ' with Result do begin',
  23222. ' DoIt;',
  23223. ' DoIt();',
  23224. ' DoSome;',
  23225. ' DoSome();',
  23226. ' end;',
  23227. 'end;',
  23228. 'begin',
  23229. '']);
  23230. ConvertProgram;
  23231. CheckSource('TestTypeHelper_PassResultElement',
  23232. LinesToStr([ // statements
  23233. 'rtl.createHelper(this, "THelper", null, function () {',
  23234. ' this.DoIt = function (e) {',
  23235. ' };',
  23236. ' this.DoSome = function (e) {',
  23237. ' };',
  23238. '});',
  23239. 'this.Foo = function (w) {',
  23240. ' var Result = 0;',
  23241. ' $mod.THelper.DoIt.call({',
  23242. ' get: function () {',
  23243. ' return Result;',
  23244. ' },',
  23245. ' set: function (v) {',
  23246. ' Result = v;',
  23247. ' }',
  23248. ' }, 123);',
  23249. ' $mod.THelper.DoIt.call({',
  23250. ' get: function () {',
  23251. ' return Result;',
  23252. ' },',
  23253. ' set: function (v) {',
  23254. ' Result = v;',
  23255. ' }',
  23256. ' }, 123);',
  23257. ' $mod.THelper.DoSome(456);',
  23258. ' $mod.THelper.DoSome(456);',
  23259. ' $mod.THelper.DoIt.call({',
  23260. ' get: function () {',
  23261. ' return Result;',
  23262. ' },',
  23263. ' set: function (v) {',
  23264. ' Result = v;',
  23265. ' }',
  23266. ' }, 123);',
  23267. ' $mod.THelper.DoIt.call({',
  23268. ' get: function () {',
  23269. ' return Result;',
  23270. ' },',
  23271. ' set: function (v) {',
  23272. ' Result = v;',
  23273. ' }',
  23274. ' }, 123);',
  23275. ' $mod.THelper.DoSome(456);',
  23276. ' $mod.THelper.DoSome(456);',
  23277. ' return Result;',
  23278. '};',
  23279. '']),
  23280. LinesToStr([ // $mod.$main
  23281. '']));
  23282. end;
  23283. procedure TTestModule.TestTypeHelper_PassArgs;
  23284. begin
  23285. StartProgram(false);
  23286. Add([
  23287. '{$modeswitch typehelpers}',
  23288. 'type',
  23289. ' THelper = type helper for word',
  23290. ' procedure DoIt(e: byte = 123);',
  23291. ' end;',
  23292. 'procedure THelper.DoIt(e: byte);',
  23293. 'begin',
  23294. 'end;',
  23295. 'procedure FooDefault(a: word);',
  23296. 'begin',
  23297. ' a.DoIt;',
  23298. ' with a do DoIt;',
  23299. 'end;',
  23300. 'procedure FooConst(const a: word);',
  23301. 'begin',
  23302. ' a.DoIt;',
  23303. ' with a do DoIt;',
  23304. 'end;',
  23305. 'procedure FooVar(var a: word);',
  23306. 'begin',
  23307. ' a.DoIt;',
  23308. ' with a do DoIt;',
  23309. 'end;',
  23310. 'begin',
  23311. '']);
  23312. ConvertProgram;
  23313. CheckSource('TestTypeHelper_PassArgs',
  23314. LinesToStr([ // statements
  23315. 'rtl.createHelper(this, "THelper", null, function () {',
  23316. ' this.DoIt = function (e) {',
  23317. ' };',
  23318. '});',
  23319. 'this.FooDefault = function (a) {',
  23320. ' $mod.THelper.DoIt.call({',
  23321. ' get: function () {',
  23322. ' return a;',
  23323. ' },',
  23324. ' set: function (v) {',
  23325. ' a = v;',
  23326. ' }',
  23327. ' }, 123);',
  23328. ' $mod.THelper.DoIt.call({',
  23329. ' get: function () {',
  23330. ' return a;',
  23331. ' },',
  23332. ' set: function (v) {',
  23333. ' a = v;',
  23334. ' }',
  23335. ' }, 123);',
  23336. '};',
  23337. 'this.FooConst = function (a) {',
  23338. ' $mod.THelper.DoIt.call({',
  23339. ' get: function () {',
  23340. ' return a;',
  23341. ' },',
  23342. ' set: function (v) {',
  23343. ' rtl.raiseE("EPropReadOnly");',
  23344. ' }',
  23345. ' }, 123);',
  23346. ' $mod.THelper.DoIt.call({',
  23347. ' get: function () {',
  23348. ' return a;',
  23349. ' },',
  23350. ' set: function () {',
  23351. ' rtl.raiseE("EPropReadOnly");',
  23352. ' }',
  23353. ' }, 123);',
  23354. '};',
  23355. 'this.FooVar = function (a) {',
  23356. ' $mod.THelper.DoIt.call(a, 123);',
  23357. ' var $with = a.get();',
  23358. ' $mod.THelper.DoIt.call(a, 123);',
  23359. '};',
  23360. '']),
  23361. LinesToStr([ // $mod.$main
  23362. '']));
  23363. end;
  23364. procedure TTestModule.TestTypeHelper_PassVarConst;
  23365. begin
  23366. StartProgram(false);
  23367. Add([
  23368. '{$modeswitch typehelpers}',
  23369. 'type',
  23370. ' THelper = type helper for word',
  23371. ' procedure DoIt(e: byte = 123);',
  23372. ' end;',
  23373. 'procedure THelper.DoIt(e: byte);',
  23374. 'begin',
  23375. 'end;',
  23376. 'var a: word;',
  23377. 'const c: word = 2;',
  23378. '{$writeableconst off}',
  23379. 'const r: word = 3;',
  23380. 'begin',
  23381. ' a.DoIt;',
  23382. ' with a do DoIt;',
  23383. ' c.DoIt;',
  23384. ' with c do DoIt;',
  23385. ' r.DoIt;',
  23386. ' with r do DoIt;',
  23387. '']);
  23388. ConvertProgram;
  23389. CheckSource('TestTypeHelper_PassVarConst',
  23390. LinesToStr([ // statements
  23391. 'rtl.createHelper(this, "THelper", null, function () {',
  23392. ' this.DoIt = function (e) {',
  23393. ' };',
  23394. '});',
  23395. 'this.a = 0;',
  23396. 'this.c = 2;',
  23397. 'this.r = 3;',
  23398. '']),
  23399. LinesToStr([ // $mod.$main
  23400. '$mod.THelper.DoIt.call({',
  23401. ' p: $mod,',
  23402. ' get: function () {',
  23403. ' return this.p.a;',
  23404. ' },',
  23405. ' set: function (v) {',
  23406. ' this.p.a = v;',
  23407. ' }',
  23408. '}, 123);',
  23409. 'var $with = $mod.a;',
  23410. '$mod.THelper.DoIt.call({',
  23411. ' get: function () {',
  23412. ' return $with;',
  23413. ' },',
  23414. ' set: function (v) {',
  23415. ' $with = v;',
  23416. ' }',
  23417. '}, 123);',
  23418. '$mod.THelper.DoIt.call({',
  23419. ' p: $mod,',
  23420. ' get: function () {',
  23421. ' return this.p.c;',
  23422. ' },',
  23423. ' set: function (v) {',
  23424. ' this.p.c = v;',
  23425. ' }',
  23426. '}, 123);',
  23427. 'var $with1 = $mod.c;',
  23428. '$mod.THelper.DoIt.call({',
  23429. ' get: function () {',
  23430. ' return $with1;',
  23431. ' },',
  23432. ' set: function (v) {',
  23433. ' $with1 = v;',
  23434. ' }',
  23435. '}, 123);',
  23436. '$mod.THelper.DoIt.call({',
  23437. ' get: function () {',
  23438. ' return 3;',
  23439. ' },',
  23440. ' set: function (v) {',
  23441. ' rtl.raiseE("EPropReadOnly");',
  23442. ' }',
  23443. '}, 123);',
  23444. 'var $with2 = 3;',
  23445. ' $mod.THelper.DoIt.call({',
  23446. ' get: function () {',
  23447. ' return $with2;',
  23448. ' },',
  23449. ' set: function () {',
  23450. ' rtl.raiseE("EPropReadOnly");',
  23451. ' }',
  23452. ' }, 123);',
  23453. '']));
  23454. end;
  23455. procedure TTestModule.TestTypeHelper_PassFuncResult;
  23456. begin
  23457. StartProgram(false);
  23458. Add([
  23459. '{$modeswitch typehelpers}',
  23460. 'type',
  23461. ' THelper = type helper for word',
  23462. ' procedure DoIt(e: byte = 123);',
  23463. ' end;',
  23464. 'procedure THelper.DoIt(e: byte);',
  23465. 'begin',
  23466. 'end;',
  23467. 'function Foo(b: byte = 1): word;',
  23468. 'begin',
  23469. 'end;',
  23470. 'begin',
  23471. ' Foo.DoIt;',
  23472. ' Foo().DoIt;',
  23473. ' with Foo do DoIt;',
  23474. ' with Foo() do DoIt;',
  23475. '']);
  23476. ConvertProgram;
  23477. CheckSource('TestTypeHelper_PassFuncResult',
  23478. LinesToStr([ // statements
  23479. 'rtl.createHelper(this, "THelper", null, function () {',
  23480. ' this.DoIt = function (e) {',
  23481. ' };',
  23482. '});',
  23483. 'this.Foo = function (b) {',
  23484. ' var Result = 0;',
  23485. ' return Result;',
  23486. '};',
  23487. '']),
  23488. LinesToStr([ // $mod.$main
  23489. '$mod.THelper.DoIt.call({',
  23490. ' a: $mod.Foo(1),',
  23491. ' get: function () {',
  23492. ' return this.a;',
  23493. ' },',
  23494. ' set: function (v) {',
  23495. ' this.a = v;',
  23496. ' }',
  23497. '}, 123);',
  23498. '$mod.THelper.DoIt.call({',
  23499. ' a: $mod.Foo(1),',
  23500. ' get: function () {',
  23501. ' return this.a;',
  23502. ' },',
  23503. ' set: function (v) {',
  23504. ' this.a = v;',
  23505. ' }',
  23506. '}, 123);',
  23507. 'var $with = $mod.Foo(1);',
  23508. '$mod.THelper.DoIt.call({',
  23509. ' get: function () {',
  23510. ' return $with;',
  23511. ' },',
  23512. ' set: function (v) {',
  23513. ' $with = v;',
  23514. ' }',
  23515. '}, 123);',
  23516. 'var $with1 = $mod.Foo(1);',
  23517. '$mod.THelper.DoIt.call({',
  23518. ' get: function () {',
  23519. ' return $with1;',
  23520. ' },',
  23521. ' set: function (v) {',
  23522. ' $with1 = v;',
  23523. ' }',
  23524. '}, 123);',
  23525. '']));
  23526. end;
  23527. procedure TTestModule.TestTypeHelper_PassPropertyField;
  23528. begin
  23529. StartProgram(false);
  23530. Add([
  23531. '{$modeswitch typehelpers}',
  23532. 'type',
  23533. ' TObject = class',
  23534. ' FField: word;',
  23535. ' procedure SetField(Value: word);',
  23536. ' property Field: word read FField write SetField;',
  23537. ' end;',
  23538. ' THelper = type helper for word',
  23539. ' procedure Fly;',
  23540. ' class procedure Run; static;',
  23541. ' end;',
  23542. 'procedure TObject.SetField(Value: word);',
  23543. 'begin',
  23544. ' Field.Fly;',
  23545. ' Field.Run;',
  23546. ' Self.Field.Fly;',
  23547. ' Self.Field.Run;',
  23548. ' with Self do begin',
  23549. ' Field.Fly;',
  23550. ' Field.Run;',
  23551. ' end;',
  23552. ' with Self.Field do begin',
  23553. ' Fly;',
  23554. ' Run;',
  23555. ' end;',
  23556. 'end;',
  23557. 'procedure THelper.Fly;',
  23558. 'begin',
  23559. 'end;',
  23560. 'class procedure THelper.Run;',
  23561. 'begin',
  23562. 'end;',
  23563. 'var',
  23564. ' o: TObject;',
  23565. 'begin',
  23566. ' o.Field.Fly;',
  23567. ' o.Field.Run;',
  23568. ' with o do begin',
  23569. ' Field.Fly;',
  23570. ' Field.Run;',
  23571. ' end;',
  23572. ' with o.Field do begin',
  23573. ' Fly;',
  23574. ' Run;',
  23575. ' end;',
  23576. '']);
  23577. ConvertProgram;
  23578. CheckSource('TestTypeHelper_PassPropertyField',
  23579. LinesToStr([ // statements
  23580. 'rtl.createClass(this, "TObject", null, function () {',
  23581. ' this.$init = function () {',
  23582. ' this.FField = 0;',
  23583. ' };',
  23584. ' this.$final = function () {',
  23585. ' };',
  23586. ' this.SetField = function (Value) {',
  23587. ' $mod.THelper.Fly.call({',
  23588. ' p: this,',
  23589. ' get: function () {',
  23590. ' return this.p.FField;',
  23591. ' },',
  23592. ' set: function (v) {',
  23593. ' this.p.FField = v;',
  23594. ' }',
  23595. ' });',
  23596. ' $mod.THelper.Run();',
  23597. ' $mod.THelper.Fly.call({',
  23598. ' p: this,',
  23599. ' get: function () {',
  23600. ' return this.p.FField;',
  23601. ' },',
  23602. ' set: function (v) {',
  23603. ' this.p.FField = v;',
  23604. ' }',
  23605. ' });',
  23606. ' $mod.THelper.Run();',
  23607. ' $mod.THelper.Fly.call({',
  23608. ' p: this,',
  23609. ' get: function () {',
  23610. ' return this.p.FField;',
  23611. ' },',
  23612. ' set: function (v) {',
  23613. ' this.p.FField = v;',
  23614. ' }',
  23615. ' });',
  23616. ' $mod.THelper.Run();',
  23617. ' var $with = this.FField;',
  23618. ' $mod.THelper.Fly.call({',
  23619. ' get: function () {',
  23620. ' return $with;',
  23621. ' },',
  23622. ' set: function (v) {',
  23623. ' $with = v;',
  23624. ' }',
  23625. ' });',
  23626. ' $mod.THelper.Run();',
  23627. ' };',
  23628. '});',
  23629. 'rtl.createHelper(this, "THelper", null, function () {',
  23630. ' this.Fly = function () {',
  23631. ' };',
  23632. ' this.Run = function () {',
  23633. ' };',
  23634. '});',
  23635. 'this.o = null;',
  23636. '']),
  23637. LinesToStr([ // $mod.$main
  23638. '$mod.THelper.Fly.call({',
  23639. ' p: $mod.o,',
  23640. ' get: function () {',
  23641. ' return this.p.FField;',
  23642. ' },',
  23643. ' set: function (v) {',
  23644. ' this.p.FField = v;',
  23645. ' }',
  23646. '});',
  23647. '$mod.THelper.Run();',
  23648. 'var $with = $mod.o;',
  23649. '$mod.THelper.Fly.call({',
  23650. ' p: $with,',
  23651. ' get: function () {',
  23652. ' return this.p.FField;',
  23653. ' },',
  23654. ' set: function (v) {',
  23655. ' this.p.FField = v;',
  23656. ' }',
  23657. '});',
  23658. '$mod.THelper.Run();',
  23659. 'var $with1 = $mod.o.FField;',
  23660. '$mod.THelper.Fly.call({',
  23661. ' get: function () {',
  23662. ' return $with1;',
  23663. ' },',
  23664. ' set: function (v) {',
  23665. ' $with1 = v;',
  23666. ' }',
  23667. '});',
  23668. '$mod.THelper.Run();',
  23669. '']));
  23670. end;
  23671. procedure TTestModule.TestTypeHelper_PassPropertyGetter;
  23672. begin
  23673. StartProgram(false);
  23674. Add([
  23675. '{$modeswitch typehelpers}',
  23676. 'type',
  23677. ' TObject = class',
  23678. ' FField: word;',
  23679. ' function GetField: word;',
  23680. ' property Field: word read GetField write FField;',
  23681. ' end;',
  23682. ' THelper = type helper for word',
  23683. ' procedure Fly;',
  23684. ' class procedure Run; static;',
  23685. ' end;',
  23686. 'function TObject.GetField: word;',
  23687. 'begin',
  23688. ' Field.Fly;',
  23689. ' Field.Run;',
  23690. ' Self.Field.Fly;',
  23691. ' Self.Field.Run;',
  23692. ' with Self do begin',
  23693. ' Field.Fly;',
  23694. ' Field.Run;',
  23695. ' end;',
  23696. ' with Self.Field do begin',
  23697. ' Fly;',
  23698. ' Run;',
  23699. ' end;',
  23700. 'end;',
  23701. 'procedure THelper.Fly;',
  23702. 'begin',
  23703. 'end;',
  23704. 'class procedure THelper.Run;',
  23705. 'begin',
  23706. 'end;',
  23707. 'var',
  23708. ' o: TObject;',
  23709. 'begin',
  23710. ' o.Field.Fly;',
  23711. ' o.Field.Run;',
  23712. ' with o do begin',
  23713. ' Field.Fly;',
  23714. ' Field.Run;',
  23715. ' end;',
  23716. ' with o.Field do begin',
  23717. ' Fly;',
  23718. ' Run;',
  23719. ' end;',
  23720. '']);
  23721. ConvertProgram;
  23722. CheckSource('TestTypeHelper_PassPropertyGetter',
  23723. LinesToStr([ // statements
  23724. 'rtl.createClass(this, "TObject", null, function () {',
  23725. ' this.$init = function () {',
  23726. ' this.FField = 0;',
  23727. ' };',
  23728. ' this.$final = function () {',
  23729. ' };',
  23730. ' this.GetField = function () {',
  23731. ' var Result = 0;',
  23732. ' $mod.THelper.Fly.call({',
  23733. ' p: this.GetField(),',
  23734. ' get: function () {',
  23735. ' return this.p;',
  23736. ' },',
  23737. ' set: function (v) {',
  23738. ' this.p = v;',
  23739. ' }',
  23740. ' });',
  23741. ' $mod.THelper.Run();',
  23742. ' $mod.THelper.Fly.call({',
  23743. ' p: this.GetField(),',
  23744. ' get: function () {',
  23745. ' return this.p;',
  23746. ' },',
  23747. ' set: function (v) {',
  23748. ' this.p = v;',
  23749. ' }',
  23750. ' });',
  23751. ' $mod.THelper.Run();',
  23752. ' $mod.THelper.Fly.call({',
  23753. ' p: this.GetField(),',
  23754. ' get: function () {',
  23755. ' return this.p;',
  23756. ' },',
  23757. ' set: function (v) {',
  23758. ' this.p = v;',
  23759. ' }',
  23760. ' });',
  23761. ' $mod.THelper.Run();',
  23762. ' var $with = this.GetField();',
  23763. ' $mod.THelper.Fly.call({',
  23764. ' get: function () {',
  23765. ' return $with;',
  23766. ' },',
  23767. ' set: function (v) {',
  23768. ' $with = v;',
  23769. ' }',
  23770. ' });',
  23771. ' $mod.THelper.Run();',
  23772. ' return Result;',
  23773. ' };',
  23774. '});',
  23775. 'rtl.createHelper(this, "THelper", null, function () {',
  23776. ' this.Fly = function () {',
  23777. ' };',
  23778. ' this.Run = function () {',
  23779. ' };',
  23780. '});',
  23781. 'this.o = null;',
  23782. '']),
  23783. LinesToStr([ // $mod.$main
  23784. '$mod.THelper.Fly.call({',
  23785. ' p: $mod.o.GetField(),',
  23786. ' get: function () {',
  23787. ' return this.p;',
  23788. ' },',
  23789. ' set: function (v) {',
  23790. ' this.p = v;',
  23791. ' }',
  23792. '});',
  23793. '$mod.THelper.Run();',
  23794. 'var $with = $mod.o;',
  23795. '$mod.THelper.Fly.call({',
  23796. ' p: $with.GetField(),',
  23797. ' get: function () {',
  23798. ' return this.p;',
  23799. ' },',
  23800. ' set: function (v) {',
  23801. ' this.p = v;',
  23802. ' }',
  23803. '});',
  23804. '$mod.THelper.Run();',
  23805. 'var $with1 = $mod.o.GetField();',
  23806. '$mod.THelper.Fly.call({',
  23807. ' get: function () {',
  23808. ' return $with1;',
  23809. ' },',
  23810. ' set: function (v) {',
  23811. ' $with1 = v;',
  23812. ' }',
  23813. '});',
  23814. '$mod.THelper.Run();',
  23815. '']));
  23816. end;
  23817. procedure TTestModule.TestTypeHelper_PassClassPropertyField;
  23818. begin
  23819. StartProgram(false);
  23820. Add([
  23821. '{$modeswitch typehelpers}',
  23822. 'type',
  23823. ' TObject = class',
  23824. ' class var FField: word;',
  23825. ' class procedure SetField(Value: word);',
  23826. ' class property Field: word read FField write SetField;',
  23827. ' end;',
  23828. ' THelper = type helper for word',
  23829. ' procedure Fly(n: byte);',
  23830. ' end;',
  23831. 'class procedure TObject.SetField(Value: word);',
  23832. 'begin',
  23833. ' Field.Fly(1);',
  23834. ' Self.Field.Fly(2);',
  23835. ' with Self do Field.Fly(3);',
  23836. ' with Self.Field do Fly(4);',
  23837. ' TObject.Field.Fly(5);',
  23838. ' with TObject do Field.Fly(6);',
  23839. ' with TObject.Field do Fly(7);',
  23840. 'end;',
  23841. 'procedure THelper.Fly(n: byte);',
  23842. 'begin',
  23843. 'end;',
  23844. 'var',
  23845. ' o: TObject;',
  23846. 'begin',
  23847. ' o.Field.Fly(11);',
  23848. ' with o do Field.Fly(12);',
  23849. ' with o.Field do Fly(13);',
  23850. ' TObject.Field.Fly(14);',
  23851. ' with TObject do Field.Fly(15);',
  23852. ' with TObject.Field do Fly(16);',
  23853. '']);
  23854. ConvertProgram;
  23855. CheckSource('TestTypeHelper_PassClassPropertyField',
  23856. LinesToStr([ // statements
  23857. 'rtl.createClass(this, "TObject", null, function () {',
  23858. ' this.FField = 0;',
  23859. ' this.$init = function () {',
  23860. ' };',
  23861. ' this.$final = function () {',
  23862. ' };',
  23863. ' this.SetField = function (Value) {',
  23864. ' $mod.THelper.Fly.call({',
  23865. ' p: this,',
  23866. ' get: function () {',
  23867. ' return this.p.FField;',
  23868. ' },',
  23869. ' set: function (v) {',
  23870. ' $mod.TObject.FField = v;',
  23871. ' }',
  23872. ' }, 1);',
  23873. ' $mod.THelper.Fly.call({',
  23874. ' p: this,',
  23875. ' get: function () {',
  23876. ' return this.p.FField;',
  23877. ' },',
  23878. ' set: function (v) {',
  23879. ' $mod.TObject.FField = v;',
  23880. ' }',
  23881. ' }, 2);',
  23882. ' $mod.THelper.Fly.call({',
  23883. ' p: this,',
  23884. ' get: function () {',
  23885. ' return this.p.FField;',
  23886. ' },',
  23887. ' set: function (v) {',
  23888. ' $mod.TObject.FField = v;',
  23889. ' }',
  23890. ' }, 3);',
  23891. ' var $with = this.FField;',
  23892. ' $mod.THelper.Fly.call({',
  23893. ' get: function () {',
  23894. ' return $with;',
  23895. ' },',
  23896. ' set: function (v) {',
  23897. ' $with = v;',
  23898. ' }',
  23899. ' }, 4);',
  23900. ' $mod.THelper.Fly.call({',
  23901. ' p: $mod.TObject,',
  23902. ' get: function () {',
  23903. ' return this.p.FField;',
  23904. ' },',
  23905. ' set: function (v) {',
  23906. ' $mod.TObject.FField = v;',
  23907. ' }',
  23908. ' }, 5);',
  23909. ' var $with1 = $mod.TObject;',
  23910. ' $mod.THelper.Fly.call({',
  23911. ' p: $with1,',
  23912. ' get: function () {',
  23913. ' return this.p.FField;',
  23914. ' },',
  23915. ' set: function (v) {',
  23916. ' $mod.TObject.FField = v;',
  23917. ' }',
  23918. ' }, 6);',
  23919. ' var $with2 = $mod.TObject.FField;',
  23920. ' $mod.THelper.Fly.call({',
  23921. ' get: function () {',
  23922. ' return $with2;',
  23923. ' },',
  23924. ' set: function (v) {',
  23925. ' $with2 = v;',
  23926. ' }',
  23927. ' }, 7);',
  23928. ' };',
  23929. '});',
  23930. 'rtl.createHelper(this, "THelper", null, function () {',
  23931. ' this.Fly = function (n) {',
  23932. ' };',
  23933. '});',
  23934. 'this.o = null;',
  23935. '']),
  23936. LinesToStr([ // $mod.$main
  23937. '$mod.THelper.Fly.call({',
  23938. ' p: $mod.o,',
  23939. ' get: function () {',
  23940. ' return this.p.FField;',
  23941. ' },',
  23942. ' set: function (v) {',
  23943. ' $mod.TObject.FField = v;',
  23944. ' }',
  23945. '}, 11);',
  23946. 'var $with = $mod.o;',
  23947. '$mod.THelper.Fly.call({',
  23948. ' p: $with,',
  23949. ' get: function () {',
  23950. ' return this.p.FField;',
  23951. ' },',
  23952. ' set: function (v) {',
  23953. ' $mod.TObject.FField = v;',
  23954. ' }',
  23955. '}, 12);',
  23956. 'var $with1 = $mod.o.FField;',
  23957. '$mod.THelper.Fly.call({',
  23958. ' get: function () {',
  23959. ' return $with1;',
  23960. ' },',
  23961. ' set: function (v) {',
  23962. ' $with1 = v;',
  23963. ' }',
  23964. '}, 13);',
  23965. '$mod.THelper.Fly.call({',
  23966. ' p: $mod.TObject,',
  23967. ' get: function () {',
  23968. ' return this.p.FField;',
  23969. ' },',
  23970. ' set: function (v) {',
  23971. ' $mod.TObject.FField = v;',
  23972. ' }',
  23973. '}, 14);',
  23974. 'var $with2 = $mod.TObject;',
  23975. '$mod.THelper.Fly.call({',
  23976. ' p: $with2,',
  23977. ' get: function () {',
  23978. ' return this.p.FField;',
  23979. ' },',
  23980. ' set: function (v) {',
  23981. ' $mod.TObject.FField = v;',
  23982. ' }',
  23983. '}, 15);',
  23984. 'var $with3 = $mod.TObject.FField;',
  23985. '$mod.THelper.Fly.call({',
  23986. ' get: function () {',
  23987. ' return $with3;',
  23988. ' },',
  23989. ' set: function (v) {',
  23990. ' $with3 = v;',
  23991. ' }',
  23992. '}, 16);',
  23993. '']));
  23994. end;
  23995. procedure TTestModule.TestTypeHelper_PassClassPropertyGetterStatic;
  23996. begin
  23997. StartProgram(false);
  23998. Add([
  23999. '{$modeswitch typehelpers}',
  24000. 'type',
  24001. ' TObject = class',
  24002. ' class var FField: word;',
  24003. ' class function GetField: word; static;',
  24004. ' class property Field: word read GetField write FField;',
  24005. ' end;',
  24006. ' THelper = type helper for word',
  24007. ' procedure Fly(n: byte);',
  24008. ' end;',
  24009. 'class function TObject.GetField: word;',
  24010. 'begin',
  24011. ' Field.Fly(1);',
  24012. ' TObject.Field.Fly(5);',
  24013. ' with TObject do Field.Fly(6);',
  24014. ' with TObject.Field do Fly(7);',
  24015. 'end;',
  24016. 'procedure THelper.Fly(n: byte);',
  24017. 'begin',
  24018. 'end;',
  24019. 'var',
  24020. ' o: TObject;',
  24021. 'begin',
  24022. ' o.Field.Fly(11);',
  24023. ' with o do Field.Fly(12);',
  24024. ' with o.Field do Fly(13);',
  24025. '']);
  24026. ConvertProgram;
  24027. CheckSource('TestTypeHelper_PassClassPropertyGetterStatic',
  24028. LinesToStr([ // statements
  24029. 'rtl.createClass(this, "TObject", null, function () {',
  24030. ' this.FField = 0;',
  24031. ' this.$init = function () {',
  24032. ' };',
  24033. ' this.$final = function () {',
  24034. ' };',
  24035. ' this.GetField = function () {',
  24036. ' var Result = 0;',
  24037. ' $mod.THelper.Fly.call({',
  24038. ' p: $mod.TObject.GetField(),',
  24039. ' get: function () {',
  24040. ' return this.p;',
  24041. ' },',
  24042. ' set: function (v) {',
  24043. ' this.p = v;',
  24044. ' }',
  24045. ' }, 1);',
  24046. ' $mod.THelper.Fly.call({',
  24047. ' p: $mod.TObject.GetField(),',
  24048. ' get: function () {',
  24049. ' return this.p;',
  24050. ' },',
  24051. ' set: function (v) {',
  24052. ' this.p = v;',
  24053. ' }',
  24054. ' }, 5);',
  24055. ' var $with = $mod.TObject;',
  24056. ' $mod.THelper.Fly.call({',
  24057. ' p: $with.GetField(),',
  24058. ' get: function () {',
  24059. ' return this.p;',
  24060. ' },',
  24061. ' set: function (v) {',
  24062. ' this.p = v;',
  24063. ' }',
  24064. ' }, 6);',
  24065. ' var $with1 = $mod.TObject.GetField();',
  24066. ' $mod.THelper.Fly.call({',
  24067. ' get: function () {',
  24068. ' return $with1;',
  24069. ' },',
  24070. ' set: function (v) {',
  24071. ' $with1 = v;',
  24072. ' }',
  24073. ' }, 7);',
  24074. ' return Result;',
  24075. ' };',
  24076. '});',
  24077. 'rtl.createHelper(this, "THelper", null, function () {',
  24078. ' this.Fly = function (n) {',
  24079. ' };',
  24080. '});',
  24081. 'this.o = null;',
  24082. '']),
  24083. LinesToStr([ // $mod.$main
  24084. '$mod.THelper.Fly.call({',
  24085. ' p: $mod.TObject.GetField(),',
  24086. ' get: function () {',
  24087. ' return this.p;',
  24088. ' },',
  24089. ' set: function (v) {',
  24090. ' this.p = v;',
  24091. ' }',
  24092. '}, 11);',
  24093. 'var $with = $mod.o;',
  24094. '$mod.THelper.Fly.call({',
  24095. ' p: $with.GetField(),',
  24096. ' get: function () {',
  24097. ' return this.p;',
  24098. ' },',
  24099. ' set: function (v) {',
  24100. ' this.p = v;',
  24101. ' }',
  24102. '}, 12);',
  24103. 'var $with1 = $mod.TObject.GetField();',
  24104. '$mod.THelper.Fly.call({',
  24105. ' get: function () {',
  24106. ' return $with1;',
  24107. ' },',
  24108. ' set: function (v) {',
  24109. ' $with1 = v;',
  24110. ' }',
  24111. '}, 13);',
  24112. '']));
  24113. end;
  24114. procedure TTestModule.TestTypeHelper_PassClassPropertyGetterNonStatic;
  24115. begin
  24116. StartProgram(false);
  24117. Add([
  24118. '{$modeswitch typehelpers}',
  24119. 'type',
  24120. ' TObject = class',
  24121. ' class var FField: word;',
  24122. ' class function GetField: word;',
  24123. ' class property Field: word read GetField write FField;',
  24124. ' end;',
  24125. ' TClass = class of TObject;',
  24126. ' THelper = type helper for word',
  24127. ' procedure Fly(n: byte);',
  24128. ' end;',
  24129. 'class function TObject.GetField: word;',
  24130. 'begin',
  24131. ' Field.Fly(1);',
  24132. ' Self.Field.Fly(5);',
  24133. ' with Self do Field.Fly(6);',
  24134. ' with Self.Field do Fly(7);',
  24135. 'end;',
  24136. 'procedure THelper.Fly(n: byte);',
  24137. 'begin',
  24138. 'end;',
  24139. 'var',
  24140. ' o: TObject;',
  24141. ' c: TClass;',
  24142. 'begin',
  24143. ' o.Field.Fly(11);',
  24144. ' with o do Field.Fly(12);',
  24145. ' with o.Field do Fly(13);',
  24146. ' c.Field.Fly(14);',
  24147. ' with c do Field.Fly(15);',
  24148. ' with c.Field do Fly(16);',
  24149. '']);
  24150. ConvertProgram;
  24151. CheckSource('TestTypeHelper_PassClassPropertyGetterNonStatic',
  24152. LinesToStr([ // statements
  24153. 'rtl.createClass(this, "TObject", null, function () {',
  24154. ' this.FField = 0;',
  24155. ' this.$init = function () {',
  24156. ' };',
  24157. ' this.$final = function () {',
  24158. ' };',
  24159. ' this.GetField = function () {',
  24160. ' var Result = 0;',
  24161. ' $mod.THelper.Fly.call({',
  24162. ' p: this.GetField(),',
  24163. ' get: function () {',
  24164. ' return this.p;',
  24165. ' },',
  24166. ' set: function (v) {',
  24167. ' this.p = v;',
  24168. ' }',
  24169. ' }, 1);',
  24170. ' $mod.THelper.Fly.call({',
  24171. ' p: this.GetField(),',
  24172. ' get: function () {',
  24173. ' return this.p;',
  24174. ' },',
  24175. ' set: function (v) {',
  24176. ' this.p = v;',
  24177. ' }',
  24178. ' }, 5);',
  24179. ' $mod.THelper.Fly.call({',
  24180. ' p: this.GetField(),',
  24181. ' get: function () {',
  24182. ' return this.p;',
  24183. ' },',
  24184. ' set: function (v) {',
  24185. ' this.p = v;',
  24186. ' }',
  24187. ' }, 6);',
  24188. ' var $with = this.GetField();',
  24189. ' $mod.THelper.Fly.call({',
  24190. ' get: function () {',
  24191. ' return $with;',
  24192. ' },',
  24193. ' set: function (v) {',
  24194. ' $with = v;',
  24195. ' }',
  24196. ' }, 7);',
  24197. ' return Result;',
  24198. ' };',
  24199. '});',
  24200. 'rtl.createHelper(this, "THelper", null, function () {',
  24201. ' this.Fly = function (n) {',
  24202. ' };',
  24203. '});',
  24204. 'this.o = null;',
  24205. 'this.c = null;',
  24206. '']),
  24207. LinesToStr([ // $mod.$main
  24208. '$mod.THelper.Fly.call({',
  24209. ' p: $mod.o.$class.GetField(),',
  24210. ' get: function () {',
  24211. ' return this.p;',
  24212. ' },',
  24213. ' set: function (v) {',
  24214. ' this.p = v;',
  24215. ' }',
  24216. '}, 11);',
  24217. 'var $with = $mod.o;',
  24218. '$mod.THelper.Fly.call({',
  24219. ' p: $with.$class.GetField(),',
  24220. ' get: function () {',
  24221. ' return this.p;',
  24222. ' },',
  24223. ' set: function (v) {',
  24224. ' this.p = v;',
  24225. ' }',
  24226. '}, 12);',
  24227. 'var $with1 = $mod.o.$class.GetField();',
  24228. '$mod.THelper.Fly.call({',
  24229. ' get: function () {',
  24230. ' return $with1;',
  24231. ' },',
  24232. ' set: function (v) {',
  24233. ' $with1 = v;',
  24234. ' }',
  24235. '}, 13);',
  24236. '$mod.THelper.Fly.call({',
  24237. ' p: $mod.c.GetField(),',
  24238. ' get: function () {',
  24239. ' return this.p;',
  24240. ' },',
  24241. ' set: function (v) {',
  24242. ' this.p = v;',
  24243. ' }',
  24244. '}, 14);',
  24245. 'var $with2 = $mod.c;',
  24246. '$mod.THelper.Fly.call({',
  24247. ' p: $with2.GetField(),',
  24248. ' get: function () {',
  24249. ' return this.p;',
  24250. ' },',
  24251. ' set: function (v) {',
  24252. ' this.p = v;',
  24253. ' }',
  24254. '}, 15);',
  24255. 'var $with3 = $mod.c.GetField();',
  24256. '$mod.THelper.Fly.call({',
  24257. ' get: function () {',
  24258. ' return $with3;',
  24259. ' },',
  24260. ' set: function (v) {',
  24261. ' $with3 = v;',
  24262. ' }',
  24263. '}, 16);',
  24264. '']));
  24265. end;
  24266. procedure TTestModule.TestTypeHelper_Property;
  24267. begin
  24268. StartProgram(false);
  24269. Add([
  24270. '{$modeswitch typehelpers}',
  24271. 'type',
  24272. ' THelper = type helper for word',
  24273. ' function GetSize: longint;',
  24274. ' procedure SetSize(Value: longint);',
  24275. ' property Size: longint read GetSize write SetSize;',
  24276. ' end;',
  24277. 'function THelper.GetSize: longint;',
  24278. 'begin',
  24279. ' Result:=Size+1;',
  24280. ' Size:=2;',
  24281. ' Result:=Self.Size+3;',
  24282. ' Self.Size:=4;',
  24283. ' with Self do begin',
  24284. ' Result:=Size+5;',
  24285. ' Size:=6;',
  24286. ' end;',
  24287. 'end;',
  24288. 'procedure THelper.SetSize(Value: longint);',
  24289. 'begin',
  24290. 'end;',
  24291. 'var w: word;',
  24292. 'begin',
  24293. ' w:=w.Size+7;',
  24294. ' w.Size:=w+8;',
  24295. ' with w do begin',
  24296. ' w:=Size+9;',
  24297. ' Size:=w+10;',
  24298. ' end;',
  24299. '']);
  24300. ConvertProgram;
  24301. CheckSource('TestTypeHelper_Property',
  24302. LinesToStr([ // statements
  24303. 'rtl.createHelper(this, "THelper", null, function () {',
  24304. ' this.GetSize = function () {',
  24305. ' var Result = 0;',
  24306. ' Result = $mod.THelper.GetSize.call(this) + 1;',
  24307. ' $mod.THelper.SetSize.call(this, 2);',
  24308. ' Result = $mod.THelper.GetSize.call(this) + 3;',
  24309. ' $mod.THelper.SetSize.call(this, 4);',
  24310. ' var $with = this.get();',
  24311. ' Result = $mod.THelper.GetSize.call(this) + 5;',
  24312. ' $mod.THelper.SetSize.call(this, 6);',
  24313. ' return Result;',
  24314. ' };',
  24315. ' this.SetSize = function (Value) {',
  24316. ' };',
  24317. '});',
  24318. 'this.w = 0;',
  24319. '']),
  24320. LinesToStr([ // $mod.$main
  24321. '$mod.w = $mod.THelper.GetSize.call({',
  24322. ' p: $mod,',
  24323. ' get: function () {',
  24324. ' return this.p.w;',
  24325. ' },',
  24326. ' set: function (v) {',
  24327. ' this.p.w = v;',
  24328. ' }',
  24329. '}) + 7;',
  24330. '$mod.THelper.SetSize.call({',
  24331. ' p: $mod,',
  24332. ' get: function () {',
  24333. ' return this.p.w;',
  24334. ' },',
  24335. ' set: function (v) {',
  24336. ' this.p.w = v;',
  24337. ' }',
  24338. '}, $mod.w + 8);',
  24339. 'var $with = $mod.w;',
  24340. '$mod.w = $mod.THelper.GetSize.call({',
  24341. ' get: function () {',
  24342. ' return $with;',
  24343. ' },',
  24344. ' set: function (v) {',
  24345. ' $with = v;',
  24346. ' }',
  24347. '}) + 9;',
  24348. '$mod.THelper.SetSize.call({',
  24349. ' get: function () {',
  24350. ' return $with;',
  24351. ' },',
  24352. ' set: function (v) {',
  24353. ' $with = v;',
  24354. ' }',
  24355. '}, $mod.w + 10);',
  24356. '']));
  24357. end;
  24358. procedure TTestModule.TestTypeHelper_Property_Array;
  24359. begin
  24360. StartProgram(false);
  24361. Add([
  24362. '{$modeswitch typehelpers}',
  24363. 'type',
  24364. ' THelper = type helper for word',
  24365. ' function GetItems(Index: byte): boolean;',
  24366. ' procedure SetItems(Index: byte; Value: boolean);',
  24367. ' property Items[Index: byte]: boolean read GetItems write SetItems;',
  24368. ' end;',
  24369. 'function THelper.GetItems(Index: byte): boolean;',
  24370. 'begin',
  24371. ' Result:=Items[1];',
  24372. ' Items[2]:=false;',
  24373. ' Result:=Self.Items[3];',
  24374. ' Self.Items[4]:=true;',
  24375. ' with Self do begin',
  24376. ' Result:=Items[5];',
  24377. ' Items[6]:=false;',
  24378. ' end;',
  24379. 'end;',
  24380. 'procedure THelper.SetItems(Index: byte; Value: boolean);',
  24381. 'begin',
  24382. 'end;',
  24383. 'var',
  24384. ' w: word;',
  24385. ' b: boolean;',
  24386. 'begin',
  24387. ' b:=w.Items[1];',
  24388. ' w.Items[2]:=b;',
  24389. ' with w do begin',
  24390. ' b:=Items[3];',
  24391. ' Items[4]:=b;',
  24392. ' end;',
  24393. '']);
  24394. ConvertProgram;
  24395. CheckSource('TestTypeHelper_Property_Array',
  24396. LinesToStr([ // statements
  24397. 'rtl.createHelper(this, "THelper", null, function () {',
  24398. ' this.GetItems = function (Index) {',
  24399. ' var Result = false;',
  24400. ' Result = $mod.THelper.GetItems.call(this, 1);',
  24401. ' $mod.THelper.SetItems.call(this, 2, false);',
  24402. ' Result = $mod.THelper.GetItems.call(this, 3);',
  24403. ' $mod.THelper.SetItems.call(this, 4, true);',
  24404. ' var $with = this.get();',
  24405. ' Result = $mod.THelper.GetItems.call(this, 5);',
  24406. ' $mod.THelper.SetItems.call(this, 6, false);',
  24407. ' return Result;',
  24408. ' };',
  24409. ' this.SetItems = function (Index, Value) {',
  24410. ' };',
  24411. '});',
  24412. 'this.w = 0;',
  24413. 'this.b = false;',
  24414. '']),
  24415. LinesToStr([ // $mod.$main
  24416. '$mod.b = $mod.THelper.GetItems.call({',
  24417. ' p: $mod,',
  24418. ' get: function () {',
  24419. ' return this.p.w;',
  24420. ' },',
  24421. ' set: function (v) {',
  24422. ' this.p.w = v;',
  24423. ' }',
  24424. '}, 1);',
  24425. '$mod.THelper.SetItems.call({',
  24426. ' p: $mod,',
  24427. ' get: function () {',
  24428. ' return this.p.w;',
  24429. ' },',
  24430. ' set: function (v) {',
  24431. ' this.p.w = v;',
  24432. ' }',
  24433. '}, 2, $mod.b);',
  24434. 'var $with = $mod.w;',
  24435. '$mod.b = $mod.THelper.GetItems.call({',
  24436. ' get: function () {',
  24437. ' return $with;',
  24438. ' },',
  24439. ' set: function (v) {',
  24440. ' $with = v;',
  24441. ' }',
  24442. '}, 3);',
  24443. '$mod.THelper.SetItems.call({',
  24444. ' get: function () {',
  24445. ' return $with;',
  24446. ' },',
  24447. ' set: function (v) {',
  24448. ' $with = v;',
  24449. ' }',
  24450. '}, 4, $mod.b);',
  24451. '']));
  24452. end;
  24453. procedure TTestModule.TestTypeHelper_ClassProperty;
  24454. begin
  24455. StartProgram(false);
  24456. Add([
  24457. '{$modeswitch typehelpers}',
  24458. 'type',
  24459. ' THelper = type helper for word',
  24460. ' class function GetSize: longint; static;',
  24461. ' class procedure SetSize(Value: longint); static;',
  24462. ' class property Size: longint read GetSize write SetSize;',
  24463. ' end;',
  24464. 'class function THelper.GetSize: longint;',
  24465. 'begin',
  24466. ' Result:=Size+1;',
  24467. ' Size:=2;',
  24468. 'end;',
  24469. 'class procedure THelper.SetSize(Value: longint);',
  24470. 'begin',
  24471. 'end;',
  24472. 'begin',
  24473. '']);
  24474. ConvertProgram;
  24475. CheckSource('TestTypeHelper_ClassProperty',
  24476. LinesToStr([ // statements
  24477. 'rtl.createHelper(this, "THelper", null, function () {',
  24478. ' this.GetSize = function () {',
  24479. ' var Result = 0;',
  24480. ' Result = $mod.THelper.GetSize() + 1;',
  24481. ' $mod.THelper.SetSize(2);',
  24482. ' return Result;',
  24483. ' };',
  24484. ' this.SetSize = function (Value) {',
  24485. ' };',
  24486. '});',
  24487. '']),
  24488. LinesToStr([ // $mod.$main
  24489. '']));
  24490. end;
  24491. procedure TTestModule.TestTypeHelper_ClassProperty_Array;
  24492. begin
  24493. StartProgram(false);
  24494. Add([
  24495. '{$modeswitch typehelpers}',
  24496. 'type',
  24497. ' THelper = type helper for word',
  24498. ' class function GetItems(Index: byte): boolean; static;',
  24499. ' class procedure SetItems(Index: byte; Value: boolean); static;',
  24500. ' class property Items[Index: byte]: boolean read GetItems write SetItems;',
  24501. ' end;',
  24502. 'class function THelper.GetItems(Index: byte): boolean;',
  24503. 'begin',
  24504. ' Result:=Items[1];',
  24505. ' Items[2]:=false;',
  24506. 'end;',
  24507. 'class procedure THelper.SetItems(Index: byte; Value: boolean);',
  24508. 'begin',
  24509. 'end;',
  24510. 'var',
  24511. ' w: word;',
  24512. ' b: boolean;',
  24513. 'begin',
  24514. ' b:=w.Items[1];',
  24515. ' w.Items[2]:=b;',
  24516. ' with w do begin',
  24517. ' b:=Items[3];',
  24518. ' Items[4]:=b;',
  24519. ' end;',
  24520. '']);
  24521. ConvertProgram;
  24522. CheckSource('TestTypeHelper_ClassProperty_Array',
  24523. LinesToStr([ // statements
  24524. 'rtl.createHelper(this, "THelper", null, function () {',
  24525. ' this.GetItems = function (Index) {',
  24526. ' var Result = false;',
  24527. ' Result = $mod.THelper.GetItems(1);',
  24528. ' $mod.THelper.SetItems(2, false);',
  24529. ' return Result;',
  24530. ' };',
  24531. ' this.SetItems = function (Index, Value) {',
  24532. ' };',
  24533. '});',
  24534. 'this.w = 0;',
  24535. 'this.b = false;',
  24536. '']),
  24537. LinesToStr([ // $mod.$main
  24538. '$mod.b = $mod.THelper.GetItems(1);',
  24539. '$mod.THelper.SetItems(2, $mod.b);',
  24540. 'var $with = $mod.w;',
  24541. '$mod.b = $mod.THelper.GetItems(3);',
  24542. '$mod.THelper.SetItems(4, $mod.b);',
  24543. '']));
  24544. end;
  24545. procedure TTestModule.TestTypeHelper_ClassMethod;
  24546. begin
  24547. StartProgram(false);
  24548. Add([
  24549. '{$modeswitch typehelpers}',
  24550. 'type',
  24551. ' THelper = type helper for word',
  24552. ' class procedure DoStatic; static;',
  24553. ' end;',
  24554. 'class procedure THelper.DoStatic;',
  24555. 'begin',
  24556. ' DoStatic;',
  24557. ' DoStatic();',
  24558. 'end;',
  24559. 'var w: word;',
  24560. 'begin',
  24561. ' w.DoStatic;',
  24562. ' w.DoStatic();',
  24563. '']);
  24564. ConvertProgram;
  24565. CheckSource('TestTypeHelper_ClassMethod',
  24566. LinesToStr([ // statements
  24567. 'rtl.createHelper(this, "THelper", null, function () {',
  24568. ' this.DoStatic = function () {',
  24569. ' $mod.THelper.DoStatic();',
  24570. ' $mod.THelper.DoStatic();',
  24571. ' };',
  24572. '});',
  24573. 'this.w = 0;',
  24574. '']),
  24575. LinesToStr([ // $mod.$main
  24576. '$mod.THelper.DoStatic();',
  24577. '$mod.THelper.DoStatic();',
  24578. '']));
  24579. end;
  24580. procedure TTestModule.TestTypeHelper_ExtClassMethodFail;
  24581. begin
  24582. StartProgram(false);
  24583. Add([
  24584. '{$modeswitch typehelpers}',
  24585. 'type',
  24586. ' THelper = type helper for word',
  24587. ' procedure Run; external name ''Run'';',
  24588. ' end;',
  24589. 'var w: word;',
  24590. 'begin',
  24591. ' w.Run;',
  24592. '']);
  24593. SetExpectedPasResolverError('Not supported: external method in type helper',nNotSupportedX);
  24594. ConvertProgram;
  24595. end;
  24596. procedure TTestModule.TestTypeHelper_Constructor;
  24597. begin
  24598. StartProgram(false);
  24599. Add([
  24600. '{$modeswitch typehelpers}',
  24601. 'type',
  24602. ' THelper = type helper for word',
  24603. ' constructor Init(e: longint);',
  24604. ' end;',
  24605. 'constructor THelper.Init(e: longint);',
  24606. 'begin',
  24607. ' Self:=e;',
  24608. ' Init(e+1);',
  24609. 'end;',
  24610. 'var w: word;',
  24611. 'begin',
  24612. ' w:=word.Init(2);',
  24613. ' w:=w.Init(3);',
  24614. ' with word do w:=Init(4);',
  24615. ' with w do w:=Init(5);',
  24616. '']);
  24617. ConvertProgram;
  24618. CheckSource('TestTypeHelper_Constructor',
  24619. LinesToStr([ // statements
  24620. 'rtl.createHelper(this, "THelper", null, function () {',
  24621. ' this.Init = function (e) {',
  24622. ' this.set(e);',
  24623. ' $mod.THelper.Init.call(this, e + 1);',
  24624. ' return this.get();',
  24625. ' };',
  24626. ' this.$new = function (fn, args) {',
  24627. ' return this[fn].apply({',
  24628. ' p: 0,',
  24629. ' get: function () {',
  24630. ' return this.p;',
  24631. ' },',
  24632. ' set: function (v) {',
  24633. ' this.p = v;',
  24634. ' }',
  24635. ' }, args);',
  24636. ' };',
  24637. '});',
  24638. 'this.w = 0;',
  24639. '']),
  24640. LinesToStr([ // $mod.$main
  24641. '$mod.w = $mod.THelper.$new("Init", [2]);',
  24642. '$mod.w = $mod.THelper.Init.call({',
  24643. ' p: $mod,',
  24644. ' get: function () {',
  24645. ' return this.p.w;',
  24646. ' },',
  24647. ' set: function (v) {',
  24648. ' this.p.w = v;',
  24649. ' }',
  24650. '}, 3);',
  24651. '$mod.w = $mod.THelper.$new("Init", [4]);',
  24652. 'var $with = $mod.w;',
  24653. '$mod.w = $mod.THelper.Init.call({',
  24654. ' get: function () {',
  24655. ' return $with;',
  24656. ' },',
  24657. ' set: function (v) {',
  24658. ' $with = v;',
  24659. ' }',
  24660. '}, 5);',
  24661. '']));
  24662. end;
  24663. procedure TTestModule.TestTypeHelper_Word;
  24664. begin
  24665. StartProgram(false);
  24666. Add([
  24667. '{$modeswitch typehelpers}',
  24668. 'type',
  24669. ' THelper = type helper for word',
  24670. ' procedure DoIt(e: byte = 123);',
  24671. ' end;',
  24672. 'procedure THelper.DoIt(e: byte);',
  24673. 'begin',
  24674. ' Self:=e;',
  24675. ' Self:=Self+1;',
  24676. ' with Self do Doit;',
  24677. 'end;',
  24678. 'begin',
  24679. ' word(3).DoIt;',
  24680. '']);
  24681. ConvertProgram;
  24682. CheckSource('TestTypeHelper_Word',
  24683. LinesToStr([ // statements
  24684. 'rtl.createHelper(this, "THelper", null, function () {',
  24685. ' this.DoIt = function (e) {',
  24686. ' this.set(e);',
  24687. ' this.set(this.get() + 1);',
  24688. ' var $with = this.get();',
  24689. ' $mod.THelper.DoIt.call(this, 123);',
  24690. ' };',
  24691. '});',
  24692. '']),
  24693. LinesToStr([ // $mod.$main
  24694. '$mod.THelper.DoIt.call({',
  24695. ' get: function () {',
  24696. ' return 3;',
  24697. ' },',
  24698. ' set: function (v) {',
  24699. ' rtl.raiseE("EPropReadOnly");',
  24700. ' }',
  24701. '}, 123);',
  24702. '']));
  24703. end;
  24704. procedure TTestModule.TestTypeHelper_Boolean;
  24705. begin
  24706. StartProgram(false);
  24707. Add([
  24708. '{$modeswitch typehelpers}',
  24709. 'type',
  24710. ' Integer = longint;',
  24711. ' THelper = type helper for boolean',
  24712. ' procedure Run(e: wordbool = true);',
  24713. ' end;',
  24714. 'procedure THelper.Run(e: wordbool);',
  24715. 'begin',
  24716. ' Self:=e;',
  24717. ' Self:=not Self;',
  24718. ' with Self do Run;',
  24719. ' if Integer(Self)=0 then ;',
  24720. 'end;',
  24721. 'begin',
  24722. ' boolean(3).Run;',
  24723. '']);
  24724. ConvertProgram;
  24725. CheckSource('TestTypeHelper_Boolean',
  24726. LinesToStr([ // statements
  24727. 'rtl.createHelper(this, "THelper", null, function () {',
  24728. ' this.Run = function (e) {',
  24729. ' this.set(e);',
  24730. ' this.set(!this.get());',
  24731. ' var $with = this.get();',
  24732. ' $mod.THelper.Run.call(this, true);',
  24733. ' if ((this.get() ? 1 : 0) === 0) ;',
  24734. ' };',
  24735. '});',
  24736. '']),
  24737. LinesToStr([ // $mod.$main
  24738. '$mod.THelper.Run.call({',
  24739. ' a: 3 != 0,',
  24740. ' get: function () {',
  24741. ' return this.a;',
  24742. ' },',
  24743. ' set: function (v) {',
  24744. ' rtl.raiseE("EPropReadOnly");',
  24745. ' }',
  24746. '}, true);',
  24747. '']));
  24748. end;
  24749. procedure TTestModule.TestTypeHelper_WordBool;
  24750. begin
  24751. StartProgram(false);
  24752. Add([
  24753. '{$modeswitch typehelpers}',
  24754. 'type',
  24755. ' Integer = longint;',
  24756. ' THelper = type helper for WordBool',
  24757. ' procedure Run(e: wordbool = true);',
  24758. ' end;',
  24759. 'procedure THelper.Run(e: wordbool);',
  24760. 'var i: integer;',
  24761. 'begin',
  24762. ' i:=Integer(Self);',
  24763. 'end;',
  24764. 'var w: wordbool;',
  24765. 'begin',
  24766. ' w.Run;',
  24767. ' wordbool(3).Run;',
  24768. '']);
  24769. ConvertProgram;
  24770. CheckSource('TestTypeHelper_WordBool',
  24771. LinesToStr([ // statements
  24772. 'rtl.createHelper(this, "THelper", null, function () {',
  24773. ' this.Run = function (e) {',
  24774. ' var i = 0;',
  24775. ' i = (this.get() ? 1 : 0);',
  24776. ' };',
  24777. '});',
  24778. 'this.w = false;',
  24779. '']),
  24780. LinesToStr([ // $mod.$main
  24781. '$mod.THelper.Run.call({',
  24782. ' p: $mod,',
  24783. ' get: function () {',
  24784. ' return this.p.w;',
  24785. ' },',
  24786. ' set: function (v) {',
  24787. ' this.p.w = v;',
  24788. ' }',
  24789. '}, true);',
  24790. '$mod.THelper.Run.call({',
  24791. ' a: 3 != 0,',
  24792. ' get: function () {',
  24793. ' return this.a;',
  24794. ' },',
  24795. ' set: function (v) {',
  24796. ' rtl.raiseE("EPropReadOnly");',
  24797. ' }',
  24798. '}, true);',
  24799. '']));
  24800. end;
  24801. procedure TTestModule.TestTypeHelper_Double;
  24802. begin
  24803. StartProgram(false);
  24804. Add([
  24805. '{$modeswitch typehelpers}',
  24806. 'type',
  24807. ' Float = type double;',
  24808. ' THelper = type helper for Float',
  24809. ' const NPI = 3.141592;',
  24810. ' function ToStr: String;',
  24811. ' end;',
  24812. 'function THelper.ToStr: String;',
  24813. 'begin',
  24814. 'end;',
  24815. 'procedure DoIt(s: string);',
  24816. 'begin',
  24817. 'end;',
  24818. 'var f: Float;',
  24819. 'begin',
  24820. ' DoIt(f.toStr);',
  24821. ' DoIt(f.toStr());',
  24822. ' (f*f).toStr;',
  24823. ' DoIt((f*f).toStr);',
  24824. '']);
  24825. ConvertProgram;
  24826. CheckSource('TestTypeHelper_Double',
  24827. LinesToStr([ // statements
  24828. 'rtl.createHelper(this, "THelper", null, function () {',
  24829. ' this.NPI = 3.141592;',
  24830. ' this.ToStr = function () {',
  24831. ' var Result = "";',
  24832. ' return Result;',
  24833. ' };',
  24834. '});',
  24835. 'this.DoIt = function (s) {',
  24836. '};',
  24837. 'this.f = 0.0;',
  24838. '']),
  24839. LinesToStr([ // $mod.$main
  24840. '$mod.DoIt($mod.THelper.ToStr.call({',
  24841. ' p: $mod,',
  24842. ' get: function () {',
  24843. ' return this.p.f;',
  24844. ' },',
  24845. ' set: function (v) {',
  24846. ' this.p.f = v;',
  24847. ' }',
  24848. '}));',
  24849. '$mod.DoIt($mod.THelper.ToStr.call({',
  24850. ' p: $mod,',
  24851. ' get: function () {',
  24852. ' return this.p.f;',
  24853. ' },',
  24854. ' set: function (v) {',
  24855. ' this.p.f = v;',
  24856. ' }',
  24857. '}));',
  24858. '$mod.THelper.ToStr.call({',
  24859. ' a: $mod.f * $mod.f,',
  24860. ' get: function () {',
  24861. ' return this.a;',
  24862. ' },',
  24863. ' set: function (v) {',
  24864. ' rtl.raiseE("EPropReadOnly");',
  24865. ' }',
  24866. '});',
  24867. '$mod.DoIt($mod.THelper.ToStr.call({',
  24868. ' a: $mod.f * $mod.f,',
  24869. ' get: function () {',
  24870. ' return this.a;',
  24871. ' },',
  24872. ' set: function (v) {',
  24873. ' rtl.raiseE("EPropReadOnly");',
  24874. ' }',
  24875. '}));',
  24876. '']));
  24877. end;
  24878. procedure TTestModule.TestTypeHelper_NativeInt;
  24879. begin
  24880. StartProgram(false);
  24881. Add([
  24882. '{$modeswitch typehelpers}',
  24883. 'type',
  24884. ' MaxInt = type nativeint;',
  24885. ' THelperI = type helper for MaxInt',
  24886. ' function ToStr: String;',
  24887. ' end;',
  24888. ' MaxUInt = type nativeuint;',
  24889. ' THelperU = type helper for MaxUInt',
  24890. ' function ToStr: String;',
  24891. ' end;',
  24892. 'function THelperI.ToStr: String;',
  24893. 'begin',
  24894. ' Result:=str(Self);',
  24895. 'end;',
  24896. 'function THelperU.ToStr: String;',
  24897. 'begin',
  24898. ' Result:=str(Self);',
  24899. 'end;',
  24900. 'procedure DoIt(s: string);',
  24901. 'begin',
  24902. 'end;',
  24903. 'var i: MaxInt;',
  24904. 'begin',
  24905. ' DoIt(i.toStr);',
  24906. ' DoIt(i.toStr());',
  24907. ' (i*i).toStr;',
  24908. ' DoIt((i*i).toStr);',
  24909. '']);
  24910. ConvertProgram;
  24911. CheckSource('TestTypeHelper_NativeInt',
  24912. LinesToStr([ // statements
  24913. 'rtl.createHelper(this, "THelperI", null, function () {',
  24914. ' this.ToStr = function () {',
  24915. ' var Result = "";',
  24916. ' Result = "" + this.get();',
  24917. ' return Result;',
  24918. ' };',
  24919. '});',
  24920. 'rtl.createHelper(this, "THelperU", null, function () {',
  24921. ' this.ToStr = function () {',
  24922. ' var Result = "";',
  24923. ' Result = "" + this.get();',
  24924. ' return Result;',
  24925. ' };',
  24926. '});',
  24927. 'this.DoIt = function (s) {',
  24928. '};',
  24929. 'this.i = 0;',
  24930. '']),
  24931. LinesToStr([ // $mod.$main
  24932. '$mod.DoIt($mod.THelperI.ToStr.call({',
  24933. ' p: $mod,',
  24934. ' get: function () {',
  24935. ' return this.p.i;',
  24936. ' },',
  24937. ' set: function (v) {',
  24938. ' this.p.i = v;',
  24939. ' }',
  24940. '}));',
  24941. '$mod.DoIt($mod.THelperI.ToStr.call({',
  24942. ' p: $mod,',
  24943. ' get: function () {',
  24944. ' return this.p.i;',
  24945. ' },',
  24946. ' set: function (v) {',
  24947. ' this.p.i = v;',
  24948. ' }',
  24949. '}));',
  24950. '$mod.THelperI.ToStr.call({',
  24951. ' a: $mod.i * $mod.i,',
  24952. ' get: function () {',
  24953. ' return this.a;',
  24954. ' },',
  24955. ' set: function (v) {',
  24956. ' rtl.raiseE("EPropReadOnly");',
  24957. ' }',
  24958. '});',
  24959. '$mod.DoIt($mod.THelperI.ToStr.call({',
  24960. ' a: $mod.i * $mod.i,',
  24961. ' get: function () {',
  24962. ' return this.a;',
  24963. ' },',
  24964. ' set: function (v) {',
  24965. ' rtl.raiseE("EPropReadOnly");',
  24966. ' }',
  24967. '}));',
  24968. '']));
  24969. end;
  24970. procedure TTestModule.TestTypeHelper_StringChar;
  24971. begin
  24972. StartProgram(false);
  24973. Add([
  24974. '{$modeswitch typehelpers}',
  24975. 'type',
  24976. ' TStringHelper = type helper for string',
  24977. ' procedure DoIt(e: byte = 123);',
  24978. ' end;',
  24979. ' TCharHelper = type helper for char',
  24980. ' procedure Fly;',
  24981. ' end;',
  24982. 'procedure TStringHelper.DoIt(e: byte);',
  24983. 'begin',
  24984. ' Self[1]:=''c'';',
  24985. ' Self[2]:=Self[3];',
  24986. 'end;',
  24987. 'procedure TCharHelper.Fly;',
  24988. 'begin',
  24989. ' Self:=''c'';',
  24990. 'end;',
  24991. 'begin',
  24992. ' ''abc''.DoIt;',
  24993. ' ''xyz''.DoIt();',
  24994. ' ''c''.Fly();',
  24995. '']);
  24996. ConvertProgram;
  24997. CheckSource('TestTypeHelper_StringChar',
  24998. LinesToStr([ // statements
  24999. 'rtl.createHelper(this, "TStringHelper", null, function () {',
  25000. ' this.DoIt = function (e) {',
  25001. ' this.set(rtl.setCharAt(this.get(), 0, "c"));',
  25002. ' this.set(rtl.setCharAt(this.get(), 1, this.get().charAt(2)));',
  25003. ' };',
  25004. '});',
  25005. 'rtl.createHelper(this, "TCharHelper", null, function () {',
  25006. ' this.Fly = function () {',
  25007. ' this.set("c");',
  25008. ' };',
  25009. '});',
  25010. '']),
  25011. LinesToStr([ // $mod.$main
  25012. '$mod.TStringHelper.DoIt.call({',
  25013. ' get: function () {',
  25014. ' return "abc";',
  25015. ' },',
  25016. ' set: function (v) {',
  25017. ' rtl.raiseE("EPropReadOnly");',
  25018. ' }',
  25019. '}, 123);',
  25020. '$mod.TStringHelper.DoIt.call({',
  25021. ' get: function () {',
  25022. ' return "xyz";',
  25023. ' },',
  25024. ' set: function (v) {',
  25025. ' rtl.raiseE("EPropReadOnly");',
  25026. ' }',
  25027. '}, 123);',
  25028. '$mod.TCharHelper.Fly.call({',
  25029. ' get: function () {',
  25030. ' return "c";',
  25031. ' },',
  25032. ' set: function (v) {',
  25033. ' rtl.raiseE("EPropReadOnly");',
  25034. ' }',
  25035. '});',
  25036. '']));
  25037. end;
  25038. procedure TTestModule.TestTypeHelper_JSValue;
  25039. begin
  25040. StartProgram(false);
  25041. Add([
  25042. '{$modeswitch typehelpers}',
  25043. 'type',
  25044. ' TExtValue = type jsvalue;',
  25045. ' THelper = type helper for TExtValue',
  25046. ' function ToStr: String;',
  25047. ' end;',
  25048. 'function THelper.ToStr: String;',
  25049. 'begin',
  25050. 'end;',
  25051. 'var',
  25052. ' s: string;',
  25053. ' v: TExtValue;',
  25054. 'begin',
  25055. ' s:=v.toStr;',
  25056. ' s:=v.toStr();',
  25057. ' TExtValue(s).toStr;',
  25058. '']);
  25059. ConvertProgram;
  25060. CheckSource('TestTypeHelper_JSValue',
  25061. LinesToStr([ // statements
  25062. 'rtl.createHelper(this, "THelper", null, function () {',
  25063. ' this.ToStr = function () {',
  25064. ' var Result = "";',
  25065. ' return Result;',
  25066. ' };',
  25067. '});',
  25068. 'this.s = "";',
  25069. 'this.v = undefined;',
  25070. '']),
  25071. LinesToStr([ // $mod.$main
  25072. '$mod.s = $mod.THelper.ToStr.call({',
  25073. ' p: $mod,',
  25074. ' get: function () {',
  25075. ' return this.p.v;',
  25076. ' },',
  25077. ' set: function (v) {',
  25078. ' this.p.v = v;',
  25079. ' }',
  25080. '});',
  25081. '$mod.s = $mod.THelper.ToStr.call({',
  25082. ' p: $mod,',
  25083. ' get: function () {',
  25084. ' return this.p.v;',
  25085. ' },',
  25086. ' set: function (v) {',
  25087. ' this.p.v = v;',
  25088. ' }',
  25089. '});',
  25090. '$mod.THelper.ToStr.call({',
  25091. ' p: $mod,',
  25092. ' get: function () {',
  25093. ' return this.p.s;',
  25094. ' },',
  25095. ' set: function (v) {',
  25096. ' rtl.raiseE("EPropReadOnly");',
  25097. ' }',
  25098. '});',
  25099. '']));
  25100. end;
  25101. procedure TTestModule.TestTypeHelper_Array;
  25102. begin
  25103. StartProgram(false);
  25104. Add([
  25105. '{$modeswitch typehelpers}',
  25106. 'type',
  25107. ' TArrOfBool = array of boolean;',
  25108. ' TArrOfJS = array of jsvalue;',
  25109. ' THelper = type helper for TArrOfBool',
  25110. ' procedure DoIt(e: byte = 123);',
  25111. ' end;',
  25112. 'procedure THelper.DoIt(e: byte);',
  25113. 'begin',
  25114. ' Self[1]:=true;',
  25115. ' Self[2]:=not Self[3];',
  25116. ' SetLength(Self,4);',
  25117. 'end;',
  25118. 'var',
  25119. ' b: TArrOfBool;',
  25120. ' j: TArrOfJS;',
  25121. 'begin',
  25122. ' b.DoIt;',
  25123. ' TArrOfBool(j).DoIt();',
  25124. '']);
  25125. ConvertProgram;
  25126. CheckSource('TestTypeHelper_Array',
  25127. LinesToStr([ // statements
  25128. 'rtl.createHelper(this, "THelper", null, function () {',
  25129. ' this.DoIt = function (e) {',
  25130. ' this.get()[1] = true;',
  25131. ' this.get()[2] = !this.get()[3];',
  25132. ' this.set(rtl.arraySetLength(this.get(), false, 4));',
  25133. ' };',
  25134. '});',
  25135. 'this.b = [];',
  25136. 'this.j = [];',
  25137. '']),
  25138. LinesToStr([ // $mod.$main
  25139. '$mod.THelper.DoIt.call({',
  25140. ' p: $mod,',
  25141. ' get: function () {',
  25142. ' return this.p.b;',
  25143. ' },',
  25144. ' set: function (v) {',
  25145. ' this.p.b = v;',
  25146. ' }',
  25147. '}, 123);',
  25148. '$mod.THelper.DoIt.call({',
  25149. ' p: $mod,',
  25150. ' get: function () {',
  25151. ' return this.p.j;',
  25152. ' },',
  25153. ' set: function (v) {',
  25154. ' this.p.j = v;',
  25155. ' }',
  25156. '}, 123);',
  25157. '']));
  25158. end;
  25159. procedure TTestModule.TestTypeHelper_EnumType;
  25160. begin
  25161. StartProgram(false);
  25162. Add([
  25163. '{$modeswitch typehelpers}',
  25164. 'type',
  25165. ' TEnum = (red,blue);',
  25166. ' THelper = type helper for TEnum',
  25167. ' procedure DoIt(e: byte = 123);',
  25168. ' class procedure Swing(w: word); static;',
  25169. ' end;',
  25170. 'procedure THelper.DoIt(e: byte);',
  25171. 'begin',
  25172. ' Self:=red;',
  25173. ' Self:=succ(Self);',
  25174. ' with Self do Doit;',
  25175. 'end;',
  25176. 'class procedure THelper.Swing(w: word);',
  25177. 'begin',
  25178. 'end;',
  25179. 'var e: TEnum;',
  25180. 'begin',
  25181. ' e.DoIt;',
  25182. ' red.DoIt;',
  25183. ' TEnum.blue.DoIt;',
  25184. ' TEnum(1).DoIt;',
  25185. ' TEnum.Swing(3);',
  25186. '']);
  25187. ConvertProgram;
  25188. CheckSource('TestTypeHelper_EnumType',
  25189. LinesToStr([ // statements
  25190. 'this.TEnum = {',
  25191. ' "0": "red",',
  25192. ' red: 0,',
  25193. ' "1": "blue",',
  25194. ' blue: 1',
  25195. '};',
  25196. 'rtl.createHelper(this, "THelper", null, function () {',
  25197. ' this.DoIt = function (e) {',
  25198. ' this.set($mod.TEnum.red);',
  25199. ' this.set(this.get() + 1);',
  25200. ' var $with = this.get();',
  25201. ' $mod.THelper.DoIt.call(this, 123);',
  25202. ' };',
  25203. ' this.Swing = function (w) {',
  25204. ' };',
  25205. '});',
  25206. 'this.e = 0;',
  25207. '']),
  25208. LinesToStr([ // $mod.$main
  25209. '$mod.THelper.DoIt.call({',
  25210. ' p: $mod,',
  25211. ' get: function () {',
  25212. ' return this.p.e;',
  25213. ' },',
  25214. ' set: function (v) {',
  25215. ' this.p.e = v;',
  25216. ' }',
  25217. '}, 123);',
  25218. '$mod.THelper.DoIt.call({',
  25219. ' p: $mod.TEnum,',
  25220. ' get: function () {',
  25221. ' return this.p.red;',
  25222. ' },',
  25223. ' set: function (v) {',
  25224. ' rtl.raiseE("EPropReadOnly");',
  25225. ' }',
  25226. '}, 123);',
  25227. '$mod.THelper.DoIt.call({',
  25228. ' p: $mod.TEnum,',
  25229. ' get: function () {',
  25230. ' return this.p.blue;',
  25231. ' },',
  25232. ' set: function (v) {',
  25233. ' rtl.raiseE("EPropReadOnly");',
  25234. ' }',
  25235. '}, 123);',
  25236. '$mod.THelper.DoIt.call({',
  25237. ' get: function () {',
  25238. ' return 1;',
  25239. ' },',
  25240. ' set: function (v) {',
  25241. ' rtl.raiseE("EPropReadOnly");',
  25242. ' }',
  25243. '}, 123);',
  25244. '$mod.THelper.Swing(3);',
  25245. '']));
  25246. end;
  25247. procedure TTestModule.TestTypeHelper_SetType;
  25248. begin
  25249. StartProgram(false);
  25250. Add([
  25251. '{$modeswitch typehelpers}',
  25252. 'type',
  25253. ' TEnum = (red,blue);',
  25254. ' TSetOfEnum = set of TEnum;',
  25255. ' THelper = type helper for TSetOfEnum',
  25256. ' procedure DoIt(e: byte = 123);',
  25257. ' constructor Init(e: TEnum);',
  25258. ' constructor InitEmpty;',
  25259. ' end;',
  25260. 'procedure THelper.DoIt(e: byte);',
  25261. 'begin',
  25262. ' Self:=[];',
  25263. ' Self:=[red];',
  25264. ' Include(Self,blue);',
  25265. 'end;',
  25266. 'constructor THelper.Init(e: TEnum);',
  25267. 'begin',
  25268. ' Self:=[];',
  25269. ' Self:=[e];',
  25270. ' Include(Self,blue);',
  25271. 'end;',
  25272. 'constructor THelper.InitEmpty;',
  25273. 'begin',
  25274. 'end;',
  25275. 'var s: TSetOfEnum;',
  25276. 'begin',
  25277. ' s.DoIt;',
  25278. //' [red].DoIt;',
  25279. //' with s do DoIt;',
  25280. //' with [red,blue] do DoIt;',
  25281. ' s:=TSetOfEnum.Init(blue);',
  25282. ' s:=s.Init(blue);',
  25283. '']);
  25284. ConvertProgram;
  25285. CheckSource('TestTypeHelper_SetType',
  25286. LinesToStr([ // statements
  25287. 'this.TEnum = {',
  25288. ' "0": "red",',
  25289. ' red: 0,',
  25290. ' "1": "blue",',
  25291. ' blue: 1',
  25292. '};',
  25293. 'rtl.createHelper(this, "THelper", null, function () {',
  25294. ' this.DoIt = function (e) {',
  25295. ' this.set({});',
  25296. ' this.set(rtl.createSet($mod.TEnum.red));',
  25297. ' this.set(rtl.includeSet(this.get(), $mod.TEnum.blue));',
  25298. ' };',
  25299. ' this.Init = function (e) {',
  25300. ' this.set({});',
  25301. ' this.set(rtl.createSet(e));',
  25302. ' this.set(rtl.includeSet(this.get(), $mod.TEnum.blue));',
  25303. ' return this.get();',
  25304. ' };',
  25305. ' this.InitEmpty = function () {',
  25306. ' return this.get();',
  25307. ' };',
  25308. ' this.$new = function (fn, args) {',
  25309. ' return this[fn].apply({',
  25310. ' p: {},',
  25311. ' get: function () {',
  25312. ' return this.p;',
  25313. ' },',
  25314. ' set: function (v) {',
  25315. ' this.p = v;',
  25316. ' }',
  25317. ' }, args);',
  25318. ' };',
  25319. '});',
  25320. 'this.s = {};',
  25321. '']),
  25322. LinesToStr([ // $mod.$main
  25323. '$mod.THelper.DoIt.call({',
  25324. ' p: $mod,',
  25325. ' get: function () {',
  25326. ' return this.p.s;',
  25327. ' },',
  25328. ' set: function (v) {',
  25329. ' this.p.s = v;',
  25330. ' }',
  25331. '}, 123);',
  25332. '$mod.s = rtl.refSet($mod.THelper.$new("Init", [$mod.TEnum.blue]));',
  25333. '$mod.s = rtl.refSet($mod.THelper.Init.call({',
  25334. ' p: $mod,',
  25335. ' get: function () {',
  25336. ' return this.p.s;',
  25337. ' },',
  25338. ' set: function (v) {',
  25339. ' this.p.s = v;',
  25340. ' }',
  25341. '}, $mod.TEnum.blue));',
  25342. '']));
  25343. end;
  25344. procedure TTestModule.TestTypeHelper_InterfaceType;
  25345. begin
  25346. StartProgram(false);
  25347. Add([
  25348. '{$interfaces com}',
  25349. '{$modeswitch typehelpers}',
  25350. 'type',
  25351. ' IUnknown = interface',
  25352. ' function _AddRef: longint;',
  25353. ' function _Release: longint;',
  25354. ' end;',
  25355. ' TObject = class(IUnknown)',
  25356. ' function _AddRef: longint; virtual; abstract;',
  25357. ' function _Release: longint; virtual; abstract;',
  25358. ' end;',
  25359. ' THelper = type helper for IUnknown',
  25360. ' procedure Fly(e: byte = 123);',
  25361. ' class procedure Run; static;',
  25362. ' end;',
  25363. 'var',
  25364. ' i: IUnknown;',
  25365. ' o: TObject;',
  25366. 'procedure THelper.Fly(e: byte);',
  25367. 'begin',
  25368. ' i:=Self;',
  25369. ' o:=Self as TObject;',
  25370. ' Self:=nil;',
  25371. ' Self:=i;',
  25372. ' Self:=o;',
  25373. ' with Self do begin',
  25374. ' Fly;',
  25375. ' Fly();',
  25376. ' end;',
  25377. 'end;',
  25378. 'class procedure THelper.Run;',
  25379. 'var l: IUnknown;',
  25380. 'begin',
  25381. ' l.Fly;',
  25382. ' l.Fly();',
  25383. 'end;',
  25384. 'begin',
  25385. ' i.Fly;',
  25386. ' i.Fly();',
  25387. ' i.Run;',
  25388. ' i.Run();',
  25389. ' IUnknown.Run;',
  25390. ' IUnknown.Run();',
  25391. '']);
  25392. ConvertProgram;
  25393. CheckSource('TestTypeHelper_InterfaceType',
  25394. LinesToStr([ // statements
  25395. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  25396. 'rtl.createClass(this, "TObject", null, function () {',
  25397. ' this.$init = function () {',
  25398. ' };',
  25399. ' this.$final = function () {',
  25400. ' };',
  25401. ' rtl.addIntf(this, $mod.IUnknown);',
  25402. '});',
  25403. 'rtl.createHelper(this, "THelper", null, function () {',
  25404. ' this.Fly = function (e) {',
  25405. ' var $ir = rtl.createIntfRefs();',
  25406. ' try {',
  25407. ' rtl.setIntfP($mod, "i", this.get());',
  25408. ' $mod.o = rtl.intfAsClass(this.get(), $mod.TObject);',
  25409. ' this.set(null);',
  25410. ' this.set($mod.i);',
  25411. ' this.set($ir.ref(1, rtl.queryIntfT($mod.o, $mod.IUnknown)));',
  25412. ' var $with = this.get();',
  25413. ' $mod.THelper.Fly.call(this, 123);',
  25414. ' $mod.THelper.Fly.call(this, 123);',
  25415. ' } finally {',
  25416. ' $ir.free();',
  25417. ' };',
  25418. ' };',
  25419. ' this.Run = function () {',
  25420. ' var l = null;',
  25421. ' try {',
  25422. ' $mod.THelper.Fly.call({',
  25423. ' get: function () {',
  25424. ' return l;',
  25425. ' },',
  25426. ' set: function (v) {',
  25427. ' l = rtl.setIntfL(l, v);',
  25428. ' }',
  25429. ' }, 123);',
  25430. ' $mod.THelper.Fly.call({',
  25431. ' get: function () {',
  25432. ' return l;',
  25433. ' },',
  25434. ' set: function (v) {',
  25435. ' l = rtl.setIntfL(l, v);',
  25436. ' }',
  25437. ' }, 123);',
  25438. ' } finally {',
  25439. ' rtl._Release(l);',
  25440. ' };',
  25441. ' };',
  25442. '});',
  25443. 'this.i = null;',
  25444. 'this.o = null;',
  25445. '']),
  25446. LinesToStr([ // $mod.$main
  25447. '$mod.THelper.Fly.call({',
  25448. ' p: $mod,',
  25449. ' get: function () {',
  25450. ' return this.p.i;',
  25451. ' },',
  25452. ' set: function (v) {',
  25453. ' rtl.setIntfP(this.p, "i", v);',
  25454. ' }',
  25455. '}, 123);',
  25456. '$mod.THelper.Fly.call({',
  25457. ' p: $mod,',
  25458. ' get: function () {',
  25459. ' return this.p.i;',
  25460. ' },',
  25461. ' set: function (v) {',
  25462. ' rtl.setIntfP(this.p, "i", v);',
  25463. ' }',
  25464. '}, 123);',
  25465. '$mod.THelper.Run();',
  25466. '$mod.THelper.Run();',
  25467. '$mod.THelper.Run();',
  25468. '$mod.THelper.Run();',
  25469. '']));
  25470. end;
  25471. procedure TTestModule.TestTypeHelper_NestedSelf;
  25472. begin
  25473. StartProgram(false);
  25474. Add([
  25475. '{$modeswitch typehelpers}',
  25476. 'type',
  25477. ' THelper = type helper for string',
  25478. ' procedure Run(Value: string);',
  25479. ' end;',
  25480. 'procedure THelper.Run(Value: string);',
  25481. ' function Sub(i: nativeint): boolean;',
  25482. ' begin',
  25483. ' Result:=Self[i+1]=Value[i];',
  25484. ' end;',
  25485. 'begin',
  25486. ' if Self[3]=Value[4] then ;',
  25487. 'end;',
  25488. 'begin',
  25489. '']);
  25490. ConvertProgram;
  25491. CheckSource('TestTypeHelper_NestedSelf',
  25492. LinesToStr([ // statements
  25493. 'rtl.createHelper(this, "THelper", null, function () {',
  25494. ' this.Run = function (Value) {',
  25495. ' var $Self = this;',
  25496. ' function Sub(i) {',
  25497. ' var Result = false;',
  25498. ' Result = $Self.get().charAt((i + 1) - 1) === Value.charAt(i - 1);',
  25499. ' return Result;',
  25500. ' };',
  25501. ' if ($Self.get().charAt(2) === Value.charAt(3)) ;',
  25502. ' };',
  25503. '});',
  25504. '']),
  25505. LinesToStr([ // $mod.$main
  25506. '']));
  25507. end;
  25508. procedure TTestModule.TestProcType;
  25509. begin
  25510. StartProgram(false);
  25511. Add([
  25512. 'type',
  25513. ' TProcInt = procedure(vI: longint = 1);',
  25514. 'procedure DoIt(vJ: longint);',
  25515. 'begin end;',
  25516. 'var',
  25517. ' b: boolean;',
  25518. ' vP, vQ: tprocint;',
  25519. 'begin',
  25520. ' vp:=nil;',
  25521. ' vp:=vp;',
  25522. ' vp:=@doit;',
  25523. ' vp;',
  25524. ' vp();',
  25525. ' vp(2);',
  25526. ' b:=vp=nil;',
  25527. ' b:=nil=vp;',
  25528. ' b:=vp=vq;',
  25529. ' b:=vp=@doit;',
  25530. ' b:=@doit=vp;',
  25531. ' b:=vp<>nil;',
  25532. ' b:=nil<>vp;',
  25533. ' b:=vp<>vq;',
  25534. ' b:=vp<>@doit;',
  25535. ' b:=@doit<>vp;',
  25536. ' b:=Assigned(vp);',
  25537. ' if Assigned(vp) then ;']);
  25538. ConvertProgram;
  25539. CheckSource('TestProcType',
  25540. LinesToStr([ // statements
  25541. 'this.DoIt = function(vJ) {',
  25542. '};',
  25543. 'this.b = false;',
  25544. 'this.vP = null;',
  25545. 'this.vQ = null;'
  25546. ]),
  25547. LinesToStr([ // $mod.$main
  25548. '$mod.vP = null;',
  25549. '$mod.vP = $mod.vP;',
  25550. '$mod.vP = $mod.DoIt;',
  25551. '$mod.vP(1);',
  25552. '$mod.vP(1);',
  25553. '$mod.vP(2);',
  25554. '$mod.b = $mod.vP === null;',
  25555. '$mod.b = null === $mod.vP;',
  25556. '$mod.b = rtl.eqCallback($mod.vP,$mod.vQ);',
  25557. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  25558. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  25559. '$mod.b = $mod.vP !== null;',
  25560. '$mod.b = null !== $mod.vP;',
  25561. '$mod.b = !rtl.eqCallback($mod.vP,$mod.vQ);',
  25562. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  25563. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  25564. '$mod.b = $mod.vP != null;',
  25565. 'if ($mod.vP != null) ;',
  25566. '']));
  25567. end;
  25568. procedure TTestModule.TestProcType_Arg;
  25569. begin
  25570. StartProgram(false);
  25571. Add([
  25572. 'type',
  25573. ' TProcInt = procedure(vI: longint = 1);',
  25574. 'procedure DoIt(vJ: longint); begin end;',
  25575. 'procedure DoSome(vP, vQ: TProcInt);',
  25576. 'var',
  25577. ' b: boolean;',
  25578. 'begin',
  25579. ' vp:=nil;',
  25580. ' vp:=vp;',
  25581. ' vp:=@doit;',
  25582. ' vp;',
  25583. ' vp();',
  25584. ' vp(2);',
  25585. ' b:=vp=nil;',
  25586. ' b:=nil=vp;',
  25587. ' b:=vp=vq;',
  25588. ' b:=vp=@doit;',
  25589. ' b:=@doit=vp;',
  25590. ' b:=vp<>nil;',
  25591. ' b:=nil<>vp;',
  25592. ' b:=vp<>vq;',
  25593. ' b:=vp<>@doit;',
  25594. ' b:=@doit<>vp;',
  25595. ' b:=Assigned(vp);',
  25596. ' if Assigned(vp) then ;',
  25597. 'end;',
  25598. 'begin',
  25599. ' DoSome(@DoIt,nil);']);
  25600. ConvertProgram;
  25601. CheckSource('TestProcType_Arg',
  25602. LinesToStr([ // statements
  25603. 'this.DoIt = function(vJ) {',
  25604. '};',
  25605. 'this.DoSome = function(vP, vQ) {',
  25606. ' var b = false;',
  25607. ' vP = null;',
  25608. ' vP = vP;',
  25609. ' vP = $mod.DoIt;',
  25610. ' vP(1);',
  25611. ' vP(1);',
  25612. ' vP(2);',
  25613. ' b = vP === null;',
  25614. ' b = null === vP;',
  25615. ' b = rtl.eqCallback(vP,vQ);',
  25616. ' b = rtl.eqCallback(vP, $mod.DoIt);',
  25617. ' b = rtl.eqCallback($mod.DoIt, vP);',
  25618. ' b = vP !== null;',
  25619. ' b = null !== vP;',
  25620. ' b = !rtl.eqCallback(vP, vQ);',
  25621. ' b = !rtl.eqCallback(vP, $mod.DoIt);',
  25622. ' b = !rtl.eqCallback($mod.DoIt, vP);',
  25623. ' b = vP != null;',
  25624. ' if (vP != null) ;',
  25625. '};',
  25626. '']),
  25627. LinesToStr([ // $mod.$main
  25628. '$mod.DoSome($mod.DoIt,null);',
  25629. '']));
  25630. end;
  25631. procedure TTestModule.TestProcType_FunctionFPC;
  25632. begin
  25633. StartProgram(false);
  25634. Add('type');
  25635. Add(' TFuncInt = function(vA: longint = 1): longint;');
  25636. Add('function DoIt(vI: longint): longint;');
  25637. Add('begin end;');
  25638. Add('var');
  25639. Add(' b: boolean;');
  25640. Add(' vP, vQ: tfuncint;');
  25641. Add('begin');
  25642. Add(' vp:=nil;');
  25643. Add(' vp:=vp;');
  25644. Add(' vp:=@doit;'); // ok in fpc and delphi
  25645. //Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  25646. Add(' vp;'); // ok in fpc and delphi
  25647. Add(' vp();');
  25648. Add(' vp(2);');
  25649. Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  25650. Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  25651. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  25652. Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  25653. Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  25654. //Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  25655. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  25656. Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  25657. Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  25658. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  25659. Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  25660. Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  25661. //Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  25662. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  25663. Add(' b:=Assigned(vp);');
  25664. //Add(' doit(vp);'); // illegal in fpc, ok in delphi
  25665. Add(' doit(vp());'); // ok in fpc and delphi
  25666. Add(' doit(vp(2));'); // ok in fpc and delphi
  25667. ConvertProgram;
  25668. CheckSource('TestProcType_FunctionFPC',
  25669. LinesToStr([ // statements
  25670. 'this.DoIt = function(vI) {',
  25671. ' var Result = 0;',
  25672. ' return Result;',
  25673. '};',
  25674. 'this.b = false;',
  25675. 'this.vP = null;',
  25676. 'this.vQ = null;'
  25677. ]),
  25678. LinesToStr([ // $mod.$main
  25679. '$mod.vP = null;',
  25680. '$mod.vP = $mod.vP;',
  25681. '$mod.vP = $mod.DoIt;',
  25682. '$mod.vP(1);',
  25683. '$mod.vP(1);',
  25684. '$mod.vP(2);',
  25685. '$mod.b = $mod.vP === null;',
  25686. '$mod.b = null === $mod.vP;',
  25687. '$mod.b = rtl.eqCallback($mod.vP,$mod.vQ);',
  25688. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  25689. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  25690. '$mod.b = 4 === $mod.vP(1);',
  25691. '$mod.b = $mod.vP !== null;',
  25692. '$mod.b = null !== $mod.vP;',
  25693. '$mod.b = !rtl.eqCallback($mod.vP,$mod.vQ);',
  25694. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  25695. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  25696. '$mod.b = 6 !== $mod.vP(1);',
  25697. '$mod.b = $mod.vP != null;',
  25698. '$mod.DoIt($mod.vP(1));',
  25699. '$mod.DoIt($mod.vP(2));',
  25700. '']));
  25701. end;
  25702. procedure TTestModule.TestProcType_FunctionDelphi;
  25703. begin
  25704. StartProgram(false);
  25705. Add('{$mode Delphi}');
  25706. Add('type');
  25707. Add(' TFuncInt = function(vA: longint = 1): longint;');
  25708. Add('function DoIt(vI: longint): longint;');
  25709. Add('begin end;');
  25710. Add('var');
  25711. Add(' b: boolean;');
  25712. Add(' vP, vQ: tfuncint;');
  25713. Add('begin');
  25714. Add(' vp:=nil;');
  25715. Add(' vp:=vp;');
  25716. Add(' vp:=@doit;'); // ok in fpc and delphi
  25717. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  25718. Add(' vp;'); // ok in fpc and delphi
  25719. Add(' vp();');
  25720. Add(' vp(2);');
  25721. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  25722. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  25723. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  25724. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  25725. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  25726. Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  25727. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  25728. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  25729. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  25730. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  25731. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  25732. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  25733. Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  25734. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  25735. Add(' b:=Assigned(vp);');
  25736. Add(' doit(vp);'); // illegal in fpc, ok in delphi
  25737. Add(' doit(vp());'); // ok in fpc and delphi
  25738. Add(' doit(vp(2));'); // ok in fpc and delphi *)
  25739. ConvertProgram;
  25740. CheckSource('TestProcType_FunctionDelphi',
  25741. LinesToStr([ // statements
  25742. 'this.DoIt = function(vI) {',
  25743. ' var Result = 0;',
  25744. ' return Result;',
  25745. '};',
  25746. 'this.b = false;',
  25747. 'this.vP = null;',
  25748. 'this.vQ = null;'
  25749. ]),
  25750. LinesToStr([ // $mod.$main
  25751. '$mod.vP = null;',
  25752. '$mod.vP = $mod.vP;',
  25753. '$mod.vP = $mod.DoIt;',
  25754. '$mod.vP = $mod.DoIt;',
  25755. '$mod.vP(1);',
  25756. '$mod.vP(1);',
  25757. '$mod.vP(2);',
  25758. '$mod.b = $mod.vP(1) === $mod.vQ(1);',
  25759. '$mod.b = $mod.vP(1) === 3;',
  25760. '$mod.b = 4 === $mod.vP(1);',
  25761. '$mod.b = $mod.vP(1) !== $mod.vQ(1);',
  25762. '$mod.b = $mod.vP(1) !== 5;',
  25763. '$mod.b = 6 !== $mod.vP(1);',
  25764. '$mod.b = $mod.vP != null;',
  25765. '$mod.DoIt($mod.vP(1));',
  25766. '$mod.DoIt($mod.vP(1));',
  25767. '$mod.DoIt($mod.vP(2));',
  25768. '']));
  25769. end;
  25770. procedure TTestModule.TestProcType_ProcedureDelphi;
  25771. begin
  25772. StartProgram(false);
  25773. Add('{$mode Delphi}');
  25774. Add('type');
  25775. Add(' TProc = procedure;');
  25776. Add('procedure DoIt;');
  25777. Add('begin end;');
  25778. Add('var');
  25779. Add(' b: boolean;');
  25780. Add(' vP, vQ: tproc;');
  25781. Add('begin');
  25782. Add(' vp:=nil;');
  25783. Add(' vp:=vp;');
  25784. Add(' vp:=vq;');
  25785. Add(' vp:=@doit;'); // ok in fpc and delphi, Note that in Delphi type of @F is Pointer, while in FPC it is the proc type
  25786. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  25787. //Add(' vp:=@doit;'); // illegal in fpc, ok in delphi (because Delphi treats @F as Pointer), not supported by resolver
  25788. Add(' vp;'); // ok in fpc and delphi
  25789. Add(' vp();');
  25790. // equal
  25791. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  25792. Add(' b:=@@vp=nil;'); // ok in fpc delphi mode, ok in delphi
  25793. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  25794. Add(' b:=nil=@@vp;'); // ok in fpc delphi mode, ok in delphi
  25795. Add(' b:=@@vp=@@vq;'); // ok in fpc delphi mode, ok in Delphi
  25796. //Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  25797. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  25798. Add(' b:=@@vp=@doit;'); // ok in fpc delphi mode, ok in delphi
  25799. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  25800. Add(' b:=@doit=@@vp;'); // ok in fpc delphi mode, ok in delphi
  25801. // unequal
  25802. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  25803. Add(' b:=@@vp<>nil;'); // ok in fpc mode delphi, ok in delphi
  25804. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  25805. Add(' b:=nil<>@@vp;'); // ok in fpc mode delphi, ok in delphi
  25806. //Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  25807. Add(' b:=@@vp<>@@vq;'); // ok in fpc mode delphi, ok in delphi
  25808. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  25809. Add(' b:=@@vp<>@doit;'); // ok in fpc mode delphi, illegal in delphi
  25810. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  25811. Add(' b:=@doit<>@@vp;'); // ok in fpc mode delphi, illegal in delphi
  25812. Add(' b:=Assigned(vp);');
  25813. ConvertProgram;
  25814. CheckSource('TestProcType_ProcedureDelphi',
  25815. LinesToStr([ // statements
  25816. 'this.DoIt = function() {',
  25817. '};',
  25818. 'this.b = false;',
  25819. 'this.vP = null;',
  25820. 'this.vQ = null;'
  25821. ]),
  25822. LinesToStr([ // $mod.$main
  25823. '$mod.vP = null;',
  25824. '$mod.vP = $mod.vP;',
  25825. '$mod.vP = $mod.vQ;',
  25826. '$mod.vP = $mod.DoIt;',
  25827. '$mod.vP = $mod.DoIt;',
  25828. '$mod.vP();',
  25829. '$mod.vP();',
  25830. '$mod.b = $mod.vP === null;',
  25831. '$mod.b = null === $mod.vP;',
  25832. '$mod.b = rtl.eqCallback($mod.vP, $mod.vQ);',
  25833. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  25834. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  25835. '$mod.b = $mod.vP !== null;',
  25836. '$mod.b = null !== $mod.vP;',
  25837. '$mod.b = !rtl.eqCallback($mod.vP, $mod.vQ);',
  25838. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  25839. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  25840. '$mod.b = $mod.vP != null;',
  25841. '']));
  25842. end;
  25843. procedure TTestModule.TestProcType_AsParam;
  25844. begin
  25845. StartProgram(false);
  25846. Add('type');
  25847. Add(' TFuncInt = function(vA: longint = 1): longint;');
  25848. Add('procedure DoIt(vG: tfuncint; const vH: tfuncint; var vI: tfuncint);');
  25849. Add('var vJ: tfuncint;');
  25850. Add('begin');
  25851. Add(' vg:=vg;');
  25852. Add(' vj:=vh;');
  25853. Add(' vi:=vi;');
  25854. Add(' doit(vg,vg,vg);');
  25855. Add(' doit(vh,vh,vj);');
  25856. Add(' doit(vi,vi,vi);');
  25857. Add(' doit(vj,vj,vj);');
  25858. Add('end;');
  25859. Add('var i: tfuncint;');
  25860. Add('begin');
  25861. Add(' doit(i,i,i);');
  25862. ConvertProgram;
  25863. CheckSource('TestProcType_AsParam',
  25864. LinesToStr([ // statements
  25865. 'this.DoIt = function (vG,vH,vI) {',
  25866. ' var vJ = null;',
  25867. ' vG = vG;',
  25868. ' vJ = vH;',
  25869. ' vI.set(vI.get());',
  25870. ' $mod.DoIt(vG, vG, {',
  25871. ' get: function () {',
  25872. ' return vG;',
  25873. ' },',
  25874. ' set: function (v) {',
  25875. ' vG = v;',
  25876. ' }',
  25877. ' });',
  25878. ' $mod.DoIt(vH, vH, {',
  25879. ' get: function () {',
  25880. ' return vJ;',
  25881. ' },',
  25882. ' set: function (v) {',
  25883. ' vJ = v;',
  25884. ' }',
  25885. ' });',
  25886. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  25887. ' $mod.DoIt(vJ, vJ, {',
  25888. ' get: function () {',
  25889. ' return vJ;',
  25890. ' },',
  25891. ' set: function (v) {',
  25892. ' vJ = v;',
  25893. ' }',
  25894. ' });',
  25895. '};',
  25896. 'this.i = null;'
  25897. ]),
  25898. LinesToStr([
  25899. '$mod.DoIt($mod.i,$mod.i,{',
  25900. ' p: $mod,',
  25901. ' get: function () {',
  25902. ' return this.p.i;',
  25903. ' },',
  25904. ' set: function (v) {',
  25905. ' this.p.i = v;',
  25906. ' }',
  25907. '});'
  25908. ]));
  25909. end;
  25910. procedure TTestModule.TestProcType_MethodFPC;
  25911. begin
  25912. StartProgram(false);
  25913. Add('type');
  25914. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  25915. Add(' TObject = class');
  25916. Add(' function DoIt(vA: longint = 1): longint;');
  25917. Add(' end;');
  25918. Add('function TObject.DoIt(vA: longint = 1): longint;');
  25919. Add('begin');
  25920. Add('end;');
  25921. Add('var');
  25922. Add(' Obj: TObject;');
  25923. Add(' vP: tfuncint;');
  25924. Add(' b: boolean;');
  25925. Add('begin');
  25926. Add(' vp:[email protected];'); // ok in fpc and delphi
  25927. //Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  25928. Add(' vp;'); // ok in fpc and delphi
  25929. Add(' vp();');
  25930. Add(' vp(2);');
  25931. Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  25932. Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  25933. Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  25934. Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  25935. ConvertProgram;
  25936. CheckSource('TestProcType_MethodFPC',
  25937. LinesToStr([ // statements
  25938. 'rtl.createClass(this, "TObject", null, function () {',
  25939. ' this.$init = function () {',
  25940. ' };',
  25941. ' this.$final = function () {',
  25942. ' };',
  25943. ' this.DoIt = function (vA) {',
  25944. ' var Result = 0;',
  25945. ' return Result;',
  25946. ' };',
  25947. '});',
  25948. 'this.Obj = null;',
  25949. 'this.vP = null;',
  25950. 'this.b = false;'
  25951. ]),
  25952. LinesToStr([
  25953. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  25954. '$mod.vP(1);',
  25955. '$mod.vP(1);',
  25956. '$mod.vP(2);',
  25957. '$mod.b = rtl.eqCallback($mod.vP, rtl.createCallback($mod.Obj, "DoIt"));',
  25958. '$mod.b = rtl.eqCallback(rtl.createCallback($mod.Obj, "DoIt"), $mod.vP);',
  25959. '$mod.b = !rtl.eqCallback($mod.vP, rtl.createCallback($mod.Obj, "DoIt"));',
  25960. '$mod.b = !rtl.eqCallback(rtl.createCallback($mod.Obj, "DoIt"), $mod.vP);',
  25961. '']));
  25962. end;
  25963. procedure TTestModule.TestProcType_MethodDelphi;
  25964. begin
  25965. StartProgram(false);
  25966. Add([
  25967. '{$mode delphi}',
  25968. 'type',
  25969. ' TFuncInt = function(vA: longint = 1): longint of object;',
  25970. ' TObject = class',
  25971. ' function DoIt(vA: longint = 1): longint;',
  25972. ' end;',
  25973. 'function TObject.DoIt(vA: longint = 1): longint;',
  25974. 'begin',
  25975. 'end;',
  25976. 'var',
  25977. ' Obj: TObject;',
  25978. ' vP: tfuncint;',
  25979. ' b: boolean;',
  25980. 'begin',
  25981. ' vp:[email protected];', // ok in fpc and delphi
  25982. ' vp:=obj.doit;', // illegal in fpc, ok in delphi
  25983. ' vp;', // ok in fpc and delphi
  25984. ' vp();',
  25985. ' vp(2);',
  25986. //' b:[email protected];', // ok in fpc, illegal in delphi
  25987. //' b:[email protected]=vp;', // ok in fpc, illegal in delphi
  25988. //' b:=vp<>@obj.doit;', // ok in fpc, illegal in delphi
  25989. //' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  25990. '']);
  25991. ConvertProgram;
  25992. CheckSource('TestProcType_MethodDelphi',
  25993. LinesToStr([ // statements
  25994. 'rtl.createClass(this, "TObject", null, function () {',
  25995. ' this.$init = function () {',
  25996. ' };',
  25997. ' this.$final = function () {',
  25998. ' };',
  25999. ' this.DoIt = function (vA) {',
  26000. ' var Result = 0;',
  26001. ' return Result;',
  26002. ' };',
  26003. '});',
  26004. 'this.Obj = null;',
  26005. 'this.vP = null;',
  26006. 'this.b = false;'
  26007. ]),
  26008. LinesToStr([
  26009. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  26010. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  26011. '$mod.vP(1);',
  26012. '$mod.vP(1);',
  26013. '$mod.vP(2);',
  26014. '']));
  26015. end;
  26016. procedure TTestModule.TestProcType_PropertyFPC;
  26017. begin
  26018. StartProgram(false);
  26019. Add('type');
  26020. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  26021. Add(' TObject = class');
  26022. Add(' FOnFoo: TFuncInt;');
  26023. Add(' function DoIt(vA: longint = 1): longint;');
  26024. Add(' function GetFoo: TFuncInt;');
  26025. Add(' procedure SetFoo(const Value: TFuncInt);');
  26026. Add(' function GetEvents(Index: longint): TFuncInt;');
  26027. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  26028. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  26029. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  26030. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  26031. Add(' end;');
  26032. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  26033. Add('function tobject.getfoo: tfuncint; begin end;');
  26034. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  26035. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  26036. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  26037. Add('var');
  26038. Add(' Obj: TObject;');
  26039. Add(' vP: tfuncint;');
  26040. Add(' b: boolean;');
  26041. Add('begin');
  26042. Add(' obj.onfoo:=nil;');
  26043. Add(' obj.onbar:=nil;');
  26044. Add(' obj.events[1]:=nil;');
  26045. Add(' obj.onfoo:=obj.onfoo;');
  26046. Add(' obj.onbar:=obj.onbar;');
  26047. Add(' obj.events[2]:=obj.events[3];');
  26048. Add(' obj.onfoo:[email protected];');
  26049. Add(' obj.onbar:[email protected];');
  26050. Add(' obj.events[4]:[email protected];');
  26051. //Add(' obj.onfoo:=obj.doit;'); // delphi
  26052. //Add(' obj.onbar:=obj.doit;'); // delphi
  26053. //Add(' obj.events[4]:=obj.doit;'); // delphi
  26054. Add(' obj.onfoo;');
  26055. Add(' obj.onbar;');
  26056. //Add(' obj.events[5];'); ToDo in pasresolver
  26057. Add(' obj.onfoo();');
  26058. Add(' obj.onbar();');
  26059. Add(' obj.events[6]();');
  26060. Add(' b:=obj.onfoo=nil;');
  26061. Add(' b:=obj.onbar=nil;');
  26062. Add(' b:=obj.events[7]=nil;');
  26063. Add(' b:=obj.onfoo<>nil;');
  26064. Add(' b:=obj.onbar<>nil;');
  26065. Add(' b:=obj.events[8]<>nil;');
  26066. Add(' b:=obj.onfoo=vp;');
  26067. Add(' b:=obj.onbar=vp;');
  26068. Add(' b:=obj.events[9]=vp;');
  26069. Add(' b:=obj.onfoo=obj.onfoo;');
  26070. Add(' b:=obj.onbar=obj.onfoo;');
  26071. Add(' b:=obj.events[10]=obj.onfoo;');
  26072. Add(' b:=obj.onfoo<>obj.onfoo;');
  26073. Add(' b:=obj.onbar<>obj.onfoo;');
  26074. Add(' b:=obj.events[11]<>obj.onfoo;');
  26075. Add(' b:[email protected];');
  26076. Add(' b:[email protected];');
  26077. Add(' b:=obj.events[12][email protected];');
  26078. Add(' b:=obj.onfoo<>@obj.doit;');
  26079. Add(' b:=obj.onbar<>@obj.doit;');
  26080. Add(' b:=obj.events[12]<>@obj.doit;');
  26081. Add(' b:=Assigned(obj.onfoo);');
  26082. Add(' b:=Assigned(obj.onbar);');
  26083. Add(' b:=Assigned(obj.events[13]);');
  26084. ConvertProgram;
  26085. CheckSource('TestProcType_PropertyFPC',
  26086. LinesToStr([ // statements
  26087. 'rtl.createClass(this, "TObject", null, function () {',
  26088. ' this.$init = function () {',
  26089. ' this.FOnFoo = null;',
  26090. ' };',
  26091. ' this.$final = function () {',
  26092. ' this.FOnFoo = undefined;',
  26093. ' };',
  26094. ' this.DoIt = function (vA) {',
  26095. ' var Result = 0;',
  26096. ' return Result;',
  26097. ' };',
  26098. 'this.GetFoo = function () {',
  26099. ' var Result = null;',
  26100. ' return Result;',
  26101. '};',
  26102. 'this.SetFoo = function (Value) {',
  26103. '};',
  26104. 'this.GetEvents = function (Index) {',
  26105. ' var Result = null;',
  26106. ' return Result;',
  26107. '};',
  26108. 'this.SetEvents = function (Index, Value) {',
  26109. '};',
  26110. '});',
  26111. 'this.Obj = null;',
  26112. 'this.vP = null;',
  26113. 'this.b = false;'
  26114. ]),
  26115. LinesToStr([
  26116. '$mod.Obj.FOnFoo = null;',
  26117. '$mod.Obj.SetFoo(null);',
  26118. '$mod.Obj.SetEvents(1, null);',
  26119. '$mod.Obj.FOnFoo = $mod.Obj.FOnFoo;',
  26120. '$mod.Obj.SetFoo($mod.Obj.GetFoo());',
  26121. '$mod.Obj.SetEvents(2, $mod.Obj.GetEvents(3));',
  26122. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  26123. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  26124. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  26125. '$mod.Obj.FOnFoo(1);',
  26126. '$mod.Obj.GetFoo();',
  26127. '$mod.Obj.FOnFoo(1);',
  26128. '$mod.Obj.GetFoo()(1);',
  26129. '$mod.Obj.GetEvents(6)(1);',
  26130. '$mod.b = $mod.Obj.FOnFoo === null;',
  26131. '$mod.b = $mod.Obj.GetFoo() === null;',
  26132. '$mod.b = $mod.Obj.GetEvents(7) === null;',
  26133. '$mod.b = $mod.Obj.FOnFoo !== null;',
  26134. '$mod.b = $mod.Obj.GetFoo() !== null;',
  26135. '$mod.b = $mod.Obj.GetEvents(8) !== null;',
  26136. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, $mod.vP);',
  26137. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), $mod.vP);',
  26138. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(9), $mod.vP);',
  26139. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, $mod.Obj.FOnFoo);',
  26140. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), $mod.Obj.FOnFoo);',
  26141. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(10), $mod.Obj.FOnFoo);',
  26142. '$mod.b = !rtl.eqCallback($mod.Obj.FOnFoo, $mod.Obj.FOnFoo);',
  26143. '$mod.b = !rtl.eqCallback($mod.Obj.GetFoo(), $mod.Obj.FOnFoo);',
  26144. '$mod.b = !rtl.eqCallback($mod.Obj.GetEvents(11), $mod.Obj.FOnFoo);',
  26145. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, rtl.createCallback($mod.Obj, "DoIt"));',
  26146. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), rtl.createCallback($mod.Obj, "DoIt"));',
  26147. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(12), rtl.createCallback($mod.Obj, "DoIt"));',
  26148. '$mod.b = !rtl.eqCallback($mod.Obj.FOnFoo, rtl.createCallback($mod.Obj, "DoIt"));',
  26149. '$mod.b = !rtl.eqCallback($mod.Obj.GetFoo(), rtl.createCallback($mod.Obj, "DoIt"));',
  26150. '$mod.b = !rtl.eqCallback($mod.Obj.GetEvents(12), rtl.createCallback($mod.Obj, "DoIt"));',
  26151. '$mod.b = $mod.Obj.FOnFoo != null;',
  26152. '$mod.b = $mod.Obj.GetFoo() != null;',
  26153. '$mod.b = $mod.Obj.GetEvents(13) != null;',
  26154. '']));
  26155. end;
  26156. procedure TTestModule.TestProcType_PropertyDelphi;
  26157. begin
  26158. StartProgram(false);
  26159. Add('{$mode delphi}');
  26160. Add('type');
  26161. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  26162. Add(' TObject = class');
  26163. Add(' FOnFoo: TFuncInt;');
  26164. Add(' function DoIt(vA: longint = 1): longint;');
  26165. Add(' function GetFoo: TFuncInt;');
  26166. Add(' procedure SetFoo(const Value: TFuncInt);');
  26167. Add(' function GetEvents(Index: longint): TFuncInt;');
  26168. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  26169. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  26170. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  26171. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  26172. Add(' end;');
  26173. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  26174. Add('function tobject.getfoo: tfuncint; begin end;');
  26175. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  26176. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  26177. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  26178. Add('var');
  26179. Add(' Obj: TObject;');
  26180. Add(' vP: tfuncint;');
  26181. Add(' b: boolean;');
  26182. Add('begin');
  26183. Add(' obj.onfoo:=nil;');
  26184. Add(' obj.onbar:=nil;');
  26185. Add(' obj.events[1]:=nil;');
  26186. Add(' obj.onfoo:=obj.onfoo;');
  26187. Add(' obj.onbar:=obj.onbar;');
  26188. Add(' obj.events[2]:=obj.events[3];');
  26189. Add(' obj.onfoo:[email protected];');
  26190. Add(' obj.onbar:[email protected];');
  26191. Add(' obj.events[4]:[email protected];');
  26192. Add(' obj.onfoo:=obj.doit;'); // delphi
  26193. Add(' obj.onbar:=obj.doit;'); // delphi
  26194. Add(' obj.events[4]:=obj.doit;'); // delphi
  26195. Add(' obj.onfoo;');
  26196. Add(' obj.onbar;');
  26197. //Add(' obj.events[5];'); ToDo in pasresolver
  26198. Add(' obj.onfoo();');
  26199. Add(' obj.onbar();');
  26200. Add(' obj.events[6]();');
  26201. //Add(' b:=obj.onfoo=nil;'); // fpc
  26202. //Add(' b:=obj.onbar=nil;'); // fpc
  26203. //Add(' b:=obj.events[7]=nil;'); // fpc
  26204. //Add(' b:=obj.onfoo<>nil;'); // fpc
  26205. //Add(' b:=obj.onbar<>nil;'); // fpc
  26206. //Add(' b:=obj.events[8]<>nil;'); // fpc
  26207. Add(' b:=obj.onfoo=vp;');
  26208. Add(' b:=obj.onbar=vp;');
  26209. //Add(' b:=obj.events[9]=vp;'); ToDo in pasresolver
  26210. Add(' b:=obj.onfoo=obj.onfoo;');
  26211. Add(' b:=obj.onbar=obj.onfoo;');
  26212. //Add(' b:=obj.events[10]=obj.onfoo;'); // ToDo in pasresolver
  26213. Add(' b:=obj.onfoo<>obj.onfoo;');
  26214. Add(' b:=obj.onbar<>obj.onfoo;');
  26215. //Add(' b:=obj.events[11]<>obj.onfoo;'); // ToDo in pasresolver
  26216. //Add(' b:[email protected];'); // fpc
  26217. //Add(' b:[email protected];'); // fpc
  26218. //Add(' b:=obj.events[12][email protected];'); // fpc
  26219. //Add(' b:=obj.onfoo<>@obj.doit;'); // fpc
  26220. //Add(' b:=obj.onbar<>@obj.doit;'); // fpc
  26221. //Add(' b:=obj.events[12]<>@obj.doit;'); // fpc
  26222. Add(' b:=Assigned(obj.onfoo);');
  26223. Add(' b:=Assigned(obj.onbar);');
  26224. Add(' b:=Assigned(obj.events[13]);');
  26225. ConvertProgram;
  26226. CheckSource('TestProcType_PropertyDelphi',
  26227. LinesToStr([ // statements
  26228. 'rtl.createClass(this, "TObject", null, function () {',
  26229. ' this.$init = function () {',
  26230. ' this.FOnFoo = null;',
  26231. ' };',
  26232. ' this.$final = function () {',
  26233. ' this.FOnFoo = undefined;',
  26234. ' };',
  26235. ' this.DoIt = function (vA) {',
  26236. ' var Result = 0;',
  26237. ' return Result;',
  26238. ' };',
  26239. 'this.GetFoo = function () {',
  26240. ' var Result = null;',
  26241. ' return Result;',
  26242. '};',
  26243. 'this.SetFoo = function (Value) {',
  26244. '};',
  26245. 'this.GetEvents = function (Index) {',
  26246. ' var Result = null;',
  26247. ' return Result;',
  26248. '};',
  26249. 'this.SetEvents = function (Index, Value) {',
  26250. '};',
  26251. '});',
  26252. 'this.Obj = null;',
  26253. 'this.vP = null;',
  26254. 'this.b = false;'
  26255. ]),
  26256. LinesToStr([
  26257. '$mod.Obj.FOnFoo = null;',
  26258. '$mod.Obj.SetFoo(null);',
  26259. '$mod.Obj.SetEvents(1, null);',
  26260. '$mod.Obj.FOnFoo = $mod.Obj.FOnFoo;',
  26261. '$mod.Obj.SetFoo($mod.Obj.GetFoo());',
  26262. '$mod.Obj.SetEvents(2, $mod.Obj.GetEvents(3));',
  26263. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  26264. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  26265. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  26266. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  26267. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  26268. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  26269. '$mod.Obj.FOnFoo(1);',
  26270. '$mod.Obj.GetFoo();',
  26271. '$mod.Obj.FOnFoo(1);',
  26272. '$mod.Obj.GetFoo()(1);',
  26273. '$mod.Obj.GetEvents(6)(1);',
  26274. '$mod.b = $mod.Obj.FOnFoo(1) === $mod.vP(1);',
  26275. '$mod.b = $mod.Obj.GetFoo() === $mod.vP(1);',
  26276. '$mod.b = $mod.Obj.FOnFoo(1) === $mod.Obj.FOnFoo(1);',
  26277. '$mod.b = $mod.Obj.GetFoo() === $mod.Obj.FOnFoo(1);',
  26278. '$mod.b = $mod.Obj.FOnFoo(1) !== $mod.Obj.FOnFoo(1);',
  26279. '$mod.b = $mod.Obj.GetFoo() !== $mod.Obj.FOnFoo(1);',
  26280. '$mod.b = $mod.Obj.FOnFoo != null;',
  26281. '$mod.b = $mod.Obj.GetFoo() != null;',
  26282. '$mod.b = $mod.Obj.GetEvents(13) != null;',
  26283. '']));
  26284. end;
  26285. procedure TTestModule.TestProcType_WithClassInstDoPropertyFPC;
  26286. begin
  26287. StartProgram(false);
  26288. Add('type');
  26289. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  26290. Add(' TObject = class');
  26291. Add(' FOnFoo: TFuncInt;');
  26292. Add(' function DoIt(vA: longint = 1): longint;');
  26293. Add(' function GetFoo: TFuncInt;');
  26294. Add(' procedure SetFoo(const Value: TFuncInt);');
  26295. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  26296. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  26297. Add(' end;');
  26298. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  26299. Add('function tobject.getfoo: tfuncint; begin end;');
  26300. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  26301. Add('var');
  26302. Add(' Obj: TObject;');
  26303. Add(' vP: tfuncint;');
  26304. Add(' b: boolean;');
  26305. Add('begin');
  26306. Add('with obj do begin');
  26307. Add(' fonfoo:=nil;');
  26308. Add(' onfoo:=nil;');
  26309. Add(' onbar:=nil;');
  26310. Add(' fonfoo:=fonfoo;');
  26311. Add(' onfoo:=onfoo;');
  26312. Add(' onbar:=onbar;');
  26313. Add(' fonfoo:=@doit;');
  26314. Add(' onfoo:=@doit;');
  26315. Add(' onbar:=@doit;');
  26316. //Add(' fonfoo:=doit;'); // delphi
  26317. //Add(' onfoo:=doit;'); // delphi
  26318. //Add(' onbar:=doit;'); // delphi
  26319. Add(' fonfoo;');
  26320. Add(' onfoo;');
  26321. Add(' onbar;');
  26322. Add(' fonfoo();');
  26323. Add(' onfoo();');
  26324. Add(' onbar();');
  26325. Add(' b:=fonfoo=nil;');
  26326. Add(' b:=onfoo=nil;');
  26327. Add(' b:=onbar=nil;');
  26328. Add(' b:=fonfoo<>nil;');
  26329. Add(' b:=onfoo<>nil;');
  26330. Add(' b:=onbar<>nil;');
  26331. Add(' b:=fonfoo=vp;');
  26332. Add(' b:=onfoo=vp;');
  26333. Add(' b:=onbar=vp;');
  26334. Add(' b:=fonfoo=fonfoo;');
  26335. Add(' b:=onfoo=onfoo;');
  26336. Add(' b:=onbar=onfoo;');
  26337. Add(' b:=fonfoo<>fonfoo;');
  26338. Add(' b:=onfoo<>onfoo;');
  26339. Add(' b:=onbar<>onfoo;');
  26340. Add(' b:=fonfoo=@doit;');
  26341. Add(' b:=onfoo=@doit;');
  26342. Add(' b:=onbar=@doit;');
  26343. Add(' b:=fonfoo<>@doit;');
  26344. Add(' b:=onfoo<>@doit;');
  26345. Add(' b:=onbar<>@doit;');
  26346. Add(' b:=Assigned(fonfoo);');
  26347. Add(' b:=Assigned(onfoo);');
  26348. Add(' b:=Assigned(onbar);');
  26349. Add('end;');
  26350. ConvertProgram;
  26351. CheckSource('TestProcType_WithClassInstDoPropertyFPC',
  26352. LinesToStr([ // statements
  26353. 'rtl.createClass(this, "TObject", null, function () {',
  26354. ' this.$init = function () {',
  26355. ' this.FOnFoo = null;',
  26356. ' };',
  26357. ' this.$final = function () {',
  26358. ' this.FOnFoo = undefined;',
  26359. ' };',
  26360. ' this.DoIt = function (vA) {',
  26361. ' var Result = 0;',
  26362. ' return Result;',
  26363. ' };',
  26364. ' this.GetFoo = function () {',
  26365. ' var Result = null;',
  26366. ' return Result;',
  26367. ' };',
  26368. ' this.SetFoo = function (Value) {',
  26369. ' };',
  26370. '});',
  26371. 'this.Obj = null;',
  26372. 'this.vP = null;',
  26373. 'this.b = false;'
  26374. ]),
  26375. LinesToStr([
  26376. 'var $with = $mod.Obj;',
  26377. '$with.FOnFoo = null;',
  26378. '$with.FOnFoo = null;',
  26379. '$with.SetFoo(null);',
  26380. '$with.FOnFoo = $with.FOnFoo;',
  26381. '$with.FOnFoo = $with.FOnFoo;',
  26382. '$with.SetFoo($with.GetFoo());',
  26383. '$with.FOnFoo = rtl.createCallback($with, "DoIt");',
  26384. '$with.FOnFoo = rtl.createCallback($with, "DoIt");',
  26385. '$with.SetFoo(rtl.createCallback($with, "DoIt"));',
  26386. '$with.FOnFoo(1);',
  26387. '$with.FOnFoo(1);',
  26388. '$with.GetFoo();',
  26389. '$with.FOnFoo(1);',
  26390. '$with.FOnFoo(1);',
  26391. '$with.GetFoo()(1);',
  26392. '$mod.b = $with.FOnFoo === null;',
  26393. '$mod.b = $with.FOnFoo === null;',
  26394. '$mod.b = $with.GetFoo() === null;',
  26395. '$mod.b = $with.FOnFoo !== null;',
  26396. '$mod.b = $with.FOnFoo !== null;',
  26397. '$mod.b = $with.GetFoo() !== null;',
  26398. '$mod.b = rtl.eqCallback($with.FOnFoo, $mod.vP);',
  26399. '$mod.b = rtl.eqCallback($with.FOnFoo, $mod.vP);',
  26400. '$mod.b = rtl.eqCallback($with.GetFoo(), $mod.vP);',
  26401. '$mod.b = rtl.eqCallback($with.FOnFoo, $with.FOnFoo);',
  26402. '$mod.b = rtl.eqCallback($with.FOnFoo, $with.FOnFoo);',
  26403. '$mod.b = rtl.eqCallback($with.GetFoo(), $with.FOnFoo);',
  26404. '$mod.b = !rtl.eqCallback($with.FOnFoo, $with.FOnFoo);',
  26405. '$mod.b = !rtl.eqCallback($with.FOnFoo, $with.FOnFoo);',
  26406. '$mod.b = !rtl.eqCallback($with.GetFoo(), $with.FOnFoo);',
  26407. '$mod.b = rtl.eqCallback($with.FOnFoo, rtl.createCallback($with, "DoIt"));',
  26408. '$mod.b = rtl.eqCallback($with.FOnFoo, rtl.createCallback($with, "DoIt"));',
  26409. '$mod.b = rtl.eqCallback($with.GetFoo(), rtl.createCallback($with, "DoIt"));',
  26410. '$mod.b = !rtl.eqCallback($with.FOnFoo, rtl.createCallback($with, "DoIt"));',
  26411. '$mod.b = !rtl.eqCallback($with.FOnFoo, rtl.createCallback($with, "DoIt"));',
  26412. '$mod.b = !rtl.eqCallback($with.GetFoo(), rtl.createCallback($with, "DoIt"));',
  26413. '$mod.b = $with.FOnFoo != null;',
  26414. '$mod.b = $with.FOnFoo != null;',
  26415. '$mod.b = $with.GetFoo() != null;',
  26416. '']));
  26417. end;
  26418. procedure TTestModule.TestProcType_Nested;
  26419. begin
  26420. StartProgram(false);
  26421. Add([
  26422. 'type',
  26423. ' TProcInt = procedure(vI: longint = 1);',
  26424. 'procedure DoIt(vJ: longint);',
  26425. 'var aProc: TProcInt;',
  26426. ' b: boolean;',
  26427. ' procedure Sub(vK: longint);',
  26428. ' var aSub: TProcInt;',
  26429. ' procedure SubSub(vK: longint);',
  26430. ' var aSubSub: TProcInt;',
  26431. ' begin;',
  26432. ' aProc:=@DoIt;',
  26433. ' aSub:=@DoIt;',
  26434. ' aSubSub:=@DoIt;',
  26435. ' aProc:=@Sub;',
  26436. ' aSub:=@Sub;',
  26437. ' aSubSub:=@Sub;',
  26438. ' aProc:=@SubSub;',
  26439. ' aSub:=@SubSub;',
  26440. ' aSubSub:=@SubSub;',
  26441. ' end;',
  26442. ' begin;',
  26443. ' end;',
  26444. 'begin;',
  26445. ' aProc:=@Sub;',
  26446. ' b:=aProc=@Sub;',
  26447. ' b:=@Sub=aProc;',
  26448. 'end;',
  26449. 'begin',
  26450. '']);
  26451. ConvertProgram;
  26452. CheckSource('TestProcType_Nested',
  26453. LinesToStr([ // statements
  26454. 'this.DoIt = function (vJ) {',
  26455. ' var aProc = null;',
  26456. ' var b = false;',
  26457. ' function Sub(vK) {',
  26458. ' var aSub = null;',
  26459. ' function SubSub(vK) {',
  26460. ' var aSubSub = null;',
  26461. ' aProc = $mod.DoIt;',
  26462. ' aSub = $mod.DoIt;',
  26463. ' aSubSub = $mod.DoIt;',
  26464. ' aProc = Sub;',
  26465. ' aSub = Sub;',
  26466. ' aSubSub = Sub;',
  26467. ' aProc = SubSub;',
  26468. ' aSub = SubSub;',
  26469. ' aSubSub = SubSub;',
  26470. ' };',
  26471. ' };',
  26472. ' aProc = Sub;',
  26473. ' b = rtl.eqCallback(aProc, Sub);',
  26474. ' b = rtl.eqCallback(Sub, aProc);',
  26475. '};',
  26476. '']),
  26477. LinesToStr([ // $mod.$main
  26478. '']));
  26479. end;
  26480. procedure TTestModule.TestProcType_NestedOfObject;
  26481. begin
  26482. StartProgram(false);
  26483. Add([
  26484. 'type',
  26485. ' TProcInt = procedure(vI: longint = 1) of object;',
  26486. ' TObject = class',
  26487. ' procedure DoIt(vJ: longint);',
  26488. ' end;',
  26489. 'procedure TObject.DoIt(vJ: longint);',
  26490. 'var aProc: TProcInt;',
  26491. ' b: boolean;',
  26492. ' procedure Sub(vK: longint);',
  26493. ' var aSub: TProcInt;',
  26494. ' procedure SubSub(vK: longint);',
  26495. ' var aSubSub: TProcInt;',
  26496. ' begin;',
  26497. ' aProc:=@DoIt;',
  26498. ' aSub:=@DoIt;',
  26499. ' aSubSub:=@DoIt;',
  26500. ' aProc:=@Sub;',
  26501. ' aSub:=@Sub;',
  26502. ' aSubSub:=@Sub;',
  26503. ' aProc:=@SubSub;',
  26504. ' aSub:=@SubSub;',
  26505. ' aSubSub:=@SubSub;',
  26506. ' end;',
  26507. ' begin;',
  26508. ' end;',
  26509. 'begin;',
  26510. ' aProc:=@Sub;',
  26511. ' b:=aProc=@Sub;',
  26512. ' b:=@Sub=aProc;',
  26513. 'end;',
  26514. 'begin',
  26515. '']);
  26516. ConvertProgram;
  26517. CheckSource('TestProcType_Nested',
  26518. LinesToStr([ // statements
  26519. 'rtl.createClass(this, "TObject", null, function () {',
  26520. ' this.$init = function () {',
  26521. ' };',
  26522. ' this.$final = function () {',
  26523. ' };',
  26524. ' this.DoIt = function (vJ) {',
  26525. ' var $Self = this;',
  26526. ' var aProc = null;',
  26527. ' var b = false;',
  26528. ' function Sub(vK) {',
  26529. ' var aSub = null;',
  26530. ' function SubSub(vK) {',
  26531. ' var aSubSub = null;',
  26532. ' aProc = rtl.createCallback($Self, "DoIt");',
  26533. ' aSub = rtl.createCallback($Self, "DoIt");',
  26534. ' aSubSub = rtl.createCallback($Self, "DoIt");',
  26535. ' aProc = Sub;',
  26536. ' aSub = Sub;',
  26537. ' aSubSub = Sub;',
  26538. ' aProc = SubSub;',
  26539. ' aSub = SubSub;',
  26540. ' aSubSub = SubSub;',
  26541. ' };',
  26542. ' };',
  26543. ' aProc = Sub;',
  26544. ' b = rtl.eqCallback(aProc, Sub);',
  26545. ' b = rtl.eqCallback(Sub, aProc);',
  26546. ' };',
  26547. '});',
  26548. '']),
  26549. LinesToStr([ // $mod.$main
  26550. '']));
  26551. end;
  26552. procedure TTestModule.TestProcType_ReferenceToProc;
  26553. begin
  26554. StartProgram(false);
  26555. Add([
  26556. 'type',
  26557. ' TProcRef = reference to procedure(i: longint = 0);',
  26558. ' TFuncRef = reference to function(i: longint = 0): longint;',
  26559. 'var',
  26560. ' p: TProcRef;',
  26561. ' f: TFuncRef;',
  26562. 'procedure DoIt(i: longint);',
  26563. 'begin',
  26564. 'end;',
  26565. 'function GetIt(i: longint): longint;',
  26566. 'begin',
  26567. ' p:=@DoIt;',
  26568. ' f:=@GetIt;',
  26569. ' f;',
  26570. ' f();',
  26571. ' f(1);',
  26572. 'end;',
  26573. 'begin',
  26574. ' p:=@DoIt;',
  26575. ' f:=@GetIt;',
  26576. ' f;',
  26577. ' f();',
  26578. ' f(1);',
  26579. ' p:=TProcRef(f);',
  26580. '']);
  26581. ConvertProgram;
  26582. CheckSource('TestProcType_ReferenceToProc',
  26583. LinesToStr([ // statements
  26584. 'this.p = null;',
  26585. 'this.f = null;',
  26586. 'this.DoIt = function (i) {',
  26587. '};',
  26588. 'this.GetIt = function (i) {',
  26589. ' var Result = 0;',
  26590. ' $mod.p = $mod.DoIt;',
  26591. ' $mod.f = $mod.GetIt;',
  26592. ' $mod.f(0);',
  26593. ' $mod.f(0);',
  26594. ' $mod.f(1);',
  26595. ' return Result;',
  26596. '};',
  26597. '']),
  26598. LinesToStr([ // $mod.$main
  26599. '$mod.p = $mod.DoIt;',
  26600. '$mod.f = $mod.GetIt;',
  26601. '$mod.f(0);',
  26602. '$mod.f(0);',
  26603. '$mod.f(1);',
  26604. '$mod.p = $mod.f;',
  26605. '']));
  26606. end;
  26607. procedure TTestModule.TestProcType_ReferenceToMethod;
  26608. begin
  26609. StartProgram(false);
  26610. Add([
  26611. 'type',
  26612. ' TFuncRef = reference to function(i: longint = 5): longint;',
  26613. ' TObject = class',
  26614. ' function Grow(s: longint): longint;',
  26615. ' end;',
  26616. 'var',
  26617. ' f: tfuncref;',
  26618. 'function tobject.grow(s: longint): longint;',
  26619. ' function GrowSub(i: longint): longint;',
  26620. ' begin',
  26621. ' f:=@grow;',
  26622. ' f:=@growsub;',
  26623. ' end;',
  26624. 'begin',
  26625. ' f:=@grow;',
  26626. ' f:=@growsub;',
  26627. 'end;',
  26628. 'begin',
  26629. '']);
  26630. ConvertProgram;
  26631. CheckSource('TestProcType_ReferenceToMethod',
  26632. LinesToStr([ // statements
  26633. 'rtl.createClass(this, "TObject", null, function () {',
  26634. ' this.$init = function () {',
  26635. ' };',
  26636. ' this.$final = function () {',
  26637. ' };',
  26638. ' this.Grow = function (s) {',
  26639. ' var $Self = this;',
  26640. ' var Result = 0;',
  26641. ' function GrowSub(i) {',
  26642. ' var Result = 0;',
  26643. ' $mod.f = rtl.createCallback($Self, "Grow");',
  26644. ' $mod.f = GrowSub;',
  26645. ' return Result;',
  26646. ' };',
  26647. ' $mod.f = rtl.createCallback($Self, "Grow");',
  26648. ' $mod.f = GrowSub;',
  26649. ' return Result;',
  26650. ' };',
  26651. '});',
  26652. 'this.f = null;',
  26653. '']),
  26654. LinesToStr([ // $mod.$main
  26655. '']));
  26656. end;
  26657. procedure TTestModule.TestProcType_Typecast;
  26658. begin
  26659. StartProgram(false);
  26660. Add([
  26661. 'type',
  26662. ' TNotifyEvent = procedure(Sender: Pointer) of object;',
  26663. ' TEvent = procedure of object;',
  26664. ' TGetter = function:longint of object;',
  26665. ' TProcA = procedure(i: longint);',
  26666. ' TFuncB = function(i, j: longint): longint;',
  26667. 'procedure DoIt(); varargs; begin end;',
  26668. 'var',
  26669. ' Notify: tnotifyevent;',
  26670. ' Event: tevent;',
  26671. ' Getter: tgetter;',
  26672. ' ProcA: tproca;',
  26673. ' FuncB: tfuncb;',
  26674. ' p: pointer;',
  26675. 'begin',
  26676. ' notify:=tnotifyevent(event);',
  26677. ' event:=tevent(event);',
  26678. ' event:=tevent(notify);',
  26679. ' event:=tevent(getter);',
  26680. ' event:=tevent(proca);',
  26681. ' proca:=tproca(funcb);',
  26682. ' funcb:=tfuncb(funcb);',
  26683. ' funcb:=tfuncb(proca);',
  26684. ' funcb:=tfuncb(getter);',
  26685. ' proca:=tproca(p);',
  26686. ' funcb:=tfuncb(p);',
  26687. ' getter:=tgetter(p);',
  26688. ' p:=pointer(notify);',
  26689. ' p:=notify;',
  26690. ' p:=pointer(proca);',
  26691. ' p:=proca;',
  26692. ' p:=pointer(funcb);',
  26693. ' p:=funcb;',
  26694. ' doit(Pointer(notify),pointer(event),pointer(proca));',
  26695. '']);
  26696. ConvertProgram;
  26697. CheckSource('TestProcType_Typecast',
  26698. LinesToStr([ // statements
  26699. 'this.DoIt = function () {',
  26700. '};',
  26701. 'this.Notify = null;',
  26702. 'this.Event = null;',
  26703. 'this.Getter = null;',
  26704. 'this.ProcA = null;',
  26705. 'this.FuncB = null;',
  26706. 'this.p = null;',
  26707. '']),
  26708. LinesToStr([ // $mod.$main
  26709. '$mod.Notify = $mod.Event;',
  26710. '$mod.Event = $mod.Event;',
  26711. '$mod.Event = $mod.Notify;',
  26712. '$mod.Event = $mod.Getter;',
  26713. '$mod.Event = $mod.ProcA;',
  26714. '$mod.ProcA = $mod.FuncB;',
  26715. '$mod.FuncB = $mod.FuncB;',
  26716. '$mod.FuncB = $mod.ProcA;',
  26717. '$mod.FuncB = $mod.Getter;',
  26718. '$mod.ProcA = $mod.p;',
  26719. '$mod.FuncB = $mod.p;',
  26720. '$mod.Getter = $mod.p;',
  26721. '$mod.p = $mod.Notify;',
  26722. '$mod.p = $mod.Notify;',
  26723. '$mod.p = $mod.ProcA;',
  26724. '$mod.p = $mod.ProcA;',
  26725. '$mod.p = $mod.FuncB;',
  26726. '$mod.p = $mod.FuncB;',
  26727. '$mod.DoIt($mod.Notify, $mod.Event, $mod.ProcA);',
  26728. '']));
  26729. end;
  26730. procedure TTestModule.TestProcType_PassProcToUntyped;
  26731. begin
  26732. StartProgram(false);
  26733. Add([
  26734. 'type',
  26735. ' TEvent = procedure of object;',
  26736. ' TFunc = function: longint;',
  26737. 'procedure DoIt(); varargs; begin end;',
  26738. 'procedure DoSome(const a; var b; p: pointer); begin end;',
  26739. 'var',
  26740. ' Event: tevent;',
  26741. ' Func: TFunc;',
  26742. 'begin',
  26743. ' doit(event,func);',
  26744. ' dosome(event,event,event);',
  26745. ' dosome(func,func,func);',
  26746. '']);
  26747. ConvertProgram;
  26748. CheckSource('TestProcType_PassProcToUntyped',
  26749. LinesToStr([ // statements
  26750. 'this.DoIt = function () {',
  26751. '};',
  26752. 'this.DoSome = function (a, b, p) {',
  26753. '};',
  26754. 'this.Event = null;',
  26755. 'this.Func = null;',
  26756. '']),
  26757. LinesToStr([ // $mod.$main
  26758. '$mod.DoIt($mod.Event, $mod.Func);',
  26759. '$mod.DoSome($mod.Event, {',
  26760. ' p: $mod,',
  26761. ' get: function () {',
  26762. ' return this.p.Event;',
  26763. ' },',
  26764. ' set: function (v) {',
  26765. ' this.p.Event = v;',
  26766. ' }',
  26767. '}, $mod.Event);',
  26768. '$mod.DoSome($mod.Func, {',
  26769. ' p: $mod,',
  26770. ' get: function () {',
  26771. ' return this.p.Func;',
  26772. ' },',
  26773. ' set: function (v) {',
  26774. ' this.p.Func = v;',
  26775. ' }',
  26776. '}, $mod.Func);',
  26777. '']));
  26778. end;
  26779. procedure TTestModule.TestProcType_PassProcToArray;
  26780. begin
  26781. StartProgram(false);
  26782. Add([
  26783. 'type',
  26784. ' TFunc = function: longint;',
  26785. ' TArrFunc = array of TFunc;',
  26786. 'procedure DoIt(Arr: TArrFunc); begin end;',
  26787. 'function GetIt: longint; begin end;',
  26788. 'var',
  26789. ' Func: tfunc;',
  26790. 'begin',
  26791. ' doit([]);',
  26792. ' doit([@GetIt]);',
  26793. ' doit([Func]);',
  26794. '']);
  26795. ConvertProgram;
  26796. CheckSource('TestProcType_PassProcToArray',
  26797. LinesToStr([ // statements
  26798. 'this.DoIt = function (Arr) {',
  26799. '};',
  26800. 'this.GetIt = function () {',
  26801. ' var Result = 0;',
  26802. ' return Result;',
  26803. '};',
  26804. 'this.Func = null;',
  26805. '']),
  26806. LinesToStr([ // $mod.$main
  26807. '$mod.DoIt([]);',
  26808. '$mod.DoIt([$mod.GetIt]);',
  26809. '$mod.DoIt([$mod.Func]);',
  26810. '']));
  26811. end;
  26812. procedure TTestModule.TestProcType_SafeCallObjFPC;
  26813. begin
  26814. StartProgram(false);
  26815. Add([
  26816. '{$modeswitch externalclass}',
  26817. 'type',
  26818. ' TProc = reference to procedure(i: longint); safecall;',
  26819. ' TEvent = procedure(i: longint) of object; safecall;',
  26820. ' TExtA = class external name ''ExtObj''',
  26821. ' procedure DoIt(Id: longint = 1); external name ''$Execute'';',
  26822. ' procedure DoSome(Id: longint = 1);',
  26823. ' procedure SetOnClick(const e: TEvent);',
  26824. ' property OnClick: TEvent write SetOnClick;',
  26825. ' class procedure Fly(Id: longint = 1); static;',
  26826. ' procedure SetOnShow(const p: TProc);',
  26827. ' property OnShow: TProc write SetOnShow;',
  26828. ' end;',
  26829. 'procedure Run(i: longint = 1);',
  26830. 'begin',
  26831. 'end;',
  26832. 'var',
  26833. ' Obj: texta;',
  26834. ' e: TEvent;',
  26835. ' p: TProc;',
  26836. 'begin',
  26837. ' e:=e;',
  26838. ' e:[email protected];',
  26839. ' e:[email protected];',
  26840. ' e:=TEvent(@obj.dosome);', // no safecall
  26841. ' obj.OnClick:[email protected];',
  26842. ' obj.OnClick:[email protected];',
  26843. ' obj.setonclick(@obj.doit);',
  26844. ' obj.setonclick(@obj.dosome);',
  26845. ' p:=@Run;',
  26846. ' p:[email protected];',
  26847. ' obj.OnShow:=@Run;',
  26848. ' obj.OnShow:[email protected];',
  26849. ' obj.setOnShow(@Run);',
  26850. ' obj.setOnShow(@TExtA.Fly);',
  26851. ' with obj do begin',
  26852. ' e:=@doit;',
  26853. ' e:=@dosome;',
  26854. ' OnClick:=@doit;',
  26855. ' OnClick:=@dosome;',
  26856. ' setonclick(@doit);',
  26857. ' setonclick(@dosome);',
  26858. ' OnShow:=@Run;',
  26859. ' setOnShow(@Run);',
  26860. ' end;']);
  26861. ConvertProgram;
  26862. CheckSource('TestProcType_SafeCallObjFPC',
  26863. LinesToStr([ // statements
  26864. 'this.Run = function (i) {',
  26865. '};',
  26866. 'this.Obj = null;',
  26867. 'this.e = null;',
  26868. 'this.p = null;',
  26869. '']),
  26870. LinesToStr([ // $mod.$main
  26871. '$mod.e = $mod.e;',
  26872. '$mod.e = rtl.createSafeCallback($mod.Obj, "$Execute");',
  26873. '$mod.e = rtl.createSafeCallback($mod.Obj, "DoSome");',
  26874. '$mod.e = rtl.createCallback($mod.Obj, "DoSome");',
  26875. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "$Execute"));',
  26876. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "DoSome"));',
  26877. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "$Execute"));',
  26878. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "DoSome"));',
  26879. '$mod.p = rtl.createSafeCallback($mod, "Run");',
  26880. '$mod.p = rtl.createSafeCallback(ExtObj, "Fly");',
  26881. '$mod.Obj.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26882. '$mod.Obj.SetOnShow(rtl.createSafeCallback(ExtObj, "Fly"));',
  26883. '$mod.Obj.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26884. '$mod.Obj.SetOnShow(rtl.createSafeCallback(ExtObj, "Fly"));',
  26885. 'var $with = $mod.Obj;',
  26886. '$mod.e = rtl.createSafeCallback($with, "$Execute");',
  26887. '$mod.e = rtl.createSafeCallback($with, "DoSome");',
  26888. '$with.SetOnClick(rtl.createSafeCallback($with, "$Execute"));',
  26889. '$with.SetOnClick(rtl.createSafeCallback($with, "DoSome"));',
  26890. '$with.SetOnClick(rtl.createSafeCallback($with, "$Execute"));',
  26891. '$with.SetOnClick(rtl.createSafeCallback($with, "DoSome"));',
  26892. '$with.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26893. '$with.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26894. '']));
  26895. end;
  26896. procedure TTestModule.TestProcType_SafeCallDelphi;
  26897. begin
  26898. StartProgram(false);
  26899. Add([
  26900. '{$mode delphi}',
  26901. '{$modeswitch externalclass}',
  26902. 'type',
  26903. ' TProc = reference to procedure(i: longint); safecall;',
  26904. ' TEvent = procedure(i: longint) of object; safecall;',
  26905. ' TExtA = class external name ''ExtObj''',
  26906. ' procedure DoIt(Id: longint = 1); external name ''$Execute'';',
  26907. ' procedure DoSome(Id: longint = 1);',
  26908. ' procedure SetOnClick(const e: TEvent);',
  26909. ' property OnClick: TEvent write SetOnClick;',
  26910. ' class procedure Fly(Id: longint = 1); static;',
  26911. ' procedure SetOnShow(const p: TProc);',
  26912. ' property OnShow: TProc write SetOnShow;',
  26913. ' end;',
  26914. 'procedure Run(i: longint = 1);',
  26915. 'begin',
  26916. 'end;',
  26917. 'var',
  26918. ' Obj: texta;',
  26919. ' e: TEvent;',
  26920. ' p: TProc;',
  26921. 'begin',
  26922. ' e:=e;',
  26923. ' e:=obj.doit;',
  26924. ' e:=obj.dosome;',
  26925. ' e:=TEvent(@obj.dosome);', // no safecall
  26926. ' obj.OnClick:=obj.doit;',
  26927. ' obj.OnClick:=obj.dosome;',
  26928. ' obj.setonclick(obj.doit);',
  26929. ' obj.setonclick(obj.dosome);',
  26930. ' p:=Run;',
  26931. ' p:=TExtA.Fly;',
  26932. ' obj.OnShow:=Run;',
  26933. ' obj.OnShow:=TExtA.Fly;',
  26934. ' obj.setOnShow(Run);',
  26935. ' obj.setOnShow(TExtA.Fly);',
  26936. ' with obj do begin',
  26937. ' e:=doit;',
  26938. ' e:=dosome;',
  26939. ' OnClick:=doit;',
  26940. ' OnClick:=dosome;',
  26941. ' setonclick(doit);',
  26942. ' setonclick(dosome);',
  26943. ' OnShow:=@Run;',
  26944. ' setOnShow(@Run);',
  26945. ' end;']);
  26946. ConvertProgram;
  26947. CheckSource('TestProcType_SafeCallDelphi',
  26948. LinesToStr([ // statements
  26949. 'this.Run = function (i) {',
  26950. '};',
  26951. 'this.Obj = null;',
  26952. 'this.e = null;',
  26953. 'this.p = null;',
  26954. '']),
  26955. LinesToStr([ // $mod.$main
  26956. '$mod.e = $mod.e;',
  26957. '$mod.e = rtl.createSafeCallback($mod.Obj, "$Execute");',
  26958. '$mod.e = rtl.createSafeCallback($mod.Obj, "DoSome");',
  26959. '$mod.e = rtl.createCallback($mod.Obj, "DoSome");',
  26960. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "$Execute"));',
  26961. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "DoSome"));',
  26962. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "$Execute"));',
  26963. '$mod.Obj.SetOnClick(rtl.createSafeCallback($mod.Obj, "DoSome"));',
  26964. '$mod.p = rtl.createSafeCallback($mod, "Run");',
  26965. '$mod.p = rtl.createSafeCallback(ExtObj, "Fly");',
  26966. '$mod.Obj.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26967. '$mod.Obj.SetOnShow(rtl.createSafeCallback(ExtObj, "Fly"));',
  26968. '$mod.Obj.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26969. '$mod.Obj.SetOnShow(rtl.createSafeCallback(ExtObj, "Fly"));',
  26970. 'var $with = $mod.Obj;',
  26971. '$mod.e = rtl.createSafeCallback($with, "$Execute");',
  26972. '$mod.e = rtl.createSafeCallback($with, "DoSome");',
  26973. '$with.SetOnClick(rtl.createSafeCallback($with, "$Execute"));',
  26974. '$with.SetOnClick(rtl.createSafeCallback($with, "DoSome"));',
  26975. '$with.SetOnClick(rtl.createSafeCallback($with, "$Execute"));',
  26976. '$with.SetOnClick(rtl.createSafeCallback($with, "DoSome"));',
  26977. '$with.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26978. '$with.SetOnShow(rtl.createSafeCallback($mod, "Run"));',
  26979. '']));
  26980. end;
  26981. procedure TTestModule.TestPointer;
  26982. begin
  26983. StartProgram(false);
  26984. Add(['type',
  26985. ' TObject = class end;',
  26986. ' TClass = class of TObject;',
  26987. ' TArrInt = array of longint;',
  26988. 'const',
  26989. ' n = nil;',
  26990. 'var',
  26991. ' v: jsvalue;',
  26992. ' Obj: tobject;',
  26993. ' C: tclass;',
  26994. ' a: tarrint;',
  26995. ' p: Pointer = nil;',
  26996. ' s: string;',
  26997. 'begin',
  26998. ' p:=p;',
  26999. ' p:=nil;',
  27000. ' if p=nil then;',
  27001. ' if nil=p then;',
  27002. ' if Assigned(p) then;',
  27003. ' p:=Pointer(v);',
  27004. ' p:=obj;',
  27005. ' p:=c;',
  27006. ' p:=a;',
  27007. ' p:=tobject;',
  27008. ' obj:=TObject(p);',
  27009. ' c:=TClass(p);',
  27010. ' a:=TArrInt(p);',
  27011. ' p:=n;',
  27012. ' p:=Pointer(a);',
  27013. ' p:=pointer(s);',
  27014. ' s:=string(p);',
  27015. '']);
  27016. ConvertProgram;
  27017. CheckSource('TestPointer',
  27018. LinesToStr([ // statements
  27019. 'rtl.createClass(this, "TObject", null, function () {',
  27020. ' this.$init = function () {',
  27021. ' };',
  27022. ' this.$final = function () {',
  27023. ' };',
  27024. '});',
  27025. 'this.n = null;',
  27026. 'this.v = undefined;',
  27027. 'this.Obj = null;',
  27028. 'this.C = null;',
  27029. 'this.a = [];',
  27030. 'this.p = null;',
  27031. 'this.s = "";',
  27032. '']),
  27033. LinesToStr([ // $mod.$main
  27034. '$mod.p = $mod.p;',
  27035. '$mod.p = null;',
  27036. 'if ($mod.p === null) ;',
  27037. 'if (null === $mod.p) ;',
  27038. 'if ($mod.p != null) ;',
  27039. '$mod.p = $mod.v;',
  27040. '$mod.p = $mod.Obj;',
  27041. '$mod.p = $mod.C;',
  27042. '$mod.p = $mod.a;',
  27043. '$mod.p = $mod.TObject;',
  27044. '$mod.Obj = $mod.p;',
  27045. '$mod.C = $mod.p;',
  27046. '$mod.a = $mod.p;',
  27047. '$mod.p = null;',
  27048. '$mod.p = $mod.a;',
  27049. '$mod.p = $mod.s;',
  27050. '$mod.s = $mod.p;',
  27051. '']));
  27052. end;
  27053. procedure TTestModule.TestPointer_Proc;
  27054. begin
  27055. StartProgram(false);
  27056. Add('type');
  27057. Add(' TObject = class');
  27058. Add(' procedure DoIt; virtual; abstract;');
  27059. Add(' end;');
  27060. Add('procedure DoSome; begin end;');
  27061. Add('var');
  27062. Add(' o: TObject;');
  27063. Add(' p: Pointer;');
  27064. Add('begin');
  27065. Add(' p:=@DoSome;');
  27066. Add(' p:[email protected];');
  27067. ConvertProgram;
  27068. CheckSource('TestPointer_Proc',
  27069. LinesToStr([ // statements
  27070. 'rtl.createClass(this, "TObject", null, function () {',
  27071. ' this.$init = function () {',
  27072. ' };',
  27073. ' this.$final = function () {',
  27074. ' };',
  27075. '});',
  27076. 'this.DoSome = function () {',
  27077. '};',
  27078. 'this.o = null;',
  27079. 'this.p = null;',
  27080. '']),
  27081. LinesToStr([ // $mod.$main
  27082. '$mod.p = $mod.DoSome;',
  27083. '$mod.p = rtl.createCallback($mod.o, "DoIt");',
  27084. '']));
  27085. end;
  27086. procedure TTestModule.TestPointer_AssignRecordFail;
  27087. begin
  27088. StartProgram(false);
  27089. Add('type');
  27090. Add(' TRec = record end;');
  27091. Add('var');
  27092. Add(' p: Pointer;');
  27093. Add(' r: TRec;');
  27094. Add('begin');
  27095. Add(' p:=r;');
  27096. SetExpectedPasResolverError('Incompatible types: got "TRec" expected "Pointer"',
  27097. nIncompatibleTypesGotExpected);
  27098. ConvertProgram;
  27099. end;
  27100. procedure TTestModule.TestPointer_AssignStaticArrayFail;
  27101. begin
  27102. StartProgram(false);
  27103. Add('type');
  27104. Add(' TArr = array[boolean] of longint;');
  27105. Add('var');
  27106. Add(' p: Pointer;');
  27107. Add(' a: TArr;');
  27108. Add('begin');
  27109. Add(' p:=a;');
  27110. SetExpectedPasResolverError('Incompatible types: got "TArr" expected "Pointer"',
  27111. nIncompatibleTypesGotExpected);
  27112. ConvertProgram;
  27113. end;
  27114. procedure TTestModule.TestPointer_TypeCastJSValueToPointer;
  27115. begin
  27116. StartProgram(false);
  27117. Add([
  27118. 'procedure DoIt(args: array of jsvalue); begin end;',
  27119. 'procedure DoAll; varargs; begin end;',
  27120. 'var',
  27121. ' v: jsvalue;',
  27122. 'begin',
  27123. ' DoIt([pointer(v)]);',
  27124. ' DoAll(pointer(v));',
  27125. '']);
  27126. ConvertProgram;
  27127. CheckSource('TestPointer_TypeCastJSValueToPointer',
  27128. LinesToStr([ // statements
  27129. 'this.DoIt = function (args) {',
  27130. '};',
  27131. 'this.DoAll = function () {',
  27132. '};',
  27133. 'this.v = undefined;',
  27134. '']),
  27135. LinesToStr([ // $mod.$main
  27136. '$mod.DoIt([$mod.v]);',
  27137. '$mod.DoAll($mod.v);',
  27138. '']));
  27139. end;
  27140. procedure TTestModule.TestPointer_NonRecordFail;
  27141. begin
  27142. StartProgram(false);
  27143. Add([
  27144. 'type',
  27145. ' p = ^longint;',
  27146. 'begin',
  27147. '']);
  27148. SetExpectedPasResolverError('Not supported: pointer of Longint',nNotSupportedX);
  27149. ConvertProgram;
  27150. end;
  27151. procedure TTestModule.TestPointer_AnonymousArgTypeFail;
  27152. begin
  27153. StartProgram(false);
  27154. Add([
  27155. 'procedure DoIt(p: ^longint); begin end;',
  27156. 'begin',
  27157. '']);
  27158. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  27159. ConvertProgram;
  27160. end;
  27161. procedure TTestModule.TestPointer_AnonymousVarTypeFail;
  27162. begin
  27163. StartProgram(false);
  27164. Add([
  27165. 'var p: ^longint;',
  27166. 'begin',
  27167. '']);
  27168. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  27169. ConvertProgram;
  27170. end;
  27171. procedure TTestModule.TestPointer_AnonymousResultTypeFail;
  27172. begin
  27173. StartProgram(false);
  27174. Add([
  27175. 'function DoIt: ^longint; begin end;',
  27176. 'begin',
  27177. '']);
  27178. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  27179. ConvertProgram;
  27180. end;
  27181. procedure TTestModule.TestPointer_AddrOperatorFail;
  27182. begin
  27183. StartProgram(false);
  27184. Add([
  27185. 'var i: longint;',
  27186. 'begin',
  27187. ' if @i=nil then ;',
  27188. '']);
  27189. SetExpectedConverterError('illegal qualifier "@" in front of "i:Longint"',nIllegalQualifierInFrontOf);
  27190. ConvertProgram;
  27191. end;
  27192. procedure TTestModule.TestPointer_ArrayParamsFail;
  27193. begin
  27194. StartProgram(false);
  27195. Add([
  27196. 'var',
  27197. ' p: Pointer;',
  27198. 'begin',
  27199. ' p:=p[1];',
  27200. '']);
  27201. SetExpectedPasResolverError('illegal qualifier "[" after "Pointer"',nIllegalQualifierAfter);
  27202. ConvertProgram;
  27203. end;
  27204. procedure TTestModule.TestPointer_PointerAddFail;
  27205. begin
  27206. StartProgram(false);
  27207. Add([
  27208. 'var',
  27209. ' p: Pointer;',
  27210. 'begin',
  27211. ' p:=p+1;',
  27212. '']);
  27213. SetExpectedPasResolverError('Operator is not overloaded: "Pointer" + "Longint"',nOperatorIsNotOverloadedAOpB);
  27214. ConvertProgram;
  27215. end;
  27216. procedure TTestModule.TestPointer_IncPointerFail;
  27217. begin
  27218. StartProgram(false);
  27219. Add([
  27220. 'var',
  27221. ' p: Pointer;',
  27222. 'begin',
  27223. ' inc(p,1);',
  27224. '']);
  27225. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Pointer", expected "integer"',
  27226. nIncompatibleTypeArgNo);
  27227. ConvertProgram;
  27228. end;
  27229. procedure TTestModule.TestPointer_Record;
  27230. begin
  27231. StartProgram(false);
  27232. Add([
  27233. 'type',
  27234. ' TRec = record x: longint; end;',
  27235. ' PRec = ^TRec;',
  27236. 'var',
  27237. ' r: TRec;',
  27238. ' p: PRec;',
  27239. ' q: ^TRec;',
  27240. ' Ptr: pointer;',
  27241. 'begin',
  27242. ' new(p);',
  27243. ' p:=@r;',
  27244. ' r:=p^;',
  27245. ' r.x:=p^.x;',
  27246. ' p^.x:=r.x;',
  27247. ' if p^.x=3 then ;',
  27248. ' if 4=p^.x then ;',
  27249. ' dispose(p);',
  27250. ' new(q);',
  27251. ' dispose(q);',
  27252. ' Ptr:=p;',
  27253. ' p:=PRec(ptr);',
  27254. '']);
  27255. ConvertProgram;
  27256. CheckSource('TestPointer_Record',
  27257. LinesToStr([ // statements
  27258. 'rtl.recNewT(this, "TRec", function () {',
  27259. ' this.x = 0;',
  27260. ' this.$eq = function (b) {',
  27261. ' return this.x === b.x;',
  27262. ' };',
  27263. ' this.$assign = function (s) {',
  27264. ' this.x = s.x;',
  27265. ' return this;',
  27266. ' };',
  27267. '});',
  27268. 'this.r = this.TRec.$new();',
  27269. 'this.p = null;',
  27270. 'this.q = null;',
  27271. 'this.Ptr = null;',
  27272. '']),
  27273. LinesToStr([ // $mod.$main
  27274. '$mod.p = $mod.TRec.$new();',
  27275. '$mod.p = $mod.r;',
  27276. '$mod.r.$assign($mod.p);',
  27277. '$mod.r.x = $mod.p.x;',
  27278. '$mod.p.x = $mod.r.x;',
  27279. 'if ($mod.p.x === 3) ;',
  27280. 'if (4 === $mod.p.x) ;',
  27281. '$mod.p = null;',
  27282. '$mod.q = $mod.TRec.$new();',
  27283. '$mod.q = null;',
  27284. '$mod.Ptr = $mod.p;',
  27285. '$mod.p = $mod.Ptr;',
  27286. '']));
  27287. end;
  27288. procedure TTestModule.TestPointer_RecordArg;
  27289. begin
  27290. StartProgram(false);
  27291. Add([
  27292. '{$modeswitch autoderef}',
  27293. 'type',
  27294. ' TRec = record x: longint; end;',
  27295. ' PRec = ^TRec;',
  27296. 'function DoIt(const a: PRec; var b: PRec; out c: PRec): TRec;',
  27297. 'begin',
  27298. ' a.x:=a.x;',
  27299. ' a^.x:=a^.x;',
  27300. ' with a^ do',
  27301. ' x:=x;',
  27302. 'end;',
  27303. 'function GetIt(p: PRec): PRec;',
  27304. 'begin',
  27305. ' p.x:=p.x;',
  27306. ' p^.x:=p^.x;',
  27307. ' with p^ do',
  27308. ' x:=x;',
  27309. 'end;',
  27310. 'var',
  27311. ' r: TRec;',
  27312. ' p: PRec;',
  27313. 'begin',
  27314. ' p:=GetIt(p);',
  27315. ' p^:=GetIt(@r)^;',
  27316. ' DoIt(p,p,p);',
  27317. ' DoIt(@r,p,p);',
  27318. '']);
  27319. ConvertProgram;
  27320. CheckSource('TestPointer_RecordArg',
  27321. LinesToStr([ // statements
  27322. 'rtl.recNewT(this, "TRec", function () {',
  27323. ' this.x = 0;',
  27324. ' this.$eq = function (b) {',
  27325. ' return this.x === b.x;',
  27326. ' };',
  27327. ' this.$assign = function (s) {',
  27328. ' this.x = s.x;',
  27329. ' return this;',
  27330. ' };',
  27331. '});',
  27332. 'this.DoIt = function (a, b, c) {',
  27333. ' var Result = $mod.TRec.$new();',
  27334. ' a.x = a.x;',
  27335. ' a.x = a.x;',
  27336. ' a.x = a.x;',
  27337. ' return Result;',
  27338. '};',
  27339. 'this.GetIt = function (p) {',
  27340. ' var Result = null;',
  27341. ' p.x = p.x;',
  27342. ' p.x = p.x;',
  27343. ' p.x = p.x;',
  27344. ' return Result;',
  27345. '};',
  27346. 'this.r = this.TRec.$new();',
  27347. 'this.p = null;',
  27348. '']),
  27349. LinesToStr([ // $mod.$main
  27350. '$mod.p = $mod.GetIt($mod.p);',
  27351. '$mod.p.$assign($mod.GetIt($mod.r));',
  27352. '$mod.DoIt($mod.p, {',
  27353. ' p: $mod,',
  27354. ' get: function () {',
  27355. ' return this.p.p;',
  27356. ' },',
  27357. ' set: function (v) {',
  27358. ' this.p.p = v;',
  27359. ' }',
  27360. '}, {',
  27361. ' p: $mod,',
  27362. ' get: function () {',
  27363. ' return this.p.p;',
  27364. ' },',
  27365. ' set: function (v) {',
  27366. ' this.p.p = v;',
  27367. ' }',
  27368. '});',
  27369. '$mod.DoIt($mod.r, {',
  27370. ' p: $mod,',
  27371. ' get: function () {',
  27372. ' return this.p.p;',
  27373. ' },',
  27374. ' set: function (v) {',
  27375. ' this.p.p = v;',
  27376. ' }',
  27377. '}, {',
  27378. ' p: $mod,',
  27379. ' get: function () {',
  27380. ' return this.p.p;',
  27381. ' },',
  27382. ' set: function (v) {',
  27383. ' this.p.p = v;',
  27384. ' }',
  27385. '});',
  27386. '']));
  27387. end;
  27388. procedure TTestModule.TestJSValue_AssignToJSValue;
  27389. begin
  27390. StartProgram(false);
  27391. Add('var');
  27392. Add(' v: jsvalue;');
  27393. Add(' i: longint;');
  27394. Add(' s: string;');
  27395. Add(' b: boolean;');
  27396. Add(' d: double;');
  27397. Add(' p: pointer;');
  27398. Add('begin');
  27399. Add(' v:=v;');
  27400. Add(' v:=1;');
  27401. Add(' v:=i;');
  27402. Add(' v:='''';');
  27403. Add(' v:=''c'';');
  27404. Add(' v:=''foo'';');
  27405. Add(' v:=s;');
  27406. Add(' v:=false;');
  27407. Add(' v:=true;');
  27408. Add(' v:=b;');
  27409. Add(' v:=0.1;');
  27410. Add(' v:=d;');
  27411. Add(' v:=nil;');
  27412. Add(' v:=p;');
  27413. ConvertProgram;
  27414. CheckSource('TestJSValue_AssignToJSValue',
  27415. LinesToStr([ // statements
  27416. 'this.v = undefined;',
  27417. 'this.i = 0;',
  27418. 'this.s = "";',
  27419. 'this.b = false;',
  27420. 'this.d = 0.0;',
  27421. 'this.p = null;',
  27422. '']),
  27423. LinesToStr([ // $mod.$main
  27424. '$mod.v = $mod.v;',
  27425. '$mod.v = 1;',
  27426. '$mod.v = $mod.i;',
  27427. '$mod.v = "";',
  27428. '$mod.v = "c";',
  27429. '$mod.v = "foo";',
  27430. '$mod.v = $mod.s;',
  27431. '$mod.v = false;',
  27432. '$mod.v = true;',
  27433. '$mod.v = $mod.b;',
  27434. '$mod.v = 0.1;',
  27435. '$mod.v = $mod.d;',
  27436. '$mod.v = null;',
  27437. '$mod.v = $mod.p;',
  27438. '']));
  27439. end;
  27440. procedure TTestModule.TestJSValue_TypeCastToBaseType;
  27441. begin
  27442. StartProgram(false);
  27443. Add('type');
  27444. Add(' integer = longint;');
  27445. Add(' TYesNo = boolean;');
  27446. Add(' TFloat = double;');
  27447. Add(' TCaption = string;');
  27448. Add(' TChar = char;');
  27449. Add('var');
  27450. Add(' v: jsvalue;');
  27451. Add(' i: integer;');
  27452. Add(' s: TCaption;');
  27453. Add(' b: TYesNo;');
  27454. Add(' d: TFloat;');
  27455. Add(' c: char;');
  27456. Add('begin');
  27457. Add(' i:=longint(v);');
  27458. Add(' i:=integer(v);');
  27459. Add(' s:=string(v);');
  27460. Add(' s:=TCaption(v);');
  27461. Add(' b:=boolean(v);');
  27462. Add(' b:=TYesNo(v);');
  27463. Add(' d:=double(v);');
  27464. Add(' d:=TFloat(v);');
  27465. Add(' c:=char(v);');
  27466. Add(' c:=TChar(v);');
  27467. ConvertProgram;
  27468. CheckSource('TestJSValue_TypeCastToBaseType',
  27469. LinesToStr([ // statements
  27470. 'this.v = undefined;',
  27471. 'this.i = 0;',
  27472. 'this.s = "";',
  27473. 'this.b = false;',
  27474. 'this.d = 0.0;',
  27475. 'this.c = "";',
  27476. '']),
  27477. LinesToStr([ // $mod.$main
  27478. '$mod.i = rtl.trunc($mod.v);',
  27479. '$mod.i = rtl.trunc($mod.v);',
  27480. '$mod.s = "" + $mod.v;',
  27481. '$mod.s = "" + $mod.v;',
  27482. '$mod.b = !($mod.v == false);',
  27483. '$mod.b = !($mod.v == false);',
  27484. '$mod.d = rtl.getNumber($mod.v);',
  27485. '$mod.d = rtl.getNumber($mod.v);',
  27486. '$mod.c = rtl.getChar($mod.v);',
  27487. '$mod.c = rtl.getChar($mod.v);',
  27488. '']));
  27489. end;
  27490. procedure TTestModule.TestJSValue_TypecastToJSValue;
  27491. begin
  27492. StartProgram(false);
  27493. Add([
  27494. 'type',
  27495. ' TArr = array of word;',
  27496. ' TRec = record end;',
  27497. ' TSet = set of boolean;',
  27498. 'procedure Fly(v: jsvalue);',
  27499. 'begin',
  27500. 'end;',
  27501. 'var',
  27502. ' a: TArr;',
  27503. ' r: TRec;',
  27504. ' s: TSet;',
  27505. 'begin',
  27506. ' Fly(jsvalue(a));',
  27507. ' Fly(jsvalue(r));',
  27508. ' Fly(jsvalue(s));',
  27509. '']);
  27510. ConvertProgram;
  27511. CheckSource('TestJSValue_TypecastToJSValue',
  27512. LinesToStr([ // statements
  27513. 'rtl.recNewT(this, "TRec", function () {',
  27514. ' this.$eq = function (b) {',
  27515. ' return true;',
  27516. ' };',
  27517. ' this.$assign = function (s) {',
  27518. ' return this;',
  27519. ' };',
  27520. '});',
  27521. 'this.Fly = function (v) {',
  27522. '};',
  27523. 'this.a = [];',
  27524. 'this.r = this.TRec.$new();',
  27525. 'this.s = {};',
  27526. '']),
  27527. LinesToStr([ // $mod.$main
  27528. '$mod.Fly($mod.a);',
  27529. '$mod.Fly($mod.r);',
  27530. '$mod.Fly($mod.s);',
  27531. '']));
  27532. end;
  27533. procedure TTestModule.TestJSValue_Equal;
  27534. begin
  27535. StartProgram(false);
  27536. Add('type');
  27537. Add(' integer = longint;');
  27538. Add(' TYesNo = boolean;');
  27539. Add(' TFloat = double;');
  27540. Add(' TCaption = string;');
  27541. Add(' TChar = char;');
  27542. Add(' TMulti = JSValue;');
  27543. Add('var');
  27544. Add(' v: jsvalue;');
  27545. Add(' i: integer;');
  27546. Add(' s: TCaption;');
  27547. Add(' b: TYesNo;');
  27548. Add(' d: TFloat;');
  27549. Add(' c: char;');
  27550. Add(' m: TMulti;');
  27551. Add('begin');
  27552. Add(' b:=v=v;');
  27553. Add(' b:=v<>v;');
  27554. Add(' b:=v=1;');
  27555. Add(' b:=v<>1;');
  27556. Add(' b:=2=v;');
  27557. Add(' b:=2<>v;');
  27558. Add(' b:=v=i;');
  27559. Add(' b:=i=v;');
  27560. Add(' b:=v=nil;');
  27561. Add(' b:=nil=v;');
  27562. Add(' b:=v=false;');
  27563. Add(' b:=true=v;');
  27564. Add(' b:=v=b;');
  27565. Add(' b:=b=v;');
  27566. Add(' b:=v=s;');
  27567. Add(' b:=s=v;');
  27568. Add(' b:=v=''foo'';');
  27569. Add(' b:=''''=v;');
  27570. Add(' b:=v=d;');
  27571. Add(' b:=d=v;');
  27572. Add(' b:=v=3.4;');
  27573. Add(' b:=5.6=v;');
  27574. Add(' b:=v=c;');
  27575. Add(' b:=c=v;');
  27576. Add(' b:=m=m;');
  27577. Add(' b:=v=m;');
  27578. Add(' b:=m=v;');
  27579. ConvertProgram;
  27580. CheckSource('TestJSValue_Equal',
  27581. LinesToStr([ // statements
  27582. 'this.v = undefined;',
  27583. 'this.i = 0;',
  27584. 'this.s = "";',
  27585. 'this.b = false;',
  27586. 'this.d = 0.0;',
  27587. 'this.c = "";',
  27588. 'this.m = undefined;',
  27589. '']),
  27590. LinesToStr([ // $mod.$main
  27591. '$mod.b = $mod.v == $mod.v;',
  27592. '$mod.b = $mod.v != $mod.v;',
  27593. '$mod.b = $mod.v == 1;',
  27594. '$mod.b = $mod.v != 1;',
  27595. '$mod.b = 2 == $mod.v;',
  27596. '$mod.b = 2 != $mod.v;',
  27597. '$mod.b = $mod.v == $mod.i;',
  27598. '$mod.b = $mod.i == $mod.v;',
  27599. '$mod.b = $mod.v == null;',
  27600. '$mod.b = null == $mod.v;',
  27601. '$mod.b = $mod.v == false;',
  27602. '$mod.b = true == $mod.v;',
  27603. '$mod.b = $mod.v == $mod.b;',
  27604. '$mod.b = $mod.b == $mod.v;',
  27605. '$mod.b = $mod.v == $mod.s;',
  27606. '$mod.b = $mod.s == $mod.v;',
  27607. '$mod.b = $mod.v == "foo";',
  27608. '$mod.b = "" == $mod.v;',
  27609. '$mod.b = $mod.v == $mod.d;',
  27610. '$mod.b = $mod.d == $mod.v;',
  27611. '$mod.b = $mod.v == 3.4;',
  27612. '$mod.b = 5.6 == $mod.v;',
  27613. '$mod.b = $mod.v == $mod.c;',
  27614. '$mod.b = $mod.c == $mod.v;',
  27615. '$mod.b = $mod.m == $mod.m;',
  27616. '$mod.b = $mod.v == $mod.m;',
  27617. '$mod.b = $mod.m == $mod.v;',
  27618. '']));
  27619. end;
  27620. procedure TTestModule.TestJSValue_If;
  27621. begin
  27622. StartProgram(false);
  27623. Add([
  27624. 'procedure Fly(var u);',
  27625. 'begin',
  27626. ' if jsvalue(u) then ;',
  27627. 'end;',
  27628. 'var',
  27629. ' v: jsvalue;',
  27630. 'begin',
  27631. ' if v then ;',
  27632. ' while v do ;',
  27633. ' repeat until v;',
  27634. '']);
  27635. ConvertProgram;
  27636. CheckSource('TestJSValue_If',
  27637. LinesToStr([ // statements
  27638. 'this.Fly = function (u) {',
  27639. ' if (u.get()) ;',
  27640. '};',
  27641. 'this.v = undefined;',
  27642. '']),
  27643. LinesToStr([ // $mod.$main
  27644. 'if ($mod.v) ;',
  27645. 'while($mod.v){',
  27646. '};',
  27647. 'do{',
  27648. '} while(!$mod.v);',
  27649. '']));
  27650. end;
  27651. procedure TTestModule.TestJSValue_Not;
  27652. begin
  27653. StartProgram(false);
  27654. Add([
  27655. 'var',
  27656. ' v: jsvalue;',
  27657. ' b: boolean;',
  27658. 'begin',
  27659. ' b:=not v;',
  27660. ' if not v then ;',
  27661. ' while not v do ;',
  27662. ' repeat until not v;',
  27663. '']);
  27664. ConvertProgram;
  27665. CheckSource('TestJSValue_If',
  27666. LinesToStr([ // statements
  27667. 'this.v = undefined;',
  27668. 'this.b = false;',
  27669. '']),
  27670. LinesToStr([ // $mod.$main
  27671. '$mod.b=!$mod.v;',
  27672. 'if (!$mod.v) ;',
  27673. 'while(!$mod.v){',
  27674. '};',
  27675. 'do{',
  27676. '} while($mod.v);',
  27677. '']));
  27678. end;
  27679. procedure TTestModule.TestJSValue_Enum;
  27680. begin
  27681. StartProgram(false);
  27682. Add('type');
  27683. Add(' TColor = (red, blue);');
  27684. Add(' TRedBlue = TColor;');
  27685. Add('var');
  27686. Add(' v: jsvalue;');
  27687. Add(' e: TColor;');
  27688. Add('begin');
  27689. Add(' v:=e;');
  27690. Add(' v:=TColor(e);');
  27691. Add(' v:=TRedBlue(e);');
  27692. Add(' e:=TColor(v);');
  27693. Add(' e:=TRedBlue(v);');
  27694. ConvertProgram;
  27695. CheckSource('TestJSValue_Enum',
  27696. LinesToStr([ // statements
  27697. 'this.TColor = {',
  27698. ' "0": "red",',
  27699. ' red: 0,',
  27700. ' "1": "blue",',
  27701. ' blue: 1',
  27702. '};',
  27703. 'this.v = undefined;',
  27704. 'this.e = 0;',
  27705. '']),
  27706. LinesToStr([ // $mod.$main
  27707. '$mod.v = $mod.e;',
  27708. '$mod.v = $mod.e;',
  27709. '$mod.v = $mod.e;',
  27710. '$mod.e = $mod.v;',
  27711. '$mod.e = $mod.v;',
  27712. '']));
  27713. end;
  27714. procedure TTestModule.TestJSValue_ClassInstance;
  27715. begin
  27716. StartProgram(false);
  27717. Add([
  27718. 'type',
  27719. ' TObject = class',
  27720. ' end;',
  27721. ' TBirdObject = TObject;',
  27722. 'var',
  27723. ' v: jsvalue;',
  27724. ' o: TObject;',
  27725. 'begin',
  27726. ' v:=o;',
  27727. ' v:=TObject(o);',
  27728. ' v:=TBirdObject(o);',
  27729. ' o:=TObject(v);',
  27730. ' o:=TBirdObject(v);',
  27731. ' if v is TObject then ;',
  27732. '']);
  27733. ConvertProgram;
  27734. CheckSource('TestJSValue_ClassInstance',
  27735. LinesToStr([ // statements
  27736. 'rtl.createClass(this, "TObject", null, function () {',
  27737. ' this.$init = function () {',
  27738. ' };',
  27739. ' this.$final = function () {',
  27740. ' };',
  27741. '});',
  27742. 'this.v = undefined;',
  27743. 'this.o = null;',
  27744. '']),
  27745. LinesToStr([ // $mod.$main
  27746. '$mod.v = $mod.o;',
  27747. '$mod.v = $mod.o;',
  27748. '$mod.v = $mod.o;',
  27749. '$mod.o = rtl.getObject($mod.v);',
  27750. '$mod.o = rtl.getObject($mod.v);',
  27751. 'if (rtl.isExt($mod.v, $mod.TObject, 1)) ;',
  27752. '']));
  27753. end;
  27754. procedure TTestModule.TestJSValue_ClassOf;
  27755. begin
  27756. StartProgram(false);
  27757. Add([
  27758. 'type',
  27759. ' TClass = class of TObject;',
  27760. ' TObject = class',
  27761. ' end;',
  27762. ' TBirds = class of TBird;',
  27763. ' TBird = class(TObject) end;',
  27764. 'var',
  27765. ' v: jsvalue;',
  27766. ' c: TClass;',
  27767. 'begin',
  27768. ' v:=c;',
  27769. ' v:=TObject;',
  27770. ' v:=TClass(c);',
  27771. ' v:=TBirds(c);',
  27772. ' c:=TClass(v);',
  27773. ' c:=TBirds(v);',
  27774. ' if v is TClass then ;',
  27775. '']);
  27776. ConvertProgram;
  27777. CheckSource('TestJSValue_ClassOf',
  27778. LinesToStr([ // statements
  27779. 'rtl.createClass(this, "TObject", null, function () {',
  27780. ' this.$init = function () {',
  27781. ' };',
  27782. ' this.$final = function () {',
  27783. ' };',
  27784. '});',
  27785. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  27786. '});',
  27787. 'this.v = undefined;',
  27788. 'this.c = null;',
  27789. '']),
  27790. LinesToStr([ // $mod.$main
  27791. '$mod.v = $mod.c;',
  27792. '$mod.v = $mod.TObject;',
  27793. '$mod.v = $mod.c;',
  27794. '$mod.v = $mod.c;',
  27795. '$mod.c = rtl.getObject($mod.v);',
  27796. '$mod.c = rtl.getObject($mod.v);',
  27797. 'if (rtl.isExt($mod.v, $mod.TObject, 2)) ;',
  27798. '']));
  27799. end;
  27800. procedure TTestModule.TestJSValue_ArrayOfJSValue;
  27801. begin
  27802. StartProgram(false);
  27803. Add([
  27804. 'type',
  27805. ' integer = longint;',
  27806. ' TArray = array of JSValue;',
  27807. ' TArrgh = tarray;',
  27808. ' TArrInt = array of integer;',
  27809. 'var',
  27810. ' v: jsvalue;',
  27811. ' TheArray: tarray = (1,''2'');',
  27812. ' Arr: tarrgh;',
  27813. ' i: integer;',
  27814. ' ArrInt: tarrint;',
  27815. 'begin',
  27816. ' arr:=thearray;',
  27817. ' thearray:=arr;',
  27818. ' setlength(arr,2);',
  27819. ' setlength(thearray,3);',
  27820. ' arr[4]:=v;',
  27821. ' arr[5]:=length(thearray);',
  27822. ' arr[6]:=nil;',
  27823. ' arr[7]:=thearray[8];',
  27824. ' arr[low(arr)]:=high(thearray);',
  27825. ' arr:=arrint;',
  27826. ' arrInt:=tarrint(arr);',
  27827. ' if TheArray = nil then ;',
  27828. ' if nil = TheArray then ;',
  27829. ' if TheArray <> nil then ;',
  27830. ' if nil <> TheArray then ;',
  27831. '']);
  27832. ConvertProgram;
  27833. CheckSource('TestJSValue_ArrayOfJSValue',
  27834. LinesToStr([ // statements
  27835. 'this.v = undefined;',
  27836. 'this.TheArray = [1, "2"];',
  27837. 'this.Arr = [];',
  27838. 'this.i = 0;',
  27839. 'this.ArrInt = [];',
  27840. '']),
  27841. LinesToStr([ // $mod.$main
  27842. '$mod.Arr = rtl.arrayRef($mod.TheArray);',
  27843. '$mod.TheArray = rtl.arrayRef($mod.Arr);',
  27844. '$mod.Arr = rtl.arraySetLength($mod.Arr,undefined,2);',
  27845. '$mod.TheArray = rtl.arraySetLength($mod.TheArray,undefined,3);',
  27846. '$mod.Arr[4] = $mod.v;',
  27847. '$mod.Arr[5] = rtl.length($mod.TheArray);',
  27848. '$mod.Arr[6] = null;',
  27849. '$mod.Arr[7] = $mod.TheArray[8];',
  27850. '$mod.Arr[0] = rtl.length($mod.TheArray) - 1;',
  27851. '$mod.Arr = rtl.arrayRef($mod.ArrInt);',
  27852. '$mod.ArrInt = $mod.Arr;',
  27853. 'if (rtl.length($mod.TheArray) === 0) ;',
  27854. 'if (rtl.length($mod.TheArray) === 0) ;',
  27855. 'if (rtl.length($mod.TheArray) > 0) ;',
  27856. 'if (rtl.length($mod.TheArray) > 0) ;',
  27857. '']));
  27858. end;
  27859. procedure TTestModule.TestJSValue_ArrayLit;
  27860. begin
  27861. StartProgram(false);
  27862. Add([
  27863. 'type',
  27864. ' TFlag = (big,small);',
  27865. ' TArray = array of JSValue;',
  27866. ' TObject = class end;',
  27867. ' TClass = class of TObject;',
  27868. 'var',
  27869. ' v: jsvalue;',
  27870. ' a: TArray;',
  27871. ' o: TObject;',
  27872. 'begin',
  27873. ' a:=[];',
  27874. ' a:=[1];',
  27875. ' a:=[1,2];',
  27876. ' a:=[big];',
  27877. ' a:=[1,big];',
  27878. ' a:=[o,nil];',
  27879. '']);
  27880. ConvertProgram;
  27881. CheckSource('TestJSValue_ArrayLit',
  27882. LinesToStr([ // statements
  27883. 'this.TFlag = {',
  27884. ' "0": "big",',
  27885. ' big: 0,',
  27886. ' "1": "small",',
  27887. ' small: 1',
  27888. '};',
  27889. 'rtl.createClass(this, "TObject", null, function () {',
  27890. ' this.$init = function () {',
  27891. ' };',
  27892. ' this.$final = function () {',
  27893. ' };',
  27894. '});',
  27895. 'this.v = undefined;',
  27896. 'this.a = [];',
  27897. 'this.o = null;',
  27898. '']),
  27899. LinesToStr([ // $mod.$main
  27900. '$mod.a = [];',
  27901. '$mod.a = [1];',
  27902. '$mod.a = [1, 2];',
  27903. '$mod.a = [$mod.TFlag.big];',
  27904. '$mod.a = [1, $mod.TFlag.big];',
  27905. '$mod.a = [$mod.o, null];',
  27906. '']));
  27907. end;
  27908. procedure TTestModule.TestJSValue_Params;
  27909. begin
  27910. StartProgram(false);
  27911. Add('type');
  27912. Add(' integer = longint;');
  27913. Add(' TYesNo = boolean;');
  27914. Add(' TFloat = double;');
  27915. Add(' TCaption = string;');
  27916. Add(' TChar = char;');
  27917. Add('function DoIt(a: jsvalue; const b: jsvalue; var c: jsvalue; out d: jsvalue): jsvalue;');
  27918. Add('var');
  27919. Add(' l: jsvalue;');
  27920. Add('begin');
  27921. Add(' a:=a;');
  27922. Add(' l:=b;');
  27923. Add(' c:=c;');
  27924. Add(' d:=d;');
  27925. Add(' Result:=l;');
  27926. Add('end;');
  27927. Add('function DoSome(a: jsvalue; const b: jsvalue): jsvalue; begin end;');
  27928. Add('var');
  27929. Add(' v: jsvalue;');
  27930. Add(' i: integer;');
  27931. Add(' b: TYesNo;');
  27932. Add(' d: TFloat;');
  27933. Add(' s: TCaption;');
  27934. Add(' c: TChar;');
  27935. Add('begin');
  27936. Add(' v:=doit(v,v,v,v);');
  27937. Add(' i:=integer(dosome(i,i));');
  27938. Add(' b:=TYesNo(dosome(b,b));');
  27939. Add(' d:=TFloat(dosome(d,d));');
  27940. Add(' s:=TCaption(dosome(s,s));');
  27941. Add(' c:=TChar(dosome(c,c));');
  27942. ConvertProgram;
  27943. CheckSource('TestJSValue_Params',
  27944. LinesToStr([ // statements
  27945. 'this.DoIt = function (a, b, c, d) {',
  27946. ' var Result = undefined;',
  27947. ' var l = undefined;',
  27948. ' a = a;',
  27949. ' l = b;',
  27950. ' c.set(c.get());',
  27951. ' d.set(d.get());',
  27952. ' Result = l;',
  27953. ' return Result;',
  27954. '};',
  27955. 'this.DoSome = function (a, b) {',
  27956. ' var Result = undefined;',
  27957. ' return Result;',
  27958. '};',
  27959. 'this.v = undefined;',
  27960. 'this.i = 0;',
  27961. 'this.b = false;',
  27962. 'this.d = 0.0;',
  27963. 'this.s = "";',
  27964. 'this.c = "";',
  27965. '']),
  27966. LinesToStr([ // $mod.$main
  27967. '$mod.v = $mod.DoIt($mod.v, $mod.v, {',
  27968. ' p: $mod,',
  27969. ' get: function () {',
  27970. ' return this.p.v;',
  27971. ' },',
  27972. ' set: function (v) {',
  27973. ' this.p.v = v;',
  27974. ' }',
  27975. '}, {',
  27976. ' p: $mod,',
  27977. ' get: function () {',
  27978. ' return this.p.v;',
  27979. ' },',
  27980. ' set: function (v) {',
  27981. ' this.p.v = v;',
  27982. ' }',
  27983. '});',
  27984. '$mod.i = rtl.trunc($mod.DoSome($mod.i, $mod.i));',
  27985. '$mod.b = !($mod.DoSome($mod.b, $mod.b) == false);',
  27986. '$mod.d = rtl.getNumber($mod.DoSome($mod.d, $mod.d));',
  27987. '$mod.s = "" + $mod.DoSome($mod.s, $mod.s);',
  27988. '$mod.c = rtl.getChar($mod.DoSome($mod.c, $mod.c));',
  27989. '']));
  27990. end;
  27991. procedure TTestModule.TestJSValue_UntypedParam;
  27992. begin
  27993. StartProgram(false);
  27994. Add('function DoIt(const a; var b; out c): jsvalue;');
  27995. Add('begin');
  27996. Add(' Result:=a;');
  27997. Add(' Result:=b;');
  27998. Add(' Result:=c;');
  27999. Add(' b:=Result;');
  28000. Add(' c:=Result;');
  28001. Add('end;');
  28002. Add('var i: longint;');
  28003. Add('begin');
  28004. Add(' doit(i,i,i);');
  28005. ConvertProgram;
  28006. CheckSource('TestJSValue_UntypedParam',
  28007. LinesToStr([ // statements
  28008. 'this.DoIt = function (a, b, c) {',
  28009. ' var Result = undefined;',
  28010. ' Result = a;',
  28011. ' Result = b.get();',
  28012. ' Result = c.get();',
  28013. ' b.set(Result);',
  28014. ' c.set(Result);',
  28015. ' return Result;',
  28016. '};',
  28017. 'this.i = 0;',
  28018. '']),
  28019. LinesToStr([ // $mod.$main
  28020. '$mod.DoIt($mod.i, {',
  28021. ' p: $mod,',
  28022. ' get: function () {',
  28023. ' return this.p.i;',
  28024. ' },',
  28025. ' set: function (v) {',
  28026. ' this.p.i = v;',
  28027. ' }',
  28028. '}, {',
  28029. ' p: $mod,',
  28030. ' get: function () {',
  28031. ' return this.p.i;',
  28032. ' },',
  28033. ' set: function (v) {',
  28034. ' this.p.i = v;',
  28035. ' }',
  28036. '});',
  28037. '']));
  28038. end;
  28039. procedure TTestModule.TestJSValue_FuncResultType;
  28040. begin
  28041. StartProgram(false);
  28042. Add('type');
  28043. Add(' integer = longint;');
  28044. Add(' TJSValueArray = array of JSValue;');
  28045. Add(' TListSortCompare = function(Item1, Item2: JSValue): Integer;');
  28046. Add('procedure Sort(P: JSValue; aList: TJSValueArray; const Compare: TListSortCompare);');
  28047. Add('begin');
  28048. Add(' while Compare(P,aList[0])>0 do ;');
  28049. Add('end;');
  28050. Add('var');
  28051. Add(' Compare: TListSortCompare;');
  28052. Add(' V: JSValue;');
  28053. Add(' i: integer;');
  28054. Add('begin');
  28055. Add(' if Compare(V,V)>0 then ;');
  28056. Add(' if Compare(i,i)>1 then ;');
  28057. Add(' if Compare(nil,false)>2 then ;');
  28058. Add(' if Compare(1,true)>3 then ;');
  28059. ConvertProgram;
  28060. CheckSource('TestJSValue_UntypedParam',
  28061. LinesToStr([ // statements
  28062. 'this.Sort = function (P, aList, Compare) {',
  28063. ' while (Compare(P, aList[0]) > 0) {',
  28064. ' };',
  28065. '};',
  28066. 'this.Compare = null;',
  28067. 'this.V = undefined;',
  28068. 'this.i = 0;',
  28069. '']),
  28070. LinesToStr([ // $mod.$main
  28071. 'if ($mod.Compare($mod.V, $mod.V) > 0) ;',
  28072. 'if ($mod.Compare($mod.i, $mod.i) > 1) ;',
  28073. 'if ($mod.Compare(null, false) > 2) ;',
  28074. 'if ($mod.Compare(1, true) > 3) ;',
  28075. '']));
  28076. end;
  28077. procedure TTestModule.TestJSValue_ProcType_Assign;
  28078. begin
  28079. StartProgram(false);
  28080. Add('type');
  28081. Add(' integer = longint;');
  28082. Add(' TObject = class');
  28083. Add(' class function GetGlob: integer;');
  28084. Add(' function Getter: integer;');
  28085. Add(' end;');
  28086. Add('class function TObject.GetGlob: integer;');
  28087. Add('var v1: jsvalue;');
  28088. Add('begin');
  28089. Add(' v1:=@GetGlob;');
  28090. Add(' v1:[email protected];');
  28091. Add('end;');
  28092. Add('function TObject.Getter: integer;');
  28093. Add('var v2: jsvalue;');
  28094. Add('begin');
  28095. Add(' v2:=@Getter;');
  28096. Add(' v2:[email protected];');
  28097. Add(' v2:=@GetGlob;');
  28098. Add(' v2:[email protected];');
  28099. Add('end;');
  28100. Add('function GetIt(i: integer): integer;');
  28101. Add('var v3: jsvalue;');
  28102. Add('begin');
  28103. Add(' v3:=@GetIt;');
  28104. Add('end;');
  28105. Add('var');
  28106. Add(' V: JSValue;');
  28107. Add(' o: TObject;');
  28108. Add('begin');
  28109. Add(' v:=@GetIt;');
  28110. Add(' v:[email protected];');
  28111. Add(' v:[email protected];');
  28112. ConvertProgram;
  28113. CheckSource('TestJSValue_ProcType_Assign',
  28114. LinesToStr([ // statements
  28115. 'rtl.createClass(this, "TObject", null, function () {',
  28116. ' this.$init = function () {',
  28117. ' };',
  28118. ' this.$final = function () {',
  28119. ' };',
  28120. ' this.GetGlob = function () {',
  28121. ' var Result = 0;',
  28122. ' var v1 = undefined;',
  28123. ' v1 = rtl.createCallback(this, "GetGlob");',
  28124. ' v1 = rtl.createCallback(this, "GetGlob");',
  28125. ' return Result;',
  28126. ' };',
  28127. ' this.Getter = function () {',
  28128. ' var Result = 0;',
  28129. ' var v2 = undefined;',
  28130. ' v2 = rtl.createCallback(this, "Getter");',
  28131. ' v2 = rtl.createCallback(this, "Getter");',
  28132. ' v2 = rtl.createCallback(this.$class, "GetGlob");',
  28133. ' v2 = rtl.createCallback(this.$class, "GetGlob");',
  28134. ' return Result;',
  28135. ' };',
  28136. '});',
  28137. 'this.GetIt = function (i) {',
  28138. ' var Result = 0;',
  28139. ' var v3 = undefined;',
  28140. ' v3 = $mod.GetIt;',
  28141. ' return Result;',
  28142. '};',
  28143. 'this.V = undefined;',
  28144. 'this.o = null;',
  28145. '']),
  28146. LinesToStr([ // $mod.$main
  28147. '$mod.V = $mod.GetIt;',
  28148. '$mod.V = rtl.createCallback($mod.o, "Getter");',
  28149. '$mod.V = rtl.createCallback($mod.o.$class, "GetGlob");',
  28150. '']));
  28151. end;
  28152. procedure TTestModule.TestJSValue_ProcType_Equal;
  28153. begin
  28154. StartProgram(false);
  28155. Add('type');
  28156. Add(' integer = longint;');
  28157. Add(' TObject = class');
  28158. Add(' class function GetGlob: integer;');
  28159. Add(' function Getter: integer;');
  28160. Add(' end;');
  28161. Add('class function TObject.GetGlob: integer;');
  28162. Add('var v1: jsvalue;');
  28163. Add('begin');
  28164. Add(' if v1=@GetGlob then;');
  28165. Add(' if [email protected] then ;');
  28166. Add('end;');
  28167. Add('function TObject.Getter: integer;');
  28168. Add('var v2: jsvalue;');
  28169. Add('begin');
  28170. Add(' if v2=@Getter then;');
  28171. Add(' if [email protected] then ;');
  28172. Add(' if v2=@GetGlob then;');
  28173. Add(' if [email protected] then;');
  28174. Add('end;');
  28175. Add('function GetIt(i: integer): integer;');
  28176. Add('var v3: jsvalue;');
  28177. Add('begin');
  28178. Add(' if v3=@GetIt then;');
  28179. Add('end;');
  28180. Add('var');
  28181. Add(' V: JSValue;');
  28182. Add(' o: TObject;');
  28183. Add('begin');
  28184. Add(' if v=@GetIt then;');
  28185. Add(' if [email protected] then;');
  28186. Add(' if [email protected] then;');
  28187. Add(' if @GetIt=v then;');
  28188. Add(' if @o.Getter=v then;');
  28189. Add(' if @o.GetGlob=v then;');
  28190. ConvertProgram;
  28191. CheckSource('TestJSValue_ProcType_Equal',
  28192. LinesToStr([ // statements
  28193. 'rtl.createClass(this, "TObject", null, function () {',
  28194. ' this.$init = function () {',
  28195. ' };',
  28196. ' this.$final = function () {',
  28197. ' };',
  28198. ' this.GetGlob = function () {',
  28199. ' var Result = 0;',
  28200. ' var v1 = undefined;',
  28201. ' if (rtl.eqCallback(v1, rtl.createCallback(this, "GetGlob"))) ;',
  28202. ' if (rtl.eqCallback(v1, rtl.createCallback(this, "GetGlob"))) ;',
  28203. ' return Result;',
  28204. ' };',
  28205. ' this.Getter = function () {',
  28206. ' var Result = 0;',
  28207. ' var v2 = undefined;',
  28208. ' if (rtl.eqCallback(v2, rtl.createCallback(this, "Getter"))) ;',
  28209. ' if (rtl.eqCallback(v2, rtl.createCallback(this, "Getter"))) ;',
  28210. ' if (rtl.eqCallback(v2, rtl.createCallback(this.$class, "GetGlob"))) ;',
  28211. ' if (rtl.eqCallback(v2, rtl.createCallback(this.$class, "GetGlob"))) ;',
  28212. ' return Result;',
  28213. ' };',
  28214. '});',
  28215. 'this.GetIt = function (i) {',
  28216. ' var Result = 0;',
  28217. ' var v3 = undefined;',
  28218. ' if (rtl.eqCallback(v3, $mod.GetIt)) ;',
  28219. ' return Result;',
  28220. '};',
  28221. 'this.V = undefined;',
  28222. 'this.o = null;',
  28223. '']),
  28224. LinesToStr([ // $mod.$main
  28225. 'if (rtl.eqCallback($mod.V, $mod.GetIt)) ;',
  28226. 'if (rtl.eqCallback($mod.V, rtl.createCallback($mod.o, "Getter"))) ;',
  28227. 'if (rtl.eqCallback($mod.V, rtl.createCallback($mod.o.$class, "GetGlob"))) ;',
  28228. 'if (rtl.eqCallback($mod.GetIt, $mod.V)) ;',
  28229. 'if (rtl.eqCallback(rtl.createCallback($mod.o, "Getter"), $mod.V)) ;',
  28230. 'if (rtl.eqCallback(rtl.createCallback($mod.o.$class, "GetGlob"), $mod.V)) ;',
  28231. '']));
  28232. end;
  28233. procedure TTestModule.TestJSValue_ProcType_Param;
  28234. begin
  28235. StartProgram(false);
  28236. Add([
  28237. 'type',
  28238. ' variant = jsvalue;',
  28239. ' TArrVariant = array of variant;',
  28240. ' TArrVar2 = TArrVariant;',
  28241. ' TFuncInt = function: longint;',
  28242. 'function GetIt: longint;',
  28243. 'begin',
  28244. 'end;',
  28245. 'procedure DoIt(p: jsvalue; Arr: TArrVar2);',
  28246. 'var v: variant;',
  28247. 'begin',
  28248. ' v:=arr[1];',
  28249. 'end;',
  28250. 'var s: string;',
  28251. 'begin',
  28252. ' DoIt(GetIt,[]);',
  28253. ' DoIt(@GetIt,[]);',
  28254. ' DoIt(1,[s,GetIt]);',
  28255. ' DoIt(1,[s,@GetIt]);',
  28256. '']);
  28257. ConvertProgram;
  28258. CheckSource('TestJSValue_ProcType_Param',
  28259. LinesToStr([ // statements
  28260. 'this.GetIt = function () {',
  28261. ' var Result = 0;',
  28262. ' return Result;',
  28263. '};',
  28264. 'this.DoIt = function (p, Arr) {',
  28265. ' var v = undefined;',
  28266. ' v = Arr[1];',
  28267. '};',
  28268. 'this.s = "";',
  28269. '']),
  28270. LinesToStr([ // $mod.$main
  28271. '$mod.DoIt($mod.GetIt(), []);',
  28272. '$mod.DoIt($mod.GetIt, []);',
  28273. '$mod.DoIt(1, [$mod.s, $mod.GetIt()]);',
  28274. '$mod.DoIt(1, [$mod.s, $mod.GetIt]);',
  28275. '']));
  28276. end;
  28277. procedure TTestModule.TestJSValue_AssignToPointerFail;
  28278. begin
  28279. StartProgram(false);
  28280. Add([
  28281. 'var',
  28282. ' v: JSValue;',
  28283. ' p: Pointer;',
  28284. 'begin',
  28285. ' p:=v;',
  28286. '']);
  28287. SetExpectedPasResolverError('Incompatible types: got "JSValue" expected "Pointer"',
  28288. nIncompatibleTypesGotExpected);
  28289. ConvertProgram;
  28290. end;
  28291. procedure TTestModule.TestJSValue_OverloadDouble;
  28292. begin
  28293. StartProgram(false);
  28294. Add([
  28295. 'type',
  28296. ' integer = longint;',
  28297. ' tdatetime = double;',
  28298. 'procedure DoIt(d: double); begin end;',
  28299. 'procedure DoIt(v: jsvalue); begin end;',
  28300. 'var',
  28301. ' d: double;',
  28302. ' dt: tdatetime;',
  28303. ' i: integer;',
  28304. ' b: byte;',
  28305. ' shi: shortint;',
  28306. ' w: word;',
  28307. ' smi: smallint;',
  28308. ' lw: longword;',
  28309. ' li: longint;',
  28310. ' ni: nativeint;',
  28311. ' nu: nativeuint;',
  28312. 'begin',
  28313. ' DoIt(d);',
  28314. ' DoIt(dt);',
  28315. ' DoIt(i);',
  28316. ' DoIt(b);',
  28317. ' DoIt(shi);',
  28318. ' DoIt(w);',
  28319. ' DoIt(smi);',
  28320. ' DoIt(lw);',
  28321. ' DoIt(li);',
  28322. ' DoIt(ni);',
  28323. ' DoIt(nu);',
  28324. '']);
  28325. ConvertProgram;
  28326. CheckSource('TestJSValue_OverloadDouble',
  28327. LinesToStr([ // statements
  28328. 'this.DoIt = function (d) {',
  28329. '};',
  28330. 'this.DoIt$1 = function (v) {',
  28331. '};',
  28332. 'this.d = 0.0;',
  28333. 'this.dt = 0.0;',
  28334. 'this.i = 0;',
  28335. 'this.b = 0;',
  28336. 'this.shi = 0;',
  28337. 'this.w = 0;',
  28338. 'this.smi = 0;',
  28339. 'this.lw = 0;',
  28340. 'this.li = 0;',
  28341. 'this.ni = 0;',
  28342. 'this.nu = 0;',
  28343. '']),
  28344. LinesToStr([ // $mod.$main
  28345. '$mod.DoIt($mod.d);',
  28346. '$mod.DoIt($mod.dt);',
  28347. '$mod.DoIt$1($mod.i);',
  28348. '$mod.DoIt$1($mod.b);',
  28349. '$mod.DoIt$1($mod.shi);',
  28350. '$mod.DoIt$1($mod.w);',
  28351. '$mod.DoIt$1($mod.smi);',
  28352. '$mod.DoIt$1($mod.lw);',
  28353. '$mod.DoIt$1($mod.li);',
  28354. '$mod.DoIt$1($mod.ni);',
  28355. '$mod.DoIt$1($mod.nu);',
  28356. '']));
  28357. end;
  28358. procedure TTestModule.TestJSValue_OverloadNativeInt;
  28359. begin
  28360. StartProgram(false);
  28361. Add([
  28362. 'type',
  28363. ' integer = longint;',
  28364. ' int53 = nativeint;',
  28365. ' tdatetime = double;',
  28366. 'procedure DoIt(n: nativeint); begin end;',
  28367. 'procedure DoIt(v: jsvalue); begin end;',
  28368. 'var',
  28369. ' d: double;',
  28370. ' dt: tdatetime;',
  28371. ' i: integer;',
  28372. ' b: byte;',
  28373. ' shi: shortint;',
  28374. ' w: word;',
  28375. ' smi: smallint;',
  28376. ' lw: longword;',
  28377. ' li: longint;',
  28378. ' ni: nativeint;',
  28379. ' nu: nativeuint;',
  28380. 'begin',
  28381. ' DoIt(d);',
  28382. ' DoIt(dt);',
  28383. ' DoIt(i);',
  28384. ' DoIt(b);',
  28385. ' DoIt(shi);',
  28386. ' DoIt(w);',
  28387. ' DoIt(smi);',
  28388. ' DoIt(lw);',
  28389. ' DoIt(li);',
  28390. ' DoIt(ni);',
  28391. ' DoIt(nu);',
  28392. '']);
  28393. ConvertProgram;
  28394. CheckSource('TestJSValue_OverloadNativeInt',
  28395. LinesToStr([ // statements
  28396. 'this.DoIt = function (n) {',
  28397. '};',
  28398. 'this.DoIt$1 = function (v) {',
  28399. '};',
  28400. 'this.d = 0.0;',
  28401. 'this.dt = 0.0;',
  28402. 'this.i = 0;',
  28403. 'this.b = 0;',
  28404. 'this.shi = 0;',
  28405. 'this.w = 0;',
  28406. 'this.smi = 0;',
  28407. 'this.lw = 0;',
  28408. 'this.li = 0;',
  28409. 'this.ni = 0;',
  28410. 'this.nu = 0;',
  28411. '']),
  28412. LinesToStr([ // $mod.$main
  28413. '$mod.DoIt$1($mod.d);',
  28414. '$mod.DoIt$1($mod.dt);',
  28415. '$mod.DoIt($mod.i);',
  28416. '$mod.DoIt($mod.b);',
  28417. '$mod.DoIt($mod.shi);',
  28418. '$mod.DoIt($mod.w);',
  28419. '$mod.DoIt($mod.smi);',
  28420. '$mod.DoIt($mod.lw);',
  28421. '$mod.DoIt($mod.li);',
  28422. '$mod.DoIt($mod.ni);',
  28423. '$mod.DoIt($mod.nu);',
  28424. '']));
  28425. end;
  28426. procedure TTestModule.TestJSValue_OverloadWord;
  28427. begin
  28428. StartProgram(false);
  28429. Add([
  28430. 'type',
  28431. ' integer = longint;',
  28432. ' int53 = nativeint;',
  28433. ' tdatetime = double;',
  28434. 'procedure DoIt(w: word); begin end;',
  28435. 'procedure DoIt(v: jsvalue); begin end;',
  28436. 'var',
  28437. ' d: double;',
  28438. ' dt: tdatetime;',
  28439. ' i: integer;',
  28440. ' b: byte;',
  28441. ' shi: shortint;',
  28442. ' w: word;',
  28443. ' smi: smallint;',
  28444. ' lw: longword;',
  28445. ' li: longint;',
  28446. ' ni: nativeint;',
  28447. ' nu: nativeuint;',
  28448. 'begin',
  28449. ' DoIt(d);',
  28450. ' DoIt(dt);',
  28451. ' DoIt(i);',
  28452. ' DoIt(b);',
  28453. ' DoIt(shi);',
  28454. ' DoIt(w);',
  28455. ' DoIt(smi);',
  28456. ' DoIt(lw);',
  28457. ' DoIt(li);',
  28458. ' DoIt(ni);',
  28459. ' DoIt(nu);',
  28460. '']);
  28461. ConvertProgram;
  28462. CheckSource('TestJSValue_OverloadWord',
  28463. LinesToStr([ // statements
  28464. 'this.DoIt = function (w) {',
  28465. '};',
  28466. 'this.DoIt$1 = function (v) {',
  28467. '};',
  28468. 'this.d = 0.0;',
  28469. 'this.dt = 0.0;',
  28470. 'this.i = 0;',
  28471. 'this.b = 0;',
  28472. 'this.shi = 0;',
  28473. 'this.w = 0;',
  28474. 'this.smi = 0;',
  28475. 'this.lw = 0;',
  28476. 'this.li = 0;',
  28477. 'this.ni = 0;',
  28478. 'this.nu = 0;',
  28479. '']),
  28480. LinesToStr([ // $mod.$main
  28481. '$mod.DoIt$1($mod.d);',
  28482. '$mod.DoIt$1($mod.dt);',
  28483. '$mod.DoIt$1($mod.i);',
  28484. '$mod.DoIt($mod.b);',
  28485. '$mod.DoIt($mod.shi);',
  28486. '$mod.DoIt($mod.w);',
  28487. '$mod.DoIt$1($mod.smi);',
  28488. '$mod.DoIt$1($mod.lw);',
  28489. '$mod.DoIt$1($mod.li);',
  28490. '$mod.DoIt$1($mod.ni);',
  28491. '$mod.DoIt$1($mod.nu);',
  28492. '']));
  28493. end;
  28494. procedure TTestModule.TestJSValue_OverloadString;
  28495. begin
  28496. StartProgram(false);
  28497. Add([
  28498. 'type',
  28499. ' uni = string;',
  28500. ' WChar = char;',
  28501. 'procedure DoIt(s: string); begin end;',
  28502. 'procedure DoIt(v: jsvalue); begin end;',
  28503. 'var',
  28504. ' s: string;',
  28505. ' c: char;',
  28506. ' u: uni;',
  28507. 'begin',
  28508. ' DoIt(s);',
  28509. ' DoIt(c);',
  28510. ' DoIt(u);',
  28511. '']);
  28512. ConvertProgram;
  28513. CheckSource('TestJSValue_OverloadString',
  28514. LinesToStr([ // statements
  28515. 'this.DoIt = function (s) {',
  28516. '};',
  28517. 'this.DoIt$1 = function (v) {',
  28518. '};',
  28519. 'this.s = "";',
  28520. 'this.c = "";',
  28521. 'this.u = "";',
  28522. '']),
  28523. LinesToStr([ // $mod.$main
  28524. '$mod.DoIt($mod.s);',
  28525. '$mod.DoIt($mod.c);',
  28526. '$mod.DoIt($mod.u);',
  28527. '']));
  28528. end;
  28529. procedure TTestModule.TestJSValue_OverloadChar;
  28530. begin
  28531. StartProgram(false);
  28532. Add([
  28533. 'type',
  28534. ' uni = string;',
  28535. ' WChar = char;',
  28536. 'procedure DoIt(c: char); begin end;',
  28537. 'procedure DoIt(v: jsvalue); begin end;',
  28538. 'var',
  28539. ' s: string;',
  28540. ' c: char;',
  28541. ' u: uni;',
  28542. 'begin',
  28543. ' DoIt(s);',
  28544. ' DoIt(c);',
  28545. ' DoIt(u);',
  28546. '']);
  28547. ConvertProgram;
  28548. CheckSource('TestJSValue_OverloadChar',
  28549. LinesToStr([ // statements
  28550. 'this.DoIt = function (c) {',
  28551. '};',
  28552. 'this.DoIt$1 = function (v) {',
  28553. '};',
  28554. 'this.s = "";',
  28555. 'this.c = "";',
  28556. 'this.u = "";',
  28557. '']),
  28558. LinesToStr([ // $mod.$main
  28559. '$mod.DoIt$1($mod.s);',
  28560. '$mod.DoIt($mod.c);',
  28561. '$mod.DoIt$1($mod.u);',
  28562. '']));
  28563. end;
  28564. procedure TTestModule.TestJSValue_OverloadPointer;
  28565. begin
  28566. StartProgram(false);
  28567. Add([
  28568. 'type',
  28569. ' TObject = class end;',
  28570. 'procedure DoIt(p: pointer); begin end;',
  28571. 'procedure DoIt(v: jsvalue); begin end;',
  28572. 'var',
  28573. ' o: TObject;',
  28574. 'begin',
  28575. ' DoIt(o);',
  28576. '']);
  28577. ConvertProgram;
  28578. CheckSource('TestJSValue_OverloadPointer',
  28579. LinesToStr([ // statements
  28580. 'rtl.createClass(this, "TObject", null, function () {',
  28581. ' this.$init = function () {',
  28582. ' };',
  28583. ' this.$final = function () {',
  28584. ' };',
  28585. '});',
  28586. 'this.DoIt = function (p) {',
  28587. '};',
  28588. 'this.DoIt$1 = function (v) {',
  28589. '};',
  28590. 'this.o = null;',
  28591. '']),
  28592. LinesToStr([ // $mod.$main
  28593. '$mod.DoIt($mod.o);',
  28594. '']));
  28595. end;
  28596. procedure TTestModule.TestJSValue_ForIn;
  28597. begin
  28598. StartProgram(false);
  28599. Add([
  28600. 'var',
  28601. ' v: JSValue;',
  28602. ' key: string;',
  28603. 'begin',
  28604. ' for key in v do begin',
  28605. ' if key=''abc'' then ;',
  28606. ' end;',
  28607. '']);
  28608. ConvertProgram;
  28609. CheckSource('TestJSValue_ForIn',
  28610. LinesToStr([ // statements
  28611. 'this.v = undefined;',
  28612. 'this.key = "";',
  28613. '']),
  28614. LinesToStr([ // $mod.$main
  28615. 'for ($mod.key in $mod.v) {',
  28616. ' if ($mod.key === "abc") ;',
  28617. '};',
  28618. '']));
  28619. end;
  28620. procedure TTestModule.TestRTTI_IntRange;
  28621. begin
  28622. WithTypeInfo:=true;
  28623. StartProgram(true,[supTypeInfo]);
  28624. Add([
  28625. '{$modeswitch externalclass}',
  28626. 'type',
  28627. ' TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;',
  28628. ' TColor = type TGraphicsColor;',
  28629. 'var',
  28630. ' p: TTypeInfo;',
  28631. ' k: TTypeKind;',
  28632. 'begin',
  28633. ' p:=typeinfo(TGraphicsColor);',
  28634. ' p:=typeinfo(TColor);',
  28635. ' k:=GetTypeKind(TGraphicsColor);',
  28636. ' k:=GetTypeKind(TColor);',
  28637. '']);
  28638. ConvertProgram;
  28639. CheckSource('TestRTTI_IntRange',
  28640. LinesToStr([ // statements
  28641. 'this.$rtti.$Int("TGraphicsColor", {',
  28642. ' minvalue: -2147483648,',
  28643. ' maxvalue: 2147483647,',
  28644. ' ordtype: 4',
  28645. '});',
  28646. 'this.$rtti.$inherited("TColor", this.$rtti["TGraphicsColor"], {});',
  28647. 'this.p = null;',
  28648. 'this.k = 0;',
  28649. '']),
  28650. LinesToStr([ // $mod.$main
  28651. '$mod.p = $mod.$rtti["TGraphicsColor"];',
  28652. '$mod.p = $mod.$rtti["TColor"];',
  28653. '$mod.k = 1;',
  28654. '$mod.k = 1;',
  28655. '']));
  28656. end;
  28657. procedure TTestModule.TestRTTI_Double;
  28658. begin
  28659. WithTypeInfo:=true;
  28660. StartProgram(true,[supTypeInfo]);
  28661. Add([
  28662. '{$modeswitch externalclass}',
  28663. 'type',
  28664. ' TFloat = type double;',
  28665. 'var',
  28666. ' p: TTypeInfo;',
  28667. 'begin',
  28668. ' p:=typeinfo(double);',
  28669. ' p:=typeinfo(TFloat);',
  28670. '']);
  28671. ConvertProgram;
  28672. CheckSource('TestRTTI_Double',
  28673. LinesToStr([ // statements
  28674. 'this.$rtti.$inherited("TFloat", rtl.double, {});',
  28675. 'this.p = null;',
  28676. '']),
  28677. LinesToStr([ // $mod.$main
  28678. '$mod.p = rtl.double;',
  28679. '$mod.p = $mod.$rtti["TFloat"];',
  28680. '']));
  28681. end;
  28682. procedure TTestModule.TestRTTI_ProcType;
  28683. begin
  28684. WithTypeInfo:=true;
  28685. StartProgram(false);
  28686. Add('type');
  28687. Add(' TProcA = procedure;');
  28688. Add(' TMethodB = procedure of object;');
  28689. Add(' TProcC = procedure; varargs;');
  28690. Add(' TProcD = procedure(i: longint; const j: string; var c: char; out d: double);');
  28691. Add(' TProcE = function: nativeint;');
  28692. Add(' TProcF = function(const p: TProcA): nativeuint;');
  28693. Add('var p: pointer;');
  28694. Add('begin');
  28695. Add(' p:=typeinfo(tproca);');
  28696. ConvertProgram;
  28697. CheckSource('TestRTTI_ProcType',
  28698. LinesToStr([ // statements
  28699. 'this.$rtti.$ProcVar("TProcA", {',
  28700. ' procsig: rtl.newTIProcSig([])',
  28701. '});',
  28702. 'this.$rtti.$MethodVar("TMethodB", {',
  28703. ' procsig: rtl.newTIProcSig([]),',
  28704. ' methodkind: 0',
  28705. '});',
  28706. 'this.$rtti.$ProcVar("TProcC", {',
  28707. ' procsig: rtl.newTIProcSig([], null, 2)',
  28708. '});',
  28709. 'this.$rtti.$ProcVar("TProcD", {',
  28710. ' procsig: rtl.newTIProcSig([["i", rtl.longint], ["j", rtl.string, 2], ["c", rtl.char, 1], ["d", rtl.double, 4]])',
  28711. '});',
  28712. 'this.$rtti.$ProcVar("TProcE", {',
  28713. ' procsig: rtl.newTIProcSig([], rtl.nativeint)',
  28714. '});',
  28715. 'this.$rtti.$ProcVar("TProcF", {',
  28716. ' procsig: rtl.newTIProcSig([["p", this.$rtti["TProcA"], 2]], rtl.nativeuint)',
  28717. '});',
  28718. 'this.p = null;',
  28719. '']),
  28720. LinesToStr([ // $mod.$main
  28721. '$mod.p = $mod.$rtti["TProcA"];',
  28722. '']));
  28723. end;
  28724. procedure TTestModule.TestRTTI_ProcType_ArgFromOtherUnit;
  28725. begin
  28726. WithTypeInfo:=true;
  28727. AddModuleWithIntfImplSrc('unit2.pas',
  28728. LinesToStr([
  28729. 'type',
  28730. ' TObject = class end;'
  28731. ]),
  28732. '');
  28733. StartUnit(true);
  28734. Add('interface');
  28735. Add('uses unit2;');
  28736. Add('type');
  28737. Add(' TProcA = function(o: tobject): tobject;');
  28738. Add('implementation');
  28739. Add('type');
  28740. Add(' TProcB = function(o: tobject): tobject;');
  28741. Add('var p: Pointer;');
  28742. Add('initialization');
  28743. Add(' p:=typeinfo(tproca);');
  28744. Add(' p:=typeinfo(tprocb);');
  28745. ConvertUnit;
  28746. CheckSource('TestRTTI_ProcType_ArgFromOtherUnit',
  28747. LinesToStr([ // statements
  28748. 'var $impl = $mod.$impl;',
  28749. 'this.$rtti.$ProcVar("TProcA", {',
  28750. ' procsig: rtl.newTIProcSig([["o", pas.unit2.$rtti["TObject"]]], pas.unit2.$rtti["TObject"])',
  28751. '});',
  28752. '']),
  28753. LinesToStr([ // this.$init
  28754. '$impl.p = $mod.$rtti["TProcA"];',
  28755. '$impl.p = $mod.$rtti["TProcB"];',
  28756. '']),
  28757. LinesToStr([ // implementation
  28758. '$mod.$rtti.$ProcVar("TProcB", {',
  28759. ' procsig: rtl.newTIProcSig([["o", pas.unit2.$rtti["TObject"]]], pas.unit2.$rtti["TObject"])',
  28760. '});',
  28761. '$impl.p = null;',
  28762. '']) );
  28763. end;
  28764. procedure TTestModule.TestRTTI_EnumAndSetType;
  28765. begin
  28766. WithTypeInfo:=true;
  28767. StartProgram(false);
  28768. Add('type');
  28769. Add(' TFlag = (light,dark);');
  28770. Add(' TFlags = set of TFlag;');
  28771. Add(' TProc = function(f: TFlags): TFlag;');
  28772. Add('var p: pointer;');
  28773. Add('begin');
  28774. Add(' p:=typeinfo(tflag);');
  28775. Add(' p:=typeinfo(tflags);');
  28776. ConvertProgram;
  28777. CheckSource('TestRTTI_EnumAndType',
  28778. LinesToStr([ // statements
  28779. 'this.TFlag = {',
  28780. ' "0": "light",',
  28781. ' light: 0,',
  28782. ' "1": "dark",',
  28783. ' dark: 1',
  28784. '};',
  28785. 'this.$rtti.$Enum("TFlag", {',
  28786. ' minvalue: 0,',
  28787. ' maxvalue: 1,',
  28788. ' ordtype: 1,',
  28789. ' enumtype: this.TFlag',
  28790. '});',
  28791. 'this.$rtti.$Set("TFlags", {',
  28792. ' comptype: this.$rtti["TFlag"]',
  28793. '});',
  28794. 'this.$rtti.$ProcVar("TProc", {',
  28795. ' procsig: rtl.newTIProcSig([["f", this.$rtti["TFlags"]]], this.$rtti["TFlag"])',
  28796. '});',
  28797. 'this.p = null;',
  28798. '']),
  28799. LinesToStr([ // $mod.$main
  28800. '$mod.p = $mod.$rtti["TFlag"];',
  28801. '$mod.p = $mod.$rtti["TFlags"];',
  28802. '']));
  28803. end;
  28804. procedure TTestModule.TestRTTI_EnumRange;
  28805. begin
  28806. WithTypeInfo:=true;
  28807. StartProgram(false);
  28808. Add([
  28809. 'type',
  28810. ' TCol = (red,green,blue);',
  28811. ' TColRg = green..blue;',
  28812. ' TSetOfColRg = set of TColRg;',
  28813. 'var p: pointer;',
  28814. 'begin',
  28815. ' p:=typeinfo(tcolrg);',
  28816. ' p:=typeinfo(tsetofcolrg);',
  28817. '']);
  28818. ConvertProgram;
  28819. end;
  28820. procedure TTestModule.TestRTTI_AnonymousEnumType;
  28821. begin
  28822. WithTypeInfo:=true;
  28823. StartProgram(false);
  28824. Add('type');
  28825. Add(' TFlags = set of (red, green);');
  28826. Add('var');
  28827. Add(' f: TFlags;');
  28828. Add('begin');
  28829. Add(' Include(f,red);');
  28830. ConvertProgram;
  28831. CheckSource('TestRTTI_AnonymousEnumType',
  28832. LinesToStr([ // statements
  28833. 'this.TFlags$a = {',
  28834. ' "0": "red",',
  28835. ' red: 0,',
  28836. ' "1": "green",',
  28837. ' green: 1',
  28838. '};',
  28839. 'this.$rtti.$Enum("TFlags$a", {',
  28840. ' minvalue: 0,',
  28841. ' maxvalue: 1,',
  28842. ' ordtype: 1,',
  28843. ' enumtype: this.TFlags$a',
  28844. '});',
  28845. 'this.$rtti.$Set("TFlags", {',
  28846. ' comptype: this.$rtti["TFlags$a"]',
  28847. '});',
  28848. 'this.f = {};',
  28849. '']),
  28850. LinesToStr([
  28851. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  28852. '']));
  28853. end;
  28854. procedure TTestModule.TestRTTI_StaticArray;
  28855. begin
  28856. WithTypeInfo:=true;
  28857. StartProgram(false);
  28858. Add('type');
  28859. Add(' TFlag = (light,dark);');
  28860. Add(' TFlagNames = array[TFlag] of string;');
  28861. Add(' TBoolNames = array[boolean] of string;');
  28862. Add(' TByteArray = array[1..32768] of byte;');
  28863. Add(' TProc = function(f: TBoolNames): TFlagNames;');
  28864. Add('var p: pointer;');
  28865. Add('begin');
  28866. Add(' p:=typeinfo(TFlagNames);');
  28867. Add(' p:=typeinfo(TBoolNames);');
  28868. ConvertProgram;
  28869. CheckSource('TestRTTI_StaticArray',
  28870. LinesToStr([ // statements
  28871. 'this.TFlag = {',
  28872. ' "0": "light",',
  28873. ' light: 0,',
  28874. ' "1": "dark",',
  28875. ' dark: 1',
  28876. '};',
  28877. 'this.$rtti.$Enum("TFlag", {',
  28878. ' minvalue: 0,',
  28879. ' maxvalue: 1,',
  28880. ' ordtype: 1,',
  28881. ' enumtype: this.TFlag',
  28882. '});',
  28883. 'this.$rtti.$StaticArray("TFlagNames", {',
  28884. ' dims: [2],',
  28885. ' eltype: rtl.string',
  28886. '});',
  28887. 'this.$rtti.$StaticArray("TBoolNames", {',
  28888. ' dims: [2],',
  28889. ' eltype: rtl.string',
  28890. '});',
  28891. 'this.$rtti.$StaticArray("TByteArray", {',
  28892. ' dims: [32768],',
  28893. ' eltype: rtl.byte',
  28894. '});',
  28895. 'this.$rtti.$ProcVar("TProc", {',
  28896. ' procsig: rtl.newTIProcSig([["f", this.$rtti["TBoolNames"]]], this.$rtti["TFlagNames"])',
  28897. '});',
  28898. 'this.p = null;',
  28899. '']),
  28900. LinesToStr([ // $mod.$main
  28901. '$mod.p = $mod.$rtti["TFlagNames"];',
  28902. '$mod.p = $mod.$rtti["TBoolNames"];',
  28903. '']));
  28904. end;
  28905. procedure TTestModule.TestRTTI_DynArray;
  28906. begin
  28907. WithTypeInfo:=true;
  28908. StartProgram(false);
  28909. Add('type');
  28910. Add(' TArrStr = array of string;');
  28911. Add(' TArr2Dim = array of tarrstr;');
  28912. Add(' TProc = function(f: TArrStr): TArr2Dim;');
  28913. Add('var p: pointer;');
  28914. Add('begin');
  28915. Add(' p:=typeinfo(tarrstr);');
  28916. Add(' p:=typeinfo(tarr2dim);');
  28917. ConvertProgram;
  28918. CheckSource('TestRTTI_DynArray',
  28919. LinesToStr([ // statements
  28920. 'this.$rtti.$DynArray("TArrStr", {',
  28921. ' eltype: rtl.string',
  28922. '});',
  28923. 'this.$rtti.$DynArray("TArr2Dim", {',
  28924. ' eltype: this.$rtti["TArrStr"]',
  28925. '});',
  28926. 'this.$rtti.$ProcVar("TProc", {',
  28927. ' procsig: rtl.newTIProcSig([["f", this.$rtti["TArrStr"]]], this.$rtti["TArr2Dim"])',
  28928. '});',
  28929. 'this.p = null;',
  28930. '']),
  28931. LinesToStr([ // $mod.$main
  28932. '$mod.p = $mod.$rtti["TArrStr"];',
  28933. '$mod.p = $mod.$rtti["TArr2Dim"];',
  28934. '']));
  28935. end;
  28936. procedure TTestModule.TestRTTI_ArrayNestedAnonymous;
  28937. begin
  28938. WithTypeInfo:=true;
  28939. StartProgram(false);
  28940. Add('type');
  28941. Add(' TArr = array of array of longint;');
  28942. Add('var a: TArr;');
  28943. Add('begin');
  28944. ConvertProgram;
  28945. CheckSource('TestRTTI_ArrayNestedAnonymous',
  28946. LinesToStr([ // statements
  28947. 'this.$rtti.$DynArray("TArr$a", {',
  28948. ' eltype: rtl.longint',
  28949. '});',
  28950. 'this.$rtti.$DynArray("TArr", {',
  28951. ' eltype: this.$rtti["TArr$a"]',
  28952. '});',
  28953. 'this.a = [];',
  28954. '']),
  28955. LinesToStr([ // $mod.$main
  28956. ]));
  28957. end;
  28958. procedure TTestModule.TestRTTI_PublishedMethodOverloadFail;
  28959. begin
  28960. WithTypeInfo:=true;
  28961. StartProgram(false);
  28962. Add('type');
  28963. Add(' TObject = class');
  28964. Add(' published');
  28965. Add(' procedure Proc; virtual; abstract;');
  28966. Add(' procedure Proc(Sender: tobject); virtual; abstract;');
  28967. Add(' end;');
  28968. Add('begin');
  28969. SetExpectedPasResolverError('Duplicate published method "Proc" at test1.pp(6,19)',
  28970. nDuplicatePublishedMethodXAtY);
  28971. ConvertProgram;
  28972. end;
  28973. procedure TTestModule.TestRTTI_PublishedMethodHideNoHint;
  28974. begin
  28975. WithTypeInfo:=true;
  28976. StartUnit(false);
  28977. Add([
  28978. 'interface',
  28979. 'type',
  28980. ' TObject = class',
  28981. ' end;',
  28982. ' {$M+}',
  28983. ' TBird = class',
  28984. ' procedure Fly;',
  28985. ' end;',
  28986. ' {$M-}',
  28987. 'type',
  28988. ' TEagle = class(TBird)',
  28989. ' procedure Fly;',
  28990. ' end;',
  28991. 'implementation',
  28992. 'procedure TBird.Fly;',
  28993. 'begin',
  28994. 'end;',
  28995. 'procedure TEagle.Fly;',
  28996. 'begin',
  28997. 'end;',
  28998. '']);
  28999. ConvertUnit;
  29000. CheckSource('TestRTTI_PublishedMethodHideNoHint',
  29001. LinesToStr([ // statements
  29002. 'rtl.createClass(this, "TObject", null, function () {',
  29003. ' this.$init = function () {',
  29004. ' };',
  29005. ' this.$final = function () {',
  29006. ' };',
  29007. '});',
  29008. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  29009. ' this.Fly = function () {',
  29010. ' };',
  29011. ' var $r = this.$rtti;',
  29012. ' $r.addMethod("Fly", 0, []);',
  29013. '});',
  29014. 'rtl.createClass(this, "TEagle", this.TBird, function () {',
  29015. ' this.Fly = function () {',
  29016. ' };',
  29017. ' var $r = this.$rtti;',
  29018. ' $r.addMethod("Fly", 0, []);',
  29019. '});',
  29020. '']),
  29021. LinesToStr([ // $mod.$main
  29022. ]));
  29023. CheckResolverUnexpectedHints(true);
  29024. end;
  29025. procedure TTestModule.TestRTTI_PublishedMethodExternalFail;
  29026. begin
  29027. WithTypeInfo:=true;
  29028. StartProgram(false);
  29029. Add('type');
  29030. Add(' TObject = class');
  29031. Add(' published');
  29032. Add(' procedure Proc; external name ''foo'';');
  29033. Add(' end;');
  29034. Add('begin');
  29035. SetExpectedPasResolverError(sPublishedNameMustMatchExternal,
  29036. nPublishedNameMustMatchExternal);
  29037. ConvertProgram;
  29038. end;
  29039. procedure TTestModule.TestRTTI_PublishedClassPropertyFail;
  29040. begin
  29041. WithTypeInfo:=true;
  29042. StartProgram(false);
  29043. Add('type');
  29044. Add(' TObject = class');
  29045. Add(' class var FA: longint;');
  29046. Add(' published');
  29047. Add(' class property A: longint read FA;');
  29048. Add(' end;');
  29049. Add('begin');
  29050. SetExpectedPasResolverError('Invalid published property modifier "class"',
  29051. nInvalidXModifierY);
  29052. ConvertProgram;
  29053. end;
  29054. procedure TTestModule.TestRTTI_PublishedClassFieldFail;
  29055. begin
  29056. WithTypeInfo:=true;
  29057. StartProgram(false);
  29058. Add('type');
  29059. Add(' TObject = class');
  29060. Add(' published');
  29061. Add(' class var FA: longint;');
  29062. Add(' end;');
  29063. Add('begin');
  29064. SetExpectedPasResolverError(sSymbolCannotBePublished,
  29065. nSymbolCannotBePublished);
  29066. ConvertProgram;
  29067. end;
  29068. procedure TTestModule.TestRTTI_PublishedFieldExternalFail;
  29069. begin
  29070. WithTypeInfo:=true;
  29071. StartProgram(false);
  29072. Add('{$modeswitch externalclass}');
  29073. Add('type');
  29074. Add(' TObject = class');
  29075. Add(' published');
  29076. Add(' V: longint; external name ''foo'';');
  29077. Add(' end;');
  29078. Add('begin');
  29079. SetExpectedPasResolverError(sPublishedNameMustMatchExternal,
  29080. nPublishedNameMustMatchExternal);
  29081. ConvertProgram;
  29082. end;
  29083. procedure TTestModule.TestRTTI_Class_Field;
  29084. begin
  29085. WithTypeInfo:=true;
  29086. StartProgram(false);
  29087. Add('{$modeswitch externalclass}');
  29088. Add('type');
  29089. Add(' TObject = class');
  29090. Add(' private');
  29091. Add(' FPropA: string;');
  29092. Add(' published');
  29093. Add(' VarLI: longint;');
  29094. Add(' VarC: char;');
  29095. Add(' VarS: string;');
  29096. Add(' VarD: double;');
  29097. Add(' VarB: boolean;');
  29098. Add(' VarLW: longword;');
  29099. Add(' VarSmI: smallint;');
  29100. Add(' VarW: word;');
  29101. Add(' VarShI: shortint;');
  29102. Add(' VarBy: byte;');
  29103. Add(' VarExt: longint external name ''VarExt'';');
  29104. Add(' ArrA, ArrB: array of byte;');
  29105. Add(' end;');
  29106. Add('var p: pointer;');
  29107. Add(' Obj: tobject;');
  29108. Add('begin');
  29109. Add(' p:=typeinfo(tobject);');
  29110. Add(' p:=typeinfo(p);');
  29111. Add(' p:=typeinfo(obj);');
  29112. ConvertProgram;
  29113. CheckSource('TestRTTI_Class_Field',
  29114. LinesToStr([ // statements
  29115. 'rtl.createClass(this, "TObject", null, function () {',
  29116. ' this.$init = function () {',
  29117. ' this.FPropA = "";',
  29118. ' this.VarLI = 0;',
  29119. ' this.VarC = "";',
  29120. ' this.VarS = "";',
  29121. ' this.VarD = 0.0;',
  29122. ' this.VarB = false;',
  29123. ' this.VarLW = 0;',
  29124. ' this.VarSmI = 0;',
  29125. ' this.VarW = 0;',
  29126. ' this.VarShI = 0;',
  29127. ' this.VarBy = 0;',
  29128. ' this.ArrA = [];',
  29129. ' this.ArrB = [];',
  29130. ' };',
  29131. ' this.$final = function () {',
  29132. ' this.ArrA = undefined;',
  29133. ' this.ArrB = undefined;',
  29134. ' };',
  29135. ' var $r = this.$rtti;',
  29136. ' $r.addField("VarLI", rtl.longint);',
  29137. ' $r.addField("VarC", rtl.char);',
  29138. ' $r.addField("VarS", rtl.string);',
  29139. ' $r.addField("VarD", rtl.double);',
  29140. ' $r.addField("VarB", rtl.boolean);',
  29141. ' $r.addField("VarLW", rtl.longword);',
  29142. ' $r.addField("VarSmI", rtl.smallint);',
  29143. ' $r.addField("VarW", rtl.word);',
  29144. ' $r.addField("VarShI", rtl.shortint);',
  29145. ' $r.addField("VarBy", rtl.byte);',
  29146. ' $r.addField("VarExt", rtl.longint);',
  29147. ' $mod.$rtti.$DynArray("TObject.ArrB$a", {',
  29148. ' eltype: rtl.byte',
  29149. ' });',
  29150. ' $r.addField("ArrA", $mod.$rtti["TObject.ArrB$a"]);',
  29151. ' $r.addField("ArrB", $mod.$rtti["TObject.ArrB$a"]);',
  29152. '});',
  29153. 'this.p = null;',
  29154. 'this.Obj = null;',
  29155. '']),
  29156. LinesToStr([ // $mod.$main
  29157. '$mod.p = $mod.$rtti["TObject"];',
  29158. '$mod.p = rtl.pointer;',
  29159. '$mod.p = $mod.Obj.$rtti;',
  29160. '']));
  29161. end;
  29162. procedure TTestModule.TestRTTI_Class_Method;
  29163. begin
  29164. WithTypeInfo:=true;
  29165. StartProgram(false);
  29166. Add([
  29167. 'type',
  29168. ' TObject = class',
  29169. ' private',
  29170. ' procedure Internal; external name ''$intern'';',
  29171. ' published',
  29172. ' procedure Click; virtual; abstract;',
  29173. ' procedure Notify(Sender: TObject); virtual; abstract;',
  29174. ' function GetNotify: boolean; external name ''GetNotify'';',
  29175. ' procedure Println(a,b: longint); varargs; virtual; abstract;',
  29176. ' function Fetch(URL: string): word; async; external name ''Fetch'';',
  29177. ' end;',
  29178. 'begin']);
  29179. ConvertProgram;
  29180. CheckSource('TestRTTI_Class_Method',
  29181. LinesToStr([ // statements
  29182. 'rtl.createClass(this, "TObject", null, function () {',
  29183. ' this.$init = function () {',
  29184. ' };',
  29185. ' this.$final = function () {',
  29186. ' };',
  29187. ' var $r = this.$rtti;',
  29188. ' $r.addMethod("Click", 0, []);',
  29189. ' $r.addMethod("Notify", 0, [["Sender", $r]]);',
  29190. ' $r.addMethod("GetNotify", 1, [], rtl.boolean, 4);',
  29191. ' $r.addMethod("Println", 0, [["a", rtl.longint], ["b", rtl.longint]], null, 2);',
  29192. ' $r.addMethod("Fetch", 1, [["URL", rtl.string]], rtl.word, 20);',
  29193. '});',
  29194. '']),
  29195. LinesToStr([ // $mod.$main
  29196. '']));
  29197. end;
  29198. procedure TTestModule.TestRTTI_Class_MethodArgFlags;
  29199. begin
  29200. WithTypeInfo:=true;
  29201. StartProgram(false);
  29202. Add('type');
  29203. Add(' TObject = class');
  29204. Add(' published');
  29205. Add(' procedure OpenArray(const Args: array of string); virtual; abstract;');
  29206. Add(' procedure ByRef(var Value: longint; out Item: longint); virtual; abstract;');
  29207. Add(' procedure Untyped(var Value; out Item); virtual; abstract;');
  29208. Add(' end;');
  29209. Add('begin');
  29210. ConvertProgram;
  29211. CheckSource('TestRTTI_Class_MethodOpenArray',
  29212. LinesToStr([ // statements
  29213. 'rtl.createClass(this, "TObject", null, function () {',
  29214. ' this.$init = function () {',
  29215. ' };',
  29216. ' this.$final = function () {',
  29217. ' };',
  29218. ' var $r = this.$rtti;',
  29219. '$r.addMethod("OpenArray", 0, [["Args", rtl.string, 10]]);',
  29220. '$r.addMethod("ByRef", 0, [["Value", rtl.longint, 1], ["Item", rtl.longint, 4]]);',
  29221. '$r.addMethod("Untyped", 0, [["Value", null, 1], ["Item", null, 4]]);',
  29222. '});',
  29223. '']),
  29224. LinesToStr([ // $mod.$main
  29225. '']));
  29226. end;
  29227. procedure TTestModule.TestRTTI_Class_Property;
  29228. begin
  29229. WithTypeInfo:=true;
  29230. StartProgram(false);
  29231. Add('{$modeswitch externalclass}');
  29232. Add('type');
  29233. Add(' TObject = class');
  29234. Add(' private');
  29235. Add(' FColor: longint;');
  29236. Add(' FColorStored: boolean;');
  29237. Add(' procedure SetColor(Value: longint); virtual; abstract;');
  29238. Add(' function GetColor: longint; virtual; abstract;');
  29239. Add(' function GetColorStored: boolean; virtual; abstract;');
  29240. Add(' FExtSize: longint external name ''$extSize'';');
  29241. Add(' FExtSizeStored: boolean external name ''$extSizeStored'';');
  29242. Add(' procedure SetExtSize(Value: longint); external name ''$setSize'';');
  29243. Add(' function GetExtSize: longint; external name ''$getSize'';');
  29244. Add(' function GetExtSizeStored: boolean; external name ''$getExtSizeStored'';');
  29245. Add(' published');
  29246. Add(' property ColorA: longint read FColor;');
  29247. Add(' property ColorB: longint write FColor;');
  29248. Add(' property ColorC: longint read GetColor write SetColor;');
  29249. Add(' property ColorD: longint read FColor write FColor stored FColorStored;');
  29250. Add(' property ExtSizeA: longint read FExtSize write FExtSize;');
  29251. Add(' property ExtSizeB: longint read GetExtSize write SetExtSize stored FExtSizeStored;');
  29252. Add(' property ExtSizeC: longint read FExtSize write FExtSize stored GetExtSizeStored;');
  29253. Add(' end;');
  29254. Add('begin');
  29255. ConvertProgram;
  29256. CheckSource('TestRTTI_Class_Property',
  29257. LinesToStr([ // statements
  29258. 'rtl.createClass(this, "TObject", null, function () {',
  29259. ' this.$init = function () {',
  29260. ' this.FColor = 0;',
  29261. ' this.FColorStored = false;',
  29262. ' };',
  29263. ' this.$final = function () {',
  29264. ' };',
  29265. ' var $r = this.$rtti;',
  29266. ' $r.addProperty("ColorA", 0, rtl.longint, "FColor", "");',
  29267. ' $r.addProperty("ColorB", 0, rtl.longint, "", "FColor");',
  29268. ' $r.addProperty("ColorC", 3, rtl.longint, "GetColor", "SetColor");',
  29269. ' $r.addProperty(',
  29270. ' "ColorD",',
  29271. ' 8,',
  29272. ' rtl.longint,',
  29273. ' "FColor",',
  29274. ' "FColor",',
  29275. ' {',
  29276. ' stored: "FColorStored"',
  29277. ' }',
  29278. ' );',
  29279. ' $r.addProperty("ExtSizeA", 0, rtl.longint, "$extSize", "$extSize");',
  29280. ' $r.addProperty(',
  29281. ' "ExtSizeB",',
  29282. ' 11,',
  29283. ' rtl.longint,',
  29284. ' "$getSize",',
  29285. ' "$setSize",',
  29286. ' {',
  29287. ' stored: "$extSizeStored"',
  29288. ' }',
  29289. ' );',
  29290. ' $r.addProperty(',
  29291. ' "ExtSizeC",',
  29292. ' 12,',
  29293. ' rtl.longint,',
  29294. ' "$extSize",',
  29295. ' "$extSize",',
  29296. ' {',
  29297. ' stored: "$getExtSizeStored"',
  29298. ' }',
  29299. ' );',
  29300. '});',
  29301. '']),
  29302. LinesToStr([ // $mod.$main
  29303. '']));
  29304. end;
  29305. procedure TTestModule.TestRTTI_Class_PropertyParams;
  29306. begin
  29307. WithTypeInfo:=true;
  29308. StartProgram(false);
  29309. Add('{$modeswitch externalclass}');
  29310. Add('type');
  29311. Add(' integer = longint;');
  29312. Add(' TObject = class');
  29313. Add(' private');
  29314. Add(' function GetItems(i: integer): tobject; virtual; abstract;');
  29315. Add(' procedure SetItems(i: integer; value: tobject); virtual; abstract;');
  29316. Add(' function GetValues(const i: integer; var b: boolean): char; virtual; abstract;');
  29317. Add(' procedure SetValues(const i: integer; var b: boolean; value: char); virtual; abstract;');
  29318. Add(' published');
  29319. Add(' property Items[Index: integer]: tobject read getitems write setitems;');
  29320. Add(' property Values[const keya: integer; var keyb: boolean]: char read getvalues write setvalues;');
  29321. Add(' end;');
  29322. Add('begin');
  29323. ConvertProgram;
  29324. CheckSource('TestRTTI_Class_PropertyParams',
  29325. LinesToStr([ // statements
  29326. 'rtl.createClass(this, "TObject", null, function () {',
  29327. ' this.$init = function () {',
  29328. ' };',
  29329. ' this.$final = function () {',
  29330. ' };',
  29331. ' var $r = this.$rtti;',
  29332. ' $r.addProperty("Items", 3, $r, "GetItems", "SetItems");',
  29333. ' $r.addProperty("Values", 3, rtl.char, "GetValues", "SetValues");',
  29334. '});',
  29335. '']),
  29336. LinesToStr([ // $mod.$main
  29337. '']));
  29338. end;
  29339. procedure TTestModule.TestRTTI_Class_OtherUnit_TypeAlias;
  29340. begin
  29341. WithTypeInfo:=true;
  29342. AddModuleWithIntfImplSrc('unit1.pas',
  29343. 'type TColor = -5..5;',
  29344. '');
  29345. StartProgram(true);
  29346. Add([
  29347. 'uses unit1;',
  29348. 'type',
  29349. ' TColorAlias = TColor;',
  29350. ' TColorTypeAlias = type TColor;',
  29351. ' TObject = class',
  29352. ' private',
  29353. ' fColor: TColor;',
  29354. ' fAlias: TColorAlias;',
  29355. ' fTypeAlias: TColorTypeAlias;',
  29356. ' published',
  29357. ' property Color: TColor read fcolor;',
  29358. ' property Alias: TColorAlias read falias;',
  29359. ' property TypeAlias: TColorTypeAlias read ftypealias;',
  29360. ' end;',
  29361. 'begin',
  29362. '']);
  29363. ConvertProgram;
  29364. CheckSource('TestRTTI_Class_OtherUnit_TypeAlias',
  29365. LinesToStr([ // statements
  29366. 'this.$rtti.$inherited("TColorTypeAlias", pas.unit1.$rtti["TColor"], {});',
  29367. 'rtl.createClass(this, "TObject", null, function () {',
  29368. ' this.$init = function () {',
  29369. ' this.fColor = 0;',
  29370. ' this.fAlias = 0;',
  29371. ' this.fTypeAlias = 0;',
  29372. ' };',
  29373. ' this.$final = function () {',
  29374. ' };',
  29375. ' var $r = this.$rtti;',
  29376. ' $r.addProperty("Color", 0, pas.unit1.$rtti["TColor"], "fColor", "");',
  29377. ' $r.addProperty("Alias", 0, pas.unit1.$rtti["TColor"], "fAlias", "");',
  29378. ' $r.addProperty("TypeAlias", 0, $mod.$rtti["TColorTypeAlias"], "fTypeAlias", "");',
  29379. '});',
  29380. '']),
  29381. LinesToStr([ // $mod.$main
  29382. '']));
  29383. end;
  29384. procedure TTestModule.TestRTTI_Class_OmitRTTI;
  29385. begin
  29386. WithTypeInfo:=true;
  29387. StartProgram(false);
  29388. Add([
  29389. '{$modeswitch omitrtti}',
  29390. 'type',
  29391. ' TObject = class',
  29392. ' private',
  29393. ' FA: byte;',
  29394. ' published',
  29395. ' property A: byte read FA write FA;',
  29396. ' end;',
  29397. 'begin']);
  29398. ConvertProgram;
  29399. CheckSource('TestRTTI_Class_OmitRTTI',
  29400. LinesToStr([ // statements
  29401. 'rtl.createClass(this, "TObject", null, function () {',
  29402. ' this.$init = function () {',
  29403. ' this.FA = 0;',
  29404. ' };',
  29405. ' this.$final = function () {',
  29406. ' };',
  29407. '});',
  29408. '']),
  29409. LinesToStr([ // $mod.$main
  29410. '']));
  29411. end;
  29412. procedure TTestModule.TestRTTI_Class_Field_AnonymousArrayOfSelfClass;
  29413. begin
  29414. WithTypeInfo:=true;
  29415. StartUnit(true,[supTObject]);
  29416. Add([
  29417. 'interface',
  29418. 'type',
  29419. ' {$M+}',
  29420. ' TBird = class',
  29421. ' published',
  29422. ' Swarm: array of TBird;',
  29423. ' end;',
  29424. 'implementation',
  29425. '']);
  29426. ConvertUnit;
  29427. CheckSource('TestRTTI_Class_Field_AnonymousArrayOfSelfClass',
  29428. LinesToStr([ // statements
  29429. 'rtl.createClass(this, "TBird", pas.system.TObject, function () {',
  29430. ' this.$init = function () {',
  29431. ' pas.system.TObject.$init.call(this);',
  29432. ' this.Swarm = [];',
  29433. ' };',
  29434. ' this.$final = function () {',
  29435. ' this.Swarm = undefined;',
  29436. ' pas.system.TObject.$final.call(this);',
  29437. ' };',
  29438. ' var $r = this.$rtti;',
  29439. ' $mod.$rtti.$DynArray("TBird.Swarm$a", {',
  29440. ' eltype: $r',
  29441. ' });',
  29442. ' $r.addField("Swarm", $mod.$rtti["TBird.Swarm$a"]);',
  29443. '});',
  29444. '']),
  29445. LinesToStr([ // $mod.$main
  29446. '']));
  29447. end;
  29448. procedure TTestModule.TestRTTI_IndexModifier;
  29449. begin
  29450. WithTypeInfo:=true;
  29451. StartProgram(false);
  29452. Add([
  29453. 'type',
  29454. ' TEnum = (red, blue);',
  29455. ' TObject = class',
  29456. ' FB: boolean;',
  29457. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  29458. ' function GetBoolBool(Index: boolean): boolean; virtual; abstract;',
  29459. ' procedure SetBoolBool(Index: boolean; b: boolean); virtual; abstract;',
  29460. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  29461. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  29462. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  29463. ' published',
  29464. ' property B1: boolean index 1 read FB write SetIntBool;',
  29465. ' property B2: boolean index TEnum.blue read GetEnumBool write FB;',
  29466. ' property I1[A: String]: boolean index 2 read GetStrIntBool write SetStrIntBool;',
  29467. ' end;',
  29468. 'begin']);
  29469. ConvertProgram;
  29470. CheckSource('TestRTTI_IndexModifier',
  29471. LinesToStr([ // statements
  29472. 'this.TEnum = {',
  29473. ' "0": "red",',
  29474. ' red: 0,',
  29475. ' "1": "blue",',
  29476. ' blue: 1',
  29477. '};',
  29478. 'this.$rtti.$Enum("TEnum", {',
  29479. ' minvalue: 0,',
  29480. ' maxvalue: 1,',
  29481. ' ordtype: 1,',
  29482. ' enumtype: this.TEnum',
  29483. '});',
  29484. 'rtl.createClass(this, "TObject", null, function () {',
  29485. ' this.$init = function () {',
  29486. ' this.FB = false;',
  29487. ' };',
  29488. ' this.$final = function () {',
  29489. ' };',
  29490. ' var $r = this.$rtti;',
  29491. ' $r.addProperty(',
  29492. ' "B1",',
  29493. ' 18,',
  29494. ' rtl.boolean,',
  29495. ' "FB",',
  29496. ' "SetIntBool",',
  29497. ' {',
  29498. ' index: 1',
  29499. ' }',
  29500. ' );',
  29501. ' $r.addProperty(',
  29502. ' "B2",',
  29503. ' 17,',
  29504. ' rtl.boolean,',
  29505. ' "GetEnumBool",',
  29506. ' "FB",',
  29507. ' {',
  29508. ' index: $mod.TEnum.blue',
  29509. ' }',
  29510. ' );',
  29511. ' $r.addProperty(',
  29512. ' "I1",',
  29513. ' 19,',
  29514. ' rtl.boolean,',
  29515. ' "GetStrIntBool",',
  29516. ' "SetStrIntBool",',
  29517. ' {',
  29518. ' index: 2',
  29519. ' }',
  29520. ' );',
  29521. '});',
  29522. '']),
  29523. LinesToStr([ // $mod.$main
  29524. '']));
  29525. end;
  29526. procedure TTestModule.TestRTTI_StoredModifier;
  29527. begin
  29528. WithTypeInfo:=true;
  29529. StartProgram(false);
  29530. Add([
  29531. 'const',
  29532. ' ConstB = true;',
  29533. 'type',
  29534. ' TObject = class',
  29535. ' private',
  29536. ' FB: boolean;',
  29537. ' function IsBStored: boolean; virtual; abstract;',
  29538. ' published',
  29539. ' property BoolA: boolean read FB stored true;',
  29540. ' property BoolB: boolean read FB stored false;',
  29541. ' property BoolC: boolean read FB stored FB;',
  29542. ' property BoolD: boolean read FB stored ConstB;',
  29543. ' property BoolE: boolean read FB stored IsBStored;',
  29544. ' end;',
  29545. 'begin']);
  29546. ConvertProgram;
  29547. CheckSource('TestRTTI_StoredModifier',
  29548. LinesToStr([ // statements
  29549. 'this.ConstB = true;',
  29550. 'rtl.createClass(this, "TObject", null, function () {',
  29551. ' this.$init = function () {',
  29552. ' this.FB = false;',
  29553. ' };',
  29554. ' this.$final = function () {',
  29555. ' };',
  29556. ' var $r = this.$rtti;',
  29557. ' $r.addProperty("BoolA", 0, rtl.boolean, "FB", "");',
  29558. ' $r.addProperty("BoolB", 4, rtl.boolean, "FB", "");',
  29559. ' $r.addProperty(',
  29560. ' "BoolC",',
  29561. ' 8,',
  29562. ' rtl.boolean,',
  29563. ' "FB",',
  29564. ' "",',
  29565. ' {',
  29566. ' stored: "FB"',
  29567. ' }',
  29568. ' );',
  29569. ' $r.addProperty("BoolD", 0, rtl.boolean, "FB", "");',
  29570. ' $r.addProperty(',
  29571. ' "BoolE",',
  29572. ' 12,',
  29573. ' rtl.boolean,',
  29574. ' "FB",',
  29575. ' "",',
  29576. ' {',
  29577. ' stored: "IsBStored"',
  29578. ' }',
  29579. ' );',
  29580. '});',
  29581. '']),
  29582. LinesToStr([ // $mod.$main
  29583. '']));
  29584. end;
  29585. procedure TTestModule.TestRTTI_DefaultValue;
  29586. begin
  29587. WithTypeInfo:=true;
  29588. StartProgram(false);
  29589. Add([
  29590. 'type',
  29591. ' TEnum = (red, blue);',
  29592. 'const',
  29593. ' CB = true or false;',
  29594. ' CI = 1+2;',
  29595. 'type',
  29596. ' TObject = class',
  29597. ' FB: boolean;',
  29598. ' FI: longint;',
  29599. ' FE: TEnum;',
  29600. ' published',
  29601. ' property B1: boolean read FB default true;',
  29602. ' property B2: boolean read FB default CB;',
  29603. ' property B3: boolean read FB default test1.cb;',
  29604. ' property I1: longint read FI default 2;',
  29605. ' property I2: longint read FI default CI;',
  29606. ' property E1: TEnum read FE default red;',
  29607. ' property E2: TEnum read FE default TEnum.blue;',
  29608. ' end;',
  29609. 'begin']);
  29610. ConvertProgram;
  29611. CheckSource('TestRTTI_DefaultValue',
  29612. LinesToStr([ // statements
  29613. 'this.TEnum = {',
  29614. ' "0": "red",',
  29615. ' red: 0,',
  29616. ' "1": "blue",',
  29617. ' blue: 1',
  29618. '};',
  29619. 'this.$rtti.$Enum("TEnum", {',
  29620. ' minvalue: 0,',
  29621. ' maxvalue: 1,',
  29622. ' ordtype: 1,',
  29623. ' enumtype: this.TEnum',
  29624. '});',
  29625. 'this.CB = true || false;',
  29626. 'this.CI = 1 + 2;',
  29627. 'rtl.createClass(this, "TObject", null, function () {',
  29628. ' this.$init = function () {',
  29629. ' this.FB = false;',
  29630. ' this.FI = 0;',
  29631. ' this.FE = 0;',
  29632. ' };',
  29633. ' this.$final = function () {',
  29634. ' };',
  29635. ' var $r = this.$rtti;',
  29636. ' $r.addProperty(',
  29637. ' "B1",',
  29638. ' 0,',
  29639. ' rtl.boolean,',
  29640. ' "FB",',
  29641. ' "",',
  29642. ' {',
  29643. ' Default: true',
  29644. ' }',
  29645. ' );',
  29646. ' $r.addProperty(',
  29647. ' "B2",',
  29648. ' 0,',
  29649. ' rtl.boolean,',
  29650. ' "FB",',
  29651. ' "",',
  29652. ' {',
  29653. ' Default: true',
  29654. ' }',
  29655. ' );',
  29656. ' $r.addProperty(',
  29657. ' "B3",',
  29658. ' 0,',
  29659. ' rtl.boolean,',
  29660. ' "FB",',
  29661. ' "",',
  29662. ' {',
  29663. ' Default: true',
  29664. ' }',
  29665. ' );',
  29666. ' $r.addProperty(',
  29667. ' "I1",',
  29668. ' 0,',
  29669. ' rtl.longint,',
  29670. ' "FI",',
  29671. ' "",',
  29672. ' {',
  29673. ' Default: 2',
  29674. ' }',
  29675. ' );',
  29676. ' $r.addProperty(',
  29677. ' "I2",',
  29678. ' 0,',
  29679. ' rtl.longint,',
  29680. ' "FI",',
  29681. ' "",',
  29682. ' {',
  29683. ' Default: 3',
  29684. ' }',
  29685. ' );',
  29686. ' $r.addProperty(',
  29687. ' "E1",',
  29688. ' 0,',
  29689. ' $mod.$rtti["TEnum"],',
  29690. ' "FE",',
  29691. ' "",',
  29692. ' {',
  29693. ' Default: $mod.TEnum.red',
  29694. ' }',
  29695. ' );',
  29696. ' $r.addProperty(',
  29697. ' "E2",',
  29698. ' 0,',
  29699. ' $mod.$rtti["TEnum"],',
  29700. ' "FE",',
  29701. ' "",',
  29702. ' {',
  29703. ' Default: $mod.TEnum.blue',
  29704. ' }',
  29705. ' );',
  29706. '});',
  29707. '']),
  29708. LinesToStr([ // $mod.$main
  29709. '']));
  29710. end;
  29711. procedure TTestModule.TestRTTI_DefaultValueSet;
  29712. begin
  29713. WithTypeInfo:=true;
  29714. StartProgram(false);
  29715. Add([
  29716. 'type',
  29717. ' TEnum = (red, blue);',
  29718. ' TSet = set of TEnum;',
  29719. 'const',
  29720. ' CSet = [red,blue];',
  29721. 'type',
  29722. ' TObject = class',
  29723. ' FSet: TSet;',
  29724. ' published',
  29725. ' property Set1: TSet read FSet default [];',
  29726. ' property Set2: TSet read FSet default [red];',
  29727. ' property Set3: TSet read FSet default [red,blue];',
  29728. ' property Set4: TSet read FSet default CSet;',
  29729. ' end;',
  29730. 'begin']);
  29731. ConvertProgram;
  29732. CheckSource('TestRTTI_DefaultValueSet',
  29733. LinesToStr([ // statements
  29734. 'this.TEnum = {',
  29735. ' "0": "red",',
  29736. ' red: 0,',
  29737. ' "1": "blue",',
  29738. ' blue: 1',
  29739. '};',
  29740. 'this.$rtti.$Enum("TEnum", {',
  29741. ' minvalue: 0,',
  29742. ' maxvalue: 1,',
  29743. ' ordtype: 1,',
  29744. ' enumtype: this.TEnum',
  29745. '});',
  29746. 'this.$rtti.$Set("TSet", {',
  29747. ' comptype: this.$rtti["TEnum"]',
  29748. '});',
  29749. 'this.CSet = rtl.createSet(this.TEnum.red, this.TEnum.blue);',
  29750. 'rtl.createClass(this, "TObject", null, function () {',
  29751. ' this.$init = function () {',
  29752. ' this.FSet = {};',
  29753. ' };',
  29754. ' this.$final = function () {',
  29755. ' this.FSet = undefined;',
  29756. ' };',
  29757. ' var $r = this.$rtti;',
  29758. ' $r.addProperty(',
  29759. ' "Set1",',
  29760. ' 0,',
  29761. ' $mod.$rtti["TSet"],',
  29762. ' "FSet",',
  29763. ' "",',
  29764. ' {',
  29765. ' Default: {}',
  29766. ' }',
  29767. ' );',
  29768. ' $r.addProperty(',
  29769. ' "Set2",',
  29770. ' 0,',
  29771. ' $mod.$rtti["TSet"],',
  29772. ' "FSet",',
  29773. ' "",',
  29774. ' {',
  29775. ' Default: rtl.createSet($mod.TEnum.red)',
  29776. ' }',
  29777. ' );',
  29778. ' $r.addProperty(',
  29779. ' "Set3",',
  29780. ' 0,',
  29781. ' $mod.$rtti["TSet"],',
  29782. ' "FSet",',
  29783. ' "",',
  29784. ' {',
  29785. ' Default: rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)',
  29786. ' }',
  29787. ' );',
  29788. ' $r.addProperty(',
  29789. ' "Set4",',
  29790. ' 0,',
  29791. ' $mod.$rtti["TSet"],',
  29792. ' "FSet",',
  29793. ' "",',
  29794. ' {',
  29795. ' Default: $mod.CSet',
  29796. ' }',
  29797. ' );',
  29798. '});',
  29799. '']),
  29800. LinesToStr([ // $mod.$main
  29801. '']));
  29802. end;
  29803. procedure TTestModule.TestRTTI_DefaultValueRangeType;
  29804. begin
  29805. WithTypeInfo:=true;
  29806. StartProgram(false);
  29807. Add([
  29808. 'type',
  29809. ' TRg = -1..1;',
  29810. 'const',
  29811. ' l = low(TRg);',
  29812. ' h = high(TRg);',
  29813. 'type',
  29814. ' TObject = class',
  29815. ' FV: TRg;',
  29816. ' published',
  29817. ' property V1: TRg read FV default -1;',
  29818. ' end;',
  29819. 'begin']);
  29820. ConvertProgram;
  29821. CheckSource('TestRTTI_DefaultValueRangeType',
  29822. LinesToStr([ // statements
  29823. 'this.$rtti.$Int("TRg", {',
  29824. ' minvalue: -1,',
  29825. ' maxvalue: 1,',
  29826. ' ordtype: 0',
  29827. '});',
  29828. 'this.l = -1;',
  29829. 'this.h = 1;',
  29830. 'rtl.createClass(this, "TObject", null, function () {',
  29831. ' this.$init = function () {',
  29832. ' this.FV = 0;',
  29833. ' };',
  29834. ' this.$final = function () {',
  29835. ' };',
  29836. ' var $r = this.$rtti;',
  29837. ' $r.addProperty(',
  29838. ' "V1",',
  29839. ' 0,',
  29840. ' $mod.$rtti["TRg"],',
  29841. ' "FV",',
  29842. ' "",',
  29843. ' {',
  29844. ' Default: -1',
  29845. ' }',
  29846. ' );',
  29847. '});',
  29848. '']),
  29849. LinesToStr([ // $mod.$main
  29850. '']));
  29851. end;
  29852. procedure TTestModule.TestRTTI_DefaultValueInherit;
  29853. begin
  29854. WithTypeInfo:=true;
  29855. StartProgram(false);
  29856. Add([
  29857. 'type',
  29858. ' TObject = class',
  29859. ' FA, FB: byte;',
  29860. ' property A: byte read FA default 1;',
  29861. ' property B: byte read FB default 2;',
  29862. ' end;',
  29863. ' TBird = class',
  29864. ' published',
  29865. ' property A;',
  29866. ' property B nodefault;',
  29867. ' end;',
  29868. 'begin']);
  29869. ConvertProgram;
  29870. CheckSource('TestRTTI_DefaultValueInherit',
  29871. LinesToStr([ // statements
  29872. 'rtl.createClass(this, "TObject", null, function () {',
  29873. ' this.$init = function () {',
  29874. ' this.FA = 0;',
  29875. ' this.FB = 0;',
  29876. ' };',
  29877. ' this.$final = function () {',
  29878. ' };',
  29879. '});',
  29880. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  29881. ' var $r = this.$rtti;',
  29882. ' $r.addProperty(',
  29883. ' "A",',
  29884. ' 0,',
  29885. ' rtl.byte,',
  29886. ' "FA",',
  29887. ' "",',
  29888. ' {',
  29889. ' Default: 1',
  29890. ' }',
  29891. ' );',
  29892. ' $r.addProperty("B", 0, rtl.byte, "FB", "");',
  29893. '});',
  29894. '']),
  29895. LinesToStr([ // $mod.$main
  29896. '']));
  29897. end;
  29898. procedure TTestModule.TestRTTI_OverrideMethod;
  29899. begin
  29900. WithTypeInfo:=true;
  29901. StartProgram(false);
  29902. Add('type');
  29903. Add(' TObject = class');
  29904. Add(' published');
  29905. Add(' procedure DoIt; virtual; abstract;');
  29906. Add(' end;');
  29907. Add(' TSky = class');
  29908. Add(' published');
  29909. Add(' procedure DoIt; override;');
  29910. Add(' end;');
  29911. Add('procedure TSky.DoIt; begin end;');
  29912. Add('begin');
  29913. ConvertProgram;
  29914. CheckSource('TestRTTI_OverrideMethod',
  29915. LinesToStr([ // statements
  29916. 'rtl.createClass(this, "TObject", null, function () {',
  29917. ' this.$init = function () {',
  29918. ' };',
  29919. ' this.$final = function () {',
  29920. ' };',
  29921. ' var $r = this.$rtti;',
  29922. ' $r.addMethod("DoIt", 0, []);',
  29923. '});',
  29924. 'rtl.createClass(this, "TSky", this.TObject, function () {',
  29925. ' this.DoIt = function () {',
  29926. ' };',
  29927. '});',
  29928. '']),
  29929. LinesToStr([ // $mod.$main
  29930. '']));
  29931. end;
  29932. procedure TTestModule.TestRTTI_ReintroduceMethod;
  29933. begin
  29934. WithTypeInfo:=true;
  29935. StartProgram(false);
  29936. Add([
  29937. 'type',
  29938. ' TObject = class',
  29939. ' published',
  29940. ' procedure DoIt;',
  29941. ' end;',
  29942. ' TSky = class',
  29943. ' published',
  29944. ' procedure DoIt; reintroduce;',
  29945. ' end;',
  29946. 'procedure TObject.DoIt; begin end;',
  29947. 'procedure TSky.DoIt;',
  29948. 'begin',
  29949. ' inherited DoIt;',
  29950. 'end;',
  29951. 'begin']);
  29952. ConvertProgram;
  29953. CheckSource('TestRTTI_ReintroduceMethod',
  29954. LinesToStr([ // statements
  29955. 'rtl.createClass(this, "TObject", null, function () {',
  29956. ' this.$init = function () {',
  29957. ' };',
  29958. ' this.$final = function () {',
  29959. ' };',
  29960. ' this.DoIt = function () {',
  29961. ' };',
  29962. ' var $r = this.$rtti;',
  29963. ' $r.addMethod("DoIt", 0, []);',
  29964. '});',
  29965. 'rtl.createClass(this, "TSky", this.TObject, function () {',
  29966. ' this.DoIt = function () {',
  29967. ' $mod.TObject.DoIt.call(this);',
  29968. ' };',
  29969. ' var $r = this.$rtti;',
  29970. ' $r.addMethod("DoIt", 0, []);',
  29971. '});',
  29972. '']),
  29973. LinesToStr([ // $mod.$main
  29974. '']));
  29975. end;
  29976. procedure TTestModule.TestRTTI_OverloadProperty;
  29977. begin
  29978. WithTypeInfo:=true;
  29979. StartProgram(false);
  29980. Add('type');
  29981. Add(' TObject = class');
  29982. Add(' protected');
  29983. Add(' FFlag: longint;');
  29984. Add(' published');
  29985. Add(' property Flag: longint read fflag;');
  29986. Add(' end;');
  29987. Add(' TSky = class');
  29988. Add(' published');
  29989. Add(' property FLAG: longint write fflag;');
  29990. Add(' end;');
  29991. Add('begin');
  29992. ConvertProgram;
  29993. CheckSource('TestRTTI_OverrideMethod',
  29994. LinesToStr([ // statements
  29995. 'rtl.createClass(this, "TObject", null, function () {',
  29996. ' this.$init = function () {',
  29997. ' this.FFlag = 0;',
  29998. ' };',
  29999. ' this.$final = function () {',
  30000. ' };',
  30001. ' var $r = this.$rtti;',
  30002. ' $r.addProperty("Flag", 0, rtl.longint, "FFlag", "");',
  30003. '});',
  30004. 'rtl.createClass(this, "TSky", this.TObject, function () {',
  30005. ' var $r = this.$rtti;',
  30006. ' $r.addProperty("Flag", 0, rtl.longint, "", "FFlag");',
  30007. '});',
  30008. '']),
  30009. LinesToStr([ // $mod.$main
  30010. '']));
  30011. end;
  30012. procedure TTestModule.TestRTTI_ClassForward;
  30013. begin
  30014. WithTypeInfo:=true;
  30015. StartProgram(false);
  30016. Add('type');
  30017. Add(' TObject = class end;');
  30018. Add(' tbridge = class;');
  30019. Add(' TProc = function: tbridge;');
  30020. Add(' TOger = class');
  30021. Add(' published');
  30022. Add(' FBridge: tbridge;');
  30023. Add(' procedure SetBridge(Value: tbridge); virtual; abstract;');
  30024. Add(' property Bridge: tbridge read fbridge write setbridge;');
  30025. Add(' end;');
  30026. Add(' TBridge = class');
  30027. Add(' FOger: toger;');
  30028. Add(' end;');
  30029. Add('var p: Pointer;');
  30030. Add(' b: tbridge;');
  30031. Add('begin');
  30032. Add(' p:=typeinfo(tbridge);');
  30033. Add(' p:=typeinfo(b);');
  30034. ConvertProgram;
  30035. CheckSource('TestRTTI_ClassForward',
  30036. LinesToStr([ // statements
  30037. 'rtl.createClass(this, "TObject", null, function () {',
  30038. ' this.$init = function () {',
  30039. ' };',
  30040. ' this.$final = function () {',
  30041. ' };',
  30042. '});',
  30043. 'this.$rtti.$Class("TBridge");',
  30044. 'this.$rtti.$ProcVar("TProc", {',
  30045. ' procsig: rtl.newTIProcSig([], this.$rtti["TBridge"])',
  30046. '});',
  30047. 'rtl.createClass(this, "TOger", this.TObject, function () {',
  30048. ' this.$init = function () {',
  30049. ' $mod.TObject.$init.call(this);',
  30050. ' this.FBridge = null;',
  30051. ' };',
  30052. ' this.$final = function () {',
  30053. ' this.FBridge = undefined;',
  30054. ' $mod.TObject.$final.call(this);',
  30055. ' };',
  30056. ' var $r = this.$rtti;',
  30057. ' $r.addField("FBridge", $mod.$rtti["TBridge"]);',
  30058. ' $r.addMethod("SetBridge", 0, [["Value", $mod.$rtti["TBridge"]]]);',
  30059. ' $r.addProperty("Bridge", 2, $mod.$rtti["TBridge"], "FBridge", "SetBridge");',
  30060. '});',
  30061. 'rtl.createClass(this, "TBridge", this.TObject, function () {',
  30062. ' this.$init = function () {',
  30063. ' $mod.TObject.$init.call(this);',
  30064. ' this.FOger = null;',
  30065. ' };',
  30066. ' this.$final = function () {',
  30067. ' this.FOger = undefined;',
  30068. ' $mod.TObject.$final.call(this);',
  30069. ' };',
  30070. '});',
  30071. 'this.p = null;',
  30072. 'this.b = null;',
  30073. '']),
  30074. LinesToStr([ // $mod.$main
  30075. '$mod.p = $mod.$rtti["TBridge"];',
  30076. '$mod.p = $mod.b.$rtti;',
  30077. '']));
  30078. end;
  30079. procedure TTestModule.TestRTTI_ClassOf;
  30080. begin
  30081. WithTypeInfo:=true;
  30082. StartProgram(false);
  30083. Add('type');
  30084. Add(' TClass = class of tobject;');
  30085. Add(' TProcA = function: TClass;');
  30086. Add(' TObject = class');
  30087. Add(' published');
  30088. Add(' C: tclass;');
  30089. Add(' end;');
  30090. Add(' tfox = class;');
  30091. Add(' TBird = class end;');
  30092. Add(' TBirds = class of tbird;');
  30093. Add(' TFox = class end;');
  30094. Add(' TFoxes = class of tfox;');
  30095. Add(' TCows = class of TCow;');
  30096. Add(' TCow = class;');
  30097. Add(' TCow = class end;');
  30098. Add('begin');
  30099. ConvertProgram;
  30100. CheckSource('TestRTTI_ClassOf',
  30101. LinesToStr([ // statements
  30102. 'this.$rtti.$Class("TObject");',
  30103. 'this.$rtti.$ClassRef("TClass", {',
  30104. ' instancetype: this.$rtti["TObject"]',
  30105. '});',
  30106. 'this.$rtti.$ProcVar("TProcA", {',
  30107. ' procsig: rtl.newTIProcSig([], this.$rtti["TClass"])',
  30108. '});',
  30109. 'rtl.createClass(this, "TObject", null, function () {',
  30110. ' this.$init = function () {',
  30111. ' this.C = null;',
  30112. ' };',
  30113. ' this.$final = function () {',
  30114. ' this.C = undefined;',
  30115. ' };',
  30116. ' var $r = this.$rtti;',
  30117. ' $r.addField("C", $mod.$rtti["TClass"]);',
  30118. '});',
  30119. 'this.$rtti.$Class("TFox");',
  30120. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  30121. '});',
  30122. 'this.$rtti.$ClassRef("TBirds", {',
  30123. ' instancetype: this.$rtti["TBird"]',
  30124. '});',
  30125. 'rtl.createClass(this, "TFox", this.TObject, function () {',
  30126. '});',
  30127. 'this.$rtti.$ClassRef("TFoxes", {',
  30128. ' instancetype: this.$rtti["TFox"]',
  30129. '});',
  30130. 'this.$rtti.$Class("TCow");',
  30131. 'this.$rtti.$ClassRef("TCows", {',
  30132. ' instancetype: this.$rtti["TCow"]',
  30133. '});',
  30134. 'rtl.createClass(this, "TCow", this.TObject, function () {',
  30135. '});',
  30136. '']),
  30137. LinesToStr([ // $mod.$main
  30138. '']));
  30139. end;
  30140. procedure TTestModule.TestRTTI_Record;
  30141. begin
  30142. WithTypeInfo:=true;
  30143. StartProgram(false);
  30144. Add('type');
  30145. Add(' integer = longint;');
  30146. Add(' TPoint = record');
  30147. Add(' x,y: integer;');
  30148. Add(' end;');
  30149. Add('var p: pointer;');
  30150. Add(' r: tpoint;');
  30151. Add('begin');
  30152. Add(' p:=typeinfo(tpoint);');
  30153. Add(' p:=typeinfo(r);');
  30154. Add(' p:=typeinfo(r.x);');
  30155. ConvertProgram;
  30156. CheckSource('TestRTTI_Record',
  30157. LinesToStr([ // statements
  30158. 'rtl.recNewT(this, "TPoint", function () {',
  30159. ' this.x = 0;',
  30160. ' this.y = 0;',
  30161. ' this.$eq = function (b) {',
  30162. ' return (this.x === b.x) && (this.y === b.y);',
  30163. ' };',
  30164. ' this.$assign = function (s) {',
  30165. ' this.x = s.x;',
  30166. ' this.y = s.y;',
  30167. ' return this;',
  30168. ' };',
  30169. ' var $r = $mod.$rtti.$Record("TPoint", {});',
  30170. ' $r.addField("x", rtl.longint);',
  30171. ' $r.addField("y", rtl.longint);',
  30172. '});',
  30173. 'this.p = null;',
  30174. 'this.r = this.TPoint.$new();',
  30175. '']),
  30176. LinesToStr([ // $mod.$main
  30177. '$mod.p = $mod.$rtti["TPoint"];',
  30178. '$mod.p = $mod.$rtti["TPoint"];',
  30179. '$mod.p = rtl.longint;',
  30180. '']));
  30181. end;
  30182. procedure TTestModule.TestRTTI_RecordAnonymousArray;
  30183. begin
  30184. WithTypeInfo:=true;
  30185. StartProgram(false);
  30186. Add('type');
  30187. Add(' TFloatRec = record');
  30188. Add(' c,d: array of char;');
  30189. // Add(' i: array of array of longint;');
  30190. Add(' end;');
  30191. Add('var p: pointer;');
  30192. Add(' r: tfloatrec;');
  30193. Add('begin');
  30194. Add(' p:=typeinfo(tfloatrec);');
  30195. Add(' p:=typeinfo(r);');
  30196. Add(' p:=typeinfo(r.d);');
  30197. ConvertProgram;
  30198. CheckSource('TestRTTI_Record',
  30199. LinesToStr([ // statements
  30200. 'rtl.recNewT(this, "TFloatRec", function () {',
  30201. ' this.$new = function () {',
  30202. ' var r = Object.create(this);',
  30203. ' r.c = [];',
  30204. ' r.d = [];',
  30205. ' return r;',
  30206. ' };',
  30207. ' this.$eq = function (b) {',
  30208. ' return (this.c === b.c) && (this.d === b.d);',
  30209. ' };',
  30210. ' this.$assign = function (s) {',
  30211. ' this.c = rtl.arrayRef(s.c);',
  30212. ' this.d = rtl.arrayRef(s.d);',
  30213. ' return this;',
  30214. ' };',
  30215. ' var $r = $mod.$rtti.$Record("TFloatRec", {});',
  30216. ' $mod.$rtti.$DynArray("TFloatRec.d$a", {',
  30217. ' eltype: rtl.char',
  30218. ' });',
  30219. ' $r.addField("c", $mod.$rtti["TFloatRec.d$a"]);',
  30220. ' $r.addField("d", $mod.$rtti["TFloatRec.d$a"]);',
  30221. '});',
  30222. 'this.p = null;',
  30223. 'this.r = this.TFloatRec.$new();',
  30224. '']),
  30225. LinesToStr([ // $mod.$main
  30226. '$mod.p = $mod.$rtti["TFloatRec"];',
  30227. '$mod.p = $mod.$rtti["TFloatRec"];',
  30228. '$mod.p = $mod.$rtti["TFloatRec.d$a"];',
  30229. '']));
  30230. end;
  30231. procedure TTestModule.TestRTTI_Record_ClassVarType;
  30232. begin
  30233. WithTypeInfo:=true;
  30234. StartProgram(false);
  30235. Add([
  30236. '{$modeswitch AdvancedRecords}',
  30237. 'type',
  30238. ' TPoint = record',
  30239. ' type TProc = procedure(w: word);',
  30240. ' class var p: TProc;',
  30241. ' end;',
  30242. 'begin',
  30243. '']);
  30244. ConvertProgram;
  30245. CheckSource('TestRTTI_Record_ClassVarType',
  30246. LinesToStr([ // statements
  30247. 'rtl.recNewT(this, "TPoint", function () {',
  30248. ' $mod.$rtti.$ProcVar("TPoint.TProc", {',
  30249. ' procsig: rtl.newTIProcSig([["w", rtl.word]])',
  30250. ' });',
  30251. ' this.p = null;',
  30252. ' this.$eq = function (b) {',
  30253. ' return true;',
  30254. ' };',
  30255. ' this.$assign = function (s) {',
  30256. ' return this;',
  30257. ' };',
  30258. ' var $r = $mod.$rtti.$Record("TPoint", {});',
  30259. ' $r.addField("p", $mod.$rtti["TPoint.TProc"]);',
  30260. '}, true);',
  30261. '']),
  30262. LinesToStr([ // $mod.$main
  30263. '']));
  30264. end;
  30265. procedure TTestModule.TestRTTI_LocalTypes;
  30266. begin
  30267. WithTypeInfo:=true;
  30268. StartProgram(false);
  30269. Add([
  30270. 'procedure DoIt;',
  30271. 'type',
  30272. ' integer = longint;',
  30273. ' TPoint = record',
  30274. ' x,y: integer;',
  30275. ' end;',
  30276. 'var p: TPoint;',
  30277. 'begin',
  30278. 'end;',
  30279. 'begin']);
  30280. ConvertProgram;
  30281. CheckSource('TestRTTI_LocalTypes',
  30282. LinesToStr([ // statements
  30283. 'var TPoint = rtl.recNewT(null, "", function () {',
  30284. ' this.x = 0;',
  30285. ' this.y = 0;',
  30286. ' this.$eq = function (b) {',
  30287. ' return (this.x === b.x) && (this.y === b.y);',
  30288. ' };',
  30289. ' this.$assign = function (s) {',
  30290. ' this.x = s.x;',
  30291. ' this.y = s.y;',
  30292. ' return this;',
  30293. ' };',
  30294. '});',
  30295. 'this.DoIt = function () {',
  30296. ' var p = TPoint.$new();',
  30297. '};',
  30298. '']),
  30299. LinesToStr([ // $mod.$main
  30300. '']));
  30301. end;
  30302. procedure TTestModule.TestRTTI_TypeInfo_BaseTypes;
  30303. begin
  30304. WithTypeInfo:=true;
  30305. StartProgram(false);
  30306. Add([
  30307. 'type',
  30308. ' TCaption = string;',
  30309. ' TYesNo = boolean;',
  30310. ' TLetter = char;',
  30311. ' TFloat = double;',
  30312. ' TPtr = pointer;',
  30313. ' TShortInt = shortint;',
  30314. ' TByte = byte;',
  30315. ' TSmallInt = smallint;',
  30316. ' TWord = word;',
  30317. ' TInt32 = longint;',
  30318. ' TDWord = longword;',
  30319. ' TValue = jsvalue;',
  30320. 'var p: TPtr;',
  30321. 'begin',
  30322. ' p:=typeinfo(string);',
  30323. ' p:=typeinfo(tcaption);',
  30324. ' p:=typeinfo(boolean);',
  30325. ' p:=typeinfo(tyesno);',
  30326. ' p:=typeinfo(char);',
  30327. ' p:=typeinfo(tletter);',
  30328. ' p:=typeinfo(double);',
  30329. ' p:=typeinfo(tfloat);',
  30330. ' p:=typeinfo(pointer);',
  30331. ' p:=typeinfo(tptr);',
  30332. ' p:=typeinfo(shortint);',
  30333. ' p:=typeinfo(tshortint);',
  30334. ' p:=typeinfo(byte);',
  30335. ' p:=typeinfo(tbyte);',
  30336. ' p:=typeinfo(smallint);',
  30337. ' p:=typeinfo(tsmallint);',
  30338. ' p:=typeinfo(word);',
  30339. ' p:=typeinfo(tword);',
  30340. ' p:=typeinfo(longword);',
  30341. ' p:=typeinfo(tdword);',
  30342. ' p:=typeinfo(jsvalue);',
  30343. ' p:=typeinfo(tvalue);',
  30344. '']);
  30345. ConvertProgram;
  30346. CheckSource('TestRTTI_TypeInfo_BaseTypes',
  30347. LinesToStr([ // statements
  30348. 'this.p = null;',
  30349. '']),
  30350. LinesToStr([ // $mod.$main
  30351. '$mod.p = rtl.string;',
  30352. '$mod.p = rtl.string;',
  30353. '$mod.p = rtl.boolean;',
  30354. '$mod.p = rtl.boolean;',
  30355. '$mod.p = rtl.char;',
  30356. '$mod.p = rtl.char;',
  30357. '$mod.p = rtl.double;',
  30358. '$mod.p = rtl.double;',
  30359. '$mod.p = rtl.pointer;',
  30360. '$mod.p = rtl.pointer;',
  30361. '$mod.p = rtl.shortint;',
  30362. '$mod.p = rtl.shortint;',
  30363. '$mod.p = rtl.byte;',
  30364. '$mod.p = rtl.byte;',
  30365. '$mod.p = rtl.smallint;',
  30366. '$mod.p = rtl.smallint;',
  30367. '$mod.p = rtl.word;',
  30368. '$mod.p = rtl.word;',
  30369. '$mod.p = rtl.longword;',
  30370. '$mod.p = rtl.longword;',
  30371. '$mod.p = rtl.jsvalue;',
  30372. '$mod.p = rtl.jsvalue;',
  30373. '']));
  30374. end;
  30375. procedure TTestModule.TestRTTI_TypeInfo_Type_BaseTypes;
  30376. begin
  30377. WithTypeInfo:=true;
  30378. StartProgram(false);
  30379. Add([
  30380. 'type',
  30381. ' TCaption = type string;',
  30382. ' TYesNo = type boolean;',
  30383. ' TLetter = type char;',
  30384. ' TFloat = type double;',
  30385. ' TPtr = type pointer;',
  30386. ' TShortInt = type shortint;',
  30387. ' TByte = type byte;',
  30388. ' TSmallInt = type smallint;',
  30389. ' TWord = type word;',
  30390. ' TInt32 = type longint;',
  30391. ' TDWord = type longword;',
  30392. ' TValue = type jsvalue;',
  30393. ' TAliasValue = type TValue;',
  30394. 'var',
  30395. ' p: TPtr;',
  30396. ' a: TAliasValue;',
  30397. 'begin',
  30398. ' p:=typeinfo(tcaption);',
  30399. ' p:=typeinfo(tyesno);',
  30400. ' p:=typeinfo(tletter);',
  30401. ' p:=typeinfo(tfloat);',
  30402. ' p:=typeinfo(tptr);',
  30403. ' p:=typeinfo(tshortint);',
  30404. ' p:=typeinfo(tbyte);',
  30405. ' p:=typeinfo(tsmallint);',
  30406. ' p:=typeinfo(tword);',
  30407. ' p:=typeinfo(tdword);',
  30408. ' p:=typeinfo(tvalue);',
  30409. ' p:=typeinfo(taliasvalue);',
  30410. ' p:=typeinfo(a);',
  30411. '']);
  30412. ConvertProgram;
  30413. CheckSource('TestRTTI_TypeInfo_Type_BaseTypes',
  30414. LinesToStr([ // statements
  30415. 'this.$rtti.$inherited("TCaption", rtl.string, {});',
  30416. 'this.$rtti.$inherited("TYesNo", rtl.boolean, {});',
  30417. 'this.$rtti.$inherited("TLetter", rtl.char, {});',
  30418. 'this.$rtti.$inherited("TFloat", rtl.double, {});',
  30419. 'this.$rtti.$inherited("TPtr", rtl.pointer, {});',
  30420. 'this.$rtti.$inherited("TShortInt", rtl.shortint, {});',
  30421. 'this.$rtti.$inherited("TByte", rtl.byte, {});',
  30422. 'this.$rtti.$inherited("TSmallInt", rtl.smallint, {});',
  30423. 'this.$rtti.$inherited("TWord", rtl.word, {});',
  30424. 'this.$rtti.$inherited("TInt32", rtl.longint, {});',
  30425. 'this.$rtti.$inherited("TDWord", rtl.longword, {});',
  30426. 'this.$rtti.$inherited("TValue", rtl.jsvalue, {});',
  30427. 'this.$rtti.$inherited("TAliasValue", this.$rtti["TValue"], {});',
  30428. 'this.p = null;',
  30429. 'this.a = undefined;',
  30430. '']),
  30431. LinesToStr([ // $mod.$main
  30432. '$mod.p = $mod.$rtti["TCaption"];',
  30433. '$mod.p = $mod.$rtti["TYesNo"];',
  30434. '$mod.p = $mod.$rtti["TLetter"];',
  30435. '$mod.p = $mod.$rtti["TFloat"];',
  30436. '$mod.p = $mod.$rtti["TPtr"];',
  30437. '$mod.p = $mod.$rtti["TShortInt"];',
  30438. '$mod.p = $mod.$rtti["TByte"];',
  30439. '$mod.p = $mod.$rtti["TSmallInt"];',
  30440. '$mod.p = $mod.$rtti["TWord"];',
  30441. '$mod.p = $mod.$rtti["TDWord"];',
  30442. '$mod.p = $mod.$rtti["TValue"];',
  30443. '$mod.p = $mod.$rtti["TAliasValue"];',
  30444. '$mod.p = $mod.$rtti["TAliasValue"];',
  30445. '']));
  30446. end;
  30447. procedure TTestModule.TestRTTI_TypeInfo_LocalFail;
  30448. begin
  30449. WithTypeInfo:=true;
  30450. StartProgram(false);
  30451. Add('procedure DoIt;');
  30452. Add('type');
  30453. Add(' integer = longint;');
  30454. Add(' TPoint = record');
  30455. Add(' x,y: integer;');
  30456. Add(' end;');
  30457. Add('var p: pointer;');
  30458. Add('begin');
  30459. Add(' p:=typeinfo(tpoint);');
  30460. Add('end;');
  30461. Add('begin');
  30462. SetExpectedPasResolverError(sSymbolCannotBePublished,nSymbolCannotBePublished);
  30463. ConvertProgram;
  30464. end;
  30465. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses1;
  30466. begin
  30467. WithTypeInfo:=true;
  30468. StartProgram(true,[supTypeInfo]);
  30469. Add([
  30470. '{$modeswitch externalclass}',
  30471. 'type',
  30472. ' TFlag = (up,down);',
  30473. ' TFlags = set of TFlag;',
  30474. 'var',
  30475. ' ti: TTypeInfo;',
  30476. ' tiInt: TTypeInfoInteger;',
  30477. ' tiEnum: TTypeInfoEnum;',
  30478. ' tiSet: TTypeInfoSet;',
  30479. 'begin',
  30480. ' ti:=typeinfo(string);',
  30481. ' ti:=typeinfo(boolean);',
  30482. ' ti:=typeinfo(char);',
  30483. ' ti:=typeinfo(double);',
  30484. ' tiInt:=typeinfo(shortint);',
  30485. ' tiInt:=typeinfo(byte);',
  30486. ' tiInt:=typeinfo(smallint);',
  30487. ' tiInt:=typeinfo(word);',
  30488. ' tiInt:=typeinfo(longint);',
  30489. ' tiInt:=typeinfo(longword);',
  30490. ' ti:=typeinfo(jsvalue);',
  30491. ' tiEnum:=typeinfo(tflag);',
  30492. ' tiSet:=typeinfo(tflags);']);
  30493. ConvertProgram;
  30494. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses1',
  30495. LinesToStr([ // statements
  30496. 'this.TFlag = {',
  30497. ' "0": "up",',
  30498. ' up: 0,',
  30499. ' "1": "down",',
  30500. ' down: 1',
  30501. '};',
  30502. 'this.$rtti.$Enum("TFlag", {',
  30503. ' minvalue: 0,',
  30504. ' maxvalue: 1,',
  30505. ' ordtype: 1,',
  30506. ' enumtype: this.TFlag',
  30507. '});',
  30508. 'this.$rtti.$Set("TFlags", {',
  30509. ' comptype: this.$rtti["TFlag"]',
  30510. '});',
  30511. 'this.ti = null;',
  30512. 'this.tiInt = null;',
  30513. 'this.tiEnum = null;',
  30514. 'this.tiSet = null;',
  30515. '']),
  30516. LinesToStr([ // $mod.$main
  30517. '$mod.ti = rtl.string;',
  30518. '$mod.ti = rtl.boolean;',
  30519. '$mod.ti = rtl.char;',
  30520. '$mod.ti = rtl.double;',
  30521. '$mod.tiInt = rtl.shortint;',
  30522. '$mod.tiInt = rtl.byte;',
  30523. '$mod.tiInt = rtl.smallint;',
  30524. '$mod.tiInt = rtl.word;',
  30525. '$mod.tiInt = rtl.longint;',
  30526. '$mod.tiInt = rtl.longword;',
  30527. '$mod.ti = rtl.jsvalue;',
  30528. '$mod.tiEnum = $mod.$rtti["TFlag"];',
  30529. '$mod.tiSet = $mod.$rtti["TFlags"];',
  30530. '']));
  30531. end;
  30532. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses2;
  30533. begin
  30534. WithTypeInfo:=true;
  30535. StartProgram(true,[supTypeInfo]);
  30536. Add('{$modeswitch externalclass}');
  30537. Add('type');
  30538. Add(' TStaticArr = array[boolean] of string;');
  30539. Add(' TDynArr = array of string;');
  30540. Add(' TProc = procedure;');
  30541. Add(' TMethod = procedure of object;');
  30542. Add('var');
  30543. Add(' StaticArray: TStaticArr;');
  30544. Add(' tiStaticArray: TTypeInfoStaticArray;');
  30545. Add(' DynArray: TDynArr;');
  30546. Add(' tiDynArray: TTypeInfoDynArray;');
  30547. Add(' ProcVar: TProc;');
  30548. Add(' tiProcVar: TTypeInfoProcVar;');
  30549. Add(' MethodVar: TMethod;');
  30550. Add(' tiMethodVar: TTypeInfoMethodVar;');
  30551. Add('begin');
  30552. Add(' tiStaticArray:=typeinfo(StaticArray);');
  30553. Add(' tiStaticArray:=typeinfo(TStaticArr);');
  30554. Add(' tiDynArray:=typeinfo(DynArray);');
  30555. Add(' tiDynArray:=typeinfo(TDynArr);');
  30556. Add(' tiProcVar:=typeinfo(ProcVar);');
  30557. Add(' tiProcVar:=typeinfo(TProc);');
  30558. Add(' tiMethodVar:=typeinfo(MethodVar);');
  30559. Add(' tiMethodVar:=typeinfo(TMethod);');
  30560. ConvertProgram;
  30561. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses2',
  30562. LinesToStr([ // statements
  30563. 'this.$rtti.$StaticArray("TStaticArr", {',
  30564. ' dims: [2],',
  30565. ' eltype: rtl.string',
  30566. '});',
  30567. 'this.$rtti.$DynArray("TDynArr", {',
  30568. ' eltype: rtl.string',
  30569. '});',
  30570. 'this.$rtti.$ProcVar("TProc", {',
  30571. ' procsig: rtl.newTIProcSig([])',
  30572. '});',
  30573. 'this.$rtti.$MethodVar("TMethod", {',
  30574. ' procsig: rtl.newTIProcSig([]),',
  30575. ' methodkind: 0',
  30576. '});',
  30577. 'this.StaticArray = rtl.arraySetLength(null,"",2);',
  30578. 'this.tiStaticArray = null;',
  30579. 'this.DynArray = [];',
  30580. 'this.tiDynArray = null;',
  30581. 'this.ProcVar = null;',
  30582. 'this.tiProcVar = null;',
  30583. 'this.MethodVar = null;',
  30584. 'this.tiMethodVar = null;',
  30585. '']),
  30586. LinesToStr([ // $mod.$main
  30587. '$mod.tiStaticArray = $mod.$rtti["TStaticArr"];',
  30588. '$mod.tiStaticArray = $mod.$rtti["TStaticArr"];',
  30589. '$mod.tiDynArray = $mod.$rtti["TDynArr"];',
  30590. '$mod.tiDynArray = $mod.$rtti["TDynArr"];',
  30591. '$mod.tiProcVar = $mod.$rtti["TProc"];',
  30592. '$mod.tiProcVar = $mod.$rtti["TProc"];',
  30593. '$mod.tiMethodVar = $mod.$rtti["TMethod"];',
  30594. '$mod.tiMethodVar = $mod.$rtti["TMethod"];',
  30595. '']));
  30596. end;
  30597. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses3;
  30598. begin
  30599. WithTypeInfo:=true;
  30600. StartProgram(true,[supTypeInfo]);
  30601. Add('{$modeswitch externalclass}');
  30602. Add('type');
  30603. Add(' TRec = record end;');
  30604. // ToDo: ^TRec
  30605. Add(' TObject = class end;');
  30606. Add(' TClass = class of tobject;');
  30607. Add('var');
  30608. Add(' Rec: trec;');
  30609. Add(' tiRecord: ttypeinforecord;');
  30610. Add(' Obj: tobject;');
  30611. Add(' tiClass: ttypeinfoclass;');
  30612. Add(' aClass: tclass;');
  30613. Add(' tiClassRef: ttypeinfoclassref;');
  30614. // ToDo: ^TRec
  30615. Add(' tiPointer: ttypeinfopointer;');
  30616. Add('begin');
  30617. Add(' tirecord:=typeinfo(trec);');
  30618. Add(' tirecord:=typeinfo(trec);');
  30619. Add(' ticlass:=typeinfo(obj);');
  30620. Add(' ticlass:=typeinfo(tobject);');
  30621. Add(' ticlass:=typeinfo(aclass);');
  30622. Add(' ticlassref:=typeinfo(tclass);');
  30623. ConvertProgram;
  30624. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses3',
  30625. LinesToStr([ // statements
  30626. 'rtl.recNewT(this, "TRec", function () {',
  30627. ' this.$eq = function (b) {',
  30628. ' return true;',
  30629. ' };',
  30630. ' this.$assign = function (s) {',
  30631. ' return this;',
  30632. ' };',
  30633. ' $mod.$rtti.$Record("TRec", {});',
  30634. '});',
  30635. 'rtl.createClass(this, "TObject", null, function () {',
  30636. ' this.$init = function () {',
  30637. ' };',
  30638. ' this.$final = function () {',
  30639. ' };',
  30640. '});',
  30641. 'this.$rtti.$ClassRef("TClass", {',
  30642. ' instancetype: this.$rtti["TObject"]',
  30643. '});',
  30644. 'this.Rec = this.TRec.$new();',
  30645. 'this.tiRecord = null;',
  30646. 'this.Obj = null;',
  30647. 'this.tiClass = null;',
  30648. 'this.aClass = null;',
  30649. 'this.tiClassRef = null;',
  30650. 'this.tiPointer = null;',
  30651. '']),
  30652. LinesToStr([ // $mod.$main
  30653. '$mod.tiRecord = $mod.$rtti["TRec"];',
  30654. '$mod.tiRecord = $mod.$rtti["TRec"];',
  30655. '$mod.tiClass = $mod.Obj.$rtti;',
  30656. '$mod.tiClass = $mod.$rtti["TObject"];',
  30657. '$mod.tiClass = $mod.aClass.$rtti;',
  30658. '$mod.tiClassRef = $mod.$rtti["TClass"];',
  30659. '']));
  30660. end;
  30661. procedure TTestModule.TestRTTI_TypeInfo_FunctionClassType;
  30662. begin
  30663. WithTypeInfo:=true;
  30664. StartProgram(true,[supTypeInfo]);
  30665. Add([
  30666. '{$modeswitch externalclass}',
  30667. 'type',
  30668. ' TClass = class of tobject;',
  30669. ' TObject = class',
  30670. ' function MyClass: TClass;',
  30671. ' class function ClassType: TClass;',
  30672. ' end;',
  30673. 'function TObject.MyClass: TClass;',
  30674. 'var t: TTypeInfoClass;',
  30675. 'begin',
  30676. ' t:=TypeInfo(Self);',
  30677. ' t:=TypeInfo(Result);',
  30678. ' t:=TypeInfo(TObject);',
  30679. 'end;',
  30680. 'class function TObject.ClassType: TClass;',
  30681. 'var t: TTypeInfoClass;',
  30682. 'begin',
  30683. ' t:=TypeInfo(Self);',
  30684. ' t:=TypeInfo(Result);',
  30685. 'end;',
  30686. 'var',
  30687. ' Obj: TObject;',
  30688. ' t: TTypeInfoClass;',
  30689. 'begin',
  30690. ' t:=TypeInfo(TObject.ClassType);',
  30691. ' t:=TypeInfo(Obj.ClassType);',
  30692. ' t:=TypeInfo(Obj.MyClass);',
  30693. '']);
  30694. ConvertProgram;
  30695. CheckSource('TestRTTI_TypeInfo_FunctionClassType',
  30696. LinesToStr([ // statements
  30697. 'this.$rtti.$Class("TObject");',
  30698. 'this.$rtti.$ClassRef("TClass", {',
  30699. ' instancetype: this.$rtti["TObject"]',
  30700. '});',
  30701. 'rtl.createClass(this, "TObject", null, function () {',
  30702. ' this.$init = function () {',
  30703. ' };',
  30704. ' this.$final = function () {',
  30705. ' };',
  30706. ' this.MyClass = function () {',
  30707. ' var Result = null;',
  30708. ' var t = null;',
  30709. ' t = this.$rtti;',
  30710. ' t = Result.$rtti;',
  30711. ' t = $mod.$rtti["TObject"];',
  30712. ' return Result;',
  30713. ' };',
  30714. ' this.ClassType = function () {',
  30715. ' var Result = null;',
  30716. ' var t = null;',
  30717. ' t = this.$rtti;',
  30718. ' t = Result.$rtti;',
  30719. ' return Result;',
  30720. ' };',
  30721. '});',
  30722. 'this.Obj = null;',
  30723. 'this.t = null;',
  30724. '']),
  30725. LinesToStr([ // $mod.$main
  30726. '$mod.t = $mod.TObject.ClassType().$rtti;',
  30727. '$mod.t = $mod.Obj.$class.ClassType().$rtti;',
  30728. '$mod.t = $mod.Obj.MyClass().$rtti;',
  30729. '']));
  30730. end;
  30731. procedure TTestModule.TestRTTI_TypeInfo_MixedUnits_PointerAndClass;
  30732. begin
  30733. WithTypeInfo:=true;
  30734. AddModuleWithIntfImplSrc('typinfo.pas',
  30735. LinesToStr([
  30736. '{$modeswitch externalclass}',
  30737. 'type',
  30738. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  30739. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo) end;',
  30740. '']),
  30741. '');
  30742. AddModuleWithIntfImplSrc('unit2.pas',
  30743. LinesToStr([
  30744. 'uses typinfo;',
  30745. 'type PTypeInfo = TTypeInfo;', // delphi compatibility code
  30746. 'procedure DoPtr(p: PTypeInfo);',
  30747. 'procedure DoInfo(t: TTypeInfo);',
  30748. 'procedure DoInt(t: TTypeInfoInteger);',
  30749. '']),
  30750. LinesToStr([
  30751. 'procedure DoPtr(p: PTypeInfo);',
  30752. 'begin end;',
  30753. 'procedure DoInfo(t: TTypeInfo);',
  30754. 'begin end;',
  30755. 'procedure DoInt(t: TTypeInfoInteger);',
  30756. 'begin end;',
  30757. '']));
  30758. StartUnit(true);
  30759. Add([
  30760. 'interface',
  30761. 'uses unit2;', // does not use unit typinfo
  30762. 'implementation',
  30763. 'var',
  30764. ' i: byte;',
  30765. ' p: pointer;',
  30766. ' t: PTypeInfo;',
  30767. 'initialization',
  30768. ' p:=typeinfo(i);',
  30769. ' t:=typeinfo(i);',
  30770. ' if p=t then ;',
  30771. ' if p=typeinfo(i) then ;',
  30772. ' if typeinfo(i)=p then ;',
  30773. ' if t=typeinfo(i) then ;',
  30774. ' if typeinfo(i)=t then ;',
  30775. ' DoPtr(p);',
  30776. ' DoPtr(t);',
  30777. ' DoPtr(typeinfo(i));',
  30778. ' DoInfo(p);',
  30779. ' DoInfo(t);',
  30780. ' DoInfo(typeinfo(i));',
  30781. ' DoInt(typeinfo(i));',
  30782. '']);
  30783. ConvertUnit;
  30784. CheckSource('TestRTTI_TypeInfo_MixedUnits_PointerAndClass',
  30785. LinesToStr([ // statements
  30786. 'var $impl = $mod.$impl;',
  30787. '']),
  30788. LinesToStr([ // this.$init
  30789. '$impl.p = rtl.byte;',
  30790. '$impl.t = rtl.byte;',
  30791. 'if ($impl.p === $impl.t) ;',
  30792. 'if ($impl.p === rtl.byte) ;',
  30793. 'if (rtl.byte === $impl.p) ;',
  30794. 'if ($impl.t === rtl.byte) ;',
  30795. 'if (rtl.byte === $impl.t) ;',
  30796. 'pas.unit2.DoPtr($impl.p);',
  30797. 'pas.unit2.DoPtr($impl.t);',
  30798. 'pas.unit2.DoPtr(rtl.byte);',
  30799. 'pas.unit2.DoInfo($impl.p);',
  30800. 'pas.unit2.DoInfo($impl.t);',
  30801. 'pas.unit2.DoInfo(rtl.byte);',
  30802. 'pas.unit2.DoInt(rtl.byte);',
  30803. '']),
  30804. LinesToStr([ // implementation
  30805. '$impl.i = 0;',
  30806. '$impl.p = null;',
  30807. '$impl.t = null;',
  30808. '']) );
  30809. end;
  30810. procedure TTestModule.TestRTTI_Interface_Corba;
  30811. begin
  30812. WithTypeInfo:=true;
  30813. StartProgram(true,[supTypeInfo]);
  30814. Add([
  30815. '{$interfaces corba}',
  30816. '{$modeswitch externalclass}',
  30817. 'type',
  30818. ' IUnknown = interface',
  30819. ' end;',
  30820. ' IBird = interface',
  30821. ' function GetItem: longint;',
  30822. ' procedure SetItem(Value: longint);',
  30823. ' property Item: longint read GetItem write SetItem;',
  30824. ' end;',
  30825. 'procedure DoIt(t: TTypeInfoInterface); begin end;',
  30826. 'var',
  30827. ' i: IBird;',
  30828. ' t: TTypeInfoInterface;',
  30829. 'begin',
  30830. ' t:=TypeInfo(IBird);',
  30831. ' t:=TypeInfo(i);',
  30832. ' DoIt(t);',
  30833. ' DoIt(TypeInfo(IBird));',
  30834. '']);
  30835. ConvertProgram;
  30836. CheckSource('TestRTTI_Interface_Corba',
  30837. LinesToStr([ // statements
  30838. 'rtl.createInterface(',
  30839. ' this,',
  30840. ' "IUnknown",',
  30841. ' "{B92D5841-758A-322B-B800-000000000000}",',
  30842. ' [],',
  30843. ' null,',
  30844. ' function () {',
  30845. ' }',
  30846. ');',
  30847. 'rtl.createInterface(',
  30848. ' this,',
  30849. ' "IBird",',
  30850. ' "{D32D5841-6264-3AE3-A2C9-B91CE922C9B9}",',
  30851. ' ["GetItem", "SetItem"],',
  30852. ' null,',
  30853. ' function () {',
  30854. ' var $r = this.$rtti;',
  30855. ' $r.addMethod("GetItem", 1, [], rtl.longint);',
  30856. ' $r.addMethod("SetItem", 0, [["Value", rtl.longint]]);',
  30857. ' $r.addProperty("Item", 3, rtl.longint, "GetItem", "SetItem");',
  30858. ' }',
  30859. ');',
  30860. 'this.DoIt = function (t) {',
  30861. '}; ',
  30862. 'this.i = null;',
  30863. 'this.t = null;',
  30864. '']),
  30865. LinesToStr([ // $mod.$main
  30866. '$mod.t = $mod.$rtti["IBird"];',
  30867. '$mod.t = $mod.i.$rtti;',
  30868. '$mod.DoIt($mod.t);',
  30869. '$mod.DoIt($mod.$rtti["IBird"]);',
  30870. '']));
  30871. end;
  30872. procedure TTestModule.TestRTTI_Interface_COM;
  30873. begin
  30874. WithTypeInfo:=true;
  30875. StartProgram(true,[supTypeInfo]);
  30876. Add([
  30877. '{$interfaces com}',
  30878. '{$modeswitch externalclass}',
  30879. 'type',
  30880. ' TGuid = record end;',
  30881. ' integer = longint;',
  30882. ' IUnknown = interface',
  30883. ' function QueryInterface(const iid: TGuid; out obj): Integer;',
  30884. ' function _AddRef: Integer;',
  30885. ' function _Release: Integer;',
  30886. ' end;',
  30887. ' IBird = interface',
  30888. ' function GetItem: longint;',
  30889. ' procedure SetItem(Value: longint);',
  30890. ' property Item: longint read GetItem write SetItem;',
  30891. ' end;',
  30892. 'var',
  30893. ' i: IBird;',
  30894. ' t: TTypeInfoInterface;',
  30895. 'begin',
  30896. ' t:=TypeInfo(IBird);',
  30897. ' t:=TypeInfo(i);',
  30898. '']);
  30899. ConvertProgram;
  30900. CheckSource('TestRTTI_Interface_COM',
  30901. LinesToStr([ // statements
  30902. 'rtl.recNewT(this, "TGuid", function () {',
  30903. ' this.$eq = function (b) {',
  30904. ' return true;',
  30905. ' };',
  30906. ' this.$assign = function (s) {',
  30907. ' return this;',
  30908. ' };',
  30909. ' $mod.$rtti.$Record("TGuid", {});',
  30910. '});',
  30911. 'rtl.createInterface(',
  30912. ' this,',
  30913. ' "IUnknown",',
  30914. ' "{D7ADB00D-1A9B-3EDC-B123-730E661DDFA9}",',
  30915. ' ["QueryInterface", "_AddRef", "_Release"],',
  30916. ' null,',
  30917. ' function () {',
  30918. ' this.$kind = "com";',
  30919. ' var $r = this.$rtti;',
  30920. ' $r.addMethod("QueryInterface", 1, [["iid", $mod.$rtti["TGuid"], 2], ["obj", null, 4]], rtl.longint);',
  30921. ' $r.addMethod("_AddRef", 1, [], rtl.longint);',
  30922. ' $r.addMethod("_Release", 1, [], rtl.longint);',
  30923. ' }',
  30924. ');',
  30925. 'rtl.createInterface(',
  30926. ' this,',
  30927. ' "IBird",',
  30928. ' "{9CC77572-0E45-3594-9A88-9E8D865C9E0A}",',
  30929. ' ["GetItem", "SetItem"],',
  30930. ' this.IUnknown,',
  30931. ' function () {',
  30932. ' var $r = this.$rtti;',
  30933. ' $r.addMethod("GetItem", 1, [], rtl.longint);',
  30934. ' $r.addMethod("SetItem", 0, [["Value", rtl.longint]]);',
  30935. ' $r.addProperty("Item", 3, rtl.longint, "GetItem", "SetItem");',
  30936. ' }',
  30937. ');',
  30938. 'this.i = null;',
  30939. 'this.t = null;',
  30940. '']),
  30941. LinesToStr([ // $mod.$main
  30942. '$mod.t = $mod.$rtti["IBird"];',
  30943. '$mod.t = $mod.i.$rtti;',
  30944. '']));
  30945. end;
  30946. procedure TTestModule.TestRTTI_ClassHelper;
  30947. begin
  30948. WithTypeInfo:=true;
  30949. StartProgram(true,[supTypeInfo]);
  30950. Add([
  30951. '{$interfaces com}',
  30952. '{$modeswitch externalclass}',
  30953. 'type',
  30954. ' TObject = class',
  30955. ' end;',
  30956. ' THelper = class helper for TObject',
  30957. ' published',
  30958. ' function GetItem: longint;',
  30959. ' property Item: longint read GetItem;',
  30960. ' end;',
  30961. 'function THelper.GetItem: longint;',
  30962. 'begin',
  30963. 'end;',
  30964. 'var',
  30965. ' t: TTypeInfoHelper;',
  30966. 'begin',
  30967. ' t:=TypeInfo(THelper);',
  30968. '']);
  30969. ConvertProgram;
  30970. CheckSource('TestRTTI_ClassHelper',
  30971. LinesToStr([ // statements
  30972. 'rtl.createClass(this, "TObject", null, function () {',
  30973. ' this.$init = function () {',
  30974. ' };',
  30975. ' this.$final = function () {',
  30976. ' };',
  30977. '});',
  30978. 'rtl.createHelper(this, "THelper", null, function () {',
  30979. ' this.GetItem = function () {',
  30980. ' var Result = 0;',
  30981. ' return Result;',
  30982. ' };',
  30983. ' var $r = this.$rtti;',
  30984. ' $r.addMethod("GetItem", 1, [], rtl.longint);',
  30985. ' $r.addProperty("Item", 1, rtl.longint, "GetItem", "");',
  30986. '});',
  30987. 'this.t = null;',
  30988. '']),
  30989. LinesToStr([ // $mod.$main
  30990. '$mod.t = $mod.$rtti["THelper"];',
  30991. '']));
  30992. end;
  30993. procedure TTestModule.TestRTTI_ExternalClass;
  30994. begin
  30995. WithTypeInfo:=true;
  30996. StartProgram(true,[supTypeInfo]);
  30997. Add([
  30998. '{$modeswitch externalclass}',
  30999. 'type',
  31000. ' TJSObject = class external name ''Object''',
  31001. ' end;',
  31002. ' TJSArray = class external name ''Array'' (TJSObject)',
  31003. ' end;',
  31004. 'var',
  31005. ' p: Pointer;',
  31006. ' tc: TTypeInfoExtClass;',
  31007. 'begin',
  31008. ' p:=typeinfo(TJSArray);']);
  31009. ConvertProgram;
  31010. CheckSource('TestRTTI_ExternalClass',
  31011. LinesToStr([ // statements
  31012. 'this.$rtti.$ExtClass("TJSObject", {',
  31013. ' jsclass: "Object"',
  31014. '});',
  31015. 'this.$rtti.$ExtClass("TJSArray", {',
  31016. ' ancestor: this.$rtti["TJSObject"],',
  31017. ' jsclass: "Array"',
  31018. '});',
  31019. 'this.p = null;',
  31020. 'this.tc = null;',
  31021. '']),
  31022. LinesToStr([ // $mod.$main
  31023. '$mod.p = $mod.$rtti["TJSArray"];',
  31024. '']));
  31025. end;
  31026. procedure TTestModule.TestRTTI_Unit;
  31027. begin
  31028. WithTypeInfo:=true;
  31029. AddModuleWithIntfImplSrc('unit2.pas',
  31030. LinesToStr([
  31031. '{$mode delphi}',
  31032. 'type',
  31033. ' TWordArray = array of word;',
  31034. ' TArray<T> = array of T;',
  31035. '']),
  31036. '');
  31037. StartUnit(true,[supTypeInfo,supTInterfacedObject]);
  31038. Add([
  31039. '{$mode delphi}',
  31040. 'interface',
  31041. 'uses unit2;',
  31042. 'type',
  31043. ' IBird = interface',
  31044. ' function Swoop: TWordArray;',
  31045. ' function Glide: TArray<word>;',
  31046. ' end;',
  31047. 'procedure Fly;',
  31048. 'implementation',
  31049. 'procedure Fly;',
  31050. 'var',
  31051. ' ta: tTypeInfoDynArray;',
  31052. ' ti: tTypeInfoInterface;',
  31053. 'begin',
  31054. ' ta:=typeinfo(TWordArray);',
  31055. ' ta:=typeinfo(TArray<word>);',
  31056. ' ti:=typeinfo(IBird);',
  31057. 'end;',
  31058. '']);
  31059. ConvertUnit;
  31060. CheckSource('TestRTTI_ExternalClass',
  31061. LinesToStr([ // statements
  31062. 'rtl.createInterface(',
  31063. ' this,',
  31064. ' "IBird",',
  31065. ' "{3B98AAAC-6116-3E17-AA85-F16786D85B09}",',
  31066. ' ["Swoop", "Glide"],',
  31067. ' pas.system.IUnknown,',
  31068. ' function () {',
  31069. ' var $r = this.$rtti;',
  31070. ' $r.addMethod("Swoop", 1, [], pas.unit2.$rtti["TWordArray"]);',
  31071. ' $r.addMethod("Glide", 1, [], pas.unit2.$rtti["TArray<System.Word>"]);',
  31072. ' }',
  31073. ');',
  31074. 'this.Fly = function () {',
  31075. ' var ta = null;',
  31076. ' var ti = null;',
  31077. ' ta = pas.unit2.$rtti["TWordArray"];',
  31078. ' ta = pas.unit2.$rtti["TArray<System.Word>"];',
  31079. ' ti = $mod.$rtti["IBird"];',
  31080. '};',
  31081. '']),
  31082. LinesToStr([ // $mod.$main
  31083. '']));
  31084. end;
  31085. procedure TTestModule.TestResourcestringProgram;
  31086. begin
  31087. AddModuleWithIntfImplSrc('unit2.pas',
  31088. LinesToStr([
  31089. 'resourcestring Title = ''Nice'';',
  31090. '']),
  31091. '');
  31092. StartProgram(true);
  31093. Add([
  31094. 'uses unit2;',
  31095. 'const Bar = ''bar'';',
  31096. 'resourcestring',
  31097. ' Red = ''red'';',
  31098. ' Foobar = ''fOo''+bar;',
  31099. 'var s: string;',
  31100. ' c: char;',
  31101. 'begin',
  31102. ' s:=red;',
  31103. ' s:=test1.red;',
  31104. ' s:=Title;',
  31105. ' c:=red[1];',
  31106. ' c:=test1.red[2];',
  31107. ' if red=foobar then ;',
  31108. ' if red[3]=red[4] then ;']);
  31109. ConvertProgram;
  31110. CheckSource('TestResourcestringProgram',
  31111. LinesToStr([ // statements
  31112. 'this.Bar = "bar";',
  31113. 'this.s = "";',
  31114. 'this.c = "";',
  31115. '$mod.$resourcestrings = {',
  31116. ' Red: {',
  31117. ' org: "red"',
  31118. ' },',
  31119. ' Foobar: {',
  31120. ' org: "fOobar"',
  31121. ' }',
  31122. '};',
  31123. '']),
  31124. LinesToStr([ // $mod.$main
  31125. '$mod.s = rtl.getResStr($mod, "Red");',
  31126. '$mod.s = rtl.getResStr($mod, "Red");',
  31127. '$mod.s = rtl.getResStr(pas.unit2, "Title");',
  31128. '$mod.c = rtl.getResStr($mod, "Red").charAt(0);',
  31129. '$mod.c = rtl.getResStr($mod, "Red").charAt(1);',
  31130. 'if (rtl.getResStr($mod, "Red") === rtl.getResStr($mod, "Foobar")) ;',
  31131. 'if (rtl.getResStr($mod, "Red").charAt(2) === rtl.getResStr($mod, "Red").charAt(3)) ;',
  31132. '']));
  31133. end;
  31134. procedure TTestModule.TestResourcestringUnit;
  31135. begin
  31136. AddModuleWithIntfImplSrc('unit2.pas',
  31137. LinesToStr([
  31138. 'resourcestring Title = ''Nice'';',
  31139. '']),
  31140. '');
  31141. StartUnit(true);
  31142. Add([
  31143. 'interface',
  31144. 'uses unit2;',
  31145. 'const Red = ''rEd'';',
  31146. 'resourcestring',
  31147. ' Blue = ''blue'';',
  31148. ' NotRed = ''not''+Red;',
  31149. 'var s: string;',
  31150. 'implementation',
  31151. 'resourcestring',
  31152. ' ImplGreen = ''green'';',
  31153. 'initialization',
  31154. ' s:=blue+ImplGreen;',
  31155. ' s:=test1.blue+test1.implgreen;',
  31156. ' s:=blue[1]+implgreen[2];',
  31157. ' s:=Title;',
  31158. '']);
  31159. ConvertUnit;
  31160. CheckSource('TestResourcestringUnit',
  31161. LinesToStr([ // statements
  31162. 'this.Red = "rEd";',
  31163. 'this.s = "";',
  31164. '$mod.$resourcestrings = {',
  31165. ' Blue: {',
  31166. ' org: "blue"',
  31167. ' },',
  31168. ' NotRed: {',
  31169. ' org: "notrEd"',
  31170. ' },',
  31171. ' ImplGreen: {',
  31172. ' org: "green"',
  31173. ' }',
  31174. '};',
  31175. '']),
  31176. LinesToStr([ // $mod.$main
  31177. '$mod.s = rtl.getResStr($mod, "Blue") + rtl.getResStr($mod, "ImplGreen");',
  31178. '$mod.s = rtl.getResStr($mod, "Blue") + rtl.getResStr($mod, "ImplGreen");',
  31179. '$mod.s = rtl.getResStr($mod, "Blue").charAt(0) + rtl.getResStr($mod, "ImplGreen").charAt(1);',
  31180. '$mod.s = rtl.getResStr(pas.unit2, "Title");',
  31181. '']));
  31182. end;
  31183. procedure TTestModule.TestResourcestringImplementation;
  31184. begin
  31185. StartUnit(false);
  31186. Add([
  31187. 'interface',
  31188. 'implementation',
  31189. 'resourcestring',
  31190. ' ImplRed = ''red'';']);
  31191. ConvertUnit;
  31192. CheckSource('TestResourcestringImplementation',
  31193. LinesToStr([ // intf statements
  31194. 'var $impl = $mod.$impl;']),
  31195. LinesToStr([ // $mod.$init
  31196. '']),
  31197. LinesToStr([ // impl statements
  31198. '$mod.$resourcestrings = {',
  31199. ' ImplRed: {',
  31200. ' org: "red"',
  31201. ' }',
  31202. '};',
  31203. '']));
  31204. end;
  31205. procedure TTestModule.TestAttributes_Members;
  31206. begin
  31207. WithTypeInfo:=true;
  31208. StartProgram(false);
  31209. Add([
  31210. '{$modeswitch PrefixedAttributes}',
  31211. 'type',
  31212. ' TObject = class',
  31213. ' constructor Create;',
  31214. ' end;',
  31215. ' TCustomAttribute = class',
  31216. ' constructor Create(Id: word);',
  31217. ' end;',
  31218. ' [Missing]',
  31219. ' TBird = class',
  31220. ' published',
  31221. ' [Tcustom]',
  31222. ' FField: word;',
  31223. ' [tcustom(14)]',
  31224. ' property Size: word read FField;',
  31225. ' [Tcustom(15)]',
  31226. ' procedure Fly; virtual; abstract;',
  31227. ' end;',
  31228. ' TRec = record',
  31229. ' [Tcustom,tcustom(14)]',
  31230. ' Size: word;',
  31231. ' end;',
  31232. 'constructor TObject.Create; begin end;',
  31233. 'constructor TCustomAttribute.Create(Id: word); begin end;',
  31234. 'begin',
  31235. '']);
  31236. ConvertProgram;
  31237. CheckSource('TestAttributes_Members',
  31238. LinesToStr([ // statements
  31239. 'rtl.createClass(this, "TObject", null, function () {',
  31240. ' this.$init = function () {',
  31241. ' };',
  31242. ' this.$final = function () {',
  31243. ' };',
  31244. ' this.Create = function () {',
  31245. ' return this;',
  31246. ' };',
  31247. '});',
  31248. 'rtl.createClass(this, "TCustomAttribute", this.TObject, function () {',
  31249. ' this.Create$1 = function (Id) {',
  31250. ' return this;',
  31251. ' };',
  31252. '});',
  31253. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  31254. ' this.$init = function () {',
  31255. ' $mod.TObject.$init.call(this);',
  31256. ' this.FField = 0;',
  31257. ' };',
  31258. ' var $r = this.$rtti;',
  31259. ' $r.addField("FField", rtl.word, {',
  31260. ' attr: [$mod.TCustomAttribute, "Create"]',
  31261. ' });',
  31262. ' $r.addProperty(',
  31263. ' "Size",',
  31264. ' 0,',
  31265. ' rtl.word,',
  31266. ' "FField",',
  31267. ' "",',
  31268. ' {',
  31269. ' attr: [$mod.TCustomAttribute, "Create$1", [14]]',
  31270. ' }',
  31271. ' );',
  31272. ' $r.addMethod("Fly", 0, [], null, 0, {',
  31273. ' attr: [$mod.TCustomAttribute, "Create$1", [15]]',
  31274. ' });',
  31275. '});',
  31276. 'rtl.recNewT(this, "TRec", function () {',
  31277. ' this.Size = 0;',
  31278. ' this.$eq = function (b) {',
  31279. ' return this.Size === b.Size;',
  31280. ' };',
  31281. ' this.$assign = function (s) {',
  31282. ' this.Size = s.Size;',
  31283. ' return this;',
  31284. ' };',
  31285. ' var $r = $mod.$rtti.$Record("TRec", {});',
  31286. ' $r.addField("Size", rtl.word, {',
  31287. ' attr: [',
  31288. ' $mod.TCustomAttribute,',
  31289. ' "Create",',
  31290. ' $mod.TCustomAttribute,',
  31291. ' "Create$1",',
  31292. ' [14]',
  31293. ' ]',
  31294. ' });',
  31295. '});',
  31296. '']),
  31297. LinesToStr([ // $mod.$main
  31298. '']));
  31299. end;
  31300. procedure TTestModule.TestAttributes_Types;
  31301. begin
  31302. WithTypeInfo:=true;
  31303. StartProgram(false);
  31304. Add([
  31305. '{$modeswitch PrefixedAttributes}',
  31306. 'type',
  31307. ' TObject = class',
  31308. ' constructor Create(Id: word);',
  31309. ' end;',
  31310. ' TCustomAttribute = class',
  31311. ' end;',
  31312. ' [TCustom(1)]',
  31313. ' TMyClass = class',
  31314. ' end;',
  31315. ' [TCustom(11)]',
  31316. ' TMyDescendant = class(TMyClass)',
  31317. ' end;',
  31318. ' [TCustom(2)]',
  31319. ' TRec = record',
  31320. ' end;',
  31321. ' [TCustom(3)]',
  31322. ' TInt = type word;',
  31323. 'constructor TObject.Create(Id: word);',
  31324. 'begin',
  31325. 'end;',
  31326. 'var p: pointer;',
  31327. 'begin',
  31328. ' p:=typeinfo(TMyClass);',
  31329. ' p:=typeinfo(TRec);',
  31330. ' p:=typeinfo(TInt);',
  31331. '']);
  31332. ConvertProgram;
  31333. CheckSource('TestAttributes_Types',
  31334. LinesToStr([ // statements
  31335. 'rtl.createClass(this, "TObject", null, function () {',
  31336. ' this.$init = function () {',
  31337. ' };',
  31338. ' this.$final = function () {',
  31339. ' };',
  31340. ' this.Create = function (Id) {',
  31341. ' return this;',
  31342. ' };',
  31343. '});',
  31344. 'rtl.createClass(this, "TCustomAttribute", this.TObject, function () {',
  31345. '});',
  31346. 'rtl.createClass(this, "TMyClass", this.TObject, function () {',
  31347. ' var $r = this.$rtti;',
  31348. ' $r.attr = [$mod.TCustomAttribute, "Create", [1]];',
  31349. '});',
  31350. 'rtl.createClass(this, "TMyDescendant", this.TMyClass, function () {',
  31351. ' var $r = this.$rtti;',
  31352. ' $r.attr = [$mod.TCustomAttribute, "Create", [11]];',
  31353. '});',
  31354. 'rtl.recNewT(this, "TRec", function () {',
  31355. ' this.$eq = function (b) {',
  31356. ' return true;',
  31357. ' };',
  31358. ' this.$assign = function (s) {',
  31359. ' return this;',
  31360. ' };',
  31361. ' $mod.$rtti.$Record("TRec", {',
  31362. ' attr: [$mod.TCustomAttribute, "Create", [2]]',
  31363. ' });',
  31364. '});',
  31365. 'this.$rtti.$inherited("TInt", rtl.word, {',
  31366. ' attr: [this.TCustomAttribute, "Create", [3]]',
  31367. '});',
  31368. 'this.p = null;',
  31369. '']),
  31370. LinesToStr([ // $mod.$main
  31371. '$mod.p = $mod.$rtti["TMyClass"];',
  31372. '$mod.p = $mod.$rtti["TRec"];',
  31373. '$mod.p = $mod.$rtti["TInt"];',
  31374. '']));
  31375. end;
  31376. procedure TTestModule.TestAttributes_HelperConstructor_Fail;
  31377. begin
  31378. WithTypeInfo:=true;
  31379. StartProgram(false);
  31380. Add([
  31381. '{$modeswitch PrefixedAttributes}',
  31382. 'type',
  31383. ' TObject = class',
  31384. ' constructor Create;',
  31385. ' end;',
  31386. ' TCustomAttribute = class',
  31387. ' end;',
  31388. ' THelper = class helper for TCustomAttribute',
  31389. ' constructor Create(Id: word);',
  31390. ' end;',
  31391. ' [TCustom(3)]',
  31392. ' TMyInt = word;',
  31393. 'constructor TObject.Create; begin end;',
  31394. 'constructor THelper.Create(Id: word); begin end;',
  31395. 'begin',
  31396. ' if typeinfo(TMyInt)=nil then ;']);
  31397. ConvertProgram;
  31398. end;
  31399. procedure TTestModule.TestAssert;
  31400. begin
  31401. StartProgram(false);
  31402. Add([
  31403. 'procedure DoIt;',
  31404. 'var',
  31405. ' b: boolean;',
  31406. ' s: string;',
  31407. 'begin',
  31408. ' {$Assertions on}',
  31409. ' Assert(b);',
  31410. 'end;',
  31411. 'begin',
  31412. ' DoIt;',
  31413. '']);
  31414. ConvertProgram;
  31415. CheckSource('TestAssert',
  31416. LinesToStr([ // statements
  31417. 'this.DoIt = function () {',
  31418. ' var b = false;',
  31419. ' var s = "";',
  31420. ' if (!b) throw "assert failed";',
  31421. '};',
  31422. '']),
  31423. LinesToStr([ // $mod.$main
  31424. '$mod.DoIt();',
  31425. '']));
  31426. end;
  31427. procedure TTestModule.TestAssert_SysUtils;
  31428. begin
  31429. AddModuleWithIntfImplSrc('SysUtils.pas',
  31430. LinesToStr([
  31431. 'type',
  31432. ' TObject = class',
  31433. ' constructor Create;',
  31434. ' end;',
  31435. ' EAssertionFailed = class',
  31436. ' constructor Create(s: string);',
  31437. ' end;',
  31438. '']),
  31439. LinesToStr([
  31440. 'constructor TObject.Create;',
  31441. 'begin end;',
  31442. 'constructor EAssertionFailed.Create(s: string);',
  31443. 'begin end;',
  31444. '']) );
  31445. StartProgram(true);
  31446. Add([
  31447. 'uses sysutils;',
  31448. 'procedure DoIt;',
  31449. 'var',
  31450. ' b: boolean;',
  31451. ' s: string;',
  31452. 'begin',
  31453. ' {$Assertions on}',
  31454. ' Assert(b);',
  31455. ' Assert(b,''msg'');',
  31456. 'end;',
  31457. 'begin',
  31458. ' DoIt;',
  31459. '']);
  31460. ConvertProgram;
  31461. CheckSource('TestAssert_SysUtils',
  31462. LinesToStr([ // statements
  31463. 'this.DoIt = function () {',
  31464. ' var b = false;',
  31465. ' var s = "";',
  31466. ' if (!b) throw pas.SysUtils.EAssertionFailed.$create("Create");',
  31467. ' if (!b) throw pas.SysUtils.EAssertionFailed.$create("Create$1", ["msg"]);',
  31468. '};',
  31469. '']),
  31470. LinesToStr([ // $mod.$main
  31471. '$mod.DoIt();',
  31472. '']));
  31473. end;
  31474. procedure TTestModule.TestObjectChecks;
  31475. begin
  31476. Scanner.CurrentBoolSwitches:=Scanner.CurrentBoolSwitches+[bsObjectChecks];
  31477. StartProgram(false);
  31478. Add([
  31479. 'type',
  31480. ' TObject = class',
  31481. ' procedure DoIt;',
  31482. ' end;',
  31483. ' TClass = class of tobject;',
  31484. ' TBird = class',
  31485. ' end;',
  31486. ' TBirdClass = class of TBird;',
  31487. 'var',
  31488. ' o : TObject;',
  31489. ' c: TClass;',
  31490. ' b: TBird;',
  31491. ' bc: TBirdClass;',
  31492. 'procedure TObject.DoIt;',
  31493. 'begin',
  31494. ' b:=TBird(o);',
  31495. 'end;',
  31496. 'begin',
  31497. ' o.DoIt;',
  31498. ' b:=TBird(o);',
  31499. ' bc:=TBirdClass(c);',
  31500. '']);
  31501. ConvertProgram;
  31502. CheckSource('TestCheckMethodCall',
  31503. LinesToStr([ // statements
  31504. 'rtl.createClass(this, "TObject", null, function () {',
  31505. ' this.$init = function () {',
  31506. ' };',
  31507. ' this.$final = function () {',
  31508. ' };',
  31509. ' this.DoIt = function () {',
  31510. ' rtl.checkMethodCall(this,$mod.TObject);',
  31511. ' $mod.b = rtl.asExt($mod.o, $mod.TBird, 1);',
  31512. ' };',
  31513. '});',
  31514. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  31515. '});',
  31516. 'this.o = null;',
  31517. 'this.c = null;',
  31518. 'this.b = null;',
  31519. 'this.bc = null;',
  31520. '']),
  31521. LinesToStr([ // $mod.$main
  31522. '$mod.o.DoIt();',
  31523. '$mod.b = rtl.asExt($mod.o,$mod.TBird, 1);',
  31524. '$mod.bc = rtl.asExt($mod.c, $mod.TBird, 2);',
  31525. '']));
  31526. end;
  31527. procedure TTestModule.TestOverflowChecks_Int;
  31528. begin
  31529. Scanner.CurrentBoolSwitches:=Scanner.CurrentBoolSwitches+[bsOverflowChecks];
  31530. StartProgram(false);
  31531. Add([
  31532. 'procedure DoIt;',
  31533. 'var',
  31534. ' b: byte;',
  31535. ' n: nativeint;',
  31536. ' u: nativeuint;',
  31537. ' c: currency;',
  31538. 'begin',
  31539. ' n:=n+n;',
  31540. ' n:=n-n;',
  31541. ' n:=n+b;',
  31542. ' n:=b-n;',
  31543. ' n:=n*n;',
  31544. ' n:=n*u;',
  31545. ' c:=c+b;',
  31546. ' c:=b+c;',
  31547. ' c:=c*b;',
  31548. ' c:=b*c;',
  31549. 'end;',
  31550. 'begin',
  31551. '']);
  31552. ConvertProgram;
  31553. CheckSource('TestOverflowChecks_Int',
  31554. LinesToStr([ // statements
  31555. 'this.DoIt = function () {',
  31556. ' var b = 0;',
  31557. ' var n = 0;',
  31558. ' var u = 0;',
  31559. ' var c = 0;',
  31560. ' n = rtl.oc(n + n);',
  31561. ' n = rtl.oc(n - n);',
  31562. ' n = rtl.oc(n + b);',
  31563. ' n = rtl.oc(b - n);',
  31564. ' n = rtl.oc(n * n);',
  31565. ' n = rtl.oc(n * u);',
  31566. ' c = rtl.oc(c + (b * 10000));',
  31567. ' c = rtl.oc((b * 10000) + c);',
  31568. ' c = rtl.oc(c * b);',
  31569. ' c = rtl.oc(b * c);',
  31570. '};',
  31571. '']),
  31572. LinesToStr([ // $mod.$main
  31573. '']));
  31574. end;
  31575. procedure TTestModule.TestRangeChecks_AssignInt;
  31576. begin
  31577. Scanner.Options:=Scanner.Options+[po_CAssignments];
  31578. StartProgram(false);
  31579. Add([
  31580. '{$R+}',
  31581. 'var',
  31582. ' b: byte = 2;',
  31583. ' w: word = 3;',
  31584. 'procedure DoIt(p: byte);',
  31585. 'begin',
  31586. ' b:=w;',
  31587. ' b+=w;',
  31588. ' b:=1;',
  31589. 'end;',
  31590. '{$R-}',
  31591. 'procedure DoSome;',
  31592. 'begin',
  31593. ' DoIt(w);',
  31594. ' b:=w;',
  31595. ' b:=2;',
  31596. 'end;',
  31597. 'begin',
  31598. '{$R+}',
  31599. '']);
  31600. ConvertProgram;
  31601. CheckSource('TestRangeChecks_AssignInt',
  31602. LinesToStr([ // statements
  31603. 'this.b = 2;',
  31604. 'this.w = 3;',
  31605. 'this.DoIt = function (p) {',
  31606. ' rtl.rc(p, 0, 255);',
  31607. ' $mod.b = rtl.rc($mod.w,0,255);',
  31608. ' rtl.rc($mod.b += $mod.w, 0, 255);',
  31609. ' $mod.b = 1;',
  31610. '};',
  31611. 'this.DoSome = function () {',
  31612. ' $mod.DoIt($mod.w);',
  31613. ' $mod.b = $mod.w;',
  31614. ' $mod.b = 2;',
  31615. '};',
  31616. '']),
  31617. LinesToStr([ // $mod.$main
  31618. '']));
  31619. end;
  31620. procedure TTestModule.TestRangeChecks_AssignIntRange;
  31621. begin
  31622. Scanner.Options:=Scanner.Options+[po_CAssignments];
  31623. StartProgram(false);
  31624. Add([
  31625. '{$R+}',
  31626. 'type Ten = 1..10;',
  31627. 'var',
  31628. ' b: Ten = 2;',
  31629. ' w: Ten = 3;',
  31630. 'procedure DoIt(p: Ten);',
  31631. 'begin',
  31632. ' b:=w;',
  31633. ' b+=w;',
  31634. ' b:=1;',
  31635. 'end;',
  31636. '{$R-}',
  31637. 'procedure DoSome;',
  31638. 'begin',
  31639. ' DoIt(w);',
  31640. ' b:=w;',
  31641. ' b:=2;',
  31642. 'end;',
  31643. 'begin',
  31644. '{$R+}',
  31645. '']);
  31646. ConvertProgram;
  31647. CheckSource('TestRangeChecks_AssignIntRange',
  31648. LinesToStr([ // statements
  31649. 'this.b = 2;',
  31650. 'this.w = 3;',
  31651. 'this.DoIt = function (p) {',
  31652. ' rtl.rc(p, 1, 10);',
  31653. ' $mod.b = rtl.rc($mod.w, 1, 10);',
  31654. ' rtl.rc($mod.b += $mod.w, 1, 10);',
  31655. ' $mod.b = 1;',
  31656. '};',
  31657. 'this.DoSome = function () {',
  31658. ' $mod.DoIt($mod.w);',
  31659. ' $mod.b = $mod.w;',
  31660. ' $mod.b = 2;',
  31661. '};',
  31662. '']),
  31663. LinesToStr([ // $mod.$main
  31664. '']));
  31665. end;
  31666. procedure TTestModule.TestRangeChecks_AssignEnum;
  31667. begin
  31668. StartProgram(false);
  31669. Add([
  31670. '{$R+}',
  31671. 'type TEnum = (red,green);',
  31672. 'var',
  31673. ' e: TEnum = red;',
  31674. 'procedure DoIt(p: TEnum);',
  31675. 'begin',
  31676. ' e:=p;',
  31677. ' p:=TEnum(0);',
  31678. ' p:=succ(e);',
  31679. 'end;',
  31680. '{$R-}',
  31681. 'procedure DoSome;',
  31682. 'begin',
  31683. ' DoIt(e);',
  31684. ' e:=TEnum(1);',
  31685. ' e:=pred(e);',
  31686. 'end;',
  31687. 'begin',
  31688. '{$R+}',
  31689. '']);
  31690. ConvertProgram;
  31691. CheckSource('TestRangeChecks_AssignEnum',
  31692. LinesToStr([ // statements
  31693. 'this.TEnum = {',
  31694. ' "0": "red",',
  31695. ' red: 0,',
  31696. ' "1": "green",',
  31697. ' green: 1',
  31698. '};',
  31699. 'this.e = this.TEnum.red;',
  31700. 'this.DoIt = function (p) {',
  31701. ' rtl.rc(p, 0, 1);',
  31702. ' $mod.e = rtl.rc(p, 0, 1);',
  31703. ' p = 0;',
  31704. ' p = rtl.rc($mod.e + 1, 0, 1);',
  31705. '};',
  31706. 'this.DoSome = function () {',
  31707. ' $mod.DoIt($mod.e);',
  31708. ' $mod.e = 1;',
  31709. ' $mod.e = $mod.e - 1;',
  31710. '};',
  31711. '']),
  31712. LinesToStr([ // $mod.$main
  31713. '']));
  31714. end;
  31715. procedure TTestModule.TestRangeChecks_AssignEnumRange;
  31716. begin
  31717. StartProgram(false);
  31718. Add([
  31719. '{$R+}',
  31720. 'type',
  31721. ' TEnum = (red,green);',
  31722. ' TEnumRg = red..green;',
  31723. 'var',
  31724. ' e: TEnumRg = red;',
  31725. 'procedure DoIt(p: TEnumRg);',
  31726. 'begin',
  31727. ' e:=p;',
  31728. ' p:=TEnumRg(0);',
  31729. ' p:=succ(e);',
  31730. 'end;',
  31731. '{$R-}',
  31732. 'procedure DoSome;',
  31733. 'begin',
  31734. ' DoIt(e);',
  31735. ' e:=TEnum(1);',
  31736. ' e:=pred(e);',
  31737. 'end;',
  31738. 'begin',
  31739. '{$R+}',
  31740. '']);
  31741. ConvertProgram;
  31742. CheckSource('TestRangeChecks_AssignEnumRange',
  31743. LinesToStr([ // statements
  31744. 'this.TEnum = {',
  31745. ' "0": "red",',
  31746. ' red: 0,',
  31747. ' "1": "green",',
  31748. ' green: 1',
  31749. '};',
  31750. 'this.e = this.TEnum.red;',
  31751. 'this.DoIt = function (p) {',
  31752. ' rtl.rc(p, 0, 1);',
  31753. ' $mod.e = rtl.rc(p, 0, 1);',
  31754. ' p = 0;',
  31755. ' p = rtl.rc($mod.e + 1, 0, 1);',
  31756. '};',
  31757. 'this.DoSome = function () {',
  31758. ' $mod.DoIt($mod.e);',
  31759. ' $mod.e = 1;',
  31760. ' $mod.e = $mod.e - 1;',
  31761. '};',
  31762. '']),
  31763. LinesToStr([ // $mod.$main
  31764. '']));
  31765. end;
  31766. procedure TTestModule.TestRangeChecks_AssignChar;
  31767. begin
  31768. StartProgram(false);
  31769. Add([
  31770. '{$R+}',
  31771. 'type',
  31772. ' TLetter = char;',
  31773. 'var',
  31774. ' b: TLetter = ''2'';',
  31775. ' w: TLetter = ''3'';',
  31776. 'procedure DoIt(p: TLetter);',
  31777. 'begin',
  31778. ' b:=w;',
  31779. ' b:=''1'';',
  31780. 'end;',
  31781. '{$R-}',
  31782. 'procedure DoSome;',
  31783. 'begin',
  31784. ' DoIt(w);',
  31785. ' b:=w;',
  31786. ' b:=''2'';',
  31787. 'end;',
  31788. 'begin',
  31789. '{$R+}',
  31790. '']);
  31791. ConvertProgram;
  31792. CheckSource('TestRangeChecks_AssignChar',
  31793. LinesToStr([ // statements
  31794. 'this.b = "2";',
  31795. 'this.w = "3";',
  31796. 'this.DoIt = function (p) {',
  31797. ' rtl.rcc(p, 0, 65535);',
  31798. ' $mod.b = rtl.rcc($mod.w, 0, 65535);',
  31799. ' $mod.b = "1";',
  31800. '};',
  31801. 'this.DoSome = function () {',
  31802. ' $mod.DoIt($mod.w);',
  31803. ' $mod.b = $mod.w;',
  31804. ' $mod.b = "2";',
  31805. '};',
  31806. '']),
  31807. LinesToStr([ // $mod.$main
  31808. '']));
  31809. end;
  31810. procedure TTestModule.TestRangeChecks_AssignCharRange;
  31811. begin
  31812. StartProgram(false);
  31813. Add([
  31814. '{$R+}',
  31815. 'type TDigit = ''0''..''9'';',
  31816. 'var',
  31817. ' b: TDigit = ''2'';',
  31818. ' w: TDigit = ''3'';',
  31819. 'procedure DoIt(p: TDigit);',
  31820. 'begin',
  31821. ' b:=w;',
  31822. ' b:=''1'';',
  31823. 'end;',
  31824. '{$R-}',
  31825. 'procedure DoSome;',
  31826. 'begin',
  31827. ' DoIt(w);',
  31828. ' b:=w;',
  31829. ' b:=''2'';',
  31830. 'end;',
  31831. 'begin',
  31832. '{$R+}',
  31833. '']);
  31834. ConvertProgram;
  31835. CheckSource('TestRangeChecks_AssignCharRange',
  31836. LinesToStr([ // statements
  31837. 'this.b = "2";',
  31838. 'this.w = "3";',
  31839. 'this.DoIt = function (p) {',
  31840. ' rtl.rcc(p, 48, 57);',
  31841. ' $mod.b = rtl.rcc($mod.w, 48, 57);',
  31842. ' $mod.b = "1";',
  31843. '};',
  31844. 'this.DoSome = function () {',
  31845. ' $mod.DoIt($mod.w);',
  31846. ' $mod.b = $mod.w;',
  31847. ' $mod.b = "2";',
  31848. '};',
  31849. '']),
  31850. LinesToStr([ // $mod.$main
  31851. '']));
  31852. end;
  31853. procedure TTestModule.TestRangeChecks_ArrayIndex;
  31854. begin
  31855. StartProgram(false);
  31856. Add([
  31857. '{$R+}',
  31858. 'type',
  31859. ' Ten = 1..10;',
  31860. ' TArr = array of Ten;',
  31861. ' TArrArr = array of TArr;',
  31862. ' TArrByte = array[byte] of Ten;',
  31863. ' TArrChar = array[''0''..''9''] of Ten;',
  31864. ' TArrByteChar = array[byte,''0''..''9''] of Ten;',
  31865. ' TObject = class',
  31866. ' A: TArr;',
  31867. ' end;',
  31868. 'procedure DoIt;',
  31869. 'var',
  31870. ' Arr: TArr;',
  31871. ' ArrArr: TArrArr;',
  31872. ' ArrByte: TArrByte;',
  31873. ' ArrChar: TArrChar;',
  31874. ' ArrByteChar: TArrByteChar;',
  31875. ' i: Ten;',
  31876. ' c: char;',
  31877. ' o: tobject;',
  31878. 'begin',
  31879. ' i:=Arr[1];',
  31880. ' i:=ArrByteChar[1,''2''];',
  31881. ' Arr[1]:=Arr[1];',
  31882. ' Arr[i]:=Arr[i];',
  31883. ' ArrByte[3]:=ArrByte[3];',
  31884. ' ArrByte[i]:=ArrByte[i];',
  31885. ' ArrChar[''5'']:=ArrChar[''5''];',
  31886. ' ArrChar[c]:=ArrChar[c];',
  31887. ' ArrByteChar[7,''7'']:=ArrByteChar[7,''7''];',
  31888. ' ArrByteChar[i,c]:=ArrByteChar[i,c];',
  31889. ' o.a[i]:=o.a[i];',
  31890. 'end;',
  31891. 'begin',
  31892. '']);
  31893. ConvertProgram;
  31894. CheckSource('TestRangeChecks_ArrayIndex',
  31895. LinesToStr([ // statements
  31896. 'rtl.createClass(this, "TObject", null, function () {',
  31897. ' this.$init = function () {',
  31898. ' this.A = [];',
  31899. ' };',
  31900. ' this.$final = function () {',
  31901. ' this.A = undefined;',
  31902. ' };',
  31903. '});',
  31904. 'this.DoIt = function () {',
  31905. ' var Arr = [];',
  31906. ' var ArrArr = [];',
  31907. ' var ArrByte = rtl.arraySetLength(null, 0, 256);',
  31908. ' var ArrChar = rtl.arraySetLength(null, 0, 10);',
  31909. ' var ArrByteChar = rtl.arraySetLength(null, 0, 256, 10);',
  31910. ' var i = 0;',
  31911. ' var c = "";',
  31912. ' var o = null;',
  31913. ' i = rtl.rc(Arr[1], 1, 10);',
  31914. ' i = rtl.rc(ArrByteChar[1][2], 1, 10);',
  31915. ' Arr[1] = rtl.rc(Arr[1], 1, 10);',
  31916. ' rtl.rcArrW(Arr, i, rtl.rcArrR(Arr, i));',
  31917. ' ArrByte[3] = rtl.rc(ArrByte[3], 1, 10);',
  31918. ' rtl.rcArrW(ArrByte, i, rtl.rcArrR(ArrByte, i));',
  31919. ' ArrChar[5] = rtl.rc(ArrChar[5], 1, 10);',
  31920. ' rtl.rcArrW(ArrChar, c.charCodeAt() - 48, rtl.rcArrR(ArrChar, c.charCodeAt() - 48));',
  31921. ' ArrByteChar[7][7] = rtl.rc(ArrByteChar[7][7], 1, 10);',
  31922. ' rtl.rcArrW(ArrByteChar, i, c.charCodeAt() - 48, rtl.rcArrR(ArrByteChar, i, c.charCodeAt() - 48));',
  31923. ' rtl.rcArrW(o.A, i, rtl.rcArrR(o.A, i));',
  31924. '};',
  31925. '']),
  31926. LinesToStr([ // $mod.$main
  31927. '']));
  31928. end;
  31929. procedure TTestModule.TestRangeChecks_ArrayOfRecIndex;
  31930. begin
  31931. StartProgram(false);
  31932. Add([
  31933. '{$R+}',
  31934. 'type',
  31935. ' Ten = 1..10;',
  31936. ' TRec = record x: Ten end;',
  31937. ' TArr = array of TRec;',
  31938. ' TArrArr = array of TArr;',
  31939. ' TObject = class',
  31940. ' A: TArr;',
  31941. ' end;',
  31942. 'procedure DoIt;',
  31943. 'var',
  31944. ' Arr: TArr;',
  31945. ' ArrArr: TArrArr;',
  31946. ' i: Ten;',
  31947. ' o: tobject;',
  31948. 'begin',
  31949. ' Arr[1]:=Arr[1];',
  31950. ' Arr[i]:=Arr[i+1];',
  31951. ' o.a[i]:=o.a[i+2];',
  31952. 'end;',
  31953. 'begin',
  31954. '']);
  31955. ConvertProgram;
  31956. CheckSource('TestRangeChecks_ArrayOfRecIndex',
  31957. LinesToStr([ // statements
  31958. 'rtl.recNewT(this, "TRec", function () {',
  31959. ' this.x = 0;',
  31960. ' this.$eq = function (b) {',
  31961. ' return this.x === b.x;',
  31962. ' };',
  31963. ' this.$assign = function (s) {',
  31964. ' this.x = s.x;',
  31965. ' return this;',
  31966. ' };',
  31967. '});',
  31968. 'rtl.createClass(this, "TObject", null, function () {',
  31969. ' this.$init = function () {',
  31970. ' this.A = [];',
  31971. ' };',
  31972. ' this.$final = function () {',
  31973. ' this.A = undefined;',
  31974. ' };',
  31975. '});',
  31976. 'this.DoIt = function () {',
  31977. ' var Arr = [];',
  31978. ' var ArrArr = [];',
  31979. ' var i = 0;',
  31980. ' var o = null;',
  31981. ' Arr[1].$assign(Arr[1]);',
  31982. ' rtl.rcArrR(Arr, i).$assign(rtl.rcArrR(Arr, i + 1));',
  31983. ' rtl.rcArrR(o.A, i).$assign(rtl.rcArrR(o.A, i + 2));',
  31984. '};',
  31985. '']),
  31986. LinesToStr([ // $mod.$main
  31987. '']));
  31988. end;
  31989. procedure TTestModule.TestRangeChecks_StringIndex;
  31990. begin
  31991. StartProgram(false);
  31992. Add([
  31993. 'type',
  31994. ' TObject = class',
  31995. ' S: string;',
  31996. ' end;',
  31997. '{$R+}',
  31998. 'procedure DoIt(var h: string);',
  31999. 'var',
  32000. ' s: string;',
  32001. ' i: longint;',
  32002. ' c: char;',
  32003. ' o: tobject;',
  32004. 'begin',
  32005. ' c:=s[1];',
  32006. ' s[i]:=s[i];',
  32007. ' h[i]:=h[i];',
  32008. ' c:=o.s[i];',
  32009. ' o.s[i]:=c;',
  32010. 'end;',
  32011. 'begin',
  32012. '']);
  32013. ConvertProgram;
  32014. CheckSource('TestRangeChecks_StringIndex',
  32015. LinesToStr([ // statements
  32016. 'rtl.createClass(this, "TObject", null, function () {',
  32017. ' this.$init = function () {',
  32018. ' this.S = "";',
  32019. ' };',
  32020. ' this.$final = function () {',
  32021. ' };',
  32022. '});',
  32023. 'this.DoIt = function (h) {',
  32024. ' var s = "";',
  32025. ' var i = 0;',
  32026. ' var c = "";',
  32027. ' var o = null;',
  32028. ' c = rtl.rcc(rtl.rcCharAt(s, 0), 0, 65535);',
  32029. ' s = rtl.rcSetCharAt(s, i - 1, rtl.rcCharAt(s, i - 1));',
  32030. ' h.set(rtl.rcSetCharAt(h.get(), i - 1, rtl.rcCharAt(h.get(), i - 1)));',
  32031. ' c = rtl.rcc(rtl.rcCharAt(o.S, i - 1), 0, 65535);',
  32032. ' o.S = rtl.rcSetCharAt(o.S, i - 1, c);',
  32033. '};',
  32034. '']),
  32035. LinesToStr([ // $mod.$main
  32036. '']));
  32037. end;
  32038. procedure TTestModule.TestRangeChecks_TypecastInt;
  32039. begin
  32040. StartProgram(false);
  32041. Add([
  32042. '{$R+}',
  32043. 'var',
  32044. ' i: nativeint;',
  32045. ' b: byte;',
  32046. ' sh: shortint;',
  32047. ' w: word;',
  32048. ' sm: smallint;',
  32049. ' lw: longword;',
  32050. ' li: longint;',
  32051. 'begin',
  32052. ' b:=12+byte(i);',
  32053. ' sh:=12+shortint(i);',
  32054. ' w:=12+word(i);',
  32055. ' sm:=12+smallint(i);',
  32056. ' lw:=12+longword(i);',
  32057. ' li:=12+longint(i);',
  32058. '']);
  32059. ConvertProgram;
  32060. CheckSource('TestRangeChecks_TypecastInt',
  32061. LinesToStr([
  32062. 'this.i = 0;',
  32063. 'this.b = 0;',
  32064. 'this.sh = 0;',
  32065. 'this.w = 0;',
  32066. 'this.sm = 0;',
  32067. 'this.lw = 0;',
  32068. 'this.li = 0;',
  32069. '']),
  32070. LinesToStr([
  32071. '$mod.b = rtl.rc(12 + rtl.rc($mod.i, 0, 255), 0, 255);',
  32072. '$mod.sh = rtl.rc(12 + rtl.rc($mod.i, -128, 127), -128, 127);',
  32073. '$mod.w = rtl.rc(12 + rtl.rc($mod.i, 0, 65535), 0, 65535);',
  32074. '$mod.sm = rtl.rc(12 + rtl.rc($mod.i, -32768, 32767), -32768, 32767);',
  32075. '$mod.lw = rtl.rc(12 + rtl.rc($mod.i, 0, 4294967295), 0, 4294967295);',
  32076. '$mod.li = rtl.rc(12 + rtl.rc($mod.i, -2147483648, 2147483647), -2147483648, 2147483647);',
  32077. '']));
  32078. end;
  32079. procedure TTestModule.TestRangeChecks_TypeHelperInt;
  32080. begin
  32081. Scanner.Options:=Scanner.Options+[po_CAssignments];
  32082. StartProgram(false);
  32083. Add([
  32084. '{$modeswitch typehelpers}',
  32085. '{$R+}',
  32086. 'type',
  32087. ' TObject = class',
  32088. ' FSize: byte;',
  32089. ' property Size: byte read FSize;',
  32090. ' end;',
  32091. ' THelper = type helper for byte',
  32092. ' procedure SetIt(w: word);',
  32093. ' end;',
  32094. 'procedure THelper.SetIt(w: word);',
  32095. 'begin',
  32096. ' Self:=w;',
  32097. 'end;',
  32098. 'function GetIt: byte;',
  32099. 'begin',
  32100. ' Result.SetIt(2);',
  32101. 'end;',
  32102. 'var',
  32103. ' b: byte = 3;',
  32104. ' o: TObject;',
  32105. 'begin',
  32106. ' b.SetIt(14);',
  32107. ' with b do SetIt(15);',
  32108. ' o.Size.SetIt(16);',
  32109. '']);
  32110. ConvertProgram;
  32111. CheckSource('TestRangeChecks_AssignInt',
  32112. LinesToStr([ // statements
  32113. 'rtl.createClass(this, "TObject", null, function () {',
  32114. ' this.$init = function () {',
  32115. ' this.FSize = 0;',
  32116. ' };',
  32117. ' this.$final = function () {',
  32118. ' };',
  32119. '});',
  32120. 'rtl.createHelper(this, "THelper", null, function () {',
  32121. ' this.SetIt = function (w) {',
  32122. ' rtl.rc(w, 0, 65535);',
  32123. ' this.set(w);',
  32124. ' };',
  32125. '});',
  32126. 'this.GetIt = function () {',
  32127. ' var Result = 0;',
  32128. ' $mod.THelper.SetIt.call({',
  32129. ' get: function () {',
  32130. ' return Result;',
  32131. ' },',
  32132. ' set: function (v) {',
  32133. ' rtl.rc(v, 0, 255);',
  32134. ' Result = v;',
  32135. ' }',
  32136. ' }, 2);',
  32137. ' return Result;',
  32138. '};',
  32139. 'this.b = 3;',
  32140. 'this.o = null;',
  32141. '']),
  32142. LinesToStr([ // $mod.$main
  32143. '$mod.THelper.SetIt.call({',
  32144. ' p: $mod,',
  32145. ' get: function () {',
  32146. ' return this.p.b;',
  32147. ' },',
  32148. ' set: function (v) {',
  32149. ' rtl.rc(v, 0, 255);',
  32150. ' this.p.b = v;',
  32151. ' }',
  32152. '}, 14);',
  32153. 'var $with = $mod.b;',
  32154. '$mod.THelper.SetIt.call({',
  32155. ' get: function () {',
  32156. ' return $with;',
  32157. ' },',
  32158. ' set: function (v) {',
  32159. ' rtl.rc(v, 0, 255);',
  32160. ' $with = v;',
  32161. ' }',
  32162. '}, 15);',
  32163. '$mod.THelper.SetIt.call({',
  32164. ' p: $mod.o,',
  32165. ' get: function () {',
  32166. ' return this.p.FSize;',
  32167. ' },',
  32168. ' set: function (v) {',
  32169. ' rtl.rc(v, 0, 255);',
  32170. ' this.p.FSize = v;',
  32171. ' }',
  32172. '}, 16);',
  32173. '']));
  32174. end;
  32175. procedure TTestModule.TestAsync_Proc;
  32176. begin
  32177. StartProgram(false);
  32178. Add([
  32179. 'procedure Fly(w: word = 1); async; forward;',
  32180. 'procedure Run(w: word = 2); async;',
  32181. 'begin',
  32182. ' Fly(w);',
  32183. ' Fly;',
  32184. ' await(Fly(w));',
  32185. ' await(Fly);',
  32186. 'end;',
  32187. 'procedure Fly(w: word); ',
  32188. 'begin',
  32189. 'end;',
  32190. 'begin',
  32191. ' Run;',
  32192. ' Run(3);',
  32193. '']);
  32194. CheckResolverUnexpectedHints();
  32195. ConvertProgram;
  32196. CheckSource('TestAsync_Proc',
  32197. LinesToStr([ // statements
  32198. 'this.Run = async function (w) {',
  32199. ' $mod.Fly(w);',
  32200. ' $mod.Fly(1);',
  32201. ' await $mod.Fly(w);',
  32202. ' await $mod.Fly(1);',
  32203. '};',
  32204. 'this.Fly = async function (w) {',
  32205. '};',
  32206. '']),
  32207. LinesToStr([
  32208. '$mod.Run(2);',
  32209. '$mod.Run(3);',
  32210. '']));
  32211. end;
  32212. procedure TTestModule.TestAsync_CallResultIsPromise;
  32213. begin
  32214. StartProgram(false);
  32215. Add([
  32216. '{$modeswitch externalclass}',
  32217. 'type',
  32218. ' TObject = class',
  32219. ' end;',
  32220. ' TJSPromise = class external name ''Promise''',
  32221. ' end;',
  32222. ' TBird = class',
  32223. ' function Fly: word; async; ',
  32224. ' end;',
  32225. 'function TBird.Fly: word; async; ',
  32226. 'begin',
  32227. ' Result:=3;',
  32228. ' Fly:=4+Result;',
  32229. ' if Result=5 then ;',
  32230. ' exit(6);',
  32231. 'end;',
  32232. 'function Run: word; async;',
  32233. 'begin',
  32234. ' Result:=11+Result;',
  32235. ' inc(Result);',
  32236. 'end;',
  32237. 'var',
  32238. ' p: TJSPromise;',
  32239. ' o: TBird;',
  32240. 'begin',
  32241. ' p:=Run;',
  32242. ' p:=Run();',
  32243. ' if Run=p then ;',
  32244. ' if p=Run then ;',
  32245. ' if Run()=p then ;',
  32246. ' if p=Run() then ;',
  32247. ' p:=o.Fly;',
  32248. ' p:=o.Fly();',
  32249. ' if o.Fly=p then ;',
  32250. ' if o.Fly()=p then ;',
  32251. ' with o do begin',
  32252. ' p:=Fly;',
  32253. ' p:=Fly();',
  32254. ' if Fly=p then ;',
  32255. ' if Fly()=p then ;',
  32256. ' end;',
  32257. '']);
  32258. CheckResolverUnexpectedHints();
  32259. ConvertProgram;
  32260. CheckSource('TestAsync_CallResultIsPromise',
  32261. LinesToStr([ // statements
  32262. 'rtl.createClass(this, "TObject", null, function () {',
  32263. ' this.$init = function () {',
  32264. ' };',
  32265. ' this.$final = function () {',
  32266. ' };',
  32267. '});',
  32268. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  32269. ' this.Fly = async function () {',
  32270. ' var Result = 0;',
  32271. ' Result = 3;',
  32272. ' Result = 4 + Result;',
  32273. ' if (Result === 5) ;',
  32274. ' return 6;',
  32275. ' return Result;',
  32276. ' };',
  32277. '});',
  32278. 'this.Run = async function () {',
  32279. ' var Result = 0;',
  32280. ' Result = 11 + Result;',
  32281. ' Result += 1;',
  32282. ' return Result;',
  32283. '};',
  32284. 'this.p = null;',
  32285. 'this.o = null;',
  32286. '']),
  32287. LinesToStr([
  32288. '$mod.p = $mod.Run();',
  32289. '$mod.p = $mod.Run();',
  32290. 'if ($mod.Run() === $mod.p) ;',
  32291. 'if ($mod.p === $mod.Run()) ;',
  32292. 'if ($mod.Run() === $mod.p) ;',
  32293. 'if ($mod.p === $mod.Run()) ;',
  32294. '$mod.p = $mod.o.Fly();',
  32295. '$mod.p = $mod.o.Fly();',
  32296. 'if ($mod.o.Fly() === $mod.p) ;',
  32297. 'if ($mod.o.Fly() === $mod.p) ;',
  32298. 'var $with = $mod.o;',
  32299. '$mod.p = $with.Fly();',
  32300. '$mod.p = $with.Fly();',
  32301. 'if ($with.Fly() === $mod.p) ;',
  32302. 'if ($with.Fly() === $mod.p) ;',
  32303. '']));
  32304. end;
  32305. procedure TTestModule.TestAsync_ConstructorFail;
  32306. begin
  32307. StartProgram(false);
  32308. Add([
  32309. 'type',
  32310. ' TObject = class',
  32311. ' end;',
  32312. ' TBird = class',
  32313. ' constructor Create; async;',
  32314. ' end;',
  32315. 'constructor TBird.Create; async;',
  32316. 'begin',
  32317. 'end;',
  32318. 'begin',
  32319. '']);
  32320. SetExpectedPasResolverError('Invalid constructor modifier async',nInvalidXModifierY);
  32321. ConvertProgram;
  32322. end;
  32323. procedure TTestModule.TestAsync_PropertyGetterFail;
  32324. begin
  32325. StartProgram(false);
  32326. Add([
  32327. 'type',
  32328. ' TObject = class',
  32329. ' end;',
  32330. ' TBird = class',
  32331. ' function GetSize: word; async;',
  32332. ' property Size: word read GetSize;',
  32333. ' end;',
  32334. 'function TBird.GetSize: word; async;',
  32335. 'begin',
  32336. 'end;',
  32337. 'begin',
  32338. '']);
  32339. SetExpectedPasResolverError('Invalid property getter modifier async',nInvalidXModifierY);
  32340. ConvertProgram;
  32341. end;
  32342. procedure TTestModule.TestAwait_NonPromiseWithTypeFail;
  32343. begin
  32344. StartProgram(false);
  32345. Add([
  32346. 'procedure Run; async;',
  32347. 'begin',
  32348. ' await(word,1);',
  32349. 'end;',
  32350. 'begin',
  32351. '']);
  32352. SetExpectedPasResolverError('Incompatible type arg no. 2: Got "Longint", expected "TJSPromise"',nIncompatibleTypeArgNo);
  32353. ConvertProgram;
  32354. end;
  32355. procedure TTestModule.TestAwait_AsyncCallTypeMismatch;
  32356. begin
  32357. StartProgram(false);
  32358. Add([
  32359. 'type',
  32360. ' TObject = class',
  32361. ' end;',
  32362. ' TBird = class',
  32363. ' end;',
  32364. 'function Fly: TObject; async;',
  32365. 'begin',
  32366. 'end;',
  32367. 'procedure Run; async;',
  32368. 'begin',
  32369. ' await(TBird,Fly);',
  32370. 'end;',
  32371. 'begin',
  32372. '']);
  32373. SetExpectedPasResolverError('Incompatible type arg no. 2: Got "TObject", expected "TBird"',nIncompatibleTypeArgNo);
  32374. ConvertProgram;
  32375. end;
  32376. procedure TTestModule.TestAWait_OutsideAsyncFail;
  32377. begin
  32378. StartProgram(false);
  32379. Add([
  32380. 'procedure Crawl(w: double); ',
  32381. 'begin',
  32382. 'end;',
  32383. 'procedure Run(w: double);',
  32384. 'begin',
  32385. ' await(Crawl(w));',
  32386. 'end;',
  32387. 'begin',
  32388. ' Run(1);']);
  32389. SetExpectedPasResolverError(sAWaitOnlyInAsyncProcedure,nAWaitOnlyInAsyncProcedure);
  32390. ConvertProgram;
  32391. end;
  32392. procedure TTestModule.TestAWait_IntegerFail;
  32393. begin
  32394. StartProgram(false);
  32395. Add([
  32396. 'function Run: word;',
  32397. 'begin',
  32398. 'end;',
  32399. 'procedure Fly(w: word); async;',
  32400. 'begin',
  32401. ' await(Run());',
  32402. 'end;',
  32403. 'begin',
  32404. ' Fly(1);']);
  32405. SetExpectedPasResolverError('async function expected, but Result:Word found',nXExpectedButYFound);
  32406. ConvertProgram;
  32407. end;
  32408. procedure TTestModule.TestAWait_ExternalClassPromise;
  32409. begin
  32410. StartProgram(false);
  32411. Add([
  32412. '{$modeswitch externalclass}',
  32413. 'type',
  32414. ' TJSPromise = class external name ''Promise''',
  32415. ' end;',
  32416. ' TJSThenable = class external name ''Thenable''',
  32417. ' end;',
  32418. 'function Fly(w: word): TJSPromise;',
  32419. 'begin',
  32420. 'end;',
  32421. 'function Jump(w: word): word; async;',
  32422. 'begin',
  32423. 'end;',
  32424. 'function Eat(w: word): TJSPromise; async;',
  32425. 'begin',
  32426. 'end;',
  32427. 'function Run(d: double): word; async;',
  32428. 'var',
  32429. ' p: TJSPromise;',
  32430. 'begin',
  32431. ' Result:=await(word,p);', // promise needs type
  32432. ' Result:=await(word,Fly(3));', // promise needs type
  32433. ' Result:=await(Jump(4));', // async non promise must omit the type
  32434. ' Result:=await(word,Jump(5));', // async call can provide fitting type
  32435. ' Result:=await(word,Eat(6));', // promise needs type
  32436. 'end;',
  32437. 'begin',
  32438. '']);
  32439. ConvertProgram;
  32440. CheckSource('TestAWait_ExternalClassPromise',
  32441. LinesToStr([ // statements
  32442. 'this.Fly = function (w) {',
  32443. ' var Result = null;',
  32444. ' return Result;',
  32445. '};',
  32446. 'this.Jump = async function (w) {',
  32447. ' var Result = 0;',
  32448. ' return Result;',
  32449. '};',
  32450. 'this.Eat = async function (w) {',
  32451. ' var Result = null;',
  32452. ' return Result;',
  32453. '};',
  32454. 'this.Run = async function (d) {',
  32455. ' var Result = 0;',
  32456. ' var p = null;',
  32457. ' Result = await p;',
  32458. ' Result = await $mod.Fly(3);',
  32459. ' Result = await $mod.Jump(4);',
  32460. ' Result = await $mod.Jump(5);',
  32461. ' Result = await $mod.Eat(6);',
  32462. ' return Result;',
  32463. '};',
  32464. '']),
  32465. LinesToStr([
  32466. ]));
  32467. CheckResolverUnexpectedHints();
  32468. end;
  32469. procedure TTestModule.TestAWait_JSValue;
  32470. begin
  32471. StartProgram(false);
  32472. Add([
  32473. '{$modeswitch externalclass}',
  32474. 'type',
  32475. ' TJSPromise = class external name ''Promise''',
  32476. ' end;',
  32477. 'function Fly(w: word): jsvalue; async;',
  32478. 'begin',
  32479. 'end;',
  32480. 'function Run(d: jsvalue; var e): word; async;',
  32481. 'begin',
  32482. ' Result:=await(word,d);', // promise needs type
  32483. ' d:=await(Fly(4));', // async non promise must omit the type
  32484. ' Result:=await(word,e);', // promise needs type
  32485. 'end;',
  32486. 'begin',
  32487. '']);
  32488. ConvertProgram;
  32489. CheckSource('TestAWait_JSValue',
  32490. LinesToStr([ // statements
  32491. 'this.Fly = async function (w) {',
  32492. ' var Result = undefined;',
  32493. ' return Result;',
  32494. '};',
  32495. 'this.Run = async function (d, e) {',
  32496. ' var Result = 0;',
  32497. ' Result = await d;',
  32498. ' d = await $mod.Fly(4);',
  32499. ' Result = await e.get();',
  32500. ' return Result;',
  32501. '};',
  32502. '']),
  32503. LinesToStr([
  32504. ]));
  32505. CheckResolverUnexpectedHints();
  32506. end;
  32507. procedure TTestModule.TestAWait_Result;
  32508. begin
  32509. StartProgram(false);
  32510. Add([
  32511. '{$modeswitch externalclass}',
  32512. 'type',
  32513. ' TJSPromise = class external name ''Promise''',
  32514. ' end;',
  32515. 'function Crawl(d: double = 1.3): TJSPromise; ',
  32516. 'begin',
  32517. 'end;',
  32518. 'function Run(d: double = 1.6): word; async;',
  32519. 'begin',
  32520. ' Result:=await(word,Crawl);',
  32521. ' Result:=await(word,Crawl(4.5));',
  32522. ' Result:=await(Run);',
  32523. ' Result:=await(Run(6.7));',
  32524. 'end;',
  32525. 'begin',
  32526. ' Run(1);']);
  32527. ConvertProgram;
  32528. CheckSource('TestAWait_Result',
  32529. LinesToStr([ // statements
  32530. 'this.Crawl = function (d) {',
  32531. ' var Result = null;',
  32532. ' return Result;',
  32533. '};',
  32534. 'this.Run = async function (d) {',
  32535. ' var Result = 0;',
  32536. ' Result = await $mod.Crawl(1.3);',
  32537. ' Result = await $mod.Crawl(4.5);',
  32538. ' Result = await $mod.Run(1.6);',
  32539. ' Result = await $mod.Run(6.7);',
  32540. ' return Result;',
  32541. '};',
  32542. '']),
  32543. LinesToStr([
  32544. '$mod.Run(1);'
  32545. ]));
  32546. CheckResolverUnexpectedHints();
  32547. end;
  32548. procedure TTestModule.TestAWait_ResultPromiseMissingTypeFail;
  32549. begin
  32550. StartProgram(false);
  32551. Add([
  32552. '{$mode objfpc}',
  32553. '{$modeswitch externalclass}',
  32554. 'type',
  32555. ' TJSPromise = class external name ''Promise''',
  32556. ' end;',
  32557. 'function Run: TJSPromise; async;',
  32558. 'begin',
  32559. 'end;',
  32560. 'procedure Fly(w: word); async;',
  32561. 'begin',
  32562. ' await(Run());',
  32563. 'end;',
  32564. 'begin',
  32565. ' Fly(1);']);
  32566. SetExpectedPasResolverError('Wrong number of parameters specified for call to "function await(aType,TJSPromise):aType"',
  32567. nWrongNumberOfParametersForCallTo);
  32568. ConvertProgram;
  32569. end;
  32570. procedure TTestModule.TestAsync_AnonymousProc;
  32571. begin
  32572. StartProgram(false);
  32573. Add([
  32574. '{$mode objfpc}',
  32575. '{$modeswitch externalclass}',
  32576. 'type',
  32577. ' TJSPromise = class external name ''Promise''',
  32578. ' end;',
  32579. 'type',
  32580. ' TFunc = reference to function(x: double): word; async;',
  32581. 'function Crawl(d: double = 1.3): word; async;',
  32582. 'begin',
  32583. 'end;',
  32584. 'var Func: TFunc;',
  32585. 'begin',
  32586. ' Func:=function(c:double):word async begin',
  32587. ' Result:=await(Crawl(c));',
  32588. ' end;',
  32589. ' Func:=function(c:double):word async assembler asm',
  32590. ' end;',
  32591. ' ']);
  32592. ConvertProgram;
  32593. CheckSource('TestAsync_AnonymousProc',
  32594. LinesToStr([ // statements
  32595. 'this.Crawl = async function (d) {',
  32596. ' var Result = 0;',
  32597. ' return Result;',
  32598. '};',
  32599. 'this.Func = null;',
  32600. '']),
  32601. LinesToStr([
  32602. '$mod.Func = async function (c) {',
  32603. ' var Result = 0;',
  32604. ' Result = await $mod.Crawl(c);',
  32605. ' return Result;',
  32606. '};',
  32607. '$mod.Func = async function (c) {',
  32608. '};',
  32609. '']));
  32610. CheckResolverUnexpectedHints();
  32611. end;
  32612. procedure TTestModule.TestAsync_ProcType;
  32613. begin
  32614. StartProgram(false);
  32615. Add([
  32616. '{$mode objfpc}',
  32617. 'type',
  32618. ' TRefFunc = reference to function(x: double = 1.3): word; async;',
  32619. ' TFunc = function(x: double = 1.1): word; async;',
  32620. ' TProc = procedure(x: longint = 7); async;',
  32621. 'function Crawl(d: double): word; async;',
  32622. 'begin',
  32623. 'end;',
  32624. 'procedure Run(e:longint); async;',
  32625. 'begin',
  32626. 'end;',
  32627. 'procedure Fly(p: TProc); async;',
  32628. 'begin',
  32629. ' await(p);',
  32630. ' await(p());',
  32631. 'end;',
  32632. 'var',
  32633. ' RefFunc: TRefFunc;',
  32634. ' Func: TFunc;',
  32635. ' Proc, ProcB: TProc;',
  32636. 'begin',
  32637. ' Func:=@Crawl;',
  32638. ' RefFunc:=@Crawl;',
  32639. ' RefFunc:=function(c:double):word async begin',
  32640. ' Result:=await(RefFunc);',
  32641. ' Result:=await(RefFunc());',
  32642. ' Result:=await(Func);',
  32643. ' Result:=await(Func());',
  32644. ' await(Proc);',
  32645. ' await(Proc());',
  32646. ' await(Proc(13));',
  32647. ' end;',
  32648. ' Proc:=@Run;',
  32649. ' if Proc=ProcB then ;',
  32650. ' ']);
  32651. ConvertProgram;
  32652. CheckResolverUnexpectedHints();
  32653. CheckSource('TestAsync_ProcType',
  32654. LinesToStr([ // statements
  32655. 'this.Crawl = async function (d) {',
  32656. ' var Result = 0;',
  32657. ' return Result;',
  32658. '};',
  32659. 'this.Run = async function (e) {',
  32660. '};',
  32661. 'this.Fly = async function (p) {',
  32662. ' await p(7);',
  32663. ' await p(7);',
  32664. '};',
  32665. 'this.RefFunc = null;',
  32666. 'this.Func = null;',
  32667. 'this.Proc = null;',
  32668. 'this.ProcB = null;',
  32669. '']),
  32670. LinesToStr([
  32671. '$mod.Func = $mod.Crawl;',
  32672. '$mod.RefFunc = $mod.Crawl;',
  32673. '$mod.RefFunc = async function (c) {',
  32674. ' var Result = 0;',
  32675. ' Result = await $mod.RefFunc(1.3);',
  32676. ' Result = await $mod.RefFunc(1.3);',
  32677. ' Result = await $mod.Func(1.1);',
  32678. ' Result = await $mod.Func(1.1);',
  32679. ' await $mod.Proc(7);',
  32680. ' await $mod.Proc(7);',
  32681. ' await $mod.Proc(13);',
  32682. ' return Result;',
  32683. '};',
  32684. '$mod.Proc = $mod.Run;',
  32685. 'if (rtl.eqCallback($mod.Proc, $mod.ProcB)) ;',
  32686. '']));
  32687. end;
  32688. procedure TTestModule.TestAsync_ProcTypeAsyncModMismatchFail;
  32689. begin
  32690. StartProgram(false);
  32691. Add([
  32692. '{$mode objfpc}',
  32693. 'type',
  32694. ' TRefFunc = reference to function(x: double = 1.3): word;',
  32695. 'function Crawl(d: double): word; async;',
  32696. 'begin',
  32697. 'end;',
  32698. 'var',
  32699. ' RefFunc: TRefFunc;',
  32700. 'begin',
  32701. ' RefFunc:=@Crawl;',
  32702. ' ']);
  32703. SetExpectedPasResolverError('procedure type modifier "async" mismatch',nXModifierMismatchY);
  32704. ConvertProgram;
  32705. end;
  32706. procedure TTestModule.TestAsync_Inherited;
  32707. begin
  32708. StartProgram(false);
  32709. Add([
  32710. '{$mode objfpc}',
  32711. '{$modeswitch externalclass}',
  32712. 'type',
  32713. ' TJSPromise = class external name ''Promise''',
  32714. ' end;',
  32715. ' TObject = class',
  32716. ' function Run(w: word = 3): word; async; virtual;',
  32717. ' end;',
  32718. ' TBird = class',
  32719. ' function Run(w: word = 3): word; async; override;',
  32720. ' end;',
  32721. 'function TObject.Run(w: word = 3): word; async;',
  32722. 'begin',
  32723. 'end;',
  32724. 'function TBird.Run(w: word = 3): word;', // async modifier not needed in impl
  32725. 'var p: TJSPromise;',
  32726. 'begin',
  32727. ' p:=inherited;',
  32728. ' p:=inherited Run;',
  32729. ' p:=inherited Run();',
  32730. ' p:=inherited Run(4);',
  32731. ' exit(p);',
  32732. ' exit(inherited);',
  32733. ' exit(inherited Run);',
  32734. ' exit(inherited Run(5));',
  32735. ' exit(6);',
  32736. 'end;',
  32737. 'begin',
  32738. ' ']);
  32739. ConvertProgram;
  32740. CheckSource('TestAsync_Inherited',
  32741. LinesToStr([ // statements
  32742. 'rtl.createClass(this, "TObject", null, function () {',
  32743. ' this.$init = function () {',
  32744. ' };',
  32745. ' this.$final = function () {',
  32746. ' };',
  32747. ' this.Run = async function (w) {',
  32748. ' var Result = 0;',
  32749. ' return Result;',
  32750. ' };',
  32751. '});',
  32752. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  32753. ' this.Run = async function (w) {',
  32754. ' var Result = 0;',
  32755. ' var p = null;',
  32756. ' p = $mod.TObject.Run.apply(this, arguments);',
  32757. ' p = $mod.TObject.Run.call(this, 3);',
  32758. ' p = $mod.TObject.Run.call(this, 3);',
  32759. ' p = $mod.TObject.Run.call(this, 4);',
  32760. ' return p;',
  32761. ' return $mod.TObject.Run.apply(this, arguments);',
  32762. ' return $mod.TObject.Run.call(this, 3);',
  32763. ' return $mod.TObject.Run.call(this, 5);',
  32764. ' return 6;',
  32765. ' return Result;',
  32766. ' };',
  32767. '});',
  32768. '']),
  32769. LinesToStr([
  32770. '']));
  32771. CheckResolverUnexpectedHints();
  32772. end;
  32773. procedure TTestModule.TestAsync_ClassInterface;
  32774. begin
  32775. StartProgram(false);
  32776. Add([
  32777. '{$mode objfpc}',
  32778. '{$modeswitch externalclass}',
  32779. 'type',
  32780. ' TJSPromise = class external name ''Promise''',
  32781. ' end;',
  32782. ' IUnknown = interface',
  32783. ' function _AddRef: longint;',
  32784. ' function _Release: longint;',
  32785. ' end;',
  32786. 'function Say(i: IUnknown): IUnknown; async;',
  32787. 'begin',
  32788. 'end;',
  32789. 'function Run: IUnknown; async;',
  32790. 'begin',
  32791. ' Result:=await(Run);',
  32792. ' Result:=await(Run());',
  32793. ' Result:=await(Run) as IUnknown;',
  32794. ' Result:=await(Say(nil));',
  32795. ' Result:=await(Say(await(Run())));',
  32796. ' Result:=await(Say(await(Run()) as IUnknown));',
  32797. ' Result:=await(Say(await(Run()) as IUnknown)) as IUnknown;',
  32798. 'end;',
  32799. 'procedure Fly;',
  32800. 'var p: TJSPromise;',
  32801. 'begin',
  32802. ' Run;',
  32803. ' Run();',
  32804. ' p:=Run;',
  32805. ' p:=Run();',
  32806. 'end;',
  32807. 'begin',
  32808. ' ']);
  32809. ConvertProgram;
  32810. CheckSource('TestAsync_ClassInterface',
  32811. LinesToStr([ // statements
  32812. 'rtl.createInterface(this, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  32813. 'this.Say = async function (i) {',
  32814. ' var Result = null;',
  32815. ' return Result;',
  32816. '};',
  32817. 'this.Run = async function () {',
  32818. ' var Result = null;',
  32819. ' var $ok = false;',
  32820. ' try {',
  32821. ' Result = rtl.setIntfL(Result, await $mod.Run());',
  32822. ' Result = rtl.setIntfL(Result, await $mod.Run());',
  32823. ' Result = rtl.setIntfL(Result, rtl.intfAsIntfT(await $mod.Run(), $mod.IUnknown));',
  32824. ' Result = rtl.setIntfL(Result, await $mod.Say(null));',
  32825. ' Result = rtl.setIntfL(Result, await $mod.Say(await $mod.Run()));',
  32826. ' Result = rtl.setIntfL(Result, await $mod.Say(rtl.intfAsIntfT(await $mod.Run(), $mod.IUnknown)));',
  32827. ' Result = rtl.setIntfL(Result, rtl.intfAsIntfT(await $mod.Say(rtl.intfAsIntfT(await $mod.Run(), $mod.IUnknown)), $mod.IUnknown));',
  32828. ' $ok = true;',
  32829. ' } finally {',
  32830. ' if (!$ok) rtl._Release(Result);',
  32831. ' };',
  32832. ' return Result;',
  32833. '};',
  32834. 'this.Fly = function () {',
  32835. ' var p = null;',
  32836. ' $mod.Run();',
  32837. ' $mod.Run();',
  32838. ' p = $mod.Run();',
  32839. ' p = $mod.Run();',
  32840. '};',
  32841. '']),
  32842. LinesToStr([
  32843. '']));
  32844. CheckResolverUnexpectedHints();
  32845. end;
  32846. procedure TTestModule.TestAsync_ClassInterface_AsyncMissmatchFail;
  32847. begin
  32848. StartProgram(true,[supTInterfacedObject]);
  32849. Add([
  32850. '{$mode objfpc}',
  32851. '{$modeswitch externalclass}',
  32852. 'type',
  32853. ' TJSPromise = class external name ''Promise''',
  32854. ' end;',
  32855. ' IBird = interface',
  32856. ' procedure Run;',
  32857. ' end;',
  32858. ' TBird = class(TInterfacedObject,IBird)',
  32859. ' procedure Run; async;',
  32860. ' end;',
  32861. 'procedure TBird.Run;',
  32862. 'begin',
  32863. 'end;',
  32864. 'begin',
  32865. ' ']);
  32866. SetExpectedPasResolverError('procedure type modifier "async" mismatch',nXModifierMismatchY);
  32867. ConvertProgram;
  32868. end;
  32869. procedure TTestModule.TestLibrary_Empty;
  32870. begin
  32871. StartLibrary(false);
  32872. Add([
  32873. '']);
  32874. ConvertLibrary;
  32875. CheckSource('TestLibrary_Empty',
  32876. LinesToStr([ // statements
  32877. '']),
  32878. LinesToStr([
  32879. '']));
  32880. CheckResolverUnexpectedHints();
  32881. end;
  32882. procedure TTestModule.TestLibrary_ExportFunc;
  32883. begin
  32884. exit;
  32885. StartLibrary(false);
  32886. Add([
  32887. 'procedure Run(w: word);',
  32888. 'begin',
  32889. 'end;',
  32890. 'exports',
  32891. ' Run,',
  32892. ' run name ''Foo'';',
  32893. '']);
  32894. ConvertLibrary;
  32895. CheckSource('TestLibrary_ExportFunc',
  32896. LinesToStr([ // statements
  32897. '']),
  32898. LinesToStr([
  32899. '']));
  32900. CheckResolverUnexpectedHints();
  32901. end;
  32902. Initialization
  32903. RegisterTests([TTestModule]);
  32904. end.