tcmodules.pas 798 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149
  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 = [coNoTypeInfo];
  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. );
  46. TSystemUnitParts = set of TSystemUnitPart;
  47. { TTestHintMessage }
  48. TTestHintMessage = class
  49. public
  50. Id: int64;
  51. MsgType: TMessageType;
  52. MsgNumber: integer;
  53. Msg: string;
  54. SourcePos: TPasSourcePos;
  55. end;
  56. { TTestPasParser }
  57. TTestPasParser = Class(TPasParser)
  58. end;
  59. TOnFindUnit = function(const aUnitName: String): TPasModule of object;
  60. { TTestEnginePasResolver }
  61. TTestEnginePasResolver = class(TPas2JsResolver)
  62. private
  63. FFilename: string;
  64. FModule: TPasModule;
  65. FOnFindUnit: TOnFindUnit;
  66. FParser: TTestPasParser;
  67. FStreamResolver: TStreamResolver;
  68. FScanner: TPas2jsPasScanner;
  69. FSource: string;
  70. public
  71. destructor Destroy; override;
  72. function FindUnit(const AName, InFilename: String; NameExpr,
  73. InFileExpr: TPasExpr): TPasModule; override;
  74. procedure UsedInterfacesFinished(Section: TPasSection); override;
  75. property OnFindUnit: TOnFindUnit read FOnFindUnit write FOnFindUnit;
  76. property Filename: string read FFilename write FFilename;
  77. property StreamResolver: TStreamResolver read FStreamResolver write FStreamResolver;
  78. property Scanner: TPas2jsPasScanner read FScanner write FScanner;
  79. property Parser: TTestPasParser read FParser write FParser;
  80. property Source: string read FSource write FSource;
  81. property Module: TPasModule read FModule;
  82. end;
  83. { TCustomTestModule }
  84. TCustomTestModule = Class(TTestCase)
  85. private
  86. FConverter: TPasToJSConverter;
  87. FEngine: TTestEnginePasResolver;
  88. FExpectedErrorClass: ExceptClass;
  89. FExpectedErrorMsg: string;
  90. FExpectedErrorNumber: integer;
  91. FFilename: string;
  92. FFileResolver: TStreamResolver;
  93. FJSImplementationSrc: TJSSourceElements;
  94. FJSImplementationUses: TJSArrayLiteral;
  95. FJSInitBody: TJSFunctionBody;
  96. FJSImplentationUses: TJSArrayLiteral;
  97. FJSInterfaceUses: TJSArrayLiteral;
  98. FJSModule: TJSSourceElements;
  99. FJSModuleSrc: TJSSourceElements;
  100. FJSSource: TStringList;
  101. FModule: TPasModule;
  102. FJSModuleCallArgs: TJSArguments;
  103. FModules: TObjectList;// list of TTestEnginePasResolver
  104. FParser: TTestPasParser;
  105. FPasProgram: TPasProgram;
  106. FHintMsgs: TObjectList; // list of TTestHintMessage
  107. FHintMsgsGood: TFPList; // list of TTestHintMessage marked as expected
  108. FJSRegModuleCall: TJSCallExpression;
  109. FScanner: TPas2jsPasScanner;
  110. FSkipTests: boolean;
  111. FSource: TStringList;
  112. FFirstPasStatement: TPasImplBlock;
  113. {$IFDEF EnablePasTreeGlobalRefCount}
  114. FElementRefCountAtSetup: int64;
  115. {$ENDIF}
  116. function GetMsgCount: integer;
  117. function GetMsgs(Index: integer): TTestHintMessage;
  118. function GetResolverCount: integer;
  119. function GetResolvers(Index: integer): TTestEnginePasResolver;
  120. function OnPasResolverFindUnit(const aUnitName: String): TPasModule;
  121. procedure OnParserLog(Sender: TObject; const Msg: String);
  122. procedure OnPasResolverLog(Sender: TObject; const Msg: String);
  123. procedure OnScannerLog(Sender: TObject; const Msg: String);
  124. protected
  125. procedure SetUp; override;
  126. function CreateConverter: TPasToJSConverter; virtual;
  127. function LoadUnit(const aUnitName: String): TPasModule;
  128. procedure InitScanner(aScanner: TPas2jsPasScanner); virtual;
  129. procedure TearDown; override;
  130. Procedure Add(Line: string); virtual;
  131. Procedure Add(const Lines: array of string);
  132. Procedure StartParsing; virtual;
  133. procedure ParseModuleQueue; virtual;
  134. procedure ParseModule; virtual;
  135. procedure ParseProgram; virtual;
  136. procedure ParseUnit; virtual;
  137. protected
  138. function FindModuleWithFilename(aFilename: string): TTestEnginePasResolver; virtual;
  139. function AddModule(aFilename: string): TTestEnginePasResolver; virtual;
  140. function AddModuleWithSrc(aFilename, Src: string): TTestEnginePasResolver; virtual;
  141. function AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  142. ImplementationSrc: string): TTestEnginePasResolver; virtual;
  143. procedure AddSystemUnit(Parts: TSystemUnitParts = []); virtual;
  144. procedure StartProgram(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []); virtual;
  145. procedure StartUnit(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []); virtual;
  146. procedure ConvertModule; virtual;
  147. procedure ConvertProgram; virtual;
  148. procedure ConvertUnit; virtual;
  149. function ConvertJSModuleToString(El: TJSElement): string; virtual;
  150. procedure CheckDottedIdentifier(Msg: string; El: TJSElement; DottedName: string);
  151. function GetDottedIdentifier(El: TJSElement): string;
  152. procedure CheckSource(Msg,Statements: String; InitStatements: string = '';
  153. ImplStatements: string = ''); virtual;
  154. procedure CheckDiff(Msg, Expected, Actual: string); virtual;
  155. procedure CheckUnit(Filename, ExpectedSrc: string); virtual;
  156. procedure CheckHint(MsgType: TMessageType; MsgNumber: integer;
  157. Msg: string; Marker: PSrcMarker = nil); virtual;
  158. procedure CheckResolverUnexpectedHints(WithSourcePos: boolean = false); virtual;
  159. procedure SetExpectedScannerError(Msg: string; MsgNumber: integer);
  160. procedure SetExpectedParserError(Msg: string; MsgNumber: integer);
  161. procedure SetExpectedPasResolverError(Msg: string; MsgNumber: integer);
  162. procedure SetExpectedConverterError(Msg: string; MsgNumber: integer);
  163. function IsErrorExpected(E: Exception): boolean;
  164. procedure HandleScannerError(E: EScannerError);
  165. procedure HandleParserError(E: EParserError);
  166. procedure HandlePasResolveError(E: EPasResolve);
  167. procedure HandlePas2JSError(E: EPas2JS);
  168. procedure HandleException(E: Exception);
  169. procedure FailException(E: Exception);
  170. procedure WriteSources(const aFilename: string; aRow, aCol: integer);
  171. function IndexOfResolver(const Filename: string): integer;
  172. function GetResolver(const Filename: string): TTestEnginePasResolver;
  173. function GetDefaultNamespace: string;
  174. property PasProgram: TPasProgram Read FPasProgram;
  175. property Resolvers[Index: integer]: TTestEnginePasResolver read GetResolvers;
  176. property ResolverCount: integer read GetResolverCount;
  177. property Engine: TTestEnginePasResolver read FEngine;
  178. property Filename: string read FFilename;
  179. Property Module: TPasModule Read FModule;
  180. property FirstPasStatement: TPasImplBlock read FFirstPasStatement;
  181. property Converter: TPasToJSConverter read FConverter;
  182. property JSSource: TStringList read FJSSource;
  183. property JSModule: TJSSourceElements read FJSModule;
  184. property JSRegModuleCall: TJSCallExpression read FJSRegModuleCall;
  185. property JSModuleCallArgs: TJSArguments read FJSModuleCallArgs;
  186. property JSImplementationUses: TJSArrayLiteral read FJSImplementationUses;
  187. property JSInterfaceUses: TJSArrayLiteral read FJSInterfaceUses;
  188. property JSModuleSrc: TJSSourceElements read FJSModuleSrc;
  189. property JSInitBody: TJSFunctionBody read FJSInitBody;
  190. property JSImplementationSrc: TJSSourceElements read FJSImplementationSrc;
  191. property ExpectedErrorClass: ExceptClass read FExpectedErrorClass write FExpectedErrorClass;
  192. property ExpectedErrorMsg: string read FExpectedErrorMsg write FExpectedErrorMsg;
  193. property ExpectedErrorNumber: integer read FExpectedErrorNumber write FExpectedErrorNumber;
  194. property SkipTests: boolean read FSkipTests write FSkipTests;
  195. public
  196. constructor Create; override;
  197. destructor Destroy; override;
  198. property Source: TStringList read FSource;
  199. property FileResolver: TStreamResolver read FFileResolver;
  200. property Scanner: TPas2jsPasScanner read FScanner;
  201. property Parser: TTestPasParser read FParser;
  202. property MsgCount: integer read GetMsgCount;
  203. property Msgs[Index: integer]: TTestHintMessage read GetMsgs;
  204. end;
  205. { TTestModule }
  206. TTestModule = class(TCustomTestModule)
  207. Published
  208. Procedure TestReservedWords;
  209. // program/units
  210. Procedure TestEmptyProgram;
  211. Procedure TestEmptyProgramUseStrict;
  212. Procedure TestEmptyUnit;
  213. Procedure TestEmptyUnitUseStrict;
  214. Procedure TestDottedUnitNames;
  215. Procedure TestDottedUnitNameImpl;
  216. Procedure TestDottedUnitExpr;
  217. Procedure Test_ModeFPCFail;
  218. Procedure Test_ModeSwitchCBlocksFail;
  219. Procedure TestUnit_UseSystem;
  220. Procedure TestUnit_Intf1Impl2Intf1;
  221. Procedure TestIncludeVersion;
  222. // vars/const
  223. Procedure TestVarInt;
  224. Procedure TestVarBaseTypes;
  225. Procedure TestBaseTypeSingleFail;
  226. Procedure TestBaseTypeExtendedFail;
  227. Procedure TestConstBaseTypes;
  228. Procedure TestUnitImplVars;
  229. Procedure TestUnitImplConsts;
  230. Procedure TestUnitImplRecord;
  231. Procedure TestRenameJSNameConflict;
  232. Procedure TestLocalConst;
  233. Procedure TestVarExternal;
  234. Procedure TestVarExternalOtherUnit;
  235. Procedure TestVarAbsoluteFail;
  236. Procedure TestConstExternal;
  237. // numbers
  238. Procedure TestDouble;
  239. Procedure TestInteger;
  240. Procedure TestIntegerRange;
  241. Procedure TestIntegerTypecasts;
  242. Procedure TestInteger_BitwiseShrNativeInt;
  243. Procedure TestInteger_BitwiseShlNativeInt;
  244. Procedure TestCurrency;
  245. Procedure TestForBoolDo;
  246. Procedure TestForIntDo;
  247. Procedure TestForIntInDo;
  248. // strings
  249. Procedure TestCharConst;
  250. Procedure TestChar_Compare;
  251. Procedure TestChar_BuiltInProcs;
  252. Procedure TestStringConst;
  253. Procedure TestStringConstSurrogate;
  254. Procedure TestString_Length;
  255. Procedure TestString_Compare;
  256. Procedure TestString_SetLength;
  257. Procedure TestString_CharAt;
  258. Procedure TestStringHMinusFail;
  259. Procedure TestStr;
  260. Procedure TestBaseType_AnsiStringFail;
  261. Procedure TestBaseType_WideStringFail;
  262. Procedure TestBaseType_ShortStringFail;
  263. Procedure TestBaseType_RawByteStringFail;
  264. Procedure TestTypeShortstring_Fail;
  265. Procedure TestCharSet_Custom;
  266. Procedure TestForCharDo;
  267. Procedure TestForCharInDo;
  268. // alias types
  269. Procedure TestAliasTypeRef;
  270. Procedure TestTypeCast_BaseTypes;
  271. Procedure TestTypeCast_AliasBaseTypes;
  272. // functions
  273. Procedure TestEmptyProc;
  274. Procedure TestProcOneParam;
  275. Procedure TestFunctionWithoutParams;
  276. Procedure TestProcedureWithoutParams;
  277. Procedure TestPrgProcVar;
  278. Procedure TestProcTwoArgs;
  279. Procedure TestProc_DefaultValue;
  280. Procedure TestUnitProcVar;
  281. Procedure TestImplProc;
  282. Procedure TestFunctionResult;
  283. Procedure TestNestedProc;
  284. Procedure TestNestedProc_ResultString;
  285. Procedure TestForwardProc;
  286. Procedure TestNestedForwardProc;
  287. Procedure TestAssignFunctionResult;
  288. Procedure TestFunctionResultInCondition;
  289. Procedure TestFunctionResultInForLoop;
  290. Procedure TestFunctionResultInTypeCast;
  291. Procedure TestExit;
  292. Procedure TestBreak;
  293. Procedure TestBreakAsVar;
  294. Procedure TestContinue;
  295. Procedure TestProc_External;
  296. Procedure TestProc_ExternalOtherUnit;
  297. Procedure TestProc_Asm;
  298. Procedure TestProc_Assembler;
  299. Procedure TestProc_VarParam;
  300. Procedure TestProc_VarParamString;
  301. Procedure TestProc_VarParamV;
  302. Procedure TestProc_Overload;
  303. Procedure TestProc_OverloadForward;
  304. Procedure TestProc_OverloadIntfImpl;
  305. Procedure TestProc_OverloadNested;
  306. Procedure TestProc_OverloadUnitCycle;
  307. Procedure TestProc_Varargs;
  308. Procedure TestProc_ConstOrder;
  309. Procedure TestProc_DuplicateConst;
  310. Procedure TestProc_LocalVarAbsolute;
  311. Procedure TestProc_LocalVarInit;
  312. Procedure TestProc_ReservedWords;
  313. // anonymous functions
  314. Procedure TestAnonymousProc_Assign_ObjFPC;
  315. Procedure TestAnonymousProc_Assign_Delphi;
  316. Procedure TestAnonymousProc_Arg;
  317. Procedure TestAnonymousProc_Typecast;
  318. Procedure TestAnonymousProc_With;
  319. Procedure TestAnonymousProc_ExceptOn;
  320. Procedure TestAnonymousProc_Nested;
  321. Procedure TestAnonymousProc_NestedAssignResult;
  322. Procedure TestAnonymousProc_Class;
  323. Procedure TestAnonymousProc_ForLoop;
  324. // enums, sets
  325. Procedure TestEnum_Name;
  326. Procedure TestEnum_Number;
  327. Procedure TestEnum_ConstFail;
  328. Procedure TestEnum_Functions;
  329. Procedure TestEnum_AsParams;
  330. Procedure TestEnumRange_Array;
  331. Procedure TestEnum_ForIn;
  332. Procedure TestEnum_ScopedNumber;
  333. Procedure TestEnum_InFunction;
  334. Procedure TestSet_Enum;
  335. Procedure TestSet_Operators;
  336. Procedure TestSet_Operator_In;
  337. Procedure TestSet_Functions;
  338. Procedure TestSet_PassAsArgClone;
  339. Procedure TestSet_AsParams;
  340. Procedure TestSet_Property;
  341. Procedure TestSet_EnumConst;
  342. Procedure TestSet_IntConst;
  343. Procedure TestSet_AnonymousEnumType;
  344. Procedure TestSet_AnonymousEnumTypeChar; // ToDo
  345. Procedure TestSet_ConstEnum;
  346. Procedure TestSet_ConstChar;
  347. Procedure TestSet_ConstInt;
  348. Procedure TestSet_InFunction;
  349. Procedure TestSet_ForIn;
  350. // statements
  351. Procedure TestNestBegin;
  352. Procedure TestIncDec;
  353. Procedure TestLoHiFpcMode;
  354. Procedure TestLoHiDelphiMode;
  355. Procedure TestAssignments;
  356. Procedure TestArithmeticOperators1;
  357. Procedure TestLogicalOperators;
  358. Procedure TestBitwiseOperators;
  359. Procedure TestFunctionInt;
  360. Procedure TestFunctionString;
  361. Procedure TestIfThen;
  362. Procedure TestForLoop;
  363. Procedure TestForLoopInsideFunction;
  364. Procedure TestForLoop_ReadVarAfter;
  365. Procedure TestForLoop_Nested;
  366. Procedure TestRepeatUntil;
  367. Procedure TestAsmBlock;
  368. Procedure TestAsmPas_Impl; // ToDo
  369. Procedure TestTryFinally;
  370. Procedure TestTryExcept;
  371. Procedure TestTryExcept_ReservedWords;
  372. Procedure TestIfThenRaiseElse;
  373. Procedure TestCaseOf;
  374. Procedure TestCaseOf_UseSwitch;
  375. Procedure TestCaseOfNoElse;
  376. Procedure TestCaseOfNoElse_UseSwitch;
  377. Procedure TestCaseOfRange;
  378. Procedure TestCaseOfString;
  379. Procedure TestCaseOfChar;
  380. Procedure TestCaseOfExternalClassConst;
  381. Procedure TestDebugger;
  382. // arrays
  383. Procedure TestArray_Dynamic;
  384. Procedure TestArray_Dynamic_Nil;
  385. Procedure TestArray_DynMultiDimensional;
  386. Procedure TestArray_StaticInt;
  387. Procedure TestArray_StaticBool;
  388. Procedure TestArray_StaticChar;
  389. Procedure TestArray_StaticMultiDim;
  390. Procedure TestArray_StaticInFunction;
  391. Procedure TestArrayOfRecord;
  392. Procedure TestArray_StaticRecord;
  393. Procedure TestArrayOfSet;
  394. Procedure TestArray_DynAsParam;
  395. Procedure TestArray_StaticAsParam;
  396. Procedure TestArrayElement_AsParams;
  397. Procedure TestArrayElementFromFuncResult_AsParams;
  398. Procedure TestArrayEnumTypeRange;
  399. Procedure TestArray_SetLengthOutArg;
  400. Procedure TestArray_SetLengthProperty;
  401. Procedure TestArray_SetLengthMultiDim;
  402. Procedure TestArray_OpenArrayOfString;
  403. Procedure TestArray_Concat;
  404. Procedure TestArray_Copy;
  405. Procedure TestArray_InsertDelete;
  406. Procedure TestArray_DynArrayConstObjFPC;
  407. Procedure TestArray_DynArrayConstDelphi;
  408. Procedure TestArray_ArrayLitAsParam;
  409. Procedure TestArray_ArrayLitMultiDimAsParam;
  410. Procedure TestArray_ArrayLitStaticAsParam;
  411. Procedure TestArray_ForInArrOfString;
  412. Procedure TestExternalClass_TypeCastArrayToExternalClass;
  413. Procedure TestExternalClass_TypeCastArrayFromExternalClass;
  414. Procedure TestArrayOfConst_TVarRec;
  415. Procedure TestArrayOfConst_PassBaseTypes;
  416. Procedure TestArrayOfConst_PassObj;
  417. // record
  418. Procedure TestRecord_Empty;
  419. Procedure TestRecord_Var;
  420. Procedure TestRecord_VarExternal;
  421. Procedure TestRecord_WithDo;
  422. Procedure TestRecord_Assign;
  423. Procedure TestRecord_AsParams;
  424. Procedure TestRecordElement_AsParams;
  425. Procedure TestRecordElementFromFuncResult_AsParams;
  426. Procedure TestRecordElementFromWith_AsParams;
  427. Procedure TestRecord_Equal;
  428. Procedure TestRecord_JSValue;
  429. Procedure TestRecord_VariantFail;
  430. Procedure TestRecord_FieldArray;
  431. Procedure TestRecord_Const;
  432. Procedure TestRecord_TypecastFail;
  433. Procedure TestRecord_InFunction;
  434. Procedure TestRecord_AnonymousFail;
  435. // ToDo: RTTI of local record
  436. // ToDo: pcu local record, name clash and rtti
  437. // advanced record
  438. Procedure TestAdvRecord_Function;
  439. Procedure TestAdvRecord_Property;
  440. Procedure TestAdvRecord_PropertyDefault;
  441. Procedure TestAdvRecord_Property_ClassMethod;
  442. Procedure TestAdvRecord_Const;
  443. Procedure TestAdvRecord_ExternalField;
  444. Procedure TestAdvRecord_SubRecord;
  445. Procedure TestAdvRecord_SubClass;
  446. Procedure TestAdvRecord_SubInterfaceFail;
  447. Procedure TestAdvRecord_Constructor;
  448. Procedure TestAdvRecord_ClassConstructor_Program;
  449. Procedure TestAdvRecord_ClassConstructor_Unit;
  450. // classes
  451. Procedure TestClass_TObjectDefaultConstructor;
  452. Procedure TestClass_TObjectConstructorWithParams;
  453. Procedure TestClass_TObjectConstructorWithDefaultParam;
  454. Procedure TestClass_Var;
  455. Procedure TestClass_Method;
  456. Procedure TestClass_Implementation;
  457. Procedure TestClass_Inheritance;
  458. Procedure TestClass_TypeAlias;
  459. Procedure TestClass_AbstractMethod;
  460. Procedure TestClass_CallInherited_ProcNoParams;
  461. Procedure TestClass_CallInherited_WithParams;
  462. Procedure TestClasS_CallInheritedConstructor;
  463. Procedure TestClass_ClassVar_Assign;
  464. Procedure TestClass_CallClassMethod;
  465. Procedure TestClass_Property;
  466. Procedure TestClass_Property_ClassMethod;
  467. Procedure TestClass_Property_Indexed;
  468. Procedure TestClass_Property_IndexSpec;
  469. Procedure TestClass_PropertyOfTypeArray;
  470. Procedure TestClass_PropertyDefault;
  471. Procedure TestClass_PropertyDefault2;
  472. Procedure TestClass_PropertyOverride;
  473. Procedure TestClass_PropertyIncVisibility;
  474. Procedure TestClass_Assigned;
  475. Procedure TestClass_WithClassDoCreate;
  476. Procedure TestClass_WithClassInstDoProperty;
  477. Procedure TestClass_WithClassInstDoPropertyWithParams;
  478. Procedure TestClass_WithClassInstDoFunc;
  479. Procedure TestClass_TypeCast;
  480. Procedure TestClass_TypeCastUntypedParam;
  481. Procedure TestClass_Overloads;
  482. Procedure TestClass_OverloadsAncestor;
  483. Procedure TestClass_OverloadConstructor;
  484. Procedure TestClass_OverloadDelphiOverride;
  485. Procedure TestClass_ReintroducedVar;
  486. Procedure TestClass_RaiseDescendant;
  487. Procedure TestClass_ExternalMethod;
  488. Procedure TestClass_ExternalVirtualNameMismatchFail;
  489. Procedure TestClass_ExternalOverrideFail;
  490. Procedure TestClass_ExternalVar;
  491. Procedure TestClass_Const;
  492. Procedure TestClass_LocalVarSelfFail;
  493. Procedure TestClass_ArgSelfFail;
  494. Procedure TestClass_NestedProcSelf;
  495. Procedure TestClass_NestedProcSelf2;
  496. Procedure TestClass_NestedProcClassSelf;
  497. Procedure TestClass_NestedProcCallInherited;
  498. Procedure TestClass_TObjectFree;
  499. Procedure TestClass_TObjectFree_VarArg;
  500. Procedure TestClass_TObjectFreeNewInstance;
  501. Procedure TestClass_TObjectFreeLowerCase;
  502. Procedure TestClass_TObjectFreeFunctionFail;
  503. Procedure TestClass_TObjectFreePropertyFail;
  504. Procedure TestClass_ForIn;
  505. Procedure TestClass_DispatchMessage;
  506. Procedure TestClass_Message_DuplicateIntFail;
  507. Procedure TestClass_DispatchMessage_WrongFieldNameFail;
  508. // class of
  509. Procedure TestClassOf_Create;
  510. Procedure TestClassOf_Call;
  511. Procedure TestClassOf_Assign;
  512. Procedure TestClassOf_Is;
  513. Procedure TestClassOf_Compare;
  514. Procedure TestClassOf_ClassVar;
  515. Procedure TestClassOf_ClassMethod;
  516. Procedure TestClassOf_ClassProperty;
  517. Procedure TestClassOf_ClassMethodSelf;
  518. Procedure TestClassOf_TypeCast;
  519. Procedure TestClassOf_ImplicitFunctionCall;
  520. Procedure TestClassOf_Const;
  521. // nested class
  522. Procedure TestNestedClass_Alias;
  523. Procedure TestNestedClass_Record;
  524. Procedure TestNestedClass_Class;
  525. // external class
  526. Procedure TestExternalClass_Var;
  527. Procedure TestExternalClass_Const;
  528. Procedure TestExternalClass_Dollar;
  529. Procedure TestExternalClass_DuplicateVarFail;
  530. Procedure TestExternalClass_Method;
  531. Procedure TestExternalClass_ClassMethod;
  532. Procedure TestExternalClass_FunctionResultInTypeCast;
  533. Procedure TestExternalClass_NonExternalOverride;
  534. Procedure TestExternalClass_OverloadHint;
  535. Procedure TestExternalClass_SameNamePublishedProperty;
  536. Procedure TestExternalClass_Property;
  537. Procedure TestExternalClass_PropertyDate;
  538. Procedure TestExternalClass_ClassProperty;
  539. Procedure TestExternalClass_ClassOf;
  540. Procedure TestExternalClass_ClassOtherUnit;
  541. Procedure TestExternalClass_Is;
  542. Procedure TestExternalClass_As;
  543. Procedure TestExternalClass_DestructorFail;
  544. Procedure TestExternalClass_New;
  545. Procedure TestExternalClass_ClassOf_New;
  546. Procedure TestExternalClass_FuncClassOf_New;
  547. Procedure TestExternalClass_New_PasClassFail;
  548. Procedure TestExternalClass_New_PasClassBracketsFail;
  549. Procedure TestExternalClass_LocalConstSameName;
  550. Procedure TestExternalClass_ReintroduceOverload;
  551. Procedure TestExternalClass_Inherited;
  552. Procedure TestExternalClass_PascalAncestorFail;
  553. Procedure TestExternalClass_NewInstance;
  554. Procedure TestExternalClass_NewInstance_NonVirtualFail;
  555. Procedure TestExternalClass_NewInstance_FirstParamNotString_Fail;
  556. Procedure TestExternalClass_NewInstance_SecondParamTyped_Fail;
  557. Procedure TestExternalClass_PascalProperty;
  558. Procedure TestExternalClass_TypeCastToRootClass;
  559. Procedure TestExternalClass_TypeCastToJSObject;
  560. Procedure TestExternalClass_TypeCastStringToExternalString;
  561. Procedure TestExternalClass_TypeCastToJSFunction;
  562. Procedure TestExternalClass_TypeCastDelphiUnrelated;
  563. Procedure TestExternalClass_CallClassFunctionOfInstanceFail;
  564. Procedure TestExternalClass_BracketAccessor;
  565. Procedure TestExternalClass_BracketAccessor_Call;
  566. Procedure TestExternalClass_BracketAccessor_2ParamsFail;
  567. Procedure TestExternalClass_BracketAccessor_ReadOnly;
  568. Procedure TestExternalClass_BracketAccessor_WriteOnly;
  569. Procedure TestExternalClass_BracketAccessor_MultiType;
  570. Procedure TestExternalClass_BracketAccessor_Index;
  571. Procedure TestExternalClass_ForInJSObject;
  572. Procedure TestExternalClass_ForInJSArray;
  573. Procedure TestExternalClass_IncompatibleArgDuplicateIdentifier;
  574. // class interfaces
  575. Procedure TestClassInterface_Corba;
  576. Procedure TestClassInterface_ProcExternalFail;
  577. Procedure TestClassInterface_Overloads;
  578. Procedure TestClassInterface_DuplicateGUIInIntfListFail;
  579. Procedure TestClassInterface_DuplicateGUIInAncestorFail;
  580. Procedure TestClassInterface_AncestorImpl;
  581. Procedure TestClassInterface_ImplReintroduce;
  582. Procedure TestClassInterface_MethodResolution;
  583. Procedure TestClassInterface_AncestorMoreInterfaces;
  584. Procedure TestClassInterface_MethodOverride;
  585. Procedure TestClassInterface_Corba_Delegation;
  586. Procedure TestClassInterface_Corba_DelegationStatic;
  587. Procedure TestClassInterface_Corba_Operators;
  588. Procedure TestClassInterface_Corba_Args;
  589. Procedure TestClassInterface_Corba_ForIn;
  590. Procedure TestClassInterface_COM_AssignVar;
  591. Procedure TestClassInterface_COM_AssignArg;
  592. Procedure TestClassInterface_COM_FunctionResult;
  593. Procedure TestClassInterface_COM_InheritedFuncResult;
  594. Procedure TestClassInterface_COM_IsAsTypeCasts;
  595. Procedure TestClassInterface_COM_PassAsArg;
  596. Procedure TestClassInterface_COM_PassToUntypedParam;
  597. Procedure TestClassInterface_COM_FunctionInExpr;
  598. Procedure TestClassInterface_COM_Property;
  599. Procedure TestClassInterface_COM_IntfProperty;
  600. Procedure TestClassInterface_COM_Delegation;
  601. Procedure TestClassInterface_COM_With;
  602. Procedure TestClassInterface_COM_ForIn;
  603. Procedure TestClassInterface_COM_ArrayOfIntfFail;
  604. Procedure TestClassInterface_COM_RecordIntfFail;
  605. Procedure TestClassInterface_COM_UnitInitialization;
  606. Procedure TestClassInterface_GUID;
  607. Procedure TestClassInterface_GUIDProperty;
  608. // helpers
  609. Procedure TestClassHelper_ClassVar;
  610. Procedure TestClassHelper_Method_AccessInstanceFields;
  611. Procedure TestClassHelper_Method_Call;
  612. Procedure TestClassHelper_Method_Nested_Call;
  613. Procedure TestClassHelper_ClassMethod_Call;
  614. Procedure TestClassHelper_ClassOf;
  615. Procedure TestClassHelper_MethodRefObjFPC;
  616. Procedure TestClassHelper_Constructor;
  617. Procedure TestClassHelper_InheritedObjFPC;
  618. Procedure TestClassHelper_Property;
  619. Procedure TestClassHelper_Property_Array;
  620. Procedure TestClassHelper_Property_Array_Default;
  621. Procedure TestClassHelper_Property_Array_DefaultDefault;
  622. Procedure TestClassHelper_ClassProperty;
  623. Procedure TestClassHelper_ClassPropertyStatic;
  624. Procedure TestClassHelper_ClassProperty_Array;
  625. Procedure TestClassHelper_ForIn;
  626. Procedure TestClassHelper_PassProperty;
  627. Procedure TestExtClassHelper_ClassVar;
  628. Procedure TestExtClassHelper_Method_Call;
  629. Procedure TestRecordHelper_ClassVar;
  630. Procedure TestRecordHelper_Method_Call;
  631. Procedure TestRecordHelper_Constructor;
  632. Procedure TestTypeHelper_ClassVar;
  633. Procedure TestTypeHelper_PassResultElement;
  634. Procedure TestTypeHelper_PassArgs;
  635. Procedure TestTypeHelper_PassVarConst;
  636. Procedure TestTypeHelper_PassFuncResult;
  637. Procedure TestTypeHelper_PassPropertyField;
  638. Procedure TestTypeHelper_PassPropertyGetter;
  639. Procedure TestTypeHelper_PassClassPropertyField;
  640. Procedure TestTypeHelper_PassClassPropertyGetterStatic;
  641. Procedure TestTypeHelper_PassClassPropertyGetterNonStatic;
  642. Procedure TestTypeHelper_Property;
  643. Procedure TestTypeHelper_Property_Array;
  644. Procedure TestTypeHelper_ClassProperty;
  645. Procedure TestTypeHelper_ClassProperty_Array;
  646. Procedure TestTypeHelper_ClassMethod;
  647. Procedure TestTypeHelper_ExtClassMethodFail;
  648. Procedure TestTypeHelper_Constructor;
  649. Procedure TestTypeHelper_Word;
  650. Procedure TestTypeHelper_Double;
  651. Procedure TestTypeHelper_StringChar;
  652. Procedure TestTypeHelper_Array;
  653. Procedure TestTypeHelper_EnumType;
  654. Procedure TestTypeHelper_SetType;
  655. Procedure TestTypeHelper_InterfaceType;
  656. // proc types
  657. Procedure TestProcType;
  658. Procedure TestProcType_Arg;
  659. Procedure TestProcType_FunctionFPC;
  660. Procedure TestProcType_FunctionDelphi;
  661. Procedure TestProcType_ProcedureDelphi;
  662. Procedure TestProcType_AsParam;
  663. Procedure TestProcType_MethodFPC;
  664. Procedure TestProcType_MethodDelphi;
  665. Procedure TestProcType_PropertyFPC;
  666. Procedure TestProcType_PropertyDelphi;
  667. Procedure TestProcType_WithClassInstDoPropertyFPC;
  668. Procedure TestProcType_Nested;
  669. Procedure TestProcType_NestedOfObject;
  670. Procedure TestProcType_ReferenceToProc;
  671. Procedure TestProcType_ReferenceToMethod;
  672. Procedure TestProcType_Typecast;
  673. Procedure TestProcType_PassProcToUntyped;
  674. Procedure TestProcType_PassProcToArray;
  675. // pointer
  676. Procedure TestPointer;
  677. Procedure TestPointer_Proc;
  678. Procedure TestPointer_AssignRecordFail;
  679. Procedure TestPointer_AssignStaticArrayFail;
  680. Procedure TestPointer_TypeCastJSValueToPointer;
  681. Procedure TestPointer_NonRecordFail;
  682. Procedure TestPointer_AnonymousArgTypeFail;
  683. Procedure TestPointer_AnonymousVarTypeFail;
  684. Procedure TestPointer_AnonymousResultTypeFail;
  685. Procedure TestPointer_AddrOperatorFail;
  686. Procedure TestPointer_ArrayParamsFail;
  687. Procedure TestPointer_PointerAddFail;
  688. Procedure TestPointer_IncPointerFail;
  689. Procedure TestPointer_Record;
  690. Procedure TestPointer_RecordArg;
  691. // jsvalue
  692. Procedure TestJSValue_AssignToJSValue;
  693. Procedure TestJSValue_TypeCastToBaseType;
  694. Procedure TestJSValue_TypecastToJSValue;
  695. Procedure TestJSValue_Equal;
  696. Procedure TestJSValue_If;
  697. Procedure TestJSValue_Not;
  698. Procedure TestJSValue_Enum;
  699. Procedure TestJSValue_ClassInstance;
  700. Procedure TestJSValue_ClassOf;
  701. Procedure TestJSValue_ArrayOfJSValue;
  702. Procedure TestJSValue_ArrayLit;
  703. Procedure TestJSValue_Params;
  704. Procedure TestJSValue_UntypedParam;
  705. Procedure TestJSValue_FuncResultType;
  706. Procedure TestJSValue_ProcType_Assign;
  707. Procedure TestJSValue_ProcType_Equal;
  708. Procedure TestJSValue_ProcType_Param;
  709. Procedure TestJSValue_AssignToPointerFail;
  710. Procedure TestJSValue_OverloadDouble;
  711. Procedure TestJSValue_OverloadNativeInt;
  712. Procedure TestJSValue_OverloadWord;
  713. Procedure TestJSValue_OverloadString;
  714. Procedure TestJSValue_OverloadChar;
  715. Procedure TestJSValue_OverloadPointer;
  716. Procedure TestJSValue_ForIn;
  717. // RTTI
  718. Procedure TestRTTI_IntRange;
  719. Procedure TestRTTI_Double;
  720. Procedure TestRTTI_ProcType;
  721. Procedure TestRTTI_ProcType_ArgFromOtherUnit;
  722. Procedure TestRTTI_EnumAndSetType;
  723. Procedure TestRTTI_EnumRange;
  724. Procedure TestRTTI_AnonymousEnumType;
  725. Procedure TestRTTI_StaticArray;
  726. Procedure TestRTTI_DynArray;
  727. Procedure TestRTTI_ArrayNestedAnonymous;
  728. Procedure TestRTTI_PublishedMethodOverloadFail;
  729. Procedure TestRTTI_PublishedMethodExternalFail;
  730. Procedure TestRTTI_PublishedClassPropertyFail;
  731. Procedure TestRTTI_PublishedClassFieldFail;
  732. Procedure TestRTTI_PublishedFieldExternalFail;
  733. Procedure TestRTTI_Class_Field;
  734. Procedure TestRTTI_Class_Method;
  735. Procedure TestRTTI_Class_MethodArgFlags;
  736. Procedure TestRTTI_Class_Property;
  737. Procedure TestRTTI_Class_PropertyParams;
  738. Procedure TestRTTI_Class_OtherUnit_TypeAlias;
  739. Procedure TestRTTI_Class_OmitRTTI;
  740. Procedure TestRTTI_IndexModifier;
  741. Procedure TestRTTI_StoredModifier;
  742. Procedure TestRTTI_DefaultValue;
  743. Procedure TestRTTI_DefaultValueSet;
  744. Procedure TestRTTI_DefaultValueRangeType;
  745. Procedure TestRTTI_DefaultValueInherit;
  746. Procedure TestRTTI_OverrideMethod;
  747. Procedure TestRTTI_OverloadProperty;
  748. // ToDo: array argument
  749. Procedure TestRTTI_ClassForward;
  750. Procedure TestRTTI_ClassOf;
  751. Procedure TestRTTI_Record;
  752. Procedure TestRTTI_RecordAnonymousArray;
  753. Procedure TestRTTI_LocalTypes;
  754. Procedure TestRTTI_TypeInfo_BaseTypes;
  755. Procedure TestRTTI_TypeInfo_Type_BaseTypes;
  756. Procedure TestRTTI_TypeInfo_LocalFail;
  757. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses1;
  758. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses2;
  759. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses3;
  760. Procedure TestRTTI_TypeInfo_FunctionClassType;
  761. Procedure TestRTTI_TypeInfo_MixedUnits_PointerAndClass;
  762. Procedure TestRTTI_Interface_Corba;
  763. Procedure TestRTTI_Interface_COM;
  764. Procedure TestRTTI_ClassHelper;
  765. // Resourcestring
  766. Procedure TestResourcestringProgram;
  767. Procedure TestResourcestringUnit;
  768. Procedure TestResourcestringImplementation;
  769. // Attributes
  770. Procedure TestAttributes_Members;
  771. Procedure TestAttributes_Types;
  772. Procedure TestAttributes_HelperConstructor_Fail;
  773. // Assertions, checks
  774. procedure TestAssert;
  775. procedure TestAssert_SysUtils;
  776. procedure TestObjectChecks;
  777. procedure TestOverflowChecks_Int;
  778. procedure TestRangeChecks_AssignInt;
  779. procedure TestRangeChecks_AssignIntRange;
  780. procedure TestRangeChecks_AssignEnum;
  781. procedure TestRangeChecks_AssignEnumRange;
  782. procedure TestRangeChecks_AssignChar;
  783. procedure TestRangeChecks_AssignCharRange;
  784. procedure TestRangeChecks_ArrayIndex;
  785. procedure TestRangeChecks_ArrayOfRecIndex;
  786. procedure TestRangeChecks_StringIndex;
  787. procedure TestRangeChecks_TypecastInt;
  788. procedure TestRangeChecks_TypeHelperInt;
  789. end;
  790. function LinesToStr(Args: array of const): string;
  791. function ExtractFileUnitName(aFilename: string): string;
  792. function JSToStr(El: TJSElement): string;
  793. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  794. implementation
  795. function LinesToStr(Args: array of const): string;
  796. var
  797. s: String;
  798. i: Integer;
  799. begin
  800. s:='';
  801. for i:=Low(Args) to High(Args) do
  802. case Args[i].VType of
  803. vtChar: s += Args[i].VChar+LineEnding;
  804. vtString: s += Args[i].VString^+LineEnding;
  805. vtPChar: s += Args[i].VPChar+LineEnding;
  806. vtWideChar: s += AnsiString(Args[i].VWideChar)+LineEnding;
  807. vtPWideChar: s += AnsiString(Args[i].VPWideChar)+LineEnding;
  808. vtAnsiString: s += AnsiString(Args[i].VAnsiString)+LineEnding;
  809. vtWidestring: s += AnsiString(WideString(Args[i].VWideString))+LineEnding;
  810. vtUnicodeString:s += AnsiString(UnicodeString(Args[i].VUnicodeString))+LineEnding;
  811. end;
  812. Result:=s;
  813. end;
  814. function ExtractFileUnitName(aFilename: string): string;
  815. var
  816. p: Integer;
  817. begin
  818. Result:=ExtractFileName(aFilename);
  819. if Result='' then exit;
  820. for p:=length(Result) downto 1 do
  821. case Result[p] of
  822. '/','\': exit;
  823. '.':
  824. begin
  825. Delete(Result,p,length(Result));
  826. exit;
  827. end;
  828. end;
  829. end;
  830. function JSToStr(El: TJSElement): string;
  831. var
  832. aWriter: TBufferWriter;
  833. aJSWriter: TJSWriter;
  834. begin
  835. aJSWriter:=nil;
  836. aWriter:=TBufferWriter.Create(1000);
  837. try
  838. aJSWriter:=TJSWriter.Create(aWriter);
  839. aJSWriter.IndentSize:=2;
  840. aJSWriter.WriteJS(El);
  841. Result:=aWriter.AsString;
  842. finally
  843. aJSWriter.Free;
  844. aWriter.Free;
  845. end;
  846. end;
  847. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  848. // search diff, ignore changes in spaces
  849. const
  850. SpaceChars = [#9,#10,#13,' '];
  851. var
  852. ExpectedP, ActualP: PChar;
  853. function FindLineEnd(p: PChar): PChar;
  854. begin
  855. Result:=p;
  856. while not (Result^ in [#0,#10,#13]) do inc(Result);
  857. end;
  858. function FindLineStart(p, MinP: PChar): PChar;
  859. begin
  860. while (p>MinP) and not (p[-1] in [#10,#13]) do dec(p);
  861. Result:=p;
  862. end;
  863. procedure SkipLineEnd(var p: PChar);
  864. begin
  865. if p^ in [#10,#13] then
  866. begin
  867. if (p[1] in [#10,#13]) and (p^<>p[1]) then
  868. inc(p,2)
  869. else
  870. inc(p);
  871. end;
  872. end;
  873. procedure DiffFound;
  874. var
  875. ActLineStartP, ActLineEndP, p, StartPos: PChar;
  876. ExpLine, ActLine: String;
  877. i, LineNo, DiffLineNo: Integer;
  878. begin
  879. writeln('Diff found "',Msg,'". Lines:');
  880. // write correct lines
  881. p:=PChar(Expected);
  882. LineNo:=0;
  883. DiffLineNo:=0;
  884. repeat
  885. StartPos:=p;
  886. while not (p^ in [#0,#10,#13]) do inc(p);
  887. ExpLine:=copy(Expected,StartPos-PChar(Expected)+1,p-StartPos);
  888. SkipLineEnd(p);
  889. inc(LineNo);
  890. if (p<=ExpectedP) and (p^<>#0) then
  891. begin
  892. writeln('= ',ExpLine);
  893. end else begin
  894. // diff line
  895. if DiffLineNo=0 then DiffLineNo:=LineNo;
  896. // write actual line
  897. ActLineStartP:=FindLineStart(ActualP,PChar(Actual));
  898. ActLineEndP:=FindLineEnd(ActualP);
  899. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  900. writeln('- ',ActLine);
  901. // write expected line
  902. writeln('+ ',ExpLine);
  903. // write empty line with pointer ^
  904. for i:=1 to 2+ExpectedP-StartPos do write(' ');
  905. writeln('^');
  906. Msg:='expected "'+ExpLine+'", but got "'+ActLine+'".';
  907. CheckSrcDiff:=false;
  908. // write up to three following actual lines to get some context
  909. for i:=1 to 3 do begin
  910. ActLineStartP:=ActLineEndP;
  911. SkipLineEnd(ActLineStartP);
  912. if ActLineStartP^=#0 then break;
  913. ActLineEndP:=FindLineEnd(ActLineStartP);
  914. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  915. writeln('~ ',ActLine);
  916. end;
  917. exit;
  918. end;
  919. until p^=#0;
  920. writeln('DiffFound Actual:-----------------------');
  921. writeln(Actual);
  922. writeln('DiffFound Expected:---------------------');
  923. writeln(Expected);
  924. writeln('DiffFound ------------------------------');
  925. Msg:='diff found, but lines are the same, internal error';
  926. CheckSrcDiff:=false;
  927. end;
  928. var
  929. IsSpaceNeeded: Boolean;
  930. LastChar, Quote: Char;
  931. begin
  932. Result:=true;
  933. Msg:='';
  934. if Expected='' then Expected:=' ';
  935. if Actual='' then Actual:=' ';
  936. ExpectedP:=PChar(Expected);
  937. ActualP:=PChar(Actual);
  938. repeat
  939. //writeln('TTestModule.CheckDiff Exp="',ExpectedP^,'" Act="',ActualP^,'"');
  940. case ExpectedP^ of
  941. #0:
  942. begin
  943. // check that rest of Actual has only spaces
  944. while ActualP^ in SpaceChars do inc(ActualP);
  945. if ActualP^<>#0 then
  946. begin
  947. DiffFound;
  948. exit;
  949. end;
  950. exit(true);
  951. end;
  952. ' ',#9,#10,#13:
  953. begin
  954. // skip space in Expected
  955. IsSpaceNeeded:=false;
  956. if ExpectedP>PChar(Expected) then
  957. LastChar:=ExpectedP[-1]
  958. else
  959. LastChar:=#0;
  960. while ExpectedP^ in SpaceChars do inc(ExpectedP);
  961. if (LastChar in ['a'..'z','A'..'Z','0'..'9','_','$'])
  962. and (ExpectedP^ in ['a'..'z','A'..'Z','0'..'9','_','$']) then
  963. IsSpaceNeeded:=true;
  964. if IsSpaceNeeded and (not (ActualP^ in SpaceChars)) then
  965. begin
  966. DiffFound;
  967. exit;
  968. end;
  969. while ActualP^ in SpaceChars do inc(ActualP);
  970. end;
  971. '''','"':
  972. begin
  973. while ActualP^ in SpaceChars do inc(ActualP);
  974. if ExpectedP^<>ActualP^ then
  975. begin
  976. DiffFound;
  977. exit;
  978. end;
  979. Quote:=ExpectedP^;
  980. repeat
  981. inc(ExpectedP);
  982. inc(ActualP);
  983. if ExpectedP^<>ActualP^ then
  984. begin
  985. DiffFound;
  986. exit;
  987. end;
  988. if (ExpectedP^ in [#0,#10,#13]) then
  989. break
  990. else if (ExpectedP^=Quote) then
  991. begin
  992. inc(ExpectedP);
  993. inc(ActualP);
  994. break;
  995. end;
  996. until false;
  997. end;
  998. else
  999. while ActualP^ in SpaceChars do inc(ActualP);
  1000. if ExpectedP^<>ActualP^ then
  1001. begin
  1002. DiffFound;
  1003. exit;
  1004. end;
  1005. inc(ExpectedP);
  1006. inc(ActualP);
  1007. end;
  1008. until false;
  1009. end;
  1010. { TTestEnginePasResolver }
  1011. destructor TTestEnginePasResolver.Destroy;
  1012. begin
  1013. FreeAndNil(FStreamResolver);
  1014. FreeAndNil(FParser);
  1015. FreeAndNil(FScanner);
  1016. FreeAndNil(FStreamResolver);
  1017. if Module<>nil then
  1018. begin
  1019. Module.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
  1020. FModule:=nil;
  1021. end;
  1022. inherited Destroy;
  1023. end;
  1024. function TTestEnginePasResolver.FindUnit(const AName, InFilename: String;
  1025. NameExpr, InFileExpr: TPasExpr): TPasModule;
  1026. begin
  1027. Result:=nil;
  1028. if InFilename<>'' then
  1029. RaiseNotYetImplemented(20180224101926,InFileExpr,'Use testcase tcunitsearch instead');
  1030. if Assigned(OnFindUnit) then
  1031. Result:=OnFindUnit(AName);
  1032. if NameExpr=nil then ;
  1033. end;
  1034. procedure TTestEnginePasResolver.UsedInterfacesFinished(Section: TPasSection);
  1035. begin
  1036. // do not parse recursively
  1037. // parse via the queue
  1038. if Section=nil then ;
  1039. end;
  1040. { TCustomTestModule }
  1041. function TCustomTestModule.GetMsgCount: integer;
  1042. begin
  1043. Result:=FHintMsgs.Count;
  1044. end;
  1045. function TCustomTestModule.GetMsgs(Index: integer): TTestHintMessage;
  1046. begin
  1047. Result:=TTestHintMessage(FHintMsgs[Index]);
  1048. end;
  1049. function TCustomTestModule.GetResolverCount: integer;
  1050. begin
  1051. Result:=FModules.Count;
  1052. end;
  1053. function TCustomTestModule.GetResolvers(Index: integer
  1054. ): TTestEnginePasResolver;
  1055. begin
  1056. Result:=TTestEnginePasResolver(FModules[Index]);
  1057. end;
  1058. function TCustomTestModule.OnPasResolverFindUnit(const aUnitName: String
  1059. ): TPasModule;
  1060. var
  1061. DefNamespace: String;
  1062. begin
  1063. //writeln('TTestModule.OnPasResolverFindUnit START Unit="',aUnitName,'"');
  1064. if (Pos('.',aUnitName)<1) then
  1065. begin
  1066. DefNamespace:=GetDefaultNamespace;
  1067. if DefNamespace<>'' then
  1068. begin
  1069. Result:=LoadUnit(DefNamespace+'.'+aUnitName);
  1070. if Result<>nil then exit;
  1071. end;
  1072. end;
  1073. Result:=LoadUnit(aUnitName);
  1074. if Result<>nil then exit;
  1075. {$IFDEF VerbosePas2JS}
  1076. writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"');
  1077. {$ENDIF}
  1078. Fail('can''t find unit "'+aUnitName+'"');
  1079. end;
  1080. procedure TCustomTestModule.OnParserLog(Sender: TObject; const Msg: String);
  1081. var
  1082. aParser: TPasParser;
  1083. Item: TTestHintMessage;
  1084. begin
  1085. aParser:=Sender as TPasParser;
  1086. Item:=TTestHintMessage.Create;
  1087. Item.Id:=aParser.LastMsgNumber;
  1088. Item.MsgType:=aParser.LastMsgType;
  1089. Item.MsgNumber:=aParser.LastMsgNumber;
  1090. Item.Msg:=Msg;
  1091. Item.SourcePos:=aParser.Scanner.CurSourcePos;
  1092. {$IFDEF VerbosePas2JS}
  1093. writeln('TCustomTestModule.OnParserLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1094. {$ENDIF}
  1095. FHintMsgs.Add(Item);
  1096. end;
  1097. procedure TCustomTestModule.OnPasResolverLog(Sender: TObject; const Msg: String
  1098. );
  1099. var
  1100. aResolver: TTestEnginePasResolver;
  1101. Item: TTestHintMessage;
  1102. begin
  1103. aResolver:=Sender as TTestEnginePasResolver;
  1104. Item:=TTestHintMessage.Create;
  1105. Item.Id:=aResolver.LastMsgId;
  1106. Item.MsgType:=aResolver.LastMsgType;
  1107. Item.MsgNumber:=aResolver.LastMsgNumber;
  1108. Item.Msg:=Msg;
  1109. Item.SourcePos:=aResolver.LastSourcePos;
  1110. {$IFDEF VerbosePas2JS}
  1111. writeln('TCustomTestModule.OnPasResolverLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1112. {$ENDIF}
  1113. FHintMsgs.Add(Item);
  1114. end;
  1115. procedure TCustomTestModule.OnScannerLog(Sender: TObject; const Msg: String);
  1116. var
  1117. Item: TTestHintMessage;
  1118. aScanner: TPas2jsPasScanner;
  1119. begin
  1120. aScanner:=Sender as TPas2jsPasScanner;
  1121. Item:=TTestHintMessage.Create;
  1122. Item.Id:=aScanner.LastMsgNumber;
  1123. Item.MsgType:=aScanner.LastMsgType;
  1124. Item.MsgNumber:=aScanner.LastMsgNumber;
  1125. Item.Msg:=Msg;
  1126. Item.SourcePos:=aScanner.CurSourcePos;
  1127. {$IFDEF VerbosePas2JS}
  1128. writeln('TCustomTestModule.OnScannerLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1129. {$ENDIF}
  1130. FHintMsgs.Add(Item);
  1131. end;
  1132. function TCustomTestModule.LoadUnit(const aUnitName: String): TPasModule;
  1133. var
  1134. i: Integer;
  1135. CurEngine: TTestEnginePasResolver;
  1136. CurUnitName: String;
  1137. begin
  1138. //writeln('TTestModule.FindUnit START Unit="',aUnitName,'"');
  1139. Result:=nil;
  1140. if (Module.ClassType=TPasModule)
  1141. and (CompareText(Module.Name,aUnitName)=0) then
  1142. exit(Module);
  1143. for i:=0 to ResolverCount-1 do
  1144. begin
  1145. CurEngine:=Resolvers[i];
  1146. CurUnitName:=ExtractFileUnitName(CurEngine.Filename);
  1147. //writeln('TTestModule.FindUnit Checking ',i,'/',ResolverCount,' ',CurEngine.Filename,' ',CurUnitName);
  1148. if CompareText(aUnitName,CurUnitName)=0 then
  1149. begin
  1150. Result:=CurEngine.Module;
  1151. if Result<>nil then exit;
  1152. //writeln('TTestModule.FindUnit PARSING unit "',CurEngine.Filename,'"');
  1153. FileResolver.FindSourceFile(aUnitName);
  1154. CurEngine.StreamResolver:=TStreamResolver.Create;
  1155. CurEngine.StreamResolver.OwnsStreams:=True;
  1156. //writeln('TTestModule.FindUnit SOURCE=',CurEngine.Source);
  1157. CurEngine.StreamResolver.AddStream(CurEngine.FileName,TStringStream.Create(CurEngine.Source));
  1158. CurEngine.Scanner:=TPas2jsPasScanner.Create(CurEngine.StreamResolver);
  1159. InitScanner(CurEngine.Scanner);
  1160. CurEngine.Parser:=TTestPasParser.Create(CurEngine.Scanner,CurEngine.StreamResolver,CurEngine);
  1161. CurEngine.Parser.Options:=po_tcmodules;
  1162. if CompareText(CurUnitName,'System')=0 then
  1163. CurEngine.Parser.ImplicitUses.Clear;
  1164. CurEngine.Scanner.OpenFile(CurEngine.Filename);
  1165. try
  1166. CurEngine.Parser.NextToken;
  1167. CurEngine.Parser.ParseUnit(CurEngine.FModule);
  1168. except
  1169. on E: Exception do
  1170. HandleException(E);
  1171. end;
  1172. //writeln('TTestModule.FindUnit END ',CurUnitName);
  1173. Result:=CurEngine.Module;
  1174. exit;
  1175. end;
  1176. end;
  1177. end;
  1178. procedure TCustomTestModule.SetUp;
  1179. begin
  1180. {$IFDEF EnablePasTreeGlobalRefCount}
  1181. FElementRefCountAtSetup:=TPasElement.GlobalRefCount;
  1182. {$ENDIF}
  1183. if FModules<>nil then
  1184. begin
  1185. writeln('TCustomTestModule.SetUp FModules<>nil');
  1186. Halt;
  1187. end;
  1188. inherited SetUp;
  1189. FSkipTests:=false;
  1190. FSource:=TStringList.Create;
  1191. FModules:=TObjectList.Create(true);
  1192. FFilename:='test1.pp';
  1193. FFileResolver:=TStreamResolver.Create;
  1194. FFileResolver.OwnsStreams:=True;
  1195. FScanner:=TPas2jsPasScanner.Create(FFileResolver);
  1196. InitScanner(FScanner);
  1197. FEngine:=AddModule(Filename);
  1198. FEngine.Scanner:=FScanner;
  1199. FScanner.Resolver:=FEngine;
  1200. FParser:=TTestPasParser.Create(FScanner,FFileResolver,FEngine);
  1201. FParser.OnLog:=@OnParserLog;
  1202. FEngine.Parser:=FParser;
  1203. Parser.Options:=po_tcmodules;
  1204. FModule:=Nil;
  1205. FConverter:=CreateConverter;
  1206. FExpectedErrorClass:=nil;
  1207. end;
  1208. function TCustomTestModule.CreateConverter: TPasToJSConverter;
  1209. begin
  1210. Result:=TPasToJSConverter.Create;
  1211. Result.Options:=co_tcmodules;
  1212. Result.Globals:=TPasToJSConverterGlobals.Create(Result);
  1213. end;
  1214. procedure TCustomTestModule.InitScanner(aScanner: TPas2jsPasScanner);
  1215. begin
  1216. aScanner.AllowedModeSwitches:=msAllPas2jsModeSwitches;
  1217. aScanner.ReadOnlyModeSwitches:=msAllPas2jsModeSwitchesReadOnly;
  1218. aScanner.CurrentModeSwitches:=OBJFPCModeSwitches*msAllPas2jsModeSwitches+msAllPas2jsModeSwitchesReadOnly;
  1219. aScanner.AllowedBoolSwitches:=bsAllPas2jsBoolSwitches;
  1220. aScanner.ReadOnlyBoolSwitches:=bsAllPas2jsBoolSwitchesReadOnly;
  1221. aScanner.CurrentBoolSwitches:=bsAllPas2jsBoolSwitchesReadOnly+[bsHints,bsNotes,bsWarnings,bsWriteableConst];
  1222. aScanner.AllowedValueSwitches:=vsAllPas2jsValueSwitches;
  1223. aScanner.ReadOnlyValueSwitches:=vsAllPas2jsValueSwitchesReadOnly;
  1224. aScanner.OnLog:=@OnScannerLog;
  1225. aScanner.CompilerVersion:='Comp.Ver.tcmodules';
  1226. end;
  1227. procedure TCustomTestModule.TearDown;
  1228. {$IFDEF CheckPasTreeRefCount}
  1229. var
  1230. El: TPasElement;
  1231. {$ENDIF}
  1232. var
  1233. i: Integer;
  1234. CurModule: TPasModule;
  1235. begin
  1236. FHintMsgs.Clear;
  1237. FHintMsgsGood.Clear;
  1238. FSkipTests:=false;
  1239. FJSRegModuleCall:=nil;
  1240. FJSModuleCallArgs:=nil;
  1241. FJSImplentationUses:=nil;
  1242. FJSInterfaceUses:=nil;
  1243. FJSModuleSrc:=nil;
  1244. FJSInitBody:=nil;
  1245. FreeAndNil(FJSSource);
  1246. FreeAndNil(FJSModule);
  1247. FreeAndNil(FConverter);
  1248. Engine.Clear;
  1249. FreeAndNil(FSource);
  1250. FreeAndNil(FFileResolver);
  1251. if FModules<>nil then
  1252. begin
  1253. for i:=0 to FModules.Count-1 do
  1254. begin
  1255. CurModule:=TTestEnginePasResolver(FModules[i]).Module;
  1256. if CurModule=nil then continue;
  1257. //writeln('TCustomTestModule.TearDown ReleaseUsedUnits ',CurModule.Name,' ',CurModule.RefCount,' ',CurModule.RefIds.Text);
  1258. CurModule.ReleaseUsedUnits;
  1259. end;
  1260. if FModule<>nil then
  1261. FModule.ReleaseUsedUnits;
  1262. for i:=0 to FModules.Count-1 do
  1263. begin
  1264. CurModule:=TTestEnginePasResolver(FModules[i]).Module;
  1265. if CurModule=nil then continue;
  1266. //writeln('TCustomTestModule.TearDown UsesReleased ',CurModule.Name,' ',CurModule.RefCount,' ',CurModule.RefIds.Text);
  1267. end;
  1268. FreeAndNil(FModules);
  1269. ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
  1270. FEngine:=nil;
  1271. end;
  1272. inherited TearDown;
  1273. {$IFDEF EnablePasTreeGlobalRefCount}
  1274. if FElementRefCountAtSetup<>TPasElement.GlobalRefCount then
  1275. begin
  1276. writeln('TCustomTestModule.TearDown GlobalRefCount Was='+IntToStr(FElementRefCountAtSetup)+' Now='+IntToStr(TPasElement.GlobalRefCount));
  1277. {$IFDEF CheckPasTreeRefCount}
  1278. El:=TPasElement.FirstRefEl;
  1279. while El<>nil do
  1280. begin
  1281. writeln(' ',GetObjName(El),' RefIds.Count=',El.RefIds.Count,':');
  1282. for i:=0 to El.RefIds.Count-1 do
  1283. writeln(' ',El.RefIds[i]);
  1284. El:=El.NextRefEl;
  1285. end;
  1286. {$ENDIF}
  1287. Halt;
  1288. Fail('TCustomTestModule.TearDown Was='+IntToStr(FElementRefCountAtSetup)+' Now='+IntToStr(TPasElement.GlobalRefCount));
  1289. end;
  1290. {$ENDIF}
  1291. end;
  1292. procedure TCustomTestModule.Add(Line: string);
  1293. begin
  1294. Source.Add(Line);
  1295. end;
  1296. procedure TCustomTestModule.Add(const Lines: array of string);
  1297. var
  1298. i: Integer;
  1299. begin
  1300. for i:=low(Lines) to high(Lines) do
  1301. Add(Lines[i]);
  1302. end;
  1303. procedure TCustomTestModule.StartParsing;
  1304. var
  1305. Src: String;
  1306. begin
  1307. Src:=Source.Text;
  1308. FEngine.Source:=Src;
  1309. FileResolver.AddStream(FileName,TStringStream.Create(Src));
  1310. Scanner.OpenFile(FileName);
  1311. Writeln('// Test : ',Self.TestName);
  1312. Writeln(Src);
  1313. end;
  1314. procedure TCustomTestModule.ParseModuleQueue;
  1315. var
  1316. i: Integer;
  1317. CurResolver: TTestEnginePasResolver;
  1318. Found: Boolean;
  1319. Section: TPasSection;
  1320. begin
  1321. // parse til exception or all modules finished
  1322. while not SkipTests do
  1323. begin
  1324. Found:=false;
  1325. for i:=0 to ResolverCount-1 do
  1326. begin
  1327. CurResolver:=Resolvers[i];
  1328. if CurResolver.CurrentParser=nil then continue;
  1329. if not CurResolver.CurrentParser.CanParseContinue(Section) then
  1330. continue;
  1331. CurResolver.Parser.ParseContinue;
  1332. Found:=true;
  1333. break;
  1334. end;
  1335. if not Found then break;
  1336. end;
  1337. for i:=0 to ResolverCount-1 do
  1338. begin
  1339. CurResolver:=Resolvers[i];
  1340. if CurResolver.Parser=nil then
  1341. begin
  1342. if CurResolver.CurrentParser<>nil then
  1343. Fail('TCustomTestModule.ParseModuleQueue '+CurResolver.Filename+' '+GetObjName(CurResolver.Parser)+'=Parser<>CurrentParser='+GetObjName(CurResolver.CurrentParser));
  1344. continue;
  1345. end;
  1346. if CurResolver.Parser.CurModule<>nil then
  1347. Fail('TCustomTestModule.ParseModuleQueue '+CurResolver.Filename+' NOT FINISHED CurModule='+GetObjName(CurResolver.Parser.CurModule));
  1348. end;
  1349. end;
  1350. procedure TCustomTestModule.ParseModule;
  1351. begin
  1352. if SkipTests then exit;
  1353. FFirstPasStatement:=nil;
  1354. try
  1355. StartParsing;
  1356. Parser.ParseMain(FModule);
  1357. ParseModuleQueue;
  1358. except
  1359. on E: Exception do
  1360. HandleException(E);
  1361. end;
  1362. if SkipTests then exit;
  1363. AssertNotNull('Module resulted in Module',Module);
  1364. AssertEquals('modulename',lowercase(ChangeFileExt(FFileName,'')),lowercase(Module.Name));
  1365. TAssert.AssertSame('Has resolver',Engine,Parser.Engine);
  1366. end;
  1367. procedure TCustomTestModule.ParseProgram;
  1368. begin
  1369. if SkipTests then exit;
  1370. ParseModule;
  1371. if SkipTests then exit;
  1372. AssertEquals('Has program',TPasProgram,Module.ClassType);
  1373. FPasProgram:=TPasProgram(Module);
  1374. AssertNotNull('Has program section',PasProgram.ProgramSection);
  1375. AssertNotNull('Has initialization section',PasProgram.InitializationSection);
  1376. if (PasProgram.InitializationSection.Elements.Count>0) then
  1377. if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
  1378. FFirstPasStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
  1379. end;
  1380. procedure TCustomTestModule.ParseUnit;
  1381. begin
  1382. if SkipTests then exit;
  1383. ParseModule;
  1384. if SkipTests then exit;
  1385. AssertEquals('Has unit (TPasModule)',TPasModule,Module.ClassType);
  1386. AssertNotNull('Has interface section',Module.InterfaceSection);
  1387. AssertNotNull('Has implementation section',Module.ImplementationSection);
  1388. if (Module.InitializationSection<>nil)
  1389. and (Module.InitializationSection.Elements.Count>0)
  1390. and (TObject(Module.InitializationSection.Elements[0]) is TPasImplBlock) then
  1391. FFirstPasStatement:=TPasImplBlock(Module.InitializationSection.Elements[0]);
  1392. end;
  1393. function TCustomTestModule.FindModuleWithFilename(aFilename: string
  1394. ): TTestEnginePasResolver;
  1395. var
  1396. i: Integer;
  1397. begin
  1398. for i:=0 to ResolverCount-1 do
  1399. if CompareText(Resolvers[i].Filename,aFilename)=0 then
  1400. exit(Resolvers[i]);
  1401. Result:=nil;
  1402. end;
  1403. function TCustomTestModule.AddModule(aFilename: string
  1404. ): TTestEnginePasResolver;
  1405. begin
  1406. //writeln('TTestModuleConverter.AddModule ',aFilename);
  1407. if FindModuleWithFilename(aFilename)<>nil then
  1408. Fail('TTestModuleConverter.AddModule: file "'+aFilename+'" already exists');
  1409. Result:=TTestEnginePasResolver.Create;
  1410. Result.Filename:=aFilename;
  1411. Result.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs);
  1412. Result.OnFindUnit:=@OnPasResolverFindUnit;
  1413. Result.OnLog:=@OnPasResolverLog;
  1414. FModules.Add(Result);
  1415. end;
  1416. function TCustomTestModule.AddModuleWithSrc(aFilename, Src: string
  1417. ): TTestEnginePasResolver;
  1418. begin
  1419. Result:=AddModule(aFilename);
  1420. Result.Source:=Src;
  1421. end;
  1422. function TCustomTestModule.AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  1423. ImplementationSrc: string): TTestEnginePasResolver;
  1424. var
  1425. Src: String;
  1426. begin
  1427. Src:='unit '+ExtractFileUnitName(aFilename)+';'+LineEnding;
  1428. Src+=LineEnding;
  1429. Src+='interface'+LineEnding;
  1430. Src+=LineEnding;
  1431. Src+=InterfaceSrc;
  1432. Src+='implementation'+LineEnding;
  1433. Src+=LineEnding;
  1434. Src+=ImplementationSrc;
  1435. Src+='end.'+LineEnding;
  1436. Result:=AddModuleWithSrc(aFilename,Src);
  1437. end;
  1438. procedure TCustomTestModule.AddSystemUnit(Parts: TSystemUnitParts);
  1439. var
  1440. Intf, Impl: TStringList;
  1441. begin
  1442. Intf:=TStringList.Create;
  1443. // interface
  1444. if supTVarRec in Parts then
  1445. Intf.Add('{$modeswitch externalclass}');
  1446. Intf.Add('type');
  1447. Intf.Add(' integer=longint;');
  1448. Intf.Add(' sizeint=nativeint;');
  1449. //'const',
  1450. //' LineEnding = #10;',
  1451. //' DirectorySeparator = ''/'';',
  1452. //' DriveSeparator = '''';',
  1453. //' AllowDirectorySeparators : set of char = [''\'',''/''];',
  1454. //' AllowDriveSeparators : set of char = [];',
  1455. if supTObject in Parts then
  1456. Intf.AddStrings([
  1457. 'type',
  1458. ' TClass = class of TObject;',
  1459. ' TObject = class',
  1460. ' constructor Create;',
  1461. ' destructor Destroy; virtual;',
  1462. ' class function ClassType: TClass; assembler;',
  1463. ' class function ClassName: String; assembler;',
  1464. ' class function ClassNameIs(const Name: string): boolean;',
  1465. ' class function ClassParent: TClass; assembler;',
  1466. ' class function InheritsFrom(aClass: TClass): boolean; assembler;',
  1467. ' class function UnitName: String; assembler;',
  1468. ' procedure AfterConstruction; virtual;',
  1469. ' procedure BeforeDestruction;virtual;',
  1470. ' function Equals(Obj: TObject): boolean; virtual;',
  1471. ' function ToString: String; virtual;',
  1472. ' end;']);
  1473. if supTVarRec in Parts then
  1474. Intf.AddStrings([
  1475. 'const',
  1476. ' vtInteger = 0;',
  1477. ' vtBoolean = 1;',
  1478. ' vtJSValue = 19;',
  1479. 'type',
  1480. ' PVarRec = ^TVarRec;',
  1481. ' TVarRec = record',
  1482. ' VType : byte;',
  1483. ' VJSValue: JSValue;',
  1484. ' vInteger: longint external name ''VJSValue'';',
  1485. ' vBoolean: boolean external name ''VJSValue'';',
  1486. ' end;',
  1487. ' TVarRecArray = array of TVarRec;',
  1488. 'function VarRecs: TVarRecArray; varargs;',
  1489. '']);
  1490. Intf.Add('var');
  1491. Intf.Add(' ExitCode: Longint = 0;');
  1492. // implementation
  1493. Impl:=TStringList.Create;
  1494. if supTObject in Parts then
  1495. Impl.AddStrings([
  1496. '// needed by ClassNameIs, the real SameText is in SysUtils',
  1497. 'function SameText(const s1, s2: String): Boolean; assembler;',
  1498. 'asm',
  1499. 'end;',
  1500. 'constructor TObject.Create; begin end;',
  1501. 'destructor TObject.Destroy; begin end;',
  1502. 'class function TObject.ClassType: TClass; assembler;',
  1503. 'asm',
  1504. 'end;',
  1505. 'class function TObject.ClassName: String; assembler;',
  1506. 'asm',
  1507. 'end;',
  1508. 'class function TObject.ClassNameIs(const Name: string): boolean;',
  1509. 'begin',
  1510. ' Result:=SameText(Name,ClassName);',
  1511. 'end;',
  1512. 'class function TObject.ClassParent: TClass; assembler;',
  1513. 'asm',
  1514. 'end;',
  1515. 'class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;',
  1516. 'asm',
  1517. 'end;',
  1518. 'class function TObject.UnitName: String; assembler;',
  1519. 'asm',
  1520. 'end;',
  1521. 'procedure TObject.AfterConstruction; begin end;',
  1522. 'procedure TObject.BeforeDestruction; begin end;',
  1523. 'function TObject.Equals(Obj: TObject): boolean;',
  1524. 'begin',
  1525. ' Result:=Obj=Self;',
  1526. 'end;',
  1527. 'function TObject.ToString: String;',
  1528. 'begin',
  1529. ' Result:=ClassName;',
  1530. 'end;'
  1531. ]);
  1532. if supTVarRec in Parts then
  1533. Impl.AddStrings([
  1534. 'function VarRecs: TVarRecArray; varargs;',
  1535. 'var',
  1536. ' v: PVarRec;',
  1537. 'begin',
  1538. ' v^.VType:=1;',
  1539. ' v^.VJSValue:=2;',
  1540. 'end;',
  1541. '']);
  1542. try
  1543. AddModuleWithIntfImplSrc('system.pp',Intf.Text,Impl.Text);
  1544. finally
  1545. Intf.Free;
  1546. Impl.Free;
  1547. end;
  1548. end;
  1549. procedure TCustomTestModule.StartProgram(NeedSystemUnit: boolean;
  1550. SystemUnitParts: TSystemUnitParts);
  1551. begin
  1552. if NeedSystemUnit then
  1553. AddSystemUnit(SystemUnitParts)
  1554. else
  1555. Parser.ImplicitUses.Clear;
  1556. Add('program '+ExtractFileUnitName(Filename)+';');
  1557. Add('');
  1558. end;
  1559. procedure TCustomTestModule.StartUnit(NeedSystemUnit: boolean;
  1560. SystemUnitParts: TSystemUnitParts);
  1561. begin
  1562. if NeedSystemUnit then
  1563. AddSystemUnit(SystemUnitParts)
  1564. else
  1565. Parser.ImplicitUses.Clear;
  1566. Add('unit Test1;');
  1567. Add('');
  1568. end;
  1569. procedure TCustomTestModule.ConvertModule;
  1570. procedure CheckUsesList(UsesName: String; Arg: TJSArrayLiteralElement;
  1571. out UsesLit: TJSArrayLiteral);
  1572. var
  1573. i: Integer;
  1574. Item: TJSElement;
  1575. Lit: TJSLiteral;
  1576. begin
  1577. UsesLit:=nil;
  1578. AssertNotNull(UsesName+' uses section',Arg.Expr);
  1579. if (Arg.Expr.ClassType=TJSLiteral) and TJSLiteral(Arg.Expr).Value.IsNull then
  1580. exit; // null is ok
  1581. AssertEquals(UsesName+' uses section param is array',TJSArrayLiteral,Arg.Expr.ClassType);
  1582. FJSInterfaceUses:=TJSArrayLiteral(Arg.Expr);
  1583. for i:=0 to FJSInterfaceUses.Elements.Count-1 do
  1584. begin
  1585. Item:=FJSInterfaceUses.Elements.Elements[i].Expr;
  1586. AssertNotNull(UsesName+' uses section item['+IntToStr(i)+'].Expr',Item);
  1587. AssertEquals(UsesName+' uses section item['+IntToStr(i)+'] is lit',TJSLiteral,Item.ClassType);
  1588. Lit:=TJSLiteral(Item);
  1589. AssertEquals(UsesName+' uses section item['+IntToStr(i)+'] is string lit',
  1590. ord(jsbase.jstString),ord(Lit.Value.ValueType));
  1591. end;
  1592. end;
  1593. procedure CheckFunctionParam(ParamName: string; Arg: TJSArrayLiteralElement;
  1594. out Src: TJSSourceElements);
  1595. var
  1596. FunDecl: TJSFunctionDeclarationStatement;
  1597. FunDef: TJSFuncDef;
  1598. FunBody: TJSFunctionBody;
  1599. begin
  1600. Src:=nil;
  1601. AssertNotNull(ParamName,Arg.Expr);
  1602. AssertEquals(ParamName+' Arg.Expr type',TJSFunctionDeclarationStatement,Arg.Expr.ClassType);
  1603. FunDecl:=Arg.Expr as TJSFunctionDeclarationStatement;
  1604. AssertNotNull(ParamName+' FunDecl.AFunction',FunDecl.AFunction);
  1605. AssertEquals(ParamName+' FunDecl.AFunction type',TJSFuncDef,FunDecl.AFunction.ClassType);
  1606. FunDef:=FunDecl.AFunction as TJSFuncDef;
  1607. AssertEquals(ParamName+' name empty','',String(FunDef.Name));
  1608. AssertNotNull(ParamName+' body',FunDef.Body);
  1609. AssertEquals(ParamName+' body type',TJSFunctionBody,FunDef.Body.ClassType);
  1610. FunBody:=FunDef.Body as TJSFunctionBody;
  1611. AssertNotNull(ParamName+' body.A',FunBody.A);
  1612. AssertEquals(ParamName+' body.A type',TJSSourceElements,FunBody.A.ClassType);
  1613. Src:=FunBody.A as TJSSourceElements;
  1614. end;
  1615. var
  1616. ModuleNameExpr: TJSLiteral;
  1617. InitFunction: TJSFunctionDeclarationStatement;
  1618. InitAssign: TJSSimpleAssignStatement;
  1619. InitName: String;
  1620. LastNode: TJSElement;
  1621. Arg: TJSArrayLiteralElement;
  1622. begin
  1623. if SkipTests then exit;
  1624. try
  1625. FJSModule:=FConverter.ConvertPasElement(Module,Engine) as TJSSourceElements;
  1626. except
  1627. on E: Exception do
  1628. HandleException(E);
  1629. end;
  1630. if SkipTests then exit;
  1631. if ExpectedErrorClass<>nil then
  1632. Fail('Missing '+ExpectedErrorClass.ClassName+' error {'+ExpectedErrorMsg+'} ('+IntToStr(ExpectedErrorNumber)+')');
  1633. FJSSource:=TStringList.Create;
  1634. FJSSource.Text:=ConvertJSModuleToString(JSModule);
  1635. {$IFDEF VerbosePas2JS}
  1636. writeln('TTestModule.ConvertModule JS:');
  1637. write(FJSSource.Text);
  1638. {$ENDIF}
  1639. // rtl.module(...
  1640. AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
  1641. AssertNotNull('register module call',JSModule.Statements.Nodes[0].Node);
  1642. AssertEquals('register module call',TJSCallExpression,JSModule.Statements.Nodes[0].Node.ClassType);
  1643. FJSRegModuleCall:=JSModule.Statements.Nodes[0].Node as TJSCallExpression;
  1644. AssertNotNull('register module rtl.module expr',JSRegModuleCall.Expr);
  1645. AssertNotNull('register module rtl.module args',JSRegModuleCall.Args);
  1646. AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
  1647. FJSModuleCallArgs:=JSRegModuleCall.Args as TJSArguments;
  1648. // parameter 'unitname'
  1649. if JSModuleCallArgs.Elements.Count<1 then
  1650. Fail('rtl.module first param unit missing');
  1651. Arg:=JSModuleCallArgs.Elements.Elements[0];
  1652. AssertNotNull('module name param',Arg.Expr);
  1653. ModuleNameExpr:=Arg.Expr as TJSLiteral;
  1654. AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
  1655. if Module is TPasProgram then
  1656. AssertEquals('module name','program',String(ModuleNameExpr.Value.AsString))
  1657. else
  1658. AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
  1659. // main uses section
  1660. if JSModuleCallArgs.Elements.Count<2 then
  1661. Fail('rtl.module second param main uses missing');
  1662. Arg:=JSModuleCallArgs.Elements.Elements[1];
  1663. CheckUsesList('interface',Arg,FJSInterfaceUses);
  1664. // program/library/interface function()
  1665. if JSModuleCallArgs.Elements.Count<3 then
  1666. Fail('rtl.module third param intf-function missing');
  1667. Arg:=JSModuleCallArgs.Elements.Elements[2];
  1668. CheckFunctionParam('module intf-function',Arg,FJSModuleSrc);
  1669. // search for $mod.$init or $mod.$main - the last statement
  1670. if Module is TPasProgram then
  1671. begin
  1672. InitName:='$main';
  1673. AssertEquals('$mod.'+InitName+' function 1',true,JSModuleSrc.Statements.Count>0);
  1674. end
  1675. else
  1676. InitName:='$init';
  1677. FJSInitBody:=nil;
  1678. if JSModuleSrc.Statements.Count>0 then
  1679. begin
  1680. LastNode:=JSModuleSrc.Statements.Nodes[JSModuleSrc.Statements.Count-1].Node;
  1681. if LastNode is TJSSimpleAssignStatement then
  1682. begin
  1683. InitAssign:=LastNode as TJSSimpleAssignStatement;
  1684. if GetDottedIdentifier(InitAssign.LHS)='$mod.'+InitName then
  1685. begin
  1686. InitFunction:=InitAssign.Expr as TJSFunctionDeclarationStatement;
  1687. FJSInitBody:=InitFunction.AFunction.Body as TJSFunctionBody;
  1688. end
  1689. else if Module is TPasProgram then
  1690. CheckDottedIdentifier('init function',InitAssign.LHS,'$mod.'+InitName);
  1691. end;
  1692. end;
  1693. // optional: implementation uses section
  1694. if JSModuleCallArgs.Elements.Count<4 then
  1695. exit;
  1696. Arg:=JSModuleCallArgs.Elements.Elements[3];
  1697. CheckUsesList('implementation',Arg,FJSImplentationUses);
  1698. // optional: implementation function()
  1699. if JSModuleCallArgs.Elements.Count<5 then
  1700. exit;
  1701. Arg:=JSModuleCallArgs.Elements.Elements[4];
  1702. CheckFunctionParam('module impl-function',Arg,FJSImplementationSrc);
  1703. end;
  1704. procedure TCustomTestModule.ConvertProgram;
  1705. begin
  1706. Add('end.');
  1707. ParseProgram;
  1708. ConvertModule;
  1709. end;
  1710. procedure TCustomTestModule.ConvertUnit;
  1711. begin
  1712. Add('end.');
  1713. ParseUnit;
  1714. ConvertModule;
  1715. end;
  1716. function TCustomTestModule.ConvertJSModuleToString(El: TJSElement): string;
  1717. begin
  1718. Result:=tcmodules.JSToStr(El);
  1719. end;
  1720. procedure TCustomTestModule.CheckDottedIdentifier(Msg: string; El: TJSElement;
  1721. DottedName: string);
  1722. begin
  1723. if DottedName='' then
  1724. begin
  1725. AssertNull(Msg,El);
  1726. end
  1727. else
  1728. begin
  1729. AssertNotNull(Msg,El);
  1730. AssertEquals(Msg,DottedName,GetDottedIdentifier(El));
  1731. end;
  1732. end;
  1733. function TCustomTestModule.GetDottedIdentifier(El: TJSElement): string;
  1734. begin
  1735. if El=nil then
  1736. Result:=''
  1737. else if El is TJSPrimaryExpressionIdent then
  1738. Result:=String(TJSPrimaryExpressionIdent(El).Name)
  1739. else if El is TJSDotMemberExpression then
  1740. Result:=GetDottedIdentifier(TJSDotMemberExpression(El).MExpr)+'.'+String(TJSDotMemberExpression(El).Name)
  1741. else
  1742. AssertEquals('GetDottedIdentifier',TJSPrimaryExpressionIdent,El.ClassType);
  1743. end;
  1744. procedure TCustomTestModule.CheckSource(Msg, Statements: String;
  1745. InitStatements: string; ImplStatements: string);
  1746. var
  1747. ActualSrc, ExpectedSrc, InitName: String;
  1748. begin
  1749. ActualSrc:=JSToStr(JSModuleSrc);
  1750. ExpectedSrc:=
  1751. 'var $mod = this;'+LineEnding
  1752. +Statements;
  1753. if coUseStrict in Converter.Options then
  1754. ExpectedSrc:='"use strict";'+LineEnding+ExpectedSrc;
  1755. if Module is TPasProgram then
  1756. InitName:='$main'
  1757. else
  1758. InitName:='$init';
  1759. if (Module is TPasProgram) or (Trim(InitStatements)<>'') then
  1760. ExpectedSrc:=ExpectedSrc+LineEnding
  1761. +'$mod.'+InitName+' = function () {'+LineEnding
  1762. +InitStatements
  1763. +'};'+LineEnding;
  1764. //writeln('TCustomTestModule.CheckSource ExpectedIntf="',ExpectedSrc,'"');
  1765. //writeln('TTestModule.CheckSource InitStatements="',Trim(InitStatements),'"');
  1766. CheckDiff(Msg,ExpectedSrc,ActualSrc);
  1767. if (JSImplementationSrc<>nil) then
  1768. begin
  1769. ActualSrc:=JSToStr(JSImplementationSrc);
  1770. ExpectedSrc:=
  1771. 'var $mod = this;'+LineEnding
  1772. +'var $impl = $mod.$impl;'+LineEnding
  1773. +ImplStatements;
  1774. end
  1775. else
  1776. begin
  1777. ActualSrc:='';
  1778. ExpectedSrc:=ImplStatements;
  1779. end;
  1780. //writeln('TTestModule.CheckSource InitStatements="',InitStatements,'"');
  1781. //writeln('TCustomTestModule.CheckSource Expected: ',ExpectedSrc);
  1782. CheckDiff(Msg,ExpectedSrc,ActualSrc);
  1783. end;
  1784. procedure TCustomTestModule.CheckDiff(Msg, Expected, Actual: string);
  1785. // search diff, ignore changes in spaces
  1786. var
  1787. s: string;
  1788. begin
  1789. if CheckSrcDiff(Expected,Actual,s) then exit;
  1790. Fail(Msg+': '+s);
  1791. end;
  1792. procedure TCustomTestModule.CheckUnit(Filename, ExpectedSrc: string);
  1793. var
  1794. aResolver: TTestEnginePasResolver;
  1795. aConverter: TPasToJSConverter;
  1796. aJSModule: TJSSourceElements;
  1797. ActualSrc: String;
  1798. begin
  1799. aResolver:=GetResolver(Filename);
  1800. AssertNotNull('missing resolver of unit '+Filename,aResolver);
  1801. {$IFDEF VerbosePas2JS}
  1802. writeln('CheckUnit '+Filename+' converting ...');
  1803. {$ENDIF}
  1804. aConverter:=CreateConverter;
  1805. aJSModule:=nil;
  1806. try
  1807. try
  1808. aJSModule:=aConverter.ConvertPasElement(aResolver.Module,aResolver) as TJSSourceElements;
  1809. except
  1810. on E: Exception do
  1811. HandleException(E);
  1812. end;
  1813. ActualSrc:=ConvertJSModuleToString(aJSModule);
  1814. {$IFDEF VerbosePas2JS}
  1815. writeln('TTestModule.CheckUnit ',Filename,' Pas:');
  1816. write(aResolver.Source);
  1817. writeln('TTestModule.CheckUnit ',Filename,' JS:');
  1818. write(ActualSrc);
  1819. {$ENDIF}
  1820. CheckDiff('Converted unit: "'+ChangeFileExt(Filename,'.js')+'"',ExpectedSrc,ActualSrc);
  1821. finally
  1822. aJSModule.Free;
  1823. aConverter.Free;
  1824. end;
  1825. end;
  1826. procedure TCustomTestModule.CheckHint(MsgType: TMessageType;
  1827. MsgNumber: integer; Msg: string; Marker: PSrcMarker);
  1828. var
  1829. i: Integer;
  1830. Item: TTestHintMessage;
  1831. Expected,Actual: string;
  1832. begin
  1833. //writeln('TCustomTestModule.CheckHint MsgCount=',MsgCount);
  1834. for i:=0 to MsgCount-1 do
  1835. begin
  1836. Item:=Msgs[i];
  1837. if (Item.MsgNumber<>MsgNumber) or (Item.Msg<>Msg) then continue;
  1838. if (Marker<>nil) then
  1839. begin
  1840. if Item.SourcePos.Row<>cardinal(Marker^.Row) then continue;
  1841. if (Item.SourcePos.Column<cardinal(Marker^.StartCol))
  1842. or (Item.SourcePos.Column>cardinal(Marker^.EndCol)) then continue;
  1843. end;
  1844. // found
  1845. FHintMsgsGood.Add(Item);
  1846. str(Item.MsgType,Actual);
  1847. str(MsgType,Expected);
  1848. AssertEquals('MsgType',Expected,Actual);
  1849. exit;
  1850. end;
  1851. // needed message missing -> show emitted messages
  1852. WriteSources('',0,0);
  1853. for i:=0 to MsgCount-1 do
  1854. begin
  1855. Item:=Msgs[i];
  1856. write('TCustomTestModule.CheckHint ',i,'/',MsgCount,' ',Item.MsgType,
  1857. ' ('+IntToStr(Item.MsgNumber),')');
  1858. if Marker<>nil then
  1859. write(' '+ExtractFileName(Item.SourcePos.FileName),'(',Item.SourcePos.Row,',',Item.SourcePos.Column,')');
  1860. writeln(' {',Item.Msg,'}');
  1861. end;
  1862. str(MsgType,Expected);
  1863. Actual:='Missing '+Expected+' ('+IntToStr(MsgNumber)+')';
  1864. if Marker<>nil then
  1865. Actual:=Actual+' '+ExtractFileName(Marker^.Filename)+'('+IntToStr(Marker^.Row)+','+IntToStr(Marker^.StartCol)+'..'+IntToStr(Marker^.EndCol)+')';
  1866. Actual:=Actual+' '+Msg;
  1867. Fail(Actual);
  1868. end;
  1869. procedure TCustomTestModule.CheckResolverUnexpectedHints(WithSourcePos: boolean
  1870. );
  1871. var
  1872. i: Integer;
  1873. s, Txt: String;
  1874. Msg: TTestHintMessage;
  1875. begin
  1876. for i:=0 to MsgCount-1 do
  1877. begin
  1878. Msg:=Msgs[i];
  1879. if FHintMsgsGood.IndexOf(Msg)>=0 then continue;
  1880. s:='';
  1881. str(Msg.MsgType,s);
  1882. Txt:='Unexpected resolver message found ['+IntToStr(Msg.Id)+'] '
  1883. +s+': ('+IntToStr(Msg.MsgNumber)+')';
  1884. if WithSourcePos then
  1885. Txt:=Txt+' '+ExtractFileName(Msg.SourcePos.FileName)+'('+IntToStr(Msg.SourcePos.Row)+','+IntToStr(Msg.SourcePos.Column)+')';
  1886. Txt:=Txt+' {'+Msg.Msg+'}';
  1887. Fail(Txt);
  1888. end;
  1889. end;
  1890. procedure TCustomTestModule.SetExpectedScannerError(Msg: string;
  1891. MsgNumber: integer);
  1892. begin
  1893. ExpectedErrorClass:=EScannerError;
  1894. ExpectedErrorMsg:=Msg;
  1895. ExpectedErrorNumber:=MsgNumber;
  1896. end;
  1897. procedure TCustomTestModule.SetExpectedParserError(Msg: string;
  1898. MsgNumber: integer);
  1899. begin
  1900. ExpectedErrorClass:=EParserError;
  1901. ExpectedErrorMsg:=Msg;
  1902. ExpectedErrorNumber:=MsgNumber;
  1903. end;
  1904. procedure TCustomTestModule.SetExpectedPasResolverError(Msg: string;
  1905. MsgNumber: integer);
  1906. begin
  1907. ExpectedErrorClass:=EPasResolve;
  1908. ExpectedErrorMsg:=Msg;
  1909. ExpectedErrorNumber:=MsgNumber;
  1910. end;
  1911. procedure TCustomTestModule.SetExpectedConverterError(Msg: string;
  1912. MsgNumber: integer);
  1913. begin
  1914. ExpectedErrorClass:=EPas2JS;
  1915. ExpectedErrorMsg:=Msg;
  1916. ExpectedErrorNumber:=MsgNumber;
  1917. end;
  1918. function TCustomTestModule.IsErrorExpected(E: Exception): boolean;
  1919. var
  1920. MsgNumber: Integer;
  1921. Msg: String;
  1922. begin
  1923. Result:=false;
  1924. if (ExpectedErrorClass=nil) or (ExpectedErrorClass<>E.ClassType) then exit;
  1925. Msg:=E.Message;
  1926. if E is EPas2JS then
  1927. MsgNumber:=EPas2JS(E).MsgNumber
  1928. else if E is EPasResolve then
  1929. MsgNumber:=EPasResolve(E).MsgNumber
  1930. else if E is EParserError then
  1931. MsgNumber:=Parser.LastMsgNumber
  1932. else if E is EScannerError then
  1933. begin
  1934. MsgNumber:=Scanner.LastMsgNumber;
  1935. Msg:=Scanner.LastMsg;
  1936. end
  1937. else
  1938. MsgNumber:=0;
  1939. Result:=(MsgNumber=ExpectedErrorNumber) and (Msg=ExpectedErrorMsg);
  1940. if Result then
  1941. SkipTests:=true;
  1942. end;
  1943. procedure TCustomTestModule.HandleScannerError(E: EScannerError);
  1944. begin
  1945. if IsErrorExpected(E) then exit;
  1946. WriteSources(Scanner.CurFilename,Scanner.CurRow,Scanner.CurColumn);
  1947. writeln('ERROR: TCustomTestModule.HandleScannerError '+E.ClassName+':'+E.Message
  1948. +' '+Scanner.CurFilename
  1949. +'('+IntToStr(Scanner.CurRow)+','+IntToStr(Scanner.CurColumn)+')');
  1950. FailException(E);
  1951. end;
  1952. procedure TCustomTestModule.HandleParserError(E: EParserError);
  1953. begin
  1954. if IsErrorExpected(E) then exit;
  1955. WriteSources(E.Filename,E.Row,E.Column);
  1956. writeln('ERROR: TCustomTestModule.HandleParserError '+E.ClassName+':'+E.Message
  1957. +' '+E.Filename+'('+IntToStr(E.Row)+','+IntToStr(E.Column)+')'
  1958. +' MainModuleScannerLine="'+Scanner.CurLine+'"'
  1959. );
  1960. FailException(E);
  1961. end;
  1962. procedure TCustomTestModule.HandlePasResolveError(E: EPasResolve);
  1963. var
  1964. P: TPasSourcePos;
  1965. begin
  1966. if IsErrorExpected(E) then exit;
  1967. P:=E.SourcePos;
  1968. WriteSources(P.FileName,P.Row,P.Column);
  1969. writeln('ERROR: TCustomTestModule.HandlePasResolveError '+E.ClassName+':'+E.Message
  1970. +' '+P.FileName+'('+IntToStr(P.Row)+','+IntToStr(P.Column)+')');
  1971. FailException(E);
  1972. end;
  1973. procedure TCustomTestModule.HandlePas2JSError(E: EPas2JS);
  1974. var
  1975. Row, Col: integer;
  1976. begin
  1977. if IsErrorExpected(E) then exit;
  1978. Engine.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,Row,Col);
  1979. WriteSources(E.PasElement.SourceFilename,Row,Col);
  1980. writeln('ERROR: TCustomTestModule.HandlePas2JSError '+E.ClassName+':'+E.Message
  1981. +' '+E.PasElement.SourceFilename
  1982. +'('+IntToStr(Row)+','+IntToStr(Col)+')');
  1983. FailException(E);
  1984. end;
  1985. procedure TCustomTestModule.HandleException(E: Exception);
  1986. begin
  1987. if E is EScannerError then
  1988. HandleScannerError(EScannerError(E))
  1989. else if E is EParserError then
  1990. HandleParserError(EParserError(E))
  1991. else if E is EPasResolve then
  1992. HandlePasResolveError(EPasResolve(E))
  1993. else if E is EPas2JS then
  1994. HandlePas2JSError(EPas2JS(E))
  1995. else
  1996. begin
  1997. if IsErrorExpected(E) then exit;
  1998. if not (E is EAssertionFailedError) then
  1999. begin
  2000. WriteSources('',0,0);
  2001. writeln('ERROR: TCustomTestModule.HandleException '+E.ClassName+':'+E.Message);
  2002. end;
  2003. FailException(E);
  2004. end;
  2005. end;
  2006. procedure TCustomTestModule.FailException(E: Exception);
  2007. var
  2008. MsgNumber: Integer;
  2009. begin
  2010. if ExpectedErrorClass<>nil then
  2011. begin
  2012. if FExpectedErrorClass=E.ClassType then
  2013. begin
  2014. if E is EPas2JS then
  2015. MsgNumber:=EPas2JS(E).MsgNumber
  2016. else if E is EPasResolve then
  2017. MsgNumber:=EPasResolve(E).MsgNumber
  2018. else if E is EParserError then
  2019. MsgNumber:=Parser.LastMsgNumber
  2020. else if E is EScannerError then
  2021. MsgNumber:=Scanner.LastMsgNumber
  2022. else
  2023. MsgNumber:=0;
  2024. AssertEquals('Expected error message ('+IntToStr(ExpectedErrorNumber)+')','{'+ExpectedErrorMsg+'}','{'+E.Message+'}');
  2025. AssertEquals('Expected {'+ExpectedErrorMsg+'}, but got msg {'+E.Message+'} number',
  2026. ExpectedErrorNumber,MsgNumber);
  2027. end else begin
  2028. AssertEquals('Wrong exception class',ExpectedErrorClass.ClassName,E.ClassName);
  2029. end;
  2030. end;
  2031. Fail(E.Message);
  2032. end;
  2033. procedure TCustomTestModule.WriteSources(const aFilename: string; aRow,
  2034. aCol: integer);
  2035. var
  2036. IsSrc: Boolean;
  2037. i, j: Integer;
  2038. SrcLines: TStringList;
  2039. Line: string;
  2040. aModule: TTestEnginePasResolver;
  2041. begin
  2042. writeln('TCustomTestModule.WriteSources File="',aFilename,'" Row=',aRow,' Col=',aCol);
  2043. for i:=0 to ResolverCount-1 do
  2044. begin
  2045. aModule:=Resolvers[i];
  2046. SrcLines:=TStringList.Create;
  2047. try
  2048. SrcLines.Text:=aModule.Source;
  2049. IsSrc:=ExtractFilename(aModule.Filename)=ExtractFileName(aFilename);
  2050. writeln('Testcode:-File="',aModule.Filename,'"----------------------------------:');
  2051. for j:=1 to SrcLines.Count do
  2052. begin
  2053. Line:=SrcLines[j-1];
  2054. if IsSrc and (j=aRow) then
  2055. begin
  2056. write('*');
  2057. Line:=LeftStr(Line,aCol-1)+'|'+copy(Line,aCol,length(Line));
  2058. end;
  2059. writeln(Format('%:4d: ',[j]),Line);
  2060. end;
  2061. finally
  2062. SrcLines.Free;
  2063. end;
  2064. end;
  2065. end;
  2066. function TCustomTestModule.IndexOfResolver(const Filename: string): integer;
  2067. var
  2068. i: Integer;
  2069. begin
  2070. for i:=0 to ResolverCount-1 do
  2071. if Filename=Resolvers[i].Filename then exit(i);
  2072. Result:=-1;
  2073. end;
  2074. function TCustomTestModule.GetResolver(const Filename: string
  2075. ): TTestEnginePasResolver;
  2076. var
  2077. i: Integer;
  2078. begin
  2079. i:=IndexOfResolver(Filename);
  2080. if i<0 then exit(nil);
  2081. Result:=Resolvers[i];
  2082. end;
  2083. function TCustomTestModule.GetDefaultNamespace: string;
  2084. var
  2085. C: TClass;
  2086. begin
  2087. Result:='';
  2088. if FModule=nil then exit;
  2089. C:=FModule.ClassType;
  2090. if (C=TPasProgram) or (C=TPasLibrary) or (C=TPasPackage) then
  2091. Result:=Engine.DefaultNameSpace;
  2092. end;
  2093. constructor TCustomTestModule.Create;
  2094. begin
  2095. inherited Create;
  2096. FHintMsgs:=TObjectList.Create(true);
  2097. FHintMsgsGood:=TFPList.Create;
  2098. end;
  2099. destructor TCustomTestModule.Destroy;
  2100. begin
  2101. FreeAndNil(FHintMsgs);
  2102. FreeAndNil(FHintMsgsGood);
  2103. inherited Destroy;
  2104. end;
  2105. { TTestModule }
  2106. procedure TTestModule.TestReservedWords;
  2107. var
  2108. i: integer;
  2109. begin
  2110. for i:=low(JSReservedWords) to High(JSReservedWords)-1 do
  2111. if CompareStr(JSReservedWords[i],JSReservedWords[i+1])>=0 then
  2112. Fail('20170203135442 '+JSReservedWords[i]+' >= '+JSReservedWords[i+1]);
  2113. for i:=low(JSReservedGlobalWords) to High(JSReservedGlobalWords)-1 do
  2114. if CompareStr(JSReservedGlobalWords[i],JSReservedGlobalWords[i+1])>=0 then
  2115. Fail('20170203135443 '+JSReservedGlobalWords[i]+' >= '+JSReservedGlobalWords[i+1]);
  2116. end;
  2117. procedure TTestModule.TestEmptyProgram;
  2118. begin
  2119. StartProgram(false);
  2120. Add('begin');
  2121. ConvertProgram;
  2122. CheckSource('TestEmptyProgram','','');
  2123. end;
  2124. procedure TTestModule.TestEmptyProgramUseStrict;
  2125. begin
  2126. Converter.Options:=Converter.Options+[coUseStrict];
  2127. StartProgram(false);
  2128. Add('begin');
  2129. ConvertProgram;
  2130. CheckSource('TestEmptyProgramUseStrict','','');
  2131. end;
  2132. procedure TTestModule.TestEmptyUnit;
  2133. begin
  2134. StartUnit(false);
  2135. Add('interface');
  2136. Add('implementation');
  2137. ConvertUnit;
  2138. CheckSource('TestEmptyUnit',
  2139. LinesToStr([
  2140. ]),
  2141. '');
  2142. end;
  2143. procedure TTestModule.TestEmptyUnitUseStrict;
  2144. begin
  2145. Converter.Options:=Converter.Options+[coUseStrict];
  2146. StartUnit(false);
  2147. Add('interface');
  2148. Add('implementation');
  2149. ConvertUnit;
  2150. CheckSource('TestEmptyUnitUseStrict',
  2151. LinesToStr([
  2152. ''
  2153. ]),
  2154. '');
  2155. end;
  2156. procedure TTestModule.TestDottedUnitNames;
  2157. begin
  2158. AddModuleWithIntfImplSrc('NS1.Unit2.pas',
  2159. LinesToStr([
  2160. 'var iV: longint;'
  2161. ]),
  2162. '');
  2163. FFilename:='ns1.test1.pp';
  2164. StartProgram(true);
  2165. Add('uses unIt2;');
  2166. Add('implementation');
  2167. Add('var');
  2168. Add(' i: longint;');
  2169. Add('begin');
  2170. Add(' i:=iv;');
  2171. Add(' i:=uNit2.iv;');
  2172. Add(' i:=Ns1.TEst1.i;');
  2173. ConvertProgram;
  2174. CheckSource('TestDottedUnitNames',
  2175. LinesToStr([
  2176. 'this.i = 0;',
  2177. '']),
  2178. LinesToStr([ // this.$init
  2179. '$mod.i = pas["NS1.Unit2"].iV;',
  2180. '$mod.i = pas["NS1.Unit2"].iV;',
  2181. '$mod.i = $mod.i;',
  2182. '']) );
  2183. end;
  2184. procedure TTestModule.TestDottedUnitNameImpl;
  2185. begin
  2186. AddModuleWithIntfImplSrc('TEST.UnitA.pas',
  2187. LinesToStr([
  2188. 'type',
  2189. ' TObject = class end;',
  2190. ' TTestA = class',
  2191. ' end;'
  2192. ]),
  2193. LinesToStr(['uses TEST.UnitB;'])
  2194. );
  2195. AddModuleWithIntfImplSrc('TEST.UnitB.pas',
  2196. LinesToStr([
  2197. 'uses TEST.UnitA;',
  2198. 'type TTestB = class(TTestA);'
  2199. ]),
  2200. ''
  2201. );
  2202. StartProgram(true);
  2203. Add('uses TEST.UnitA;');
  2204. Add('begin');
  2205. ConvertProgram;
  2206. CheckSource('TestDottedUnitNameImpl',
  2207. LinesToStr([
  2208. '']),
  2209. LinesToStr([ // this.$init
  2210. '']) );
  2211. CheckUnit('TEST.UnitA.pas',
  2212. LinesToStr([
  2213. 'rtl.module("TEST.UnitA", ["system"], function () {',
  2214. ' var $mod = this;',
  2215. ' rtl.createClass($mod, "TObject", null, function () {',
  2216. ' this.$init = function () {',
  2217. ' };',
  2218. ' this.$final = function () {',
  2219. ' };',
  2220. ' });',
  2221. ' rtl.createClass($mod, "TTestA", $mod.TObject, function () {',
  2222. ' });',
  2223. '}, ["TEST.UnitB"]);'
  2224. ]));
  2225. CheckUnit('TEST.UnitB.pas',
  2226. LinesToStr([
  2227. 'rtl.module("TEST.UnitB", ["system","TEST.UnitA"], function () {',
  2228. ' var $mod = this;',
  2229. ' rtl.createClass($mod, "TTestB", pas["TEST.UnitA"].TTestA, function () {',
  2230. ' });',
  2231. '});'
  2232. ]));
  2233. end;
  2234. procedure TTestModule.TestDottedUnitExpr;
  2235. begin
  2236. AddModuleWithIntfImplSrc('NS2.SubNs2.Unit2.pas',
  2237. LinesToStr([
  2238. 'procedure DoIt;'
  2239. ]),
  2240. 'procedure DoIt; begin end;');
  2241. FFilename:='Ns1.SubNs1.Test1.pp';
  2242. StartProgram(true);
  2243. Add('uses Ns2.sUbnS2.unIt2;');
  2244. Add('implementation');
  2245. Add('var');
  2246. Add(' i: longint;');
  2247. Add('begin');
  2248. Add(' ns2.subns2.unit2.doit;');
  2249. Add(' i:=Ns1.SubNS1.TEst1.i;');
  2250. ConvertProgram;
  2251. CheckSource('TestDottedUnitExpr',
  2252. LinesToStr([
  2253. 'this.i = 0;',
  2254. '']),
  2255. LinesToStr([ // this.$init
  2256. 'pas["NS2.SubNs2.Unit2"].DoIt();',
  2257. '$mod.i = $mod.i;',
  2258. '']) );
  2259. end;
  2260. procedure TTestModule.Test_ModeFPCFail;
  2261. begin
  2262. StartProgram(false);
  2263. Add('{$mode FPC}');
  2264. Add('begin');
  2265. SetExpectedScannerError('Invalid mode: "FPC"',nErrInvalidMode);
  2266. ConvertProgram;
  2267. end;
  2268. procedure TTestModule.Test_ModeSwitchCBlocksFail;
  2269. begin
  2270. StartProgram(false);
  2271. Add('{$modeswitch cblocks-}');
  2272. Add('begin');
  2273. SetExpectedScannerError('Invalid mode switch: "cblocks-"',nErrInvalidModeSwitch);
  2274. ConvertProgram;
  2275. end;
  2276. procedure TTestModule.TestUnit_UseSystem;
  2277. begin
  2278. StartUnit(true);
  2279. Add([
  2280. 'interface',
  2281. 'var i: integer;',
  2282. 'implementation']);
  2283. ConvertUnit;
  2284. CheckSource('TestUnit_UseSystem',
  2285. LinesToStr([
  2286. 'this.i = 0;',
  2287. '']),
  2288. LinesToStr([
  2289. '']) );
  2290. end;
  2291. procedure TTestModule.TestUnit_Intf1Impl2Intf1;
  2292. begin
  2293. AddModuleWithIntfImplSrc('unit1.pp',
  2294. LinesToStr([
  2295. 'type number = longint;']),
  2296. LinesToStr([
  2297. 'uses test1;',
  2298. 'procedure DoIt;',
  2299. 'begin',
  2300. ' i:=3;',
  2301. 'end;']));
  2302. StartUnit(true);
  2303. Add([
  2304. 'interface',
  2305. 'uses unit1;',
  2306. 'var i: number;',
  2307. 'implementation']);
  2308. ConvertUnit;
  2309. CheckSource('TestUnit_Intf1Impl2Intf1',
  2310. LinesToStr([
  2311. 'this.i = 0;',
  2312. '']),
  2313. LinesToStr([
  2314. '']) );
  2315. end;
  2316. procedure TTestModule.TestIncludeVersion;
  2317. begin
  2318. StartProgram(false);
  2319. Add([
  2320. 'var',
  2321. ' s: string;',
  2322. ' i: word;',
  2323. 'begin',
  2324. ' s:={$I %line%};',
  2325. ' i:={$I %linenum%};',
  2326. ' s:={$I %currentroutine%};',
  2327. ' s:={$I %pas2jsversion%};',
  2328. ' s:={$I %pas2jstarget%};',
  2329. ' s:={$I %pas2jstargetos%};',
  2330. ' s:={$I %pas2jstargetcpu%};',
  2331. ' s:={$I %file%};',
  2332. '']);
  2333. ConvertProgram;
  2334. CheckSource('TestIncludeVersion',
  2335. LinesToStr([
  2336. 'this.s="";',
  2337. 'this.i = 0;']),
  2338. LinesToStr([
  2339. '$mod.s = "7";',
  2340. '$mod.i = 8;',
  2341. '$mod.s = "<anonymous>";',
  2342. '$mod.s = "Comp.Ver.tcmodules";',
  2343. '$mod.s = "Browser";',
  2344. '$mod.s = "Browser";',
  2345. '$mod.s = "ECMAScript5";',
  2346. '$mod.s = "test1.pp";',
  2347. '']));
  2348. end;
  2349. procedure TTestModule.TestVarInt;
  2350. begin
  2351. StartProgram(false);
  2352. Add('var MyI: longint;');
  2353. Add('begin');
  2354. ConvertProgram;
  2355. CheckSource('TestVarInt','this.MyI=0;','');
  2356. end;
  2357. procedure TTestModule.TestVarBaseTypes;
  2358. begin
  2359. StartProgram(false);
  2360. Add('var');
  2361. Add(' i: longint;');
  2362. Add(' s: string;');
  2363. Add(' c: char;');
  2364. Add(' b: boolean;');
  2365. Add(' d: double;');
  2366. Add(' i2: longint = 3;');
  2367. Add(' s2: string = ''foo'';');
  2368. Add(' c2: char = ''4'';');
  2369. Add(' b2: boolean = true;');
  2370. Add(' d2: double = 5.6;');
  2371. Add(' i3: longint = $707;');
  2372. Add(' i4: nativeint = 9007199254740991;');
  2373. Add(' i5: nativeint = -9007199254740991-1;');
  2374. Add(' i6: nativeint = $fffffffffffff;');
  2375. Add(' i7: nativeint = -$fffffffffffff-1;');
  2376. Add(' i8: byte = 00;');
  2377. Add(' u8: nativeuint = $fffffffffffff;');
  2378. Add(' u9: nativeuint = $0000000000000;');
  2379. Add(' u10: nativeuint = $00ff00;');
  2380. Add('begin');
  2381. ConvertProgram;
  2382. CheckSource('TestVarBaseTypes',
  2383. LinesToStr([
  2384. 'this.i = 0;',
  2385. 'this.s = "";',
  2386. 'this.c = "";',
  2387. 'this.b = false;',
  2388. 'this.d = 0.0;',
  2389. 'this.i2 = 3;',
  2390. 'this.s2 = "foo";',
  2391. 'this.c2 = "4";',
  2392. 'this.b2 = true;',
  2393. 'this.d2 = 5.6;',
  2394. 'this.i3 = 0x707;',
  2395. 'this.i4 = 9007199254740991;',
  2396. 'this.i5 = -9007199254740991-1;',
  2397. 'this.i6 = 0xfffffffffffff;',
  2398. 'this.i7 =-0xfffffffffffff-1;',
  2399. 'this.i8 = 0;',
  2400. 'this.u8 = 0xfffffffffffff;',
  2401. 'this.u9 = 0x0;',
  2402. 'this.u10 = 0xff00;'
  2403. ]),
  2404. '');
  2405. end;
  2406. procedure TTestModule.TestBaseTypeSingleFail;
  2407. begin
  2408. StartProgram(false);
  2409. Add('var s: single;');
  2410. SetExpectedPasResolverError('identifier not found "single"',PasResolveEval.nIdentifierNotFound);
  2411. ConvertProgram;
  2412. end;
  2413. procedure TTestModule.TestBaseTypeExtendedFail;
  2414. begin
  2415. StartProgram(false);
  2416. Add('var e: extended;');
  2417. SetExpectedPasResolverError('identifier not found "extended"',PasResolveEval.nIdentifierNotFound);
  2418. ConvertProgram;
  2419. end;
  2420. procedure TTestModule.TestConstBaseTypes;
  2421. begin
  2422. StartProgram(false);
  2423. Add('const');
  2424. Add(' i: longint = 3;');
  2425. Add(' s: string = ''foo'';');
  2426. Add(' c: char = ''4'';');
  2427. Add(' b: boolean = true;');
  2428. Add(' d: double = 5.6;');
  2429. Add(' e = low(word);');
  2430. Add(' f = high(word);');
  2431. Add('begin');
  2432. ConvertProgram;
  2433. CheckSource('TestVarBaseTypes',
  2434. LinesToStr([
  2435. 'this.i=3;',
  2436. 'this.s="foo";',
  2437. 'this.c="4";',
  2438. 'this.b=true;',
  2439. 'this.d=5.6;',
  2440. 'this.e = 0;',
  2441. 'this.f = 65535;'
  2442. ]),
  2443. '');
  2444. end;
  2445. procedure TTestModule.TestAliasTypeRef;
  2446. begin
  2447. StartProgram(false);
  2448. Add('type');
  2449. Add(' a=longint;');
  2450. Add(' b=a;');
  2451. Add('var');
  2452. Add(' c: A;');
  2453. Add(' d: B;');
  2454. Add('begin');
  2455. ConvertProgram;
  2456. CheckSource('TestAliasTypeRef',
  2457. LinesToStr([ // statements
  2458. 'this.c = 0;',
  2459. 'this.d = 0;'
  2460. ]),
  2461. LinesToStr([ // this.$main
  2462. ''
  2463. ]));
  2464. end;
  2465. procedure TTestModule.TestTypeCast_BaseTypes;
  2466. begin
  2467. StartProgram(false);
  2468. Add([
  2469. 'var',
  2470. ' i: longint;',
  2471. ' b: boolean;',
  2472. ' d: double;',
  2473. ' s: string;',
  2474. ' c: char;',
  2475. 'begin',
  2476. ' i:=longint(i);',
  2477. ' i:=longint(b);',
  2478. ' b:=boolean(b);',
  2479. ' b:=boolean(i);',
  2480. ' d:=double(d);',
  2481. ' d:=double(i);',
  2482. ' s:=string(s);',
  2483. ' s:=string(c);',
  2484. ' c:=char(c);',
  2485. ' c:=char(i);',
  2486. ' c:=char(65);',
  2487. ' c:=char(#10);',
  2488. ' c:=char(#$E000);',
  2489. '']);
  2490. ConvertProgram;
  2491. CheckSource('TestAliasTypeRef',
  2492. LinesToStr([ // statements
  2493. 'this.i = 0;',
  2494. 'this.b = false;',
  2495. 'this.d = 0.0;',
  2496. 'this.s = "";',
  2497. 'this.c = "";',
  2498. '']),
  2499. LinesToStr([ // this.$main
  2500. '$mod.i = $mod.i;',
  2501. '$mod.i = ($mod.b ? 1 : 0);',
  2502. '$mod.b = $mod.b;',
  2503. '$mod.b = $mod.i != 0;',
  2504. '$mod.d = $mod.d;',
  2505. '$mod.d = $mod.i;',
  2506. '$mod.s = $mod.s;',
  2507. '$mod.s = $mod.c;',
  2508. '$mod.c = $mod.c;',
  2509. '$mod.c = String.fromCharCode($mod.i);',
  2510. '$mod.c = "A";',
  2511. '$mod.c = "\n";',
  2512. '$mod.c = "";',
  2513. '']));
  2514. end;
  2515. procedure TTestModule.TestTypeCast_AliasBaseTypes;
  2516. begin
  2517. StartProgram(false);
  2518. Add('type');
  2519. Add(' integer = longint;');
  2520. Add(' TYesNo = boolean;');
  2521. Add(' TFloat = double;');
  2522. Add(' TCaption = string;');
  2523. Add(' TChar = char;');
  2524. Add('var');
  2525. Add(' i: integer;');
  2526. Add(' b: TYesNo;');
  2527. Add(' d: TFloat;');
  2528. Add(' s: TCaption;');
  2529. Add(' c: TChar;');
  2530. Add('begin');
  2531. Add(' i:=integer(i);');
  2532. Add(' i:=integer(b);');
  2533. Add(' b:=TYesNo(b);');
  2534. Add(' b:=TYesNo(i);');
  2535. Add(' d:=TFloat(d);');
  2536. Add(' d:=TFloat(i);');
  2537. Add(' s:=TCaption(s);');
  2538. Add(' s:=TCaption(c);');
  2539. Add(' c:=TChar(c);');
  2540. ConvertProgram;
  2541. CheckSource('TestAliasTypeRef',
  2542. LinesToStr([ // statements
  2543. 'this.i = 0;',
  2544. 'this.b = false;',
  2545. 'this.d = 0.0;',
  2546. 'this.s = "";',
  2547. 'this.c = "";',
  2548. '']),
  2549. LinesToStr([ // this.$main
  2550. '$mod.i = $mod.i;',
  2551. '$mod.i = ($mod.b ? 1 : 0);',
  2552. '$mod.b = $mod.b;',
  2553. '$mod.b = $mod.i != 0;',
  2554. '$mod.d = $mod.d;',
  2555. '$mod.d = $mod.i;',
  2556. '$mod.s = $mod.s;',
  2557. '$mod.s = $mod.c;',
  2558. '$mod.c = $mod.c;',
  2559. '']));
  2560. end;
  2561. procedure TTestModule.TestEmptyProc;
  2562. begin
  2563. StartProgram(false);
  2564. Add('procedure Test;');
  2565. Add('begin');
  2566. Add('end;');
  2567. Add('begin');
  2568. ConvertProgram;
  2569. CheckSource('TestEmptyProc',
  2570. LinesToStr([ // statements
  2571. 'this.Test = function () {',
  2572. '};'
  2573. ]),
  2574. LinesToStr([ // this.$main
  2575. ''
  2576. ]));
  2577. end;
  2578. procedure TTestModule.TestProcOneParam;
  2579. begin
  2580. StartProgram(false);
  2581. Add('procedure ProcA(i: longint);');
  2582. Add('begin');
  2583. Add('end;');
  2584. Add('begin');
  2585. Add(' PROCA(3);');
  2586. ConvertProgram;
  2587. CheckSource('TestProcOneParam',
  2588. LinesToStr([ // statements
  2589. 'this.ProcA = function (i) {',
  2590. '};'
  2591. ]),
  2592. LinesToStr([ // this.$main
  2593. '$mod.ProcA(3);'
  2594. ]));
  2595. end;
  2596. procedure TTestModule.TestFunctionWithoutParams;
  2597. begin
  2598. StartProgram(false);
  2599. Add('function FuncA: longint;');
  2600. Add('begin');
  2601. Add('end;');
  2602. Add('var i: longint;');
  2603. Add('begin');
  2604. Add(' I:=FUNCA();');
  2605. Add(' I:=FUNCA;');
  2606. Add(' FUNCA();');
  2607. Add(' FUNCA;');
  2608. ConvertProgram;
  2609. CheckSource('TestProcWithoutParams',
  2610. LinesToStr([ // statements
  2611. 'this.FuncA = function () {',
  2612. ' var Result = 0;',
  2613. ' return Result;',
  2614. '};',
  2615. 'this.i=0;'
  2616. ]),
  2617. LinesToStr([ // this.$main
  2618. '$mod.i=$mod.FuncA();',
  2619. '$mod.i=$mod.FuncA();',
  2620. '$mod.FuncA();',
  2621. '$mod.FuncA();'
  2622. ]));
  2623. end;
  2624. procedure TTestModule.TestProcedureWithoutParams;
  2625. begin
  2626. StartProgram(false);
  2627. Add('procedure ProcA;');
  2628. Add('begin');
  2629. Add('end;');
  2630. Add('begin');
  2631. Add(' PROCA();');
  2632. Add(' PROCA;');
  2633. ConvertProgram;
  2634. CheckSource('TestProcWithoutParams',
  2635. LinesToStr([ // statements
  2636. 'this.ProcA = function () {',
  2637. '};'
  2638. ]),
  2639. LinesToStr([ // this.$main
  2640. '$mod.ProcA();',
  2641. '$mod.ProcA();'
  2642. ]));
  2643. end;
  2644. procedure TTestModule.TestIncDec;
  2645. begin
  2646. StartProgram(false);
  2647. Add([
  2648. 'procedure DoIt(var i: longint);',
  2649. 'begin',
  2650. ' inc(i);',
  2651. ' inc(i,2);',
  2652. 'end;',
  2653. 'var',
  2654. ' Bar: longint;',
  2655. 'begin',
  2656. ' inc(bar);',
  2657. ' inc(bar,2);',
  2658. ' dec(bar);',
  2659. ' dec(bar,3);',
  2660. '']);
  2661. ConvertProgram;
  2662. CheckSource('TestIncDec',
  2663. LinesToStr([ // statements
  2664. 'this.DoIt = function (i) {',
  2665. ' i.set(i.get()+1);',
  2666. ' i.set(i.get()+2);',
  2667. '};',
  2668. 'this.Bar = 0;'
  2669. ]),
  2670. LinesToStr([ // this.$main
  2671. '$mod.Bar+=1;',
  2672. '$mod.Bar+=2;',
  2673. '$mod.Bar-=1;',
  2674. '$mod.Bar-=3;'
  2675. ]));
  2676. end;
  2677. procedure TTestModule.TestLoHiFpcMode;
  2678. begin
  2679. StartProgram(false);
  2680. Add([
  2681. '{$mode objfpc}',
  2682. 'const',
  2683. ' LoByte1 = Lo(Word($1234));',
  2684. ' HiByte1 = Hi(Word($1234));',
  2685. ' LoByte2 = Lo(SmallInt($1234));',
  2686. ' HiByte2 = Hi(SmallInt($1234));',
  2687. ' LoWord1 = Lo($1234CDEF);',
  2688. ' HiWord1 = Hi($1234CDEF);',
  2689. ' LoWord2 = Lo(-$1234CDEF);',
  2690. ' HiWord2 = Hi(-$1234CDEF);',
  2691. ' lo4:byte=lo(byte($34));',
  2692. ' hi4:byte=hi(byte($34));',
  2693. ' lo5:byte=lo(shortint(-$34));',
  2694. ' hi5:byte=hi(shortint(-$34));',
  2695. ' lo6:longword=lo($123456789ABCD);',
  2696. ' hi6:longword=hi($123456789ABCD);',
  2697. ' lo7:longword=lo(-$123456789ABCD);',
  2698. ' hi7:longword=hi(-$123456789ABCD);',
  2699. 'var',
  2700. ' b: Byte;',
  2701. ' ss: shortint;',
  2702. ' w: Word;',
  2703. ' si: SmallInt;',
  2704. ' lw: LongWord;',
  2705. ' li: LongInt;',
  2706. ' b2: Byte;',
  2707. ' ni: nativeint;',
  2708. 'begin',
  2709. ' w := $1234;',
  2710. ' ss := -$12;',
  2711. ' b := lo(ss);',
  2712. ' b := HI(ss);',
  2713. ' b := lo(w);',
  2714. ' b := HI(w);',
  2715. ' b2 := lo(b);',
  2716. ' b2 := hi(b);',
  2717. ' lw := $1234CDEF;',
  2718. ' w := lo(lw);',
  2719. ' w := hi(lw);',
  2720. ' ni := $123456789ABCD;',
  2721. ' lw := lo(ni);',
  2722. ' lw := hi(ni);',
  2723. '']);
  2724. ConvertProgram;
  2725. CheckSource('TestLoHiFpcMode',
  2726. LinesToStr([ // statements
  2727. 'this.LoByte1 = 0x1234 & 0xFF;',
  2728. 'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
  2729. 'this.LoByte2 = 0x1234 & 0xFF;',
  2730. 'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
  2731. 'this.LoWord1 = 0x1234CDEF & 0xFFFF;',
  2732. 'this.HiWord1 = (0x1234CDEF >> 16) & 0xFFFF;',
  2733. 'this.LoWord2 = -0x1234CDEF & 0xFFFF;',
  2734. 'this.HiWord2 = (-0x1234CDEF >> 16) & 0xFFFF;',
  2735. 'this.lo4 = 0x34 & 0xF;',
  2736. 'this.hi4 = (0x34 >> 4) & 0xF;',
  2737. 'this.lo5 = (((-0x34 & 255) << 24) >> 24) & 0xFF;',
  2738. 'this.hi5 = ((((-0x34 & 255) << 24) >> 24) >> 8) & 0xFF;',
  2739. 'this.lo6 = 0x123456789ABCD >>> 0;',
  2740. 'this.hi6 = 74565 >>> 0;',
  2741. 'this.lo7 = -0x123456789ABCD >>> 0;',
  2742. 'this.hi7 = Math.floor(-0x123456789ABCD / 4294967296) >>> 0;',
  2743. 'this.b = 0;',
  2744. 'this.ss = 0;',
  2745. 'this.w = 0;',
  2746. 'this.si = 0;',
  2747. 'this.lw = 0;',
  2748. 'this.li = 0;',
  2749. 'this.b2 = 0;',
  2750. 'this.ni = 0;',
  2751. '']),
  2752. LinesToStr([ // this.$main
  2753. '$mod.w = 0x1234;',
  2754. '$mod.ss = -0x12;',
  2755. '$mod.b = $mod.ss & 0xFF;',
  2756. '$mod.b = ($mod.ss >> 8) & 0xFF;',
  2757. '$mod.b = $mod.w & 0xFF;',
  2758. '$mod.b = ($mod.w >> 8) & 0xFF;',
  2759. '$mod.b2 = $mod.b & 0xF;',
  2760. '$mod.b2 = ($mod.b >> 4) & 0xF;',
  2761. '$mod.lw = 0x1234CDEF;',
  2762. '$mod.w = $mod.lw & 0xFFFF;',
  2763. '$mod.w = ($mod.lw >> 16) & 0xFFFF;',
  2764. '$mod.ni = 0x123456789ABCD;',
  2765. '$mod.lw = $mod.ni >>> 0;',
  2766. '$mod.lw = Math.floor($mod.ni / 4294967296) >>> 0;',
  2767. '']));
  2768. end;
  2769. procedure TTestModule.TestLoHiDelphiMode;
  2770. begin
  2771. StartProgram(false);
  2772. Add([
  2773. '{$mode delphi}',
  2774. 'const',
  2775. ' LoByte1 = Lo(Word($1234));',
  2776. ' HiByte1 = Hi(Word($1234));',
  2777. ' LoByte2 = Lo(SmallInt($1234));',
  2778. ' HiByte2 = Hi(SmallInt($1234));',
  2779. ' LoByte3 = Lo($1234CDEF);',
  2780. ' HiByte3 = Hi($1234CDEF);',
  2781. ' LoByte4 = Lo(-$1234CDEF);',
  2782. ' HiByte4 = Hi(-$1234CDEF);',
  2783. 'var',
  2784. ' b: Byte;',
  2785. ' w: Word;',
  2786. ' si: SmallInt;',
  2787. ' lw: LongWord;',
  2788. ' li: LongInt;',
  2789. 'begin',
  2790. ' w := $1234;',
  2791. ' b := lo(w);',
  2792. ' b := HI(w);',
  2793. ' lw := $1234CDEF;',
  2794. ' b := lo(lw);',
  2795. ' b := hi(lw);',
  2796. '']);
  2797. ConvertProgram;
  2798. CheckSource('TestLoHiDelphiMode',
  2799. LinesToStr([ // statements
  2800. 'this.LoByte1 = 0x1234 & 0xFF;',
  2801. 'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
  2802. 'this.LoByte2 = 0x1234 & 0xFF;',
  2803. 'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
  2804. 'this.LoByte3 = 0x1234CDEF & 0xFF;',
  2805. 'this.HiByte3 = (0x1234CDEF >> 8) & 0xFF;',
  2806. 'this.LoByte4 = -0x1234CDEF & 0xFF;',
  2807. 'this.HiByte4 = (-0x1234CDEF >> 8) & 0xFF;',
  2808. 'this.b = 0;',
  2809. 'this.w = 0;',
  2810. 'this.si = 0;',
  2811. 'this.lw = 0;',
  2812. 'this.li = 0;'
  2813. ]),
  2814. LinesToStr([ // this.$main
  2815. '$mod.w = 0x1234;',
  2816. '$mod.b = $mod.w & 0xFF;',
  2817. '$mod.b = ($mod.w >> 8) & 0xFF;',
  2818. '$mod.lw = 0x1234CDEF;',
  2819. '$mod.b = $mod.lw & 0xFF;',
  2820. '$mod.b = ($mod.lw >> 8) & 0xFF;'
  2821. ]));
  2822. end;
  2823. procedure TTestModule.TestAssignments;
  2824. begin
  2825. StartProgram(false);
  2826. Parser.Options:=Parser.Options+[po_cassignments];
  2827. Add('var');
  2828. Add(' Bar:longint;');
  2829. Add('begin');
  2830. Add(' bar:=3;');
  2831. Add(' bar+=4;');
  2832. Add(' bar-=5;');
  2833. Add(' bar*=6;');
  2834. ConvertProgram;
  2835. CheckSource('TestAssignments',
  2836. LinesToStr([ // statements
  2837. 'this.Bar = 0;'
  2838. ]),
  2839. LinesToStr([ // this.$main
  2840. '$mod.Bar=3;',
  2841. '$mod.Bar+=4;',
  2842. '$mod.Bar-=5;',
  2843. '$mod.Bar*=6;'
  2844. ]));
  2845. end;
  2846. procedure TTestModule.TestArithmeticOperators1;
  2847. begin
  2848. StartProgram(false);
  2849. Add('var');
  2850. Add(' vA,vB,vC:longint;');
  2851. Add('begin');
  2852. Add(' va:=1;');
  2853. Add(' vb:=va+va;');
  2854. Add(' vb:=va div vb;');
  2855. Add(' vb:=va mod vb;');
  2856. Add(' vb:=va+va*vb+va div vb;');
  2857. Add(' vc:=-va;');
  2858. Add(' va:=va-vb;');
  2859. Add(' vb:=va;');
  2860. Add(' if va<vb then vc:=va else vc:=vb;');
  2861. ConvertProgram;
  2862. CheckSource('TestArithmeticOperators1',
  2863. LinesToStr([ // statements
  2864. 'this.vA = 0;',
  2865. 'this.vB = 0;',
  2866. 'this.vC = 0;'
  2867. ]),
  2868. LinesToStr([ // this.$main
  2869. '$mod.vA = 1;',
  2870. '$mod.vB = $mod.vA + $mod.vA;',
  2871. '$mod.vB = Math.floor($mod.vA / $mod.vB);',
  2872. '$mod.vB = $mod.vA % $mod.vB;',
  2873. '$mod.vB = $mod.vA + ($mod.vA * $mod.vB) + Math.floor($mod.vA / $mod.vB);',
  2874. '$mod.vC = -$mod.vA;',
  2875. '$mod.vA = $mod.vA - $mod.vB;',
  2876. '$mod.vB = $mod.vA;',
  2877. 'if ($mod.vA < $mod.vB){ $mod.vC = $mod.vA } else $mod.vC = $mod.vB;'
  2878. ]));
  2879. end;
  2880. procedure TTestModule.TestLogicalOperators;
  2881. begin
  2882. StartProgram(false);
  2883. Add('var');
  2884. Add(' vA,vB,vC:boolean;');
  2885. Add('begin');
  2886. Add(' va:=vb and vc;');
  2887. Add(' va:=vb or vc;');
  2888. Add(' va:=vb xor vc;');
  2889. Add(' va:=true and vc;');
  2890. Add(' va:=(vb and vc) or (va and vb);');
  2891. Add(' va:=not vb;');
  2892. ConvertProgram;
  2893. CheckSource('TestLogicalOperators',
  2894. LinesToStr([ // statements
  2895. 'this.vA = false;',
  2896. 'this.vB = false;',
  2897. 'this.vC = false;'
  2898. ]),
  2899. LinesToStr([ // this.$main
  2900. '$mod.vA = $mod.vB && $mod.vC;',
  2901. '$mod.vA = $mod.vB || $mod.vC;',
  2902. '$mod.vA = $mod.vB ^ $mod.vC;',
  2903. '$mod.vA = true && $mod.vC;',
  2904. '$mod.vA = ($mod.vB && $mod.vC) || ($mod.vA && $mod.vB);',
  2905. '$mod.vA = !$mod.vB;'
  2906. ]));
  2907. end;
  2908. procedure TTestModule.TestBitwiseOperators;
  2909. begin
  2910. StartProgram(false);
  2911. Add([
  2912. 'var',
  2913. ' vA,vB,vC:longint;',
  2914. ' X,Y,Z: nativeint;',
  2915. 'begin',
  2916. ' va:=vb and vc;',
  2917. ' va:=vb or vc;',
  2918. ' va:=vb xor vc;',
  2919. ' va:=vb shl vc;',
  2920. ' va:=vb shr vc;',
  2921. ' va:=3 and vc;',
  2922. ' va:=(vb and vc) or (va and vb);',
  2923. ' va:=not vb;',
  2924. ' X:=Y and Z;',
  2925. ' X:=Y and va;',
  2926. ' X:=Y or Z;',
  2927. ' X:=Y or va;',
  2928. ' X:=Y xor Z;',
  2929. ' X:=Y xor va;',
  2930. '']);
  2931. ConvertProgram;
  2932. CheckSource('TestBitwiseOperators',
  2933. LinesToStr([ // statements
  2934. 'this.vA = 0;',
  2935. 'this.vB = 0;',
  2936. 'this.vC = 0;',
  2937. 'this.X = 0;',
  2938. 'this.Y = 0;',
  2939. 'this.Z = 0;',
  2940. '']),
  2941. LinesToStr([ // this.$main
  2942. '$mod.vA = $mod.vB & $mod.vC;',
  2943. '$mod.vA = $mod.vB | $mod.vC;',
  2944. '$mod.vA = $mod.vB ^ $mod.vC;',
  2945. '$mod.vA = $mod.vB << $mod.vC;',
  2946. '$mod.vA = $mod.vB >>> $mod.vC;',
  2947. '$mod.vA = 3 & $mod.vC;',
  2948. '$mod.vA = ($mod.vB & $mod.vC) | ($mod.vA & $mod.vB);',
  2949. '$mod.vA = ~$mod.vB;',
  2950. '$mod.X = rtl.and($mod.Y, $mod.Z);',
  2951. '$mod.X = $mod.Y & $mod.vA;',
  2952. '$mod.X = rtl.or($mod.Y, $mod.Z);',
  2953. '$mod.X = rtl.or($mod.Y, $mod.vA);',
  2954. '$mod.X = rtl.xor($mod.Y, $mod.Z);',
  2955. '$mod.X = rtl.xor($mod.Y, $mod.vA);',
  2956. '']));
  2957. end;
  2958. procedure TTestModule.TestPrgProcVar;
  2959. begin
  2960. StartProgram(false);
  2961. Add('procedure Proc1;');
  2962. Add('type');
  2963. Add(' t1=longint;');
  2964. Add('var');
  2965. Add(' vA:t1;');
  2966. Add('begin');
  2967. Add('end;');
  2968. Add('begin');
  2969. ConvertProgram;
  2970. CheckSource('TestPrgProcVar',
  2971. LinesToStr([ // statements
  2972. 'this.Proc1 = function () {',
  2973. ' var vA=0;',
  2974. '};'
  2975. ]),
  2976. LinesToStr([ // this.$main
  2977. ''
  2978. ]));
  2979. end;
  2980. procedure TTestModule.TestUnitProcVar;
  2981. begin
  2982. StartUnit(false);
  2983. Add('interface');
  2984. Add('');
  2985. Add('type tA=string; // unit scope');
  2986. Add('procedure Proc1;');
  2987. Add('');
  2988. Add('implementation');
  2989. Add('');
  2990. Add('procedure Proc1;');
  2991. Add('type tA=longint; // local proc scope');
  2992. Add('var v1:tA; // using local tA');
  2993. Add('begin');
  2994. Add('end;');
  2995. Add('var v2:tA; // using interface tA');
  2996. ConvertUnit;
  2997. CheckSource('TestUnitProcVar',
  2998. LinesToStr([ // statements
  2999. 'var $impl = $mod.$impl;',
  3000. 'this.Proc1 = function () {',
  3001. ' var v1 = 0;',
  3002. '};',
  3003. '']),
  3004. // this.$init
  3005. '',
  3006. // implementation
  3007. LinesToStr([
  3008. '$impl.v2 = "";',
  3009. '']));
  3010. end;
  3011. procedure TTestModule.TestImplProc;
  3012. begin
  3013. StartUnit(false);
  3014. Add('interface');
  3015. Add('');
  3016. Add('procedure Proc1;');
  3017. Add('');
  3018. Add('implementation');
  3019. Add('');
  3020. Add('procedure Proc1; begin end;');
  3021. Add('procedure Proc2; begin end;');
  3022. Add('initialization');
  3023. Add(' Proc1;');
  3024. Add(' Proc2;');
  3025. ConvertUnit;
  3026. CheckSource('TestImplProc',
  3027. LinesToStr([ // statements
  3028. 'var $impl = $mod.$impl;',
  3029. 'this.Proc1 = function () {',
  3030. '};',
  3031. '']),
  3032. LinesToStr([ // this.$init
  3033. '$mod.Proc1();',
  3034. '$impl.Proc2();',
  3035. '']),
  3036. LinesToStr([ // implementation
  3037. '$impl.Proc2 = function () {',
  3038. '};',
  3039. ''])
  3040. );
  3041. end;
  3042. procedure TTestModule.TestFunctionResult;
  3043. begin
  3044. StartProgram(false);
  3045. Add('function Func1: longint;');
  3046. Add('begin');
  3047. Add(' Result:=3;');
  3048. Add(' Func1:=4;');
  3049. Add('end;');
  3050. Add('begin');
  3051. ConvertProgram;
  3052. CheckSource('TestFunctionResult',
  3053. LinesToStr([ // statements
  3054. 'this.Func1 = function () {',
  3055. ' var Result = 0;',
  3056. ' Result = 3;',
  3057. ' Result = 4;',
  3058. ' return Result;',
  3059. '};'
  3060. ]),
  3061. '');
  3062. end;
  3063. procedure TTestModule.TestNestedProc;
  3064. begin
  3065. StartProgram(false);
  3066. Add([
  3067. 'var vInUnit: longint;',
  3068. 'function DoIt(pA,pD: longint): longint;',
  3069. 'var',
  3070. ' vB: longint;',
  3071. ' vC: longint;',
  3072. ' function Nesty(pA: longint): longint; ',
  3073. ' var vB: longint;',
  3074. ' begin',
  3075. ' Result:=pa+vb+vc+pd+vInUnit;',
  3076. ' nesty:=3;',
  3077. ' doit:=4;',
  3078. ' exit;',
  3079. ' end;',
  3080. 'begin',
  3081. ' Result:=pa+vb+vc;',
  3082. ' doit:=6;',
  3083. ' exit;',
  3084. 'end;',
  3085. 'begin']);
  3086. ConvertProgram;
  3087. CheckSource('TestNestedProc',
  3088. LinesToStr([ // statements
  3089. 'this.vInUnit = 0;',
  3090. 'this.DoIt = function (pA, pD) {',
  3091. ' var Result = 0;',
  3092. ' var vB = 0;',
  3093. ' var vC = 0;',
  3094. ' function Nesty(pA) {',
  3095. ' var Result$1 = 0;',
  3096. ' var vB = 0;',
  3097. ' Result$1 = pA + vB + vC + pD + $mod.vInUnit;',
  3098. ' Result$1 = 3;',
  3099. ' Result = 4;',
  3100. ' return Result$1;',
  3101. ' return Result$1;',
  3102. ' };',
  3103. ' Result = pA + vB + vC;',
  3104. ' Result = 6;',
  3105. ' return Result;',
  3106. ' return Result;',
  3107. '};'
  3108. ]),
  3109. '');
  3110. end;
  3111. procedure TTestModule.TestNestedProc_ResultString;
  3112. begin
  3113. StartProgram(false);
  3114. Add([
  3115. 'function DoIt: string;',
  3116. ' function Nesty: string; ',
  3117. ' begin',
  3118. ' nesty:=#65#66;',
  3119. ' nesty[1]:=#67;',
  3120. ' doit:=#68;',
  3121. ' doit[2]:=#69;',
  3122. ' end;',
  3123. 'begin',
  3124. ' doit:=#70;',
  3125. ' doit[3]:=#71;',
  3126. 'end;',
  3127. 'begin']);
  3128. ConvertProgram;
  3129. CheckSource('TestNestedProc_ResultString',
  3130. LinesToStr([ // statements
  3131. 'this.DoIt = function () {',
  3132. ' var Result = "";',
  3133. ' function Nesty() {',
  3134. ' var Result$1 = "";',
  3135. ' Result$1 = "AB";',
  3136. ' Result$1 = rtl.setCharAt(Result$1, 0, "C");',
  3137. ' Result = "D";',
  3138. ' Result = rtl.setCharAt(Result, 1, "E");',
  3139. ' return Result$1;',
  3140. ' };',
  3141. ' Result = "F";',
  3142. ' Result = rtl.setCharAt(Result, 2, "G");',
  3143. ' return Result;',
  3144. '};'
  3145. ]),
  3146. '');
  3147. end;
  3148. procedure TTestModule.TestForwardProc;
  3149. begin
  3150. StartProgram(false);
  3151. Add('procedure FuncA(Bar: longint); forward;');
  3152. Add('procedure FuncB(Bar: longint);');
  3153. Add('begin');
  3154. Add(' funca(bar);');
  3155. Add('end;');
  3156. Add('procedure funca(bar: longint);');
  3157. Add('begin');
  3158. Add(' if bar=3 then ;');
  3159. Add('end;');
  3160. Add('begin');
  3161. Add(' funca(4);');
  3162. Add(' funcb(5);');
  3163. ConvertProgram;
  3164. CheckSource('TestForwardProc',
  3165. LinesToStr([ // statements'
  3166. 'this.FuncB = function (Bar) {',
  3167. ' $mod.FuncA(Bar);',
  3168. '};',
  3169. 'this.FuncA = function (Bar) {',
  3170. ' if (Bar === 3);',
  3171. '};'
  3172. ]),
  3173. LinesToStr([
  3174. '$mod.FuncA(4);',
  3175. '$mod.FuncB(5);'
  3176. ])
  3177. );
  3178. end;
  3179. procedure TTestModule.TestNestedForwardProc;
  3180. begin
  3181. StartProgram(false);
  3182. Add('procedure FuncA;');
  3183. Add(' procedure FuncB(i: longint); forward;');
  3184. Add(' procedure FuncC(i: longint);');
  3185. Add(' begin');
  3186. Add(' funcb(i);');
  3187. Add(' end;');
  3188. Add(' procedure FuncB(i: longint);');
  3189. Add(' begin');
  3190. Add(' if i=3 then ;');
  3191. Add(' end;');
  3192. Add('begin');
  3193. Add(' funcc(4)');
  3194. Add('end;');
  3195. Add('begin');
  3196. Add(' funca;');
  3197. ConvertProgram;
  3198. CheckSource('TestNestedForwardProc',
  3199. LinesToStr([ // statements'
  3200. 'this.FuncA = function () {',
  3201. ' function FuncC(i) {',
  3202. ' FuncB(i);',
  3203. ' };',
  3204. ' function FuncB(i) {',
  3205. ' if (i === 3);',
  3206. ' };',
  3207. ' FuncC(4);',
  3208. '};'
  3209. ]),
  3210. LinesToStr([
  3211. '$mod.FuncA();'
  3212. ])
  3213. );
  3214. end;
  3215. procedure TTestModule.TestAssignFunctionResult;
  3216. begin
  3217. StartProgram(false);
  3218. Add('function Func1: longint;');
  3219. Add('begin');
  3220. Add('end;');
  3221. Add('var i: longint;');
  3222. Add('begin');
  3223. Add(' i:=func1();');
  3224. Add(' i:=func1()+func1();');
  3225. ConvertProgram;
  3226. CheckSource('TestAssignFunctionResult',
  3227. LinesToStr([ // statements
  3228. 'this.Func1 = function () {',
  3229. ' var Result = 0;',
  3230. ' return Result;',
  3231. '};',
  3232. 'this.i = 0;'
  3233. ]),
  3234. LinesToStr([
  3235. '$mod.i = $mod.Func1();',
  3236. '$mod.i = $mod.Func1() + $mod.Func1();'
  3237. ]));
  3238. end;
  3239. procedure TTestModule.TestFunctionResultInCondition;
  3240. begin
  3241. StartProgram(false);
  3242. Add('function Func1: longint;');
  3243. Add('begin');
  3244. Add('end;');
  3245. Add('function Func2: boolean;');
  3246. Add('begin');
  3247. Add('end;');
  3248. Add('var i: longint;');
  3249. Add('begin');
  3250. Add(' if func2 then ;');
  3251. Add(' if i=func1() then ;');
  3252. Add(' if i=func1 then ;');
  3253. ConvertProgram;
  3254. CheckSource('TestFunctionResultInCondition',
  3255. LinesToStr([ // statements
  3256. 'this.Func1 = function () {',
  3257. ' var Result = 0;',
  3258. ' return Result;',
  3259. '};',
  3260. 'this.Func2 = function () {',
  3261. ' var Result = false;',
  3262. ' return Result;',
  3263. '};',
  3264. 'this.i = 0;'
  3265. ]),
  3266. LinesToStr([
  3267. 'if ($mod.Func2());',
  3268. 'if ($mod.i === $mod.Func1());',
  3269. 'if ($mod.i === $mod.Func1());'
  3270. ]));
  3271. end;
  3272. procedure TTestModule.TestFunctionResultInForLoop;
  3273. begin
  3274. StartProgram(false);
  3275. Add([
  3276. 'function Func1(a: array of longint): longint;',
  3277. 'begin',
  3278. ' for Result:=High(a) downto Low(a) do if a[Result]=0 then exit;',
  3279. ' for Result in a do if a[Result]=0 then exit;',
  3280. 'end;',
  3281. 'begin',
  3282. ' Func1([1,2,3])']);
  3283. ConvertProgram;
  3284. CheckSource('TestFunctionResultInForLoop',
  3285. LinesToStr([ // statements
  3286. 'this.Func1 = function (a) {',
  3287. ' var Result = 0;',
  3288. ' for (var $l1 = rtl.length(a) - 1; $l1 >= 0; $l1--) {',
  3289. ' Result = $l1;',
  3290. ' if (a[Result] === 0) return Result;',
  3291. ' };',
  3292. ' for (var $in2 = a, $l3 = 0, $end4 = rtl.length($in2) - 1; $l3 <= $end4; $l3++) {',
  3293. ' Result = $in2[$l3];',
  3294. ' if (a[Result] === 0) return Result;',
  3295. ' };',
  3296. ' return Result;',
  3297. '};',
  3298. '']),
  3299. LinesToStr([
  3300. '$mod.Func1([1, 2, 3]);'
  3301. ]));
  3302. end;
  3303. procedure TTestModule.TestFunctionResultInTypeCast;
  3304. begin
  3305. StartProgram(false);
  3306. Add([
  3307. 'function GetInt: longint;',
  3308. 'begin',
  3309. 'end;',
  3310. 'begin',
  3311. ' if Byte(GetInt)=0 then ;',
  3312. '']);
  3313. ConvertProgram;
  3314. CheckSource('TestFunctionResultInTypeCast',
  3315. LinesToStr([ // statements
  3316. 'this.GetInt = function () {',
  3317. ' var Result = 0;',
  3318. ' return Result;',
  3319. '};',
  3320. '']),
  3321. LinesToStr([
  3322. 'if (($mod.GetInt() & 255) === 0) ;'
  3323. ]));
  3324. end;
  3325. procedure TTestModule.TestExit;
  3326. begin
  3327. StartProgram(false);
  3328. Add('procedure ProcA;');
  3329. Add('begin');
  3330. Add(' exit;');
  3331. Add('end;');
  3332. Add('function FuncB: longint;');
  3333. Add('begin');
  3334. Add(' exit;');
  3335. Add(' exit(3);');
  3336. Add('end;');
  3337. Add('function FuncC: string;');
  3338. Add('begin');
  3339. Add(' exit;');
  3340. Add(' exit(''a'');');
  3341. Add(' exit(''abc'');');
  3342. Add('end;');
  3343. Add('begin');
  3344. Add(' exit;');
  3345. Add(' exit(1);');
  3346. ConvertProgram;
  3347. CheckSource('TestExit',
  3348. LinesToStr([ // statements
  3349. 'this.ProcA = function () {',
  3350. ' return;',
  3351. '};',
  3352. 'this.FuncB = function () {',
  3353. ' var Result = 0;',
  3354. ' return Result;',
  3355. ' return 3;',
  3356. ' return Result;',
  3357. '};',
  3358. 'this.FuncC = function () {',
  3359. ' var Result = "";',
  3360. ' return Result;',
  3361. ' return "a";',
  3362. ' return "abc";',
  3363. ' return Result;',
  3364. '};'
  3365. ]),
  3366. LinesToStr([
  3367. 'return;',
  3368. 'return 1;',
  3369. '']));
  3370. end;
  3371. procedure TTestModule.TestBreak;
  3372. begin
  3373. StartProgram(false);
  3374. Add([
  3375. 'var',
  3376. ' i: longint;',
  3377. 'begin',
  3378. ' repeat',
  3379. ' break;',
  3380. ' until true;',
  3381. ' while true do',
  3382. ' break;',
  3383. ' for i:=1 to 2 do',
  3384. ' break;']);
  3385. ConvertProgram;
  3386. CheckSource('TestBreak',
  3387. LinesToStr([ // statements
  3388. 'this.i = 0;'
  3389. ]),
  3390. LinesToStr([
  3391. 'do {',
  3392. ' break;',
  3393. '} while (!true);',
  3394. 'while (true) break;',
  3395. 'for ($mod.i = 1; $mod.i <= 2; $mod.i++) break;',
  3396. '']));
  3397. end;
  3398. procedure TTestModule.TestBreakAsVar;
  3399. begin
  3400. StartProgram(false);
  3401. Add([
  3402. 'procedure DoIt(break: boolean);',
  3403. 'begin',
  3404. ' if break then ;',
  3405. 'end;',
  3406. 'var',
  3407. ' break: boolean;',
  3408. 'begin',
  3409. ' if break then ;']);
  3410. ConvertProgram;
  3411. CheckSource('TestBreakAsVar',
  3412. LinesToStr([ // statements
  3413. 'this.DoIt = function (Break) {',
  3414. ' if (Break) ;',
  3415. '};',
  3416. 'this.Break = false;',
  3417. '']),
  3418. LinesToStr([
  3419. 'if($mod.Break) ;',
  3420. '']));
  3421. end;
  3422. procedure TTestModule.TestContinue;
  3423. begin
  3424. StartProgram(false);
  3425. Add('var i: longint;');
  3426. Add('begin');
  3427. Add(' repeat');
  3428. Add(' continue;');
  3429. Add(' until true;');
  3430. Add(' while true do');
  3431. Add(' continue;');
  3432. Add(' for i:=1 to 2 do');
  3433. Add(' continue;');
  3434. ConvertProgram;
  3435. CheckSource('TestContinue',
  3436. LinesToStr([ // statements
  3437. 'this.i = 0;'
  3438. ]),
  3439. LinesToStr([
  3440. 'do {',
  3441. ' continue;',
  3442. '} while (!true);',
  3443. 'while (true) continue;',
  3444. 'for ($mod.i = 1; $mod.i <= 2; $mod.i++) continue;',
  3445. '']));
  3446. end;
  3447. procedure TTestModule.TestProc_External;
  3448. begin
  3449. StartProgram(false);
  3450. Add('procedure Foo; external name ''console.log'';');
  3451. Add('function Bar: longint; external name ''get.item'';');
  3452. Add('function Bla(s: string): longint; external name ''apply.something'';');
  3453. Add('var');
  3454. Add(' i: longint;');
  3455. Add('begin');
  3456. Add(' Foo;');
  3457. Add(' i:=Bar;');
  3458. Add(' i:=Bla(''abc'');');
  3459. ConvertProgram;
  3460. CheckSource('TestProc_External',
  3461. LinesToStr([ // statements
  3462. 'this.i = 0;'
  3463. ]),
  3464. LinesToStr([
  3465. 'console.log();',
  3466. '$mod.i = get.item();',
  3467. '$mod.i = apply.something("abc");'
  3468. ]));
  3469. end;
  3470. procedure TTestModule.TestProc_ExternalOtherUnit;
  3471. begin
  3472. AddModuleWithIntfImplSrc('unit2.pas',
  3473. LinesToStr([
  3474. 'procedure Now; external name ''Date.now'';',
  3475. 'procedure DoIt;'
  3476. ]),
  3477. 'procedure doit; begin end;');
  3478. StartUnit(true);
  3479. Add('interface');
  3480. Add('uses unit2;');
  3481. Add('implementation');
  3482. Add('begin');
  3483. Add(' now;');
  3484. Add(' now();');
  3485. Add(' uNit2.now;');
  3486. Add(' uNit2.now();');
  3487. Add(' doit;');
  3488. Add(' uNit2.doit;');
  3489. ConvertUnit;
  3490. CheckSource('TestProc_ExternalOtherUnit',
  3491. LinesToStr([
  3492. '']),
  3493. LinesToStr([
  3494. 'Date.now();',
  3495. 'Date.now();',
  3496. 'Date.now();',
  3497. 'Date.now();',
  3498. 'pas.unit2.DoIt();',
  3499. 'pas.unit2.DoIt();',
  3500. '']));
  3501. end;
  3502. procedure TTestModule.TestProc_Asm;
  3503. begin
  3504. StartProgram(false);
  3505. Add([
  3506. '{$mode delphi}',
  3507. 'function DoIt: longint;',
  3508. 'begin;',
  3509. ' asm',
  3510. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3511. ' end;',
  3512. ' asm console.log(); end;',
  3513. ' asm',
  3514. ' s = "'' ";',
  3515. ' s = ''" '';',
  3516. ' s = s + "world" + "''";',
  3517. ' // end',
  3518. ' s = ''end'';',
  3519. ' s = "end";',
  3520. ' s = "foo\"bar";',
  3521. ' s = ''a\''b'';',
  3522. ' s = `${expr}\`-"-''-`;',
  3523. ' s = `multi',
  3524. 'line`;',
  3525. ' end;',
  3526. 'end;',
  3527. 'procedure Fly;',
  3528. 'asm',
  3529. ' return;',
  3530. 'end;',
  3531. 'begin']);
  3532. ConvertProgram;
  3533. CheckSource('TestProc_Asm',
  3534. LinesToStr([ // statements
  3535. 'this.DoIt = function () {',
  3536. ' var Result = 0;',
  3537. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3538. ' console.log();',
  3539. ' s = "'' ";',
  3540. ' s = ''" '';',
  3541. ' s = s + "world" + "''";',
  3542. ' // end',
  3543. ' s = ''end'';',
  3544. ' s = "end";',
  3545. ' s = "foo\"bar";',
  3546. ' s = ''a\''b'';',
  3547. ' s = `${expr}\`-"-''-`;',
  3548. ' s = `multi',
  3549. 'line`;',
  3550. ' return Result;',
  3551. '};',
  3552. 'this.Fly = function () {',
  3553. ' return;',
  3554. '};',
  3555. '']),
  3556. LinesToStr([
  3557. ''
  3558. ]));
  3559. end;
  3560. procedure TTestModule.TestProc_Assembler;
  3561. begin
  3562. StartProgram(false);
  3563. Add('function DoIt: longint; assembler;');
  3564. Add('asm');
  3565. Add('{ a:{ b:{}, c:[]}, d:''1'' };');
  3566. Add('end;');
  3567. Add('begin');
  3568. ConvertProgram;
  3569. CheckSource('TestProc_Assembler',
  3570. LinesToStr([ // statements
  3571. 'this.DoIt = function () {',
  3572. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3573. '};'
  3574. ]),
  3575. LinesToStr([
  3576. ''
  3577. ]));
  3578. end;
  3579. procedure TTestModule.TestProc_VarParam;
  3580. begin
  3581. StartProgram(false);
  3582. Add('type integer = longint;');
  3583. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  3584. Add('var vJ: integer;');
  3585. Add('begin');
  3586. Add(' vg:=vg+1;');
  3587. Add(' vj:=vh+2;');
  3588. Add(' vi:=vi+3;');
  3589. Add(' doit(vg,vg,vg);');
  3590. Add(' doit(vh,vh,vj);');
  3591. Add(' doit(vi,vi,vi);');
  3592. Add(' doit(vj,vj,vj);');
  3593. Add('end;');
  3594. Add('var i: integer;');
  3595. Add('begin');
  3596. Add(' doit(i,i,i);');
  3597. ConvertProgram;
  3598. CheckSource('TestProc_VarParam',
  3599. LinesToStr([ // statements
  3600. 'this.DoIt = function (vG,vH,vI) {',
  3601. ' var vJ = 0;',
  3602. ' vG = vG + 1;',
  3603. ' vJ = vH + 2;',
  3604. ' vI.set(vI.get()+3);',
  3605. ' $mod.DoIt(vG, vG, {',
  3606. ' get: function () {',
  3607. ' return vG;',
  3608. ' },',
  3609. ' set: function (v) {',
  3610. ' vG = v;',
  3611. ' }',
  3612. ' });',
  3613. ' $mod.DoIt(vH, vH, {',
  3614. ' get: function () {',
  3615. ' return vJ;',
  3616. ' },',
  3617. ' set: function (v) {',
  3618. ' vJ = v;',
  3619. ' }',
  3620. ' });',
  3621. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  3622. ' $mod.DoIt(vJ, vJ, {',
  3623. ' get: function () {',
  3624. ' return vJ;',
  3625. ' },',
  3626. ' set: function (v) {',
  3627. ' vJ = v;',
  3628. ' }',
  3629. ' });',
  3630. '};',
  3631. 'this.i = 0;'
  3632. ]),
  3633. LinesToStr([
  3634. '$mod.DoIt($mod.i,$mod.i,{',
  3635. ' p: $mod,',
  3636. ' get: function () {',
  3637. ' return this.p.i;',
  3638. ' },',
  3639. ' set: function (v) {',
  3640. ' this.p.i = v;',
  3641. ' }',
  3642. '});'
  3643. ]));
  3644. end;
  3645. procedure TTestModule.TestProc_VarParamString;
  3646. begin
  3647. StartProgram(false);
  3648. Add(['type TCaption = string;',
  3649. 'procedure DoIt(vA: TCaption; var vB: TCaption; out vC: TCaption);',
  3650. 'var c: char;',
  3651. 'begin',
  3652. ' va[1]:=c;',
  3653. ' vb[2]:=c;',
  3654. ' vc[3]:=c;',
  3655. 'end;',
  3656. 'begin']);
  3657. ConvertProgram;
  3658. CheckSource('TestProc_VarParamString',
  3659. LinesToStr([ // statements
  3660. 'this.DoIt = function (vA,vB,vC) {',
  3661. ' var c = "";',
  3662. ' vA = rtl.setCharAt(vA, 0, c);',
  3663. ' vB.set(rtl.setCharAt(vB.get(), 1, c));',
  3664. ' vC.set(rtl.setCharAt(vC.get(), 2, c));',
  3665. '};',
  3666. '']),
  3667. LinesToStr([
  3668. ]));
  3669. end;
  3670. procedure TTestModule.TestProc_VarParamV;
  3671. begin
  3672. StartProgram(false);
  3673. Add([
  3674. 'procedure Inc2(var i: longint);',
  3675. 'begin',
  3676. ' i:=i+2;',
  3677. 'end;',
  3678. 'procedure DoIt(v: longint);',
  3679. 'var p: array of longint;',
  3680. 'begin',
  3681. ' Inc2(v);',
  3682. ' Inc2(p[v]);',
  3683. 'end;',
  3684. 'begin']);
  3685. ConvertProgram;
  3686. CheckSource('TestProc_VarParamV',
  3687. LinesToStr([ // statements
  3688. 'this.Inc2 = function (i) {',
  3689. ' i.set(i.get()+2);',
  3690. '};',
  3691. 'this.DoIt = function (v) {',
  3692. ' var p = [];',
  3693. ' $mod.Inc2({get: function () {',
  3694. ' return v;',
  3695. ' }, set: function (w) {',
  3696. ' v = w;',
  3697. ' }});',
  3698. ' $mod.Inc2({',
  3699. ' a: v,',
  3700. ' p: p,',
  3701. ' get: function () {',
  3702. ' return this.p[this.a];',
  3703. ' },',
  3704. ' set: function (v) {',
  3705. ' this.p[this.a] = v;',
  3706. ' }',
  3707. ' });',
  3708. '};',
  3709. '']),
  3710. LinesToStr([
  3711. '']));
  3712. end;
  3713. procedure TTestModule.TestProc_Overload;
  3714. begin
  3715. StartProgram(false);
  3716. Add('procedure DoIt(vI: longint); begin end;');
  3717. Add('procedure DoIt(vI, vJ: longint); begin end;');
  3718. Add('procedure DoIt(vD: double); begin end;');
  3719. Add('begin');
  3720. Add(' DoIt(1);');
  3721. Add(' DoIt(2,3);');
  3722. Add(' DoIt(4.5);');
  3723. ConvertProgram;
  3724. CheckSource('TestProcedureOverload',
  3725. LinesToStr([ // statements
  3726. 'this.DoIt = function (vI) {',
  3727. '};',
  3728. 'this.DoIt$1 = function (vI, vJ) {',
  3729. '};',
  3730. 'this.DoIt$2 = function (vD) {',
  3731. '};',
  3732. '']),
  3733. LinesToStr([
  3734. '$mod.DoIt(1);',
  3735. '$mod.DoIt$1(2, 3);',
  3736. '$mod.DoIt$2(4.5);',
  3737. '']));
  3738. end;
  3739. procedure TTestModule.TestProc_OverloadForward;
  3740. begin
  3741. StartProgram(false);
  3742. Add('procedure DoIt(vI: longint); forward;');
  3743. Add('procedure DoIt(vI, vJ: longint); begin end;');
  3744. Add('procedure doit(vi: longint); begin end;');
  3745. Add('begin');
  3746. Add(' doit(1);');
  3747. Add(' doit(2,3);');
  3748. ConvertProgram;
  3749. CheckSource('TestProcedureOverloadForward',
  3750. LinesToStr([ // statements
  3751. 'this.DoIt$1 = function (vI, vJ) {',
  3752. '};',
  3753. 'this.DoIt = function (vI) {',
  3754. '};',
  3755. '']),
  3756. LinesToStr([
  3757. '$mod.DoIt(1);',
  3758. '$mod.DoIt$1(2, 3);',
  3759. '']));
  3760. end;
  3761. procedure TTestModule.TestProc_OverloadIntfImpl;
  3762. begin
  3763. StartUnit(false);
  3764. Add('interface');
  3765. Add('procedure DoIt(vI: longint);');
  3766. Add('procedure DoIt(vI, vJ: longint);');
  3767. Add('implementation');
  3768. Add('procedure DoIt(vI, vJ, vK, vL, vM: longint); forward;');
  3769. Add('procedure DoIt(vI, vJ, vK: longint); begin end;');
  3770. Add('procedure DoIt(vi: longint); begin end;');
  3771. Add('procedure DoIt(vI, vJ, vK, vL: longint); begin end;');
  3772. Add('procedure DoIt(vi, vj: longint); begin end;');
  3773. Add('procedure DoIt(vi, vj, vk, vl, vm: longint); begin end;');
  3774. Add('begin');
  3775. Add(' doit(1);');
  3776. Add(' doit(2,3);');
  3777. Add(' doit(4,5,6);');
  3778. Add(' doit(7,8,9,10);');
  3779. Add(' doit(11,12,13,14,15);');
  3780. ConvertUnit;
  3781. CheckSource('TestProcedureOverloadUnit',
  3782. LinesToStr([ // statements
  3783. 'var $impl = $mod.$impl;',
  3784. 'this.DoIt = function (vI) {',
  3785. '};',
  3786. 'this.DoIt$1 = function (vI, vJ) {',
  3787. '};',
  3788. '']),
  3789. LinesToStr([ // this.$init
  3790. '$mod.DoIt(1);',
  3791. '$mod.DoIt$1(2, 3);',
  3792. '$impl.DoIt$3(4,5,6);',
  3793. '$impl.DoIt$4(7,8,9,10);',
  3794. '$impl.DoIt$2(11,12,13,14,15);',
  3795. '']),
  3796. LinesToStr([ // implementation
  3797. '$impl.DoIt$3 = function (vI, vJ, vK) {',
  3798. '};',
  3799. '$impl.DoIt$4 = function (vI, vJ, vK, vL) {',
  3800. '};',
  3801. '$impl.DoIt$2 = function (vI, vJ, vK, vL, vM) {',
  3802. '};',
  3803. '']));
  3804. end;
  3805. procedure TTestModule.TestProc_OverloadNested;
  3806. begin
  3807. StartProgram(false);
  3808. Add([
  3809. 'procedure DoIt(vA: longint); overload; forward;',
  3810. 'procedure DoIt(vB, vC: longint); overload;',
  3811. 'begin // 2 param overload',
  3812. ' doit(1);',
  3813. ' doit(1,2);',
  3814. 'end;',
  3815. 'procedure doit(vA: longint);',
  3816. ' procedure DoIt(vA, vB, vC: longint); overload; forward;',
  3817. ' procedure DoIt(vA, vB, vC, vD: longint); overload;',
  3818. ' begin // 4 param overload',
  3819. ' doit(1);',
  3820. ' doit(1,2);',
  3821. ' doit(1,2,3);',
  3822. ' doit(1,2,3,4);',
  3823. ' end;',
  3824. ' procedure doit(vA, vB, vC: longint);',
  3825. ' procedure DoIt(vA, vB, vC, vD, vE: longint); overload; forward;',
  3826. ' procedure DoIt(vA, vB, vC, vD, vE, vF: longint); overload;',
  3827. ' begin // 6 param overload',
  3828. ' doit(1);',
  3829. ' doit(1,2);',
  3830. ' doit(1,2,3);',
  3831. ' doit(1,2,3,4);',
  3832. ' doit(1,2,3,4,5);',
  3833. ' doit(1,2,3,4,5,6);',
  3834. ' end;',
  3835. ' procedure doit(vA, vB, vC, vD, vE: longint);',
  3836. ' begin // 5 param overload',
  3837. ' doit(1);',
  3838. ' doit(1,2);',
  3839. ' doit(1,2,3);',
  3840. ' doit(1,2,3,4);',
  3841. ' doit(1,2,3,4,5);',
  3842. ' doit(1,2,3,4,5,6);',
  3843. ' end;',
  3844. ' begin // 3 param overload',
  3845. ' doit(1);',
  3846. ' doit(1,2);',
  3847. ' doit(1,2,3);',
  3848. ' doit(1,2,3,4);',
  3849. ' doit(1,2,3,4,5);',
  3850. ' doit(1,2,3,4,5,6);',
  3851. ' end;',
  3852. 'begin // 1 param overload',
  3853. ' doit(1);',
  3854. ' doit(1,2);',
  3855. ' doit(1,2,3);',
  3856. ' doit(1,2,3,4);',
  3857. 'end;',
  3858. 'begin // main',
  3859. ' doit(1);',
  3860. ' doit(1,2);']);
  3861. ConvertProgram;
  3862. CheckSource('TestProcedureOverloadNested',
  3863. LinesToStr([ // statements
  3864. 'this.DoIt$1 = function (vB, vC) {',
  3865. ' $mod.DoIt(1);',
  3866. ' $mod.DoIt$1(1, 2);',
  3867. '};',
  3868. 'this.DoIt = function (vA) {',
  3869. ' function DoIt$3(vA, vB, vC, vD) {',
  3870. ' $mod.DoIt(1);',
  3871. ' $mod.DoIt$1(1, 2);',
  3872. ' DoIt$2(1, 2, 3);',
  3873. ' DoIt$3(1, 2, 3, 4);',
  3874. ' };',
  3875. ' function DoIt$2(vA, vB, vC) {',
  3876. ' function DoIt$5(vA, vB, vC, vD, vE, vF) {',
  3877. ' $mod.DoIt(1);',
  3878. ' $mod.DoIt$1(1, 2);',
  3879. ' DoIt$2(1, 2, 3);',
  3880. ' DoIt$3(1, 2, 3, 4);',
  3881. ' DoIt$4(1, 2, 3, 4, 5);',
  3882. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  3883. ' };',
  3884. ' function DoIt$4(vA, vB, vC, vD, vE) {',
  3885. ' $mod.DoIt(1);',
  3886. ' $mod.DoIt$1(1, 2);',
  3887. ' DoIt$2(1, 2, 3);',
  3888. ' DoIt$3(1, 2, 3, 4);',
  3889. ' DoIt$4(1, 2, 3, 4, 5);',
  3890. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  3891. ' };',
  3892. ' $mod.DoIt(1);',
  3893. ' $mod.DoIt$1(1, 2);',
  3894. ' DoIt$2(1, 2, 3);',
  3895. ' DoIt$3(1, 2, 3, 4);',
  3896. ' DoIt$4(1, 2, 3, 4, 5);',
  3897. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  3898. ' };',
  3899. ' $mod.DoIt(1);',
  3900. ' $mod.DoIt$1(1, 2);',
  3901. ' DoIt$2(1, 2, 3);',
  3902. ' DoIt$3(1, 2, 3, 4);',
  3903. '};',
  3904. '']),
  3905. LinesToStr([
  3906. '$mod.DoIt(1);',
  3907. '$mod.DoIt$1(1, 2);',
  3908. '']));
  3909. end;
  3910. procedure TTestModule.TestProc_OverloadUnitCycle;
  3911. begin
  3912. AddModuleWithIntfImplSrc('Unit2.pas',
  3913. LinesToStr([
  3914. 'type',
  3915. ' TObject = class',
  3916. ' procedure DoIt(b: boolean); virtual; abstract;',
  3917. ' procedure DoIt(i: longint); virtual; abstract;',
  3918. ' end;',
  3919. '']),
  3920. 'uses test1;');
  3921. StartUnit(true);
  3922. Add([
  3923. 'interface',
  3924. 'uses unit2;',
  3925. 'type',
  3926. ' TEagle = class(TObject)',
  3927. ' procedure DoIt(b: boolean); override;',
  3928. ' procedure DoIt(i: longint); override;',
  3929. ' end;',
  3930. 'implementation',
  3931. 'procedure TEagle.DoIt(b: boolean); begin end;',
  3932. 'procedure TEagle.DoIt(i: longint); begin end;',
  3933. '']);
  3934. ConvertUnit;
  3935. CheckSource('TestProc_OverloadUnitCycle',
  3936. LinesToStr([ // statements
  3937. 'rtl.createClass($mod, "TEagle", pas.Unit2.TObject, function () {',
  3938. ' this.DoIt = function (b) {',
  3939. ' };',
  3940. ' this.DoIt$1 = function (i) {',
  3941. ' };',
  3942. '});',
  3943. '']),
  3944. '',
  3945. LinesToStr([
  3946. '']));
  3947. end;
  3948. procedure TTestModule.TestProc_Varargs;
  3949. begin
  3950. StartProgram(false);
  3951. Add([
  3952. 'procedure ProcA(i:longint); varargs; external name ''ProcA'';',
  3953. 'procedure ProcB; varargs; external name ''ProcB'';',
  3954. 'procedure ProcC(i: longint = 17); varargs; external name ''ProcC'';',
  3955. 'function GetIt: longint; begin end;',
  3956. 'begin',
  3957. ' ProcA(1);',
  3958. ' ProcA(1,2);',
  3959. ' ProcA(1,2.0);',
  3960. ' ProcA(1,2,3);',
  3961. ' ProcA(1,''2'');',
  3962. ' ProcA(2,'''');',
  3963. ' ProcA(3,false);',
  3964. ' ProcB;',
  3965. ' ProcB();',
  3966. ' ProcB(4);',
  3967. ' ProcB(''foo'');',
  3968. ' ProcC;',
  3969. ' ProcC();',
  3970. ' ProcC(4);',
  3971. ' ProcC(5,''foo'');',
  3972. ' ProcB(GetIt);',
  3973. ' ProcB(GetIt());',
  3974. ' ProcB(GetIt,GetIt());']);
  3975. ConvertProgram;
  3976. CheckSource('TestProc_Varargs',
  3977. LinesToStr([ // statements
  3978. 'this.GetIt = function () {',
  3979. ' var Result = 0;',
  3980. ' return Result;',
  3981. '};',
  3982. '']),
  3983. LinesToStr([
  3984. 'ProcA(1);',
  3985. 'ProcA(1, 2);',
  3986. 'ProcA(1, 2.0);',
  3987. 'ProcA(1, 2, 3);',
  3988. 'ProcA(1, "2");',
  3989. 'ProcA(2, "");',
  3990. 'ProcA(3, false);',
  3991. 'ProcB();',
  3992. 'ProcB();',
  3993. 'ProcB(4);',
  3994. 'ProcB("foo");',
  3995. 'ProcC(17);',
  3996. 'ProcC(17);',
  3997. 'ProcC(4);',
  3998. 'ProcC(5, "foo");',
  3999. 'ProcB($mod.GetIt());',
  4000. 'ProcB($mod.GetIt());',
  4001. 'ProcB($mod.GetIt(), $mod.GetIt());',
  4002. '']));
  4003. end;
  4004. procedure TTestModule.TestProc_ConstOrder;
  4005. begin
  4006. StartProgram(false);
  4007. Add([
  4008. 'const A = 3;',
  4009. 'const B = A+1;',
  4010. 'procedure DoIt;',
  4011. 'const C = A+1;',
  4012. 'const D = B+1;',
  4013. 'const E = D+C+B+A;',
  4014. 'begin',
  4015. 'end;',
  4016. 'begin'
  4017. ]);
  4018. ConvertProgram;
  4019. CheckSource('TestProc_ConstOrder',
  4020. LinesToStr([ // statements
  4021. 'this.A = 3;',
  4022. 'this.B = 3 + 1;',
  4023. 'var C = 3 + 1;',
  4024. 'var D = 4 + 1;',
  4025. 'var E = 5 + 4 + 4 + 3;',
  4026. 'this.DoIt = function () {',
  4027. '};',
  4028. '']),
  4029. LinesToStr([
  4030. ''
  4031. ]));
  4032. end;
  4033. procedure TTestModule.TestProc_DuplicateConst;
  4034. begin
  4035. StartProgram(false);
  4036. Add([
  4037. 'const A = 1;',
  4038. 'procedure DoIt;',
  4039. 'const A = 2;',
  4040. ' procedure SubIt;',
  4041. ' const A = 21;',
  4042. ' begin',
  4043. ' end;',
  4044. 'begin',
  4045. 'end;',
  4046. 'procedure DoSome;',
  4047. 'const A = 3;',
  4048. 'begin',
  4049. 'end;',
  4050. 'begin'
  4051. ]);
  4052. ConvertProgram;
  4053. CheckSource('TestProc_DuplicateConst',
  4054. LinesToStr([ // statements
  4055. 'this.A = 1;',
  4056. 'var A$1 = 2;',
  4057. 'var A$2 = 21;',
  4058. 'this.DoIt = function () {',
  4059. ' function SubIt() {',
  4060. ' };',
  4061. '};',
  4062. 'var A$3 = 3;',
  4063. 'this.DoSome = function () {',
  4064. '};',
  4065. '']),
  4066. LinesToStr([
  4067. ''
  4068. ]));
  4069. end;
  4070. procedure TTestModule.TestProc_LocalVarAbsolute;
  4071. begin
  4072. StartProgram(false);
  4073. Add([
  4074. 'type',
  4075. ' TObject = class',
  4076. ' Index: longint;',
  4077. ' procedure DoAbs(Item: pointer);',
  4078. ' end;',
  4079. 'procedure TObject.DoAbs(Item: pointer);',
  4080. 'var',
  4081. ' o: TObject absolute Item;',
  4082. 'begin',
  4083. ' if o.Index<o.Index then o.Index:=o.Index;',
  4084. 'end;',
  4085. 'procedure DoIt(i: longint; p: pointer);',
  4086. 'var',
  4087. ' d: double absolute i;',
  4088. ' s: string absolute d;',
  4089. ' oi: TObject absolute i;',
  4090. ' op: TObject absolute p;',
  4091. 'begin',
  4092. ' if d=d then d:=d;',
  4093. ' if s=s then s:=s;',
  4094. ' if oi.Index<oi.Index then oi.Index:=oi.Index;',
  4095. ' if op.Index=op.Index then op.Index:=op.Index;',
  4096. 'end;',
  4097. 'begin']);
  4098. ConvertProgram;
  4099. CheckSource('TestProc_LocalVarAbsolute',
  4100. LinesToStr([ // statements
  4101. 'rtl.createClass($mod, "TObject", null, function () {',
  4102. ' this.$init = function () {',
  4103. ' this.Index = 0;',
  4104. ' };',
  4105. ' this.$final = function () {',
  4106. ' };',
  4107. ' this.DoAbs = function (Item) {',
  4108. ' if (Item.Index < Item.Index) Item.Index = Item.Index;',
  4109. ' };',
  4110. '});',
  4111. 'this.DoIt = function (i, p) {',
  4112. ' if (i === i) i = i;',
  4113. ' if (i === i) i = i;',
  4114. ' if (i.Index < i.Index) i.Index = i.Index;',
  4115. ' if (p.Index === p.Index) p.Index = p.Index;',
  4116. '};'
  4117. ]),
  4118. LinesToStr([
  4119. ]));
  4120. end;
  4121. procedure TTestModule.TestProc_LocalVarInit;
  4122. begin
  4123. StartProgram(false);
  4124. Add([
  4125. 'type TBytes = array of byte;',
  4126. 'procedure DoIt;',
  4127. 'const c = 4;',
  4128. 'var',
  4129. ' b: byte = 1;',
  4130. ' w: word = 2+c;',
  4131. ' p: pointer = nil;',
  4132. ' Buffer: TBytes = nil;',
  4133. 'begin',
  4134. 'end;',
  4135. 'begin']);
  4136. ConvertProgram;
  4137. CheckSource('TestProc_LocalVarInit',
  4138. LinesToStr([ // statements
  4139. 'var c = 4;',
  4140. 'this.DoIt = function () {',
  4141. ' var b = 1;',
  4142. ' var w = 2 + 4;',
  4143. ' var p = null;',
  4144. ' var Buffer = [];',
  4145. '};',
  4146. '']),
  4147. LinesToStr([
  4148. ]));
  4149. end;
  4150. procedure TTestModule.TestProc_ReservedWords;
  4151. begin
  4152. StartProgram(false);
  4153. Add([
  4154. 'procedure Date(ArrayBuffer: longint);',
  4155. 'const',
  4156. ' NaN: longint = 3;',
  4157. 'var',
  4158. ' &Boolean: longint;',
  4159. ' procedure Error(ArrayBuffer: longint);',
  4160. ' begin',
  4161. ' end;',
  4162. 'begin',
  4163. ' Nan:=&bOolean;',
  4164. 'end;',
  4165. 'begin',
  4166. ' Date(1);']);
  4167. ConvertProgram;
  4168. CheckSource('TestProc_ReservedWords',
  4169. LinesToStr([ // statements
  4170. 'var naN = 3;',
  4171. 'this.Date = function (arrayBuffer) {',
  4172. ' var boolean = 0;',
  4173. ' function error(arrayBuffer) {',
  4174. ' };',
  4175. ' naN = boolean;',
  4176. '};',
  4177. '']),
  4178. LinesToStr([
  4179. ' $mod.Date(1);'
  4180. ]));
  4181. end;
  4182. procedure TTestModule.TestAnonymousProc_Assign_ObjFPC;
  4183. begin
  4184. StartProgram(false);
  4185. Add([
  4186. '{$mode objfpc}',
  4187. 'type',
  4188. ' TFunc = reference to function(x: word): word;',
  4189. 'var Func: TFunc;',
  4190. 'procedure DoIt(a: word);',
  4191. 'begin',
  4192. ' Func:=function(b:word): word',
  4193. ' begin',
  4194. ' Result:=a+b;',
  4195. ' exit(b);',
  4196. ' exit(Result);',
  4197. ' end;',// test semicolon
  4198. ' a:=3;',
  4199. 'end;',
  4200. 'begin',
  4201. ' Func:=function(c:word):word begin',
  4202. ' Result:=3+c;',
  4203. ' exit(c);',
  4204. ' exit(Result);',
  4205. ' end;']);
  4206. ConvertProgram;
  4207. CheckSource('TestAnonymousProc_Assign_ObjFPC',
  4208. LinesToStr([ // statements
  4209. 'this.Func = null;',
  4210. 'this.DoIt = function (a) {',
  4211. ' $mod.Func = function (b) {',
  4212. ' var Result = 0;',
  4213. ' Result = a + b;',
  4214. ' return b;',
  4215. ' return Result;',
  4216. ' return Result;',
  4217. ' };',
  4218. ' a = 3;',
  4219. '};',
  4220. '']),
  4221. LinesToStr([
  4222. '$mod.Func = function (c) {',
  4223. ' var Result = 0;',
  4224. ' Result = 3 + c;',
  4225. ' return c;',
  4226. ' return Result;',
  4227. ' return Result;',
  4228. '};',
  4229. '']));
  4230. end;
  4231. procedure TTestModule.TestAnonymousProc_Assign_Delphi;
  4232. begin
  4233. StartProgram(false);
  4234. Add([
  4235. '{$mode delphi}',
  4236. 'type',
  4237. ' TProc = reference to procedure(x: word);',
  4238. 'procedure DoIt(a: word);',
  4239. 'var Proc: TProc;',
  4240. 'begin',
  4241. ' Proc:=procedure(b:word) begin end;',
  4242. 'end;',
  4243. 'var Proc: TProc;',
  4244. 'begin',
  4245. ' Proc:=procedure(c:word) begin end;',
  4246. '']);
  4247. ConvertProgram;
  4248. CheckSource('TestAnonymousProc_Assign_Delphi',
  4249. LinesToStr([ // statements
  4250. 'this.DoIt = function (a) {',
  4251. ' var Proc = null;',
  4252. ' Proc = function (b) {',
  4253. ' };',
  4254. '};',
  4255. 'this.Proc = null;',
  4256. '']),
  4257. LinesToStr([
  4258. '$mod.Proc = function (c) {',
  4259. '};',
  4260. '']));
  4261. end;
  4262. procedure TTestModule.TestAnonymousProc_Arg;
  4263. begin
  4264. StartProgram(false);
  4265. Add([
  4266. 'type',
  4267. ' TProc = reference to procedure;',
  4268. ' TFunc = reference to function(x: word): word;',
  4269. 'procedure DoMore(f,g: TProc);',
  4270. 'begin',
  4271. 'end;',
  4272. 'procedure DoOdd(v: jsvalue);',
  4273. 'begin',
  4274. 'end;',
  4275. 'procedure DoIt(f: TFunc);',
  4276. 'begin',
  4277. ' DoIt(function(b:word): word',
  4278. ' begin',
  4279. ' Result:=1+b;',
  4280. ' end);',
  4281. ' DoMore(procedure begin end, procedure begin end);',
  4282. ' DoOdd(procedure begin end);',
  4283. 'end;',
  4284. 'begin',
  4285. ' DoMore(procedure begin end,',
  4286. ' procedure assembler asm',
  4287. ' console.log("c");',
  4288. ' end);',
  4289. '']);
  4290. ConvertProgram;
  4291. CheckSource('TestAnonymousProc_Arg',
  4292. LinesToStr([ // statements
  4293. 'this.DoMore = function (f, g) {',
  4294. '};',
  4295. 'this.DoOdd = function (v) {',
  4296. '};',
  4297. 'this.DoIt = function (f) {',
  4298. ' $mod.DoIt(function (b) {',
  4299. ' var Result = 0;',
  4300. ' Result = 1 + b;',
  4301. ' return Result;',
  4302. ' });',
  4303. ' $mod.DoMore(function () {',
  4304. ' }, function () {',
  4305. ' });',
  4306. ' $mod.DoOdd(function () {',
  4307. ' });',
  4308. '};',
  4309. '']),
  4310. LinesToStr([
  4311. '$mod.DoMore(function () {',
  4312. '}, function () {',
  4313. ' console.log("c");',
  4314. '});',
  4315. '']));
  4316. end;
  4317. procedure TTestModule.TestAnonymousProc_Typecast;
  4318. begin
  4319. StartProgram(false);
  4320. Add([
  4321. 'type',
  4322. ' TProc = reference to procedure(w: word);',
  4323. ' TArr = array of word;',
  4324. ' TFuncArr = reference to function: TArr;',
  4325. 'procedure DoIt(p: TProc);',
  4326. 'var',
  4327. ' w: word;',
  4328. ' a: TArr;',
  4329. 'begin',
  4330. ' p:=TProc(procedure(b: smallint) begin end);',
  4331. ' a:=TFuncArr(function: TArr begin end)();',
  4332. ' w:=TFuncArr(function: TArr begin end)()[3];',
  4333. 'end;',
  4334. 'begin']);
  4335. ConvertProgram;
  4336. CheckSource('TestAnonymousProc_Typecast',
  4337. LinesToStr([ // statements
  4338. 'this.DoIt = function (p) {',
  4339. ' var w = 0;',
  4340. ' var a = [];',
  4341. ' p = function (b) {',
  4342. ' };',
  4343. ' a = function () {',
  4344. ' var Result = [];',
  4345. ' return Result;',
  4346. ' }();',
  4347. ' w = function () {',
  4348. ' var Result = [];',
  4349. ' return Result;',
  4350. ' }()[3];',
  4351. '};',
  4352. '']),
  4353. LinesToStr([
  4354. '']));
  4355. end;
  4356. procedure TTestModule.TestAnonymousProc_With;
  4357. begin
  4358. StartProgram(false);
  4359. Add([
  4360. 'type',
  4361. ' TProc = reference to procedure(w: word);',
  4362. ' TObject = class',
  4363. ' b: boolean;',
  4364. ' end;',
  4365. 'var',
  4366. ' p: TProc;',
  4367. ' bird: TObject;',
  4368. 'begin',
  4369. ' with bird do',
  4370. ' p:=procedure(w: word)',
  4371. ' begin',
  4372. ' b:=w>2;',
  4373. ' end;',
  4374. '']);
  4375. ConvertProgram;
  4376. CheckSource('TestAnonymousProc_With',
  4377. LinesToStr([ // statements
  4378. 'rtl.createClass($mod, "TObject", null, function () {',
  4379. ' this.$init = function () {',
  4380. ' this.b = false;',
  4381. ' };',
  4382. ' this.$final = function () {',
  4383. ' };',
  4384. '});',
  4385. 'this.p = null;',
  4386. 'this.bird = null;',
  4387. '']),
  4388. LinesToStr([
  4389. 'var $with1 = $mod.bird;',
  4390. '$mod.p = function (w) {',
  4391. ' $with1.b = w > 2;',
  4392. '};',
  4393. '']));
  4394. end;
  4395. procedure TTestModule.TestAnonymousProc_ExceptOn;
  4396. begin
  4397. StartProgram(false);
  4398. Add([
  4399. 'type',
  4400. ' TProc = reference to procedure;',
  4401. ' TObject = class',
  4402. ' b: boolean;',
  4403. ' end;',
  4404. 'procedure DoIt;',
  4405. 'var',
  4406. ' p: TProc;',
  4407. 'begin',
  4408. ' try',
  4409. ' except',
  4410. ' on E: TObject do',
  4411. ' p:=procedure',
  4412. ' begin',
  4413. ' E.b:=true;',
  4414. ' end;',
  4415. ' end;',
  4416. 'end;',
  4417. 'begin']);
  4418. ConvertProgram;
  4419. CheckSource('TestAnonymousProc_ExceptOn',
  4420. LinesToStr([ // statements
  4421. 'rtl.createClass($mod, "TObject", null, function () {',
  4422. ' this.$init = function () {',
  4423. ' this.b = false;',
  4424. ' };',
  4425. ' this.$final = function () {',
  4426. ' };',
  4427. '});',
  4428. 'this.DoIt = function () {',
  4429. ' var p = null;',
  4430. ' try {} catch ($e) {',
  4431. ' if ($mod.TObject.isPrototypeOf($e)) {',
  4432. ' var E = $e;',
  4433. ' p = function () {',
  4434. ' E.b = true;',
  4435. ' };',
  4436. ' } else throw $e',
  4437. ' };',
  4438. '};',
  4439. '']),
  4440. LinesToStr([
  4441. '']));
  4442. end;
  4443. procedure TTestModule.TestAnonymousProc_Nested;
  4444. begin
  4445. StartProgram(false);
  4446. Add([
  4447. 'type',
  4448. ' TProc = reference to procedure;',
  4449. ' TObject = class',
  4450. ' i: byte;',
  4451. ' procedure DoIt;',
  4452. ' end;',
  4453. 'procedure TObject.DoIt;',
  4454. 'var',
  4455. ' p: TProc;',
  4456. ' procedure Sub;',
  4457. ' begin',
  4458. ' p:=procedure',
  4459. ' begin',
  4460. ' i:=3;',
  4461. ' Self.i:=4;',
  4462. ' p:=procedure',
  4463. ' procedure SubSub;',
  4464. ' begin',
  4465. ' i:=13;',
  4466. ' Self.i:=14;',
  4467. ' end;',
  4468. ' begin',
  4469. ' i:=13;',
  4470. ' Self.i:=14;',
  4471. ' end;',
  4472. ' end;',
  4473. ' end;',
  4474. 'begin',
  4475. 'end;',
  4476. 'begin']);
  4477. ConvertProgram;
  4478. CheckSource('TestAnonymousProc_Nested',
  4479. LinesToStr([ // statements
  4480. 'rtl.createClass($mod, "TObject", null, function () {',
  4481. ' this.$init = function () {',
  4482. ' this.i = 0;',
  4483. ' };',
  4484. ' this.$final = function () {',
  4485. ' };',
  4486. ' this.DoIt = function () {',
  4487. ' var $Self = this;',
  4488. ' var p = null;',
  4489. ' function Sub() {',
  4490. ' p = function () {',
  4491. ' $Self.i = 3;',
  4492. ' $Self.i = 4;',
  4493. ' p = function () {',
  4494. ' function SubSub() {',
  4495. ' $Self.i = 13;',
  4496. ' $Self.i = 14;',
  4497. ' };',
  4498. ' $Self.i = 13;',
  4499. ' $Self.i = 14;',
  4500. ' };',
  4501. ' };',
  4502. ' };',
  4503. ' };',
  4504. '});',
  4505. '']),
  4506. LinesToStr([
  4507. '']));
  4508. end;
  4509. procedure TTestModule.TestAnonymousProc_NestedAssignResult;
  4510. begin
  4511. StartProgram(false);
  4512. Add([
  4513. 'type',
  4514. ' TProc = reference to procedure;',
  4515. 'function DoIt: TProc;',
  4516. ' function Sub: TProc;',
  4517. ' begin',
  4518. ' Result:=procedure',
  4519. ' begin',
  4520. ' Sub:=procedure',
  4521. ' procedure SubSub;',
  4522. ' begin',
  4523. ' Result:=nil;',
  4524. ' Sub:=nil;',
  4525. ' DoIt:=nil;',
  4526. ' end;',
  4527. ' begin',
  4528. ' Result:=nil;',
  4529. ' Sub:=nil;',
  4530. ' DoIt:=nil;',
  4531. ' end;',
  4532. ' end;',
  4533. ' end;',
  4534. 'begin',
  4535. 'end;',
  4536. 'begin']);
  4537. ConvertProgram;
  4538. CheckSource('TestAnonymousProc_NestedAssignResult',
  4539. LinesToStr([ // statements
  4540. 'this.DoIt = function () {',
  4541. ' var Result = null;',
  4542. ' function Sub() {',
  4543. ' var Result$1 = null;',
  4544. ' Result$1 = function () {',
  4545. ' Result$1 = function () {',
  4546. ' function SubSub() {',
  4547. ' Result$1 = null;',
  4548. ' Result$1 = null;',
  4549. ' Result = null;',
  4550. ' };',
  4551. ' Result$1 = null;',
  4552. ' Result$1 = null;',
  4553. ' Result = null;',
  4554. ' };',
  4555. ' };',
  4556. ' return Result$1;',
  4557. ' };',
  4558. ' return Result;',
  4559. '};',
  4560. '']),
  4561. LinesToStr([
  4562. '']));
  4563. end;
  4564. procedure TTestModule.TestAnonymousProc_Class;
  4565. begin
  4566. StartProgram(false);
  4567. Add([
  4568. 'type',
  4569. ' TProc = reference to procedure;',
  4570. ' TObject = class',
  4571. ' Size: word;',
  4572. ' function GetIt: TProc;',
  4573. ' end;',
  4574. 'function TObject.GetIt: TProc;',
  4575. 'begin',
  4576. ' Result:=procedure',
  4577. ' begin',
  4578. ' Size:=Size;',
  4579. ' end;',
  4580. 'end;',
  4581. 'begin']);
  4582. ConvertProgram;
  4583. CheckSource('TestAnonymousProc_Class',
  4584. LinesToStr([ // statements
  4585. 'rtl.createClass($mod, "TObject", null, function () {',
  4586. ' this.$init = function () {',
  4587. ' this.Size = 0;',
  4588. ' };',
  4589. ' this.$final = function () {',
  4590. ' };',
  4591. ' this.GetIt = function () {',
  4592. ' var $Self = this;',
  4593. ' var Result = null;',
  4594. ' Result = function () {',
  4595. ' $Self.Size = $Self.Size;',
  4596. ' };',
  4597. ' return Result;',
  4598. ' };',
  4599. '});',
  4600. '']),
  4601. LinesToStr([
  4602. '']));
  4603. end;
  4604. procedure TTestModule.TestAnonymousProc_ForLoop;
  4605. begin
  4606. StartProgram(false);
  4607. Add([
  4608. 'type TProc = reference to procedure;',
  4609. 'procedure Foo(p: TProc);',
  4610. 'begin',
  4611. 'end;',
  4612. 'procedure DoIt;',
  4613. 'var i: word;',
  4614. ' a: word;',
  4615. 'begin',
  4616. ' for i:=1 to 10 do begin',
  4617. ' Foo(procedure begin a:=3; end);',
  4618. ' end;',
  4619. 'end;',
  4620. 'begin',
  4621. ' DoIt;']);
  4622. ConvertProgram;
  4623. CheckSource('TestAnonymousProc_ForLoop',
  4624. LinesToStr([ // statements
  4625. 'this.Foo = function (p) {',
  4626. '};',
  4627. 'this.DoIt = function () {',
  4628. ' var i = 0;',
  4629. ' var a = 0;',
  4630. ' for (i = 1; i <= 10; i++) {',
  4631. ' $mod.Foo(function () {',
  4632. ' a = 3;',
  4633. ' });',
  4634. ' };',
  4635. '};',
  4636. '']),
  4637. LinesToStr([
  4638. '$mod.DoIt();'
  4639. ]));
  4640. end;
  4641. procedure TTestModule.TestEnum_Name;
  4642. begin
  4643. StartProgram(false);
  4644. Add('type TMyEnum = (Red, Green, Blue);');
  4645. Add('var e: TMyEnum;');
  4646. Add('var f: TMyEnum = Blue;');
  4647. Add('begin');
  4648. Add(' e:=green;');
  4649. Add(' e:=default(TMyEnum);');
  4650. ConvertProgram;
  4651. CheckSource('TestEnumName',
  4652. LinesToStr([ // statements
  4653. 'this.TMyEnum = {',
  4654. ' "0":"Red",',
  4655. ' Red:0,',
  4656. ' "1":"Green",',
  4657. ' Green:1,',
  4658. ' "2":"Blue",',
  4659. ' Blue:2',
  4660. ' };',
  4661. 'this.e = 0;',
  4662. 'this.f = $mod.TMyEnum.Blue;'
  4663. ]),
  4664. LinesToStr([
  4665. '$mod.e=$mod.TMyEnum.Green;',
  4666. '$mod.e=$mod.TMyEnum.Red;'
  4667. ]));
  4668. end;
  4669. procedure TTestModule.TestEnum_Number;
  4670. begin
  4671. Converter.Options:=Converter.Options+[coEnumNumbers];
  4672. StartProgram(false);
  4673. Add('type TMyEnum = (Red, Green);');
  4674. Add('var');
  4675. Add(' e: TMyEnum;');
  4676. Add(' f: TMyEnum = Green;');
  4677. Add(' i: longint;');
  4678. Add('begin');
  4679. Add(' e:=green;');
  4680. Add(' i:=longint(e);');
  4681. ConvertProgram;
  4682. CheckSource('TestEnumNumber',
  4683. LinesToStr([ // statements
  4684. 'this.TMyEnum = {',
  4685. ' "0":"Red",',
  4686. ' Red:0,',
  4687. ' "1":"Green",',
  4688. ' Green:1',
  4689. ' };',
  4690. 'this.e = 0;',
  4691. 'this.f = 1;',
  4692. 'this.i = 0;'
  4693. ]),
  4694. LinesToStr([
  4695. '$mod.e=1;',
  4696. '$mod.i=$mod.e;'
  4697. ]));
  4698. end;
  4699. procedure TTestModule.TestEnum_ConstFail;
  4700. begin
  4701. StartProgram(false);
  4702. Add([
  4703. 'type TMyEnum = (Red = 100, Green = 101);',
  4704. 'var',
  4705. ' e: TMyEnum;',
  4706. ' f: TMyEnum = Green;',
  4707. 'begin',
  4708. ' e:=green;']);
  4709. SetExpectedPasResolverError('not yet implemented: Red:TPasEnumValue [20180126202434] enum const',3002);
  4710. ConvertProgram;
  4711. end;
  4712. procedure TTestModule.TestEnum_Functions;
  4713. begin
  4714. StartProgram(false);
  4715. Add([
  4716. 'type TMyEnum = (Red, Green);',
  4717. 'procedure DoIt(var e: TMyEnum; var i: word);',
  4718. 'var',
  4719. ' v: longint;',
  4720. ' s: string;',
  4721. 'begin',
  4722. ' val(s,e,v);',
  4723. ' val(s,e,i);',
  4724. 'end;',
  4725. 'var',
  4726. ' e: TMyEnum;',
  4727. ' i: longint;',
  4728. ' s: string;',
  4729. ' b: boolean;',
  4730. 'begin',
  4731. ' i:=ord(red);',
  4732. ' i:=ord(green);',
  4733. ' i:=ord(e);',
  4734. ' i:=ord(b);',
  4735. ' e:=low(tmyenum);',
  4736. ' e:=low(e);',
  4737. ' b:=low(boolean);',
  4738. ' e:=high(tmyenum);',
  4739. ' e:=high(e);',
  4740. ' b:=high(boolean);',
  4741. ' e:=pred(green);',
  4742. ' e:=pred(e);',
  4743. ' b:=pred(b);',
  4744. ' e:=succ(red);',
  4745. ' e:=succ(e);',
  4746. ' b:=succ(b);',
  4747. ' e:=tmyenum(1);',
  4748. ' e:=tmyenum(i);',
  4749. ' s:=str(e);',
  4750. ' str(e,s);',
  4751. ' str(red,s);',
  4752. ' s:=str(e:3);',
  4753. ' writestr(s,e:3,red);',
  4754. ' val(s,e,i);',
  4755. ' e:=TMyEnum(i);',
  4756. ' i:=longint(e);']);
  4757. ConvertProgram;
  4758. CheckSource('TestEnum_Functions',
  4759. LinesToStr([ // statements
  4760. 'this.TMyEnum = {',
  4761. ' "0":"Red",',
  4762. ' Red:0,',
  4763. ' "1":"Green",',
  4764. ' Green:1',
  4765. ' };',
  4766. 'this.DoIt = function (e, i) {',
  4767. ' var v = 0;',
  4768. ' var s = "";',
  4769. ' e.set(rtl.valEnum(s, $mod.TMyEnum, function (w) {',
  4770. ' v = w;',
  4771. ' }));',
  4772. ' e.set(rtl.valEnum(s, $mod.TMyEnum, i.set));',
  4773. '};',
  4774. 'this.e = 0;',
  4775. 'this.i = 0;',
  4776. 'this.s = "";',
  4777. 'this.b = false;',
  4778. '']),
  4779. LinesToStr([
  4780. '$mod.i=$mod.TMyEnum.Red;',
  4781. '$mod.i=$mod.TMyEnum.Green;',
  4782. '$mod.i=$mod.e;',
  4783. '$mod.i=$mod.b+0;',
  4784. '$mod.e=$mod.TMyEnum.Red;',
  4785. '$mod.e=$mod.TMyEnum.Red;',
  4786. '$mod.b=false;',
  4787. '$mod.e=$mod.TMyEnum.Green;',
  4788. '$mod.e=$mod.TMyEnum.Green;',
  4789. '$mod.b=true;',
  4790. '$mod.e=$mod.TMyEnum.Green-1;',
  4791. '$mod.e=$mod.e-1;',
  4792. '$mod.b=false;',
  4793. '$mod.e=$mod.TMyEnum.Red+1;',
  4794. '$mod.e=$mod.e+1;',
  4795. '$mod.b=true;',
  4796. '$mod.e=1;',
  4797. '$mod.e=$mod.i;',
  4798. '$mod.s = $mod.TMyEnum[$mod.e];',
  4799. '$mod.s = $mod.TMyEnum[$mod.e];',
  4800. '$mod.s = $mod.TMyEnum[$mod.TMyEnum.Red];',
  4801. '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3);',
  4802. '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3)+$mod.TMyEnum[$mod.TMyEnum.Red];',
  4803. '$mod.e = rtl.valEnum($mod.s, $mod.TMyEnum, function (v) {',
  4804. ' $mod.i = v;',
  4805. '});',
  4806. '$mod.e=$mod.i;',
  4807. '$mod.i=$mod.e;',
  4808. '']));
  4809. end;
  4810. procedure TTestModule.TestEnum_AsParams;
  4811. begin
  4812. StartProgram(false);
  4813. Add('type TEnum = (Red,Blue);');
  4814. Add('procedure DoIt(vG: TEnum; const vH: TEnum; var vI: TEnum);');
  4815. Add('var vJ: TEnum;');
  4816. Add('begin');
  4817. Add(' vg:=vg;');
  4818. Add(' vj:=vh;');
  4819. Add(' vi:=vi;');
  4820. Add(' doit(vg,vg,vg);');
  4821. Add(' doit(vh,vh,vj);');
  4822. Add(' doit(vi,vi,vi);');
  4823. Add(' doit(vj,vj,vj);');
  4824. Add('end;');
  4825. Add('var i: TEnum;');
  4826. Add('begin');
  4827. Add(' doit(i,i,i);');
  4828. ConvertProgram;
  4829. CheckSource('TestEnum_AsParams',
  4830. LinesToStr([ // statements
  4831. 'this.TEnum = {',
  4832. ' "0": "Red",',
  4833. ' Red: 0,',
  4834. ' "1": "Blue",',
  4835. ' Blue: 1',
  4836. '};',
  4837. 'this.DoIt = function (vG,vH,vI) {',
  4838. ' var vJ = 0;',
  4839. ' vG = vG;',
  4840. ' vJ = vH;',
  4841. ' vI.set(vI.get());',
  4842. ' $mod.DoIt(vG, vG, {',
  4843. ' get: function () {',
  4844. ' return vG;',
  4845. ' },',
  4846. ' set: function (v) {',
  4847. ' vG = v;',
  4848. ' }',
  4849. ' });',
  4850. ' $mod.DoIt(vH, vH, {',
  4851. ' get: function () {',
  4852. ' return vJ;',
  4853. ' },',
  4854. ' set: function (v) {',
  4855. ' vJ = v;',
  4856. ' }',
  4857. ' });',
  4858. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  4859. ' $mod.DoIt(vJ, vJ, {',
  4860. ' get: function () {',
  4861. ' return vJ;',
  4862. ' },',
  4863. ' set: function (v) {',
  4864. ' vJ = v;',
  4865. ' }',
  4866. ' });',
  4867. '};',
  4868. 'this.i = 0;'
  4869. ]),
  4870. LinesToStr([
  4871. '$mod.DoIt($mod.i,$mod.i,{',
  4872. ' p: $mod,',
  4873. ' get: function () {',
  4874. ' return this.p.i;',
  4875. ' },',
  4876. ' set: function (v) {',
  4877. ' this.p.i = v;',
  4878. ' }',
  4879. '});'
  4880. ]));
  4881. end;
  4882. procedure TTestModule.TestEnumRange_Array;
  4883. begin
  4884. StartProgram(false);
  4885. Add([
  4886. 'type',
  4887. ' TEnum = (Red, Green, Blue);',
  4888. ' TEnumRg = green..blue;',
  4889. ' TArr = array[TEnumRg] of byte;',
  4890. ' TArr2 = array[green..blue] of byte;',
  4891. 'var',
  4892. ' a: TArr;',
  4893. ' b: TArr = (3,4);',
  4894. ' c: TArr2 = (5,6);',
  4895. 'begin',
  4896. ' a[green] := b[blue];',
  4897. ' c[green] := c[blue];',
  4898. '']);
  4899. ConvertProgram;
  4900. CheckSource('TestEnumRange_Array',
  4901. LinesToStr([ // statements
  4902. 'this.TEnum = {',
  4903. ' "0": "Red",',
  4904. ' Red: 0,',
  4905. ' "1": "Green",',
  4906. ' Green: 1,',
  4907. ' "2": "Blue",',
  4908. ' Blue: 2',
  4909. '};',
  4910. 'this.a = rtl.arraySetLength(null, 0, 2);',
  4911. 'this.b = [3, 4];',
  4912. 'this.c = [5, 6];',
  4913. '']),
  4914. LinesToStr([
  4915. ' $mod.a[$mod.TEnum.Green - 1] = $mod.b[$mod.TEnum.Blue - 1];',
  4916. ' $mod.c[$mod.TEnum.Green - 1] = $mod.c[$mod.TEnum.Blue - 1];',
  4917. '']));
  4918. end;
  4919. procedure TTestModule.TestEnum_ForIn;
  4920. begin
  4921. StartProgram(false);
  4922. Add([
  4923. 'type',
  4924. ' TEnum = (Red, Green, Blue);',
  4925. ' TEnumRg = green..blue;',
  4926. ' TArr = array[TEnum] of byte;',
  4927. ' TArrRg = array[TEnumRg] of byte;',
  4928. 'var',
  4929. ' e: TEnum;',
  4930. ' a1: TArr = (3,4,5);',
  4931. ' a2: TArrRg = (11,12);',
  4932. ' b: byte;',
  4933. 'begin',
  4934. ' for e in TEnum do ;',
  4935. ' for e in TEnumRg do ;',
  4936. ' for e in TArr do ;',
  4937. ' for e in TArrRg do ;',
  4938. ' for b in a1 do ;',
  4939. ' for b in a2 do ;',
  4940. '']);
  4941. ConvertProgram;
  4942. CheckSource('TestEnum_ForIn',
  4943. LinesToStr([ // statements
  4944. 'this.TEnum = {',
  4945. ' "0": "Red",',
  4946. ' Red: 0,',
  4947. ' "1": "Green",',
  4948. ' Green: 1,',
  4949. ' "2": "Blue",',
  4950. ' Blue: 2',
  4951. '};',
  4952. 'this.e = 0;',
  4953. 'this.a1 = [3, 4, 5];',
  4954. 'this.a2 = [11, 12];',
  4955. 'this.b = 0;',
  4956. '']),
  4957. LinesToStr([
  4958. ' for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  4959. ' for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  4960. ' for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  4961. ' for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  4962. ' for (var $in1 = $mod.a1, $l2 = 0, $end3 = rtl.length($in1) - 1; $l2 <= $end3; $l2++) $mod.b = $in1[$l2];',
  4963. ' for (var $in4 = $mod.a2, $l5 = 0, $end6 = rtl.length($in4) - 1; $l5 <= $end6; $l5++) $mod.b = $in4[$l5];',
  4964. '']));
  4965. end;
  4966. procedure TTestModule.TestEnum_ScopedNumber;
  4967. begin
  4968. Converter.Options:=Converter.Options+[coEnumNumbers];
  4969. StartProgram(false);
  4970. Add([
  4971. 'type',
  4972. ' TEnum = (Red, Green);',
  4973. 'var',
  4974. ' e: TEnum;',
  4975. 'begin',
  4976. ' e:=TEnum.Green;',
  4977. '']);
  4978. ConvertProgram;
  4979. CheckSource('TestEnum_ScopedNumber',
  4980. LinesToStr([ // statements
  4981. 'this.TEnum = {',
  4982. ' "0": "Red",',
  4983. ' Red: 0,',
  4984. ' "1": "Green",',
  4985. ' Green: 1',
  4986. '};',
  4987. 'this.e = 0;',
  4988. '']),
  4989. LinesToStr([
  4990. '$mod.e = 1;']));
  4991. end;
  4992. procedure TTestModule.TestEnum_InFunction;
  4993. begin
  4994. StartProgram(false);
  4995. Add([
  4996. 'const TEnum = 3;',
  4997. 'procedure DoIt;',
  4998. 'type',
  4999. ' TEnum = (Red, Green, Blue);',
  5000. ' procedure Sub;',
  5001. ' type',
  5002. ' TEnumSub = (Left, Right);',
  5003. ' var',
  5004. ' es: TEnumSub;',
  5005. ' begin',
  5006. ' es:=Left;',
  5007. ' end;',
  5008. 'var',
  5009. ' e, e2: TEnum;',
  5010. 'begin',
  5011. ' if e in [red,blue] then e2:=e;',
  5012. 'end;',
  5013. 'begin']);
  5014. ConvertProgram;
  5015. CheckSource('TestEnum_InFunction',
  5016. LinesToStr([ // statements
  5017. 'this.TEnum = 3;',
  5018. 'var TEnum$1 = {',
  5019. ' "0":"Red",',
  5020. ' Red:0,',
  5021. ' "1":"Green",',
  5022. ' Green:1,',
  5023. ' "2":"Blue",',
  5024. ' Blue:2',
  5025. ' };',
  5026. 'var TEnumSub = {',
  5027. ' "0": "Left",',
  5028. ' Left: 0,',
  5029. ' "1": "Right",',
  5030. ' Right: 1',
  5031. '};',
  5032. 'this.DoIt = function () {',
  5033. ' function Sub() {',
  5034. ' var es = 0;',
  5035. ' es = TEnumSub.Left;',
  5036. ' };',
  5037. ' var e = 0;',
  5038. ' var e2 = 0;',
  5039. ' if (e in rtl.createSet(TEnum$1.Red, TEnum$1.Blue)) e2 = e;',
  5040. '};',
  5041. '']),
  5042. LinesToStr([
  5043. '']));
  5044. end;
  5045. procedure TTestModule.TestSet_Enum;
  5046. begin
  5047. StartProgram(false);
  5048. Add([
  5049. 'type',
  5050. ' TColor = (Red, Green, Blue);',
  5051. ' TColors = set of TColor;',
  5052. 'var',
  5053. ' c: TColor;',
  5054. ' s: TColors;',
  5055. ' t: TColors = [];',
  5056. ' u: TColors = [Red];',
  5057. 'begin',
  5058. ' s:=[];',
  5059. ' s:=[Green];',
  5060. ' s:=[Green,Blue];',
  5061. ' s:=[Red..Blue];',
  5062. ' s:=[Red,Green..Blue];',
  5063. ' s:=[Red,c];',
  5064. ' s:=t;',
  5065. ' s:=default(TColors);',
  5066. '']);
  5067. ConvertProgram;
  5068. CheckSource('TestSet',
  5069. LinesToStr([ // statements
  5070. 'this.TColor = {',
  5071. ' "0":"Red",',
  5072. ' Red:0,',
  5073. ' "1":"Green",',
  5074. ' Green:1,',
  5075. ' "2":"Blue",',
  5076. ' Blue:2',
  5077. ' };',
  5078. 'this.c = 0;',
  5079. 'this.s = {};',
  5080. 'this.t = {};',
  5081. 'this.u = rtl.createSet($mod.TColor.Red);'
  5082. ]),
  5083. LinesToStr([
  5084. '$mod.s={};',
  5085. '$mod.s=rtl.createSet($mod.TColor.Green);',
  5086. '$mod.s=rtl.createSet($mod.TColor.Green,$mod.TColor.Blue);',
  5087. '$mod.s=rtl.createSet(null,$mod.TColor.Red,$mod.TColor.Blue);',
  5088. '$mod.s=rtl.createSet($mod.TColor.Red,null,$mod.TColor.Green,$mod.TColor.Blue);',
  5089. '$mod.s=rtl.createSet($mod.TColor.Red,$mod.c);',
  5090. '$mod.s=rtl.refSet($mod.t);',
  5091. '$mod.s={};',
  5092. '']));
  5093. end;
  5094. procedure TTestModule.TestSet_Operators;
  5095. begin
  5096. StartProgram(false);
  5097. Add('type');
  5098. Add(' TColor = (Red, Green, Blue);');
  5099. Add(' TColors = set of tcolor;');
  5100. Add('var');
  5101. Add(' vC: TColor;');
  5102. Add(' vS: TColors;');
  5103. Add(' vT: TColors;');
  5104. Add(' vU: TColors;');
  5105. Add(' B: boolean;');
  5106. Add('begin');
  5107. Add(' include(vs,green);');
  5108. Add(' exclude(vs,vc);');
  5109. Add(' vs:=vt+vu;');
  5110. Add(' vs:=vt+[red];');
  5111. Add(' vs:=[red]+vt;');
  5112. Add(' vs:=[red]+[green];');
  5113. Add(' vs:=vt-vu;');
  5114. Add(' vs:=vt-[red];');
  5115. Add(' vs:=[red]-vt;');
  5116. Add(' vs:=[red]-[green];');
  5117. Add(' vs:=vt*vu;');
  5118. Add(' vs:=vt*[red];');
  5119. Add(' vs:=[red]*vt;');
  5120. Add(' vs:=[red]*[green];');
  5121. Add(' vs:=vt><vu;');
  5122. Add(' vs:=vt><[red];');
  5123. Add(' vs:=[red]><vt;');
  5124. Add(' vs:=[red]><[green];');
  5125. Add(' b:=vt=vu;');
  5126. Add(' b:=vt=[red];');
  5127. Add(' b:=[red]=vt;');
  5128. Add(' b:=[red]=[green];');
  5129. Add(' b:=vt<>vu;');
  5130. Add(' b:=vt<>[red];');
  5131. Add(' b:=[red]<>vt;');
  5132. Add(' b:=[red]<>[green];');
  5133. Add(' b:=vt<=vu;');
  5134. Add(' b:=vt<=[red];');
  5135. Add(' b:=[red]<=vt;');
  5136. Add(' b:=[red]<=[green];');
  5137. Add(' b:=vt>=vu;');
  5138. Add(' b:=vt>=[red];');
  5139. Add(' b:=[red]>=vt;');
  5140. Add(' b:=[red]>=[green];');
  5141. ConvertProgram;
  5142. CheckSource('TestSet_Operators',
  5143. LinesToStr([ // statements
  5144. 'this.TColor = {',
  5145. ' "0":"Red",',
  5146. ' Red:0,',
  5147. ' "1":"Green",',
  5148. ' Green:1,',
  5149. ' "2":"Blue",',
  5150. ' Blue:2',
  5151. ' };',
  5152. 'this.vC = 0;',
  5153. 'this.vS = {};',
  5154. 'this.vT = {};',
  5155. 'this.vU = {};',
  5156. 'this.B = false;'
  5157. ]),
  5158. LinesToStr([
  5159. '$mod.vS = rtl.includeSet($mod.vS,$mod.TColor.Green);',
  5160. '$mod.vS = rtl.excludeSet($mod.vS,$mod.vC);',
  5161. '$mod.vS = rtl.unionSet($mod.vT, $mod.vU);',
  5162. '$mod.vS = rtl.unionSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5163. '$mod.vS = rtl.unionSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5164. '$mod.vS = rtl.unionSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5165. '$mod.vS = rtl.diffSet($mod.vT, $mod.vU);',
  5166. '$mod.vS = rtl.diffSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5167. '$mod.vS = rtl.diffSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5168. '$mod.vS = rtl.diffSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5169. '$mod.vS = rtl.intersectSet($mod.vT, $mod.vU);',
  5170. '$mod.vS = rtl.intersectSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5171. '$mod.vS = rtl.intersectSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5172. '$mod.vS = rtl.intersectSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5173. '$mod.vS = rtl.symDiffSet($mod.vT, $mod.vU);',
  5174. '$mod.vS = rtl.symDiffSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5175. '$mod.vS = rtl.symDiffSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5176. '$mod.vS = rtl.symDiffSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5177. '$mod.B = rtl.eqSet($mod.vT, $mod.vU);',
  5178. '$mod.B = rtl.eqSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5179. '$mod.B = rtl.eqSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5180. '$mod.B = rtl.eqSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5181. '$mod.B = rtl.neSet($mod.vT, $mod.vU);',
  5182. '$mod.B = rtl.neSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5183. '$mod.B = rtl.neSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5184. '$mod.B = rtl.neSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5185. '$mod.B = rtl.leSet($mod.vT, $mod.vU);',
  5186. '$mod.B = rtl.leSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5187. '$mod.B = rtl.leSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5188. '$mod.B = rtl.leSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5189. '$mod.B = rtl.geSet($mod.vT, $mod.vU);',
  5190. '$mod.B = rtl.geSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5191. '$mod.B = rtl.geSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5192. '$mod.B = rtl.geSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5193. '']));
  5194. end;
  5195. procedure TTestModule.TestSet_Operator_In;
  5196. begin
  5197. StartProgram(false);
  5198. Add('type');
  5199. Add(' TColor = (Red, Green, Blue);');
  5200. Add(' TColors = set of tcolor;');
  5201. Add('var');
  5202. Add(' vC: tcolor;');
  5203. Add(' vT: tcolors;');
  5204. Add(' B: boolean;');
  5205. Add('begin');
  5206. Add(' b:=red in vt;');
  5207. Add(' b:=vc in vt;');
  5208. Add(' b:=green in [red..blue];');
  5209. Add(' b:=vc in [red..blue];');
  5210. Add(' ');
  5211. Add(' if red in vt then ;');
  5212. Add(' while vC in vt do ;');
  5213. Add(' repeat');
  5214. Add(' until vC in vt;');
  5215. ConvertProgram;
  5216. CheckSource('TestSet_Operator_In',
  5217. LinesToStr([ // statements
  5218. 'this.TColor = {',
  5219. ' "0":"Red",',
  5220. ' Red:0,',
  5221. ' "1":"Green",',
  5222. ' Green:1,',
  5223. ' "2":"Blue",',
  5224. ' Blue:2',
  5225. ' };',
  5226. 'this.vC = 0;',
  5227. 'this.vT = {};',
  5228. 'this.B = false;'
  5229. ]),
  5230. LinesToStr([
  5231. '$mod.B = $mod.TColor.Red in $mod.vT;',
  5232. '$mod.B = $mod.vC in $mod.vT;',
  5233. '$mod.B = $mod.TColor.Green in rtl.createSet(null, $mod.TColor.Red, $mod.TColor.Blue);',
  5234. '$mod.B = $mod.vC in rtl.createSet(null, $mod.TColor.Red, $mod.TColor.Blue);',
  5235. 'if ($mod.TColor.Red in $mod.vT) ;',
  5236. 'while ($mod.vC in $mod.vT) {',
  5237. '};',
  5238. 'do {',
  5239. '} while (!($mod.vC in $mod.vT));',
  5240. '']));
  5241. end;
  5242. procedure TTestModule.TestSet_Functions;
  5243. begin
  5244. StartProgram(false);
  5245. Add('type');
  5246. Add(' TMyEnum = (Red, Green);');
  5247. Add(' TMyEnums = set of TMyEnum;');
  5248. Add('var');
  5249. Add(' e: TMyEnum;');
  5250. Add(' s: TMyEnums;');
  5251. Add('begin');
  5252. Add(' e:=Low(TMyEnums);');
  5253. Add(' e:=Low(s);');
  5254. Add(' e:=High(TMyEnums);');
  5255. Add(' e:=High(s);');
  5256. ConvertProgram;
  5257. CheckSource('TestSetFunctions',
  5258. LinesToStr([ // statements
  5259. 'this.TMyEnum = {',
  5260. ' "0":"Red",',
  5261. ' Red:0,',
  5262. ' "1":"Green",',
  5263. ' Green:1',
  5264. ' };',
  5265. 'this.e = 0;',
  5266. 'this.s = {};'
  5267. ]),
  5268. LinesToStr([
  5269. '$mod.e=$mod.TMyEnum.Red;',
  5270. '$mod.e=$mod.TMyEnum.Red;',
  5271. '$mod.e=$mod.TMyEnum.Green;',
  5272. '$mod.e=$mod.TMyEnum.Green;',
  5273. '']));
  5274. end;
  5275. procedure TTestModule.TestSet_PassAsArgClone;
  5276. begin
  5277. StartProgram(false);
  5278. Add('type');
  5279. Add(' TMyEnum = (Red, Green);');
  5280. Add(' TMyEnums = set of TMyEnum;');
  5281. Add('procedure DoDefault(s: tmyenums); begin end;');
  5282. Add('procedure DoConst(const s: tmyenums); begin end;');
  5283. Add('var');
  5284. Add(' aSet: tmyenums;');
  5285. Add('begin');
  5286. Add(' dodefault(aset);');
  5287. Add(' doconst(aset);');
  5288. ConvertProgram;
  5289. CheckSource('TestSetFunctions',
  5290. LinesToStr([ // statements
  5291. 'this.TMyEnum = {',
  5292. ' "0":"Red",',
  5293. ' Red:0,',
  5294. ' "1":"Green",',
  5295. ' Green:1',
  5296. ' };',
  5297. 'this.DoDefault = function (s) {',
  5298. '};',
  5299. 'this.DoConst = function (s) {',
  5300. '};',
  5301. 'this.aSet = {};'
  5302. ]),
  5303. LinesToStr([
  5304. '$mod.DoDefault(rtl.refSet($mod.aSet));',
  5305. '$mod.DoConst($mod.aSet);',
  5306. '']));
  5307. end;
  5308. procedure TTestModule.TestSet_AsParams;
  5309. begin
  5310. StartProgram(false);
  5311. Add([
  5312. 'type TEnum = (Red,Blue);',
  5313. 'type TEnums = set of TEnum;',
  5314. 'function DoIt(vG: TEnums; const vH: TEnums; var vI: TEnums): TEnums;',
  5315. 'var vJ: TEnums;',
  5316. 'begin',
  5317. ' Include(vg,red);',
  5318. ' Include(result,blue);',
  5319. ' vg:=vg;',
  5320. ' vj:=vh;',
  5321. ' vi:=vi;',
  5322. ' doit(vg,vg,vg);',
  5323. ' doit(vh,vh,vj);',
  5324. ' doit(vi,vi,vi);',
  5325. ' doit(vj,vj,vj);',
  5326. 'end;',
  5327. 'var i: TEnums;',
  5328. 'begin',
  5329. ' doit(i,i,i);']);
  5330. ConvertProgram;
  5331. CheckSource('TestSet_AsParams',
  5332. LinesToStr([ // statements
  5333. 'this.TEnum = {',
  5334. ' "0": "Red",',
  5335. ' Red: 0,',
  5336. ' "1": "Blue",',
  5337. ' Blue: 1',
  5338. '};',
  5339. 'this.DoIt = function (vG,vH,vI) {',
  5340. ' var Result = {};',
  5341. ' var vJ = {};',
  5342. ' vG = rtl.includeSet(vG, $mod.TEnum.Red);',
  5343. ' Result = rtl.includeSet(Result, $mod.TEnum.Blue);',
  5344. ' vG = rtl.refSet(vG);',
  5345. ' vJ = rtl.refSet(vH);',
  5346. ' vI.set(rtl.refSet(vI.get()));',
  5347. ' $mod.DoIt(rtl.refSet(vG), vG, {',
  5348. ' get: function () {',
  5349. ' return vG;',
  5350. ' },',
  5351. ' set: function (v) {',
  5352. ' vG = v;',
  5353. ' }',
  5354. ' });',
  5355. ' $mod.DoIt(rtl.refSet(vH), vH, {',
  5356. ' get: function () {',
  5357. ' return vJ;',
  5358. ' },',
  5359. ' set: function (v) {',
  5360. ' vJ = v;',
  5361. ' }',
  5362. ' });',
  5363. ' $mod.DoIt(rtl.refSet(vI.get()), vI.get(), vI);',
  5364. ' $mod.DoIt(rtl.refSet(vJ), vJ, {',
  5365. ' get: function () {',
  5366. ' return vJ;',
  5367. ' },',
  5368. ' set: function (v) {',
  5369. ' vJ = v;',
  5370. ' }',
  5371. ' });',
  5372. ' return Result;',
  5373. '};',
  5374. 'this.i = {};'
  5375. ]),
  5376. LinesToStr([
  5377. '$mod.DoIt(rtl.refSet($mod.i),$mod.i,{',
  5378. ' p: $mod,',
  5379. ' get: function () {',
  5380. ' return this.p.i;',
  5381. ' },',
  5382. ' set: function (v) {',
  5383. ' this.p.i = v;',
  5384. ' }',
  5385. '});'
  5386. ]));
  5387. end;
  5388. procedure TTestModule.TestSet_Property;
  5389. begin
  5390. StartProgram(false);
  5391. Add('type');
  5392. Add(' TEnum = (Red,Blue);');
  5393. Add(' TEnums = set of TEnum;');
  5394. Add(' TObject = class');
  5395. Add(' function GetColors: TEnums; external name ''GetColors'';');
  5396. Add(' procedure SetColors(const Value: TEnums); external name ''SetColors'';');
  5397. Add(' property Colors: TEnums read GetColors write SetColors;');
  5398. Add(' end;');
  5399. Add('procedure DoIt(i: TEnums; const j: TEnums; var k: TEnums; out l: TEnums);');
  5400. Add('begin end;');
  5401. Add('var Obj: TObject;');
  5402. Add('begin');
  5403. Add(' Include(Obj.Colors,Red);');
  5404. Add(' Exclude(Obj.Colors,Red);');
  5405. //Add(' DoIt(Obj.Colors,Obj.Colors,Obj.Colors,Obj.Colors);');
  5406. ConvertProgram;
  5407. CheckSource('TestSet_Property',
  5408. LinesToStr([ // statements
  5409. 'this.TEnum = {',
  5410. ' "0": "Red",',
  5411. ' Red: 0,',
  5412. ' "1": "Blue",',
  5413. ' Blue: 1',
  5414. '};',
  5415. 'rtl.createClass($mod, "TObject", null, function () {',
  5416. ' this.$init = function () {',
  5417. ' };',
  5418. ' this.$final = function () {',
  5419. ' };',
  5420. '});',
  5421. 'this.DoIt = function (i, j, k, l) {',
  5422. '};',
  5423. 'this.Obj = null;',
  5424. '']),
  5425. LinesToStr([
  5426. '$mod.Obj.SetColors(rtl.includeSet($mod.Obj.GetColors(), $mod.TEnum.Red));',
  5427. '$mod.Obj.SetColors(rtl.excludeSet($mod.Obj.GetColors(), $mod.TEnum.Red));',
  5428. '']));
  5429. end;
  5430. procedure TTestModule.TestSet_EnumConst;
  5431. begin
  5432. StartProgram(false);
  5433. Add([
  5434. 'type',
  5435. ' TEnum = (Red,Blue);',
  5436. ' TEnums = set of TEnum;',
  5437. 'const',
  5438. ' Orange = red;',
  5439. 'var',
  5440. ' Enum: tenum;',
  5441. ' Enums: tenums;',
  5442. 'begin',
  5443. ' Include(enums,orange);',
  5444. ' Exclude(enums,orange);',
  5445. ' if orange in enums then;',
  5446. ' if orange in [orange,red] then;']);
  5447. ConvertProgram;
  5448. CheckSource('TestSet_EnumConst',
  5449. LinesToStr([ // statements
  5450. 'this.TEnum = {',
  5451. ' "0": "Red",',
  5452. ' Red: 0,',
  5453. ' "1": "Blue",',
  5454. ' Blue: 1',
  5455. '};',
  5456. 'this.Orange = $mod.TEnum.Red;',
  5457. 'this.Enum = 0;',
  5458. 'this.Enums = {};',
  5459. '']),
  5460. LinesToStr([
  5461. '$mod.Enums = rtl.includeSet($mod.Enums, $mod.TEnum.Red);',
  5462. '$mod.Enums = rtl.excludeSet($mod.Enums, $mod.TEnum.Red);',
  5463. 'if ($mod.TEnum.Red in $mod.Enums) ;',
  5464. 'if ($mod.TEnum.Red in rtl.createSet($mod.TEnum.Red, $mod.TEnum.Red)) ;',
  5465. '']));
  5466. end;
  5467. procedure TTestModule.TestSet_IntConst;
  5468. begin
  5469. StartProgram(false);
  5470. Add([
  5471. 'type',
  5472. ' TEnums = set of Byte;',
  5473. 'const',
  5474. ' Orange = 0;',
  5475. 'var',
  5476. ' Enum: byte;',
  5477. ' Enums: tenums;',
  5478. 'begin',
  5479. ' Enums:=[];',
  5480. ' Enums:=[0];',
  5481. ' Enums:=[1..2];',
  5482. //' Include(enums,orange);',
  5483. //' Exclude(enums,orange);',
  5484. ' if orange in enums then;',
  5485. ' if orange in [orange,1] then;']);
  5486. ConvertProgram;
  5487. CheckSource('TestSet_IntConst',
  5488. LinesToStr([ // statements
  5489. 'this.Orange = 0;',
  5490. 'this.Enum = 0;',
  5491. 'this.Enums = {};',
  5492. '']),
  5493. LinesToStr([
  5494. '$mod.Enums = {};',
  5495. '$mod.Enums = rtl.createSet(0);',
  5496. '$mod.Enums = rtl.createSet(null, 1, 2);',
  5497. 'if (0 in $mod.Enums) ;',
  5498. 'if (0 in rtl.createSet(0, 1)) ;',
  5499. '']));
  5500. end;
  5501. procedure TTestModule.TestSet_AnonymousEnumType;
  5502. begin
  5503. StartProgram(false);
  5504. Add('type');
  5505. Add(' TFlags = set of (red, green);');
  5506. Add('const');
  5507. Add(' favorite = red;');
  5508. Add('var');
  5509. Add(' f: TFlags;');
  5510. Add(' i: longint;');
  5511. Add('begin');
  5512. Add(' Include(f,red);');
  5513. Add(' Include(f,favorite);');
  5514. Add(' i:=ord(red);');
  5515. Add(' i:=ord(favorite);');
  5516. Add(' i:=ord(low(TFlags));');
  5517. Add(' i:=ord(low(f));');
  5518. Add(' i:=ord(low(favorite));');
  5519. Add(' i:=ord(high(TFlags));');
  5520. Add(' i:=ord(high(f));');
  5521. Add(' i:=ord(high(favorite));');
  5522. Add(' f:=[green,favorite];');
  5523. ConvertProgram;
  5524. CheckSource('TestSet_AnonymousEnumType',
  5525. LinesToStr([ // statements
  5526. 'this.TFlags$a = {',
  5527. ' "0": "red",',
  5528. ' red: 0,',
  5529. ' "1": "green",',
  5530. ' green: 1',
  5531. '};',
  5532. 'this.favorite = $mod.TFlags$a.red;',
  5533. 'this.f = {};',
  5534. 'this.i = 0;',
  5535. '']),
  5536. LinesToStr([
  5537. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  5538. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  5539. '$mod.i = $mod.TFlags$a.red;',
  5540. '$mod.i = $mod.TFlags$a.red;',
  5541. '$mod.i = $mod.TFlags$a.red;',
  5542. '$mod.i = $mod.TFlags$a.red;',
  5543. '$mod.i = $mod.TFlags$a.red;',
  5544. '$mod.i = $mod.TFlags$a.green;',
  5545. '$mod.i = $mod.TFlags$a.green;',
  5546. '$mod.i = $mod.TFlags$a.green;',
  5547. '$mod.f = rtl.createSet($mod.TFlags$a.green, $mod.TFlags$a.red);',
  5548. '']));
  5549. end;
  5550. procedure TTestModule.TestSet_AnonymousEnumTypeChar;
  5551. begin
  5552. exit;
  5553. StartProgram(false);
  5554. Add([
  5555. 'type',
  5556. ' TAtoZ = ''A''..''Z'';',
  5557. ' TSetOfAZ = set of TAtoZ;',
  5558. 'var',
  5559. ' c: char;',
  5560. ' a: TAtoZ;',
  5561. ' s: TSetOfAZ = [''P'',''A''];',
  5562. ' i: longint;',
  5563. 'begin',
  5564. ' Include(s,''S'');',
  5565. ' Include(s,c);',
  5566. ' Include(s,a);',
  5567. ' c:=low(TAtoZ);',
  5568. ' i:=ord(low(TAtoZ));',
  5569. ' a:=high(TAtoZ);',
  5570. ' a:=high(TSetOfAtoZ);',
  5571. ' s:=[a,c,''M''];',
  5572. '']);
  5573. ConvertProgram;
  5574. CheckSource('TestSet_AnonymousEnumTypeChar',
  5575. LinesToStr([ // statements
  5576. '']),
  5577. LinesToStr([
  5578. '']));
  5579. end;
  5580. procedure TTestModule.TestSet_ConstEnum;
  5581. begin
  5582. StartProgram(false);
  5583. Add([
  5584. 'type',
  5585. ' TEnum = (red,blue,green);',
  5586. ' TEnums = set of TEnum;',
  5587. 'const',
  5588. ' teAny = [low(TEnum)..high(TEnum)];',
  5589. ' teRedBlue = [low(TEnum)..pred(high(TEnum))];',
  5590. 'var',
  5591. ' e: TEnum;',
  5592. ' s: TEnums;',
  5593. 'begin',
  5594. ' if blue in teAny then;',
  5595. ' if blue in teAny+[e] then;',
  5596. ' if blue in teAny+teRedBlue then;',
  5597. ' if e in [red,blue] then;',
  5598. ' s:=teAny;',
  5599. ' s:=teAny+[e];',
  5600. ' s:=[e]+teAny;',
  5601. ' s:=teAny+teRedBlue;',
  5602. ' s:=teAny+teRedBlue+[e];',
  5603. '']);
  5604. ConvertProgram;
  5605. CheckSource('TestSet_ConstEnum',
  5606. LinesToStr([ // statements
  5607. 'this.TEnum = {',
  5608. ' "0": "red",',
  5609. ' red: 0,',
  5610. ' "1": "blue",',
  5611. ' blue: 1,',
  5612. ' "2": "green",',
  5613. ' green: 2',
  5614. '};',
  5615. 'this.teAny = rtl.createSet(null, $mod.TEnum.red, $mod.TEnum.green);',
  5616. 'this.teRedBlue = rtl.createSet(null, $mod.TEnum.red, $mod.TEnum.green - 1);',
  5617. 'this.e = 0;',
  5618. 'this.s = {};',
  5619. '']),
  5620. LinesToStr([
  5621. 'if ($mod.TEnum.blue in $mod.teAny) ;',
  5622. 'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, rtl.createSet($mod.e))) ;',
  5623. 'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, $mod.teRedBlue)) ;',
  5624. 'if ($mod.e in rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)) ;',
  5625. '$mod.s = rtl.refSet($mod.teAny);',
  5626. '$mod.s = rtl.unionSet($mod.teAny, rtl.createSet($mod.e));',
  5627. '$mod.s = rtl.unionSet(rtl.createSet($mod.e), $mod.teAny);',
  5628. '$mod.s = rtl.unionSet($mod.teAny, $mod.teRedBlue);',
  5629. '$mod.s = rtl.unionSet(rtl.unionSet($mod.teAny, $mod.teRedBlue), rtl.createSet($mod.e));',
  5630. '']));
  5631. end;
  5632. procedure TTestModule.TestSet_ConstChar;
  5633. begin
  5634. StartProgram(false);
  5635. Add([
  5636. 'const',
  5637. ' LowChars = [''a''..''z''];',
  5638. ' Chars = LowChars+[''A''..''Z''];',
  5639. ' sc = [''А'', ''Я''];',
  5640. 'var',
  5641. ' c: char;',
  5642. ' s: string;',
  5643. 'begin',
  5644. ' if c in lowchars then ;',
  5645. ' if ''a'' in lowchars then ;',
  5646. ' if s[1] in lowchars then ;',
  5647. ' if c in chars then ;',
  5648. ' if c in [''a''..''z'',''_''] then ;',
  5649. ' if ''b'' in [''a''..''z'',''_''] then ;',
  5650. ' if ''Я'' in sc then ;',
  5651. '']);
  5652. ConvertProgram;
  5653. CheckSource('TestSet_ConstChar',
  5654. LinesToStr([ // statements
  5655. 'this.LowChars = rtl.createSet(null, 97, 122);',
  5656. 'this.Chars = rtl.unionSet($mod.LowChars, rtl.createSet(null, 65, 90));',
  5657. 'this.sc = rtl.createSet(1040, 1071);',
  5658. 'this.c = "";',
  5659. 'this.s = "";',
  5660. '']),
  5661. LinesToStr([
  5662. 'if ($mod.c.charCodeAt() in $mod.LowChars) ;',
  5663. 'if (97 in $mod.LowChars) ;',
  5664. 'if ($mod.s.charCodeAt(0) in $mod.LowChars) ;',
  5665. 'if ($mod.c.charCodeAt() in $mod.Chars) ;',
  5666. 'if ($mod.c.charCodeAt() in rtl.createSet(null, 97, 122, 95)) ;',
  5667. 'if (98 in rtl.createSet(null, 97, 122, 95)) ;',
  5668. 'if (1071 in $mod.sc) ;',
  5669. '']));
  5670. end;
  5671. procedure TTestModule.TestSet_ConstInt;
  5672. begin
  5673. StartProgram(false);
  5674. Add([
  5675. 'const',
  5676. ' Months = [1..12];',
  5677. ' Mirror = [-12..-1]+Months;',
  5678. 'var',
  5679. ' i: smallint;',
  5680. 'begin',
  5681. ' if 3 in Months then;',
  5682. ' if i in Months+[i] then;',
  5683. ' if i in Months+Mirror then;',
  5684. ' if i in [4..6,8] then;',
  5685. '']);
  5686. ConvertProgram;
  5687. CheckSource('TestSet_ConstInt',
  5688. LinesToStr([ // statements
  5689. 'this.Months = rtl.createSet(null, 1, 12);',
  5690. 'this.Mirror = rtl.unionSet(rtl.createSet(null, -12, -1), $mod.Months);',
  5691. 'this.i = 0;',
  5692. '']),
  5693. LinesToStr([
  5694. 'if (3 in $mod.Months) ;',
  5695. 'if ($mod.i in rtl.unionSet($mod.Months, rtl.createSet($mod.i))) ;',
  5696. 'if ($mod.i in rtl.unionSet($mod.Months, $mod.Mirror)) ;',
  5697. 'if ($mod.i in rtl.createSet(null, 4, 6, 8)) ;',
  5698. '']));
  5699. end;
  5700. procedure TTestModule.TestSet_InFunction;
  5701. begin
  5702. StartProgram(false);
  5703. Add([
  5704. 'const',
  5705. ' TEnum = 3;',
  5706. ' TSetOfEnum = 4;',
  5707. ' TSetOfAno = 5;',
  5708. 'procedure DoIt;',
  5709. 'type',
  5710. ' TEnum = (red, blue);',
  5711. ' TSetOfEnum = set of TEnum;',
  5712. ' TSetOfAno = set of (up,down);',
  5713. 'var',
  5714. ' e: TEnum;',
  5715. ' se: TSetOfEnum;',
  5716. ' sa: TSetOfAno;',
  5717. 'begin',
  5718. ' se:=[e];',
  5719. ' sa:=[up];',
  5720. 'end;',
  5721. 'begin',
  5722. '']);
  5723. ConvertProgram;
  5724. CheckSource('TestSet_InFunction',
  5725. LinesToStr([ // statements
  5726. 'this.TEnum = 3;',
  5727. 'this.TSetOfEnum = 4;',
  5728. 'this.TSetOfAno = 5;',
  5729. 'var TEnum$1 = {',
  5730. ' "0": "red",',
  5731. ' red: 0,',
  5732. ' "1": "blue",',
  5733. ' blue: 1',
  5734. '};',
  5735. 'var TSetOfAno$a = {',
  5736. ' "0": "up",',
  5737. ' up: 0,',
  5738. ' "1": "down",',
  5739. ' down: 1',
  5740. '};',
  5741. 'this.DoIt = function () {',
  5742. ' var e = 0;',
  5743. ' var se = {};',
  5744. ' var sa = {};',
  5745. ' se = rtl.createSet(e);',
  5746. ' sa = rtl.createSet(TSetOfAno$a.up);',
  5747. '};',
  5748. '']),
  5749. LinesToStr([
  5750. '']));
  5751. end;
  5752. procedure TTestModule.TestSet_ForIn;
  5753. begin
  5754. StartProgram(false);
  5755. Add([
  5756. 'type',
  5757. ' TEnum = (Red, Green, Blue);',
  5758. ' TEnumRg = green..blue;',
  5759. ' TSetOfEnum = set of TEnum;',
  5760. ' TSetOfEnumRg = set of TEnumRg;',
  5761. 'var',
  5762. ' e, e2: TEnum;',
  5763. ' er: TEnum;',
  5764. ' s: TSetOfEnum;',
  5765. 'begin',
  5766. ' for e in TSetOfEnum do ;',
  5767. ' for e in TSetOfEnumRg do ;',
  5768. ' for e in [] do e2:=e;',
  5769. ' for e in [red..green] do e2:=e;',
  5770. ' for e in [green,blue] do e2:=e;',
  5771. ' for e in [red,blue] do e2:=e;',
  5772. ' for e in s do e2:=e;',
  5773. ' for er in TSetOfEnumRg do ;',
  5774. '']);
  5775. ConvertProgram;
  5776. CheckSource('TestSet_ForIn',
  5777. LinesToStr([ // statements
  5778. 'this.TEnum = {',
  5779. ' "0":"Red",',
  5780. ' Red:0,',
  5781. ' "1":"Green",',
  5782. ' Green:1,',
  5783. ' "2":"Blue",',
  5784. ' Blue:2',
  5785. ' };',
  5786. 'this.e = 0;',
  5787. 'this.e2 = 0;',
  5788. 'this.er = 0;',
  5789. 'this.s = {};',
  5790. '']),
  5791. LinesToStr([
  5792. 'for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  5793. 'for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  5794. 'for ($mod.e = 0; $mod.e <= 1; $mod.e++) $mod.e2 = $mod.e;',
  5795. 'for ($mod.e = 1; $mod.e <= 2; $mod.e++) $mod.e2 = $mod.e;',
  5796. 'for ($mod.e in rtl.createSet($mod.TEnum.Red, $mod.TEnum.Blue)) $mod.e2 = $mod.e;',
  5797. 'for (var $l1 in $mod.s){',
  5798. ' $mod.e = +$l1;',
  5799. ' $mod.e2 = $mod.e;',
  5800. '};',
  5801. 'for ($mod.er = 1; $mod.er <= 2; $mod.er++) ;',
  5802. '']));
  5803. end;
  5804. procedure TTestModule.TestNestBegin;
  5805. begin
  5806. StartProgram(false);
  5807. Add('begin');
  5808. Add(' begin');
  5809. Add(' begin');
  5810. Add(' end;');
  5811. Add(' begin');
  5812. Add(' if true then ;');
  5813. Add(' end;');
  5814. Add(' end;');
  5815. ConvertProgram;
  5816. CheckSource('TestNestBegin',
  5817. '',
  5818. 'if (true) ;');
  5819. end;
  5820. procedure TTestModule.TestUnitImplVars;
  5821. begin
  5822. StartUnit(false);
  5823. Add('interface');
  5824. Add('implementation');
  5825. Add('var');
  5826. Add(' V1:longint;');
  5827. Add(' V2:longint = 3;');
  5828. Add(' V3:string = ''abc'';');
  5829. ConvertUnit;
  5830. CheckSource('TestUnitImplVars',
  5831. LinesToStr([ // statements
  5832. 'var $impl = $mod.$impl;',
  5833. '']),
  5834. '', // this.$init
  5835. LinesToStr([ // implementation
  5836. '$impl.V1 = 0;',
  5837. '$impl.V2 = 3;',
  5838. '$impl.V3 = "abc";',
  5839. '']) );
  5840. end;
  5841. procedure TTestModule.TestUnitImplConsts;
  5842. begin
  5843. StartUnit(false);
  5844. Add('interface');
  5845. Add('implementation');
  5846. Add('const');
  5847. Add(' v1 = 3;');
  5848. Add(' v2:longint = 4;');
  5849. Add(' v3:string = ''abc'';');
  5850. ConvertUnit;
  5851. CheckSource('TestUnitImplConsts',
  5852. LinesToStr([ // statements
  5853. 'var $impl = $mod.$impl;',
  5854. '']),
  5855. '', // this.$init
  5856. LinesToStr([ // implementation
  5857. '$impl.v1 = 3;',
  5858. '$impl.v2 = 4;',
  5859. '$impl.v3 = "abc";',
  5860. '']) );
  5861. end;
  5862. procedure TTestModule.TestUnitImplRecord;
  5863. begin
  5864. StartUnit(false);
  5865. Add('interface');
  5866. Add('implementation');
  5867. Add('type');
  5868. Add(' TMyRecord = record');
  5869. Add(' i: longint;');
  5870. Add(' end;');
  5871. Add('var aRec: TMyRecord;');
  5872. Add('initialization');
  5873. Add(' arec.i:=3;');
  5874. ConvertUnit;
  5875. CheckSource('TestUnitImplRecord',
  5876. LinesToStr([ // statements
  5877. 'var $impl = $mod.$impl;',
  5878. '']),
  5879. // this.$init
  5880. '$impl.aRec.i = 3;',
  5881. LinesToStr([ // implementation
  5882. 'rtl.recNewT($impl, "TMyRecord", function () {',
  5883. ' this.i = 0;',
  5884. ' this.$eq = function (b) {',
  5885. ' return this.i === b.i;',
  5886. ' };',
  5887. ' this.$assign = function (s) {',
  5888. ' this.i = s.i;',
  5889. ' return this;',
  5890. ' };',
  5891. '});',
  5892. '$impl.aRec = $impl.TMyRecord.$new();',
  5893. '']) );
  5894. end;
  5895. procedure TTestModule.TestRenameJSNameConflict;
  5896. begin
  5897. StartProgram(false);
  5898. Add('var apply: longint;');
  5899. Add('var bind: longint;');
  5900. Add('var call: longint;');
  5901. Add('begin');
  5902. ConvertProgram;
  5903. CheckSource('TestRenameJSNameConflict',
  5904. LinesToStr([ // statements
  5905. 'this.Apply = 0;',
  5906. 'this.Bind = 0;',
  5907. 'this.Call = 0;'
  5908. ]),
  5909. LinesToStr([ // this.$main
  5910. ''
  5911. ]));
  5912. end;
  5913. procedure TTestModule.TestLocalConst;
  5914. begin
  5915. StartProgram(false);
  5916. Add('procedure DoIt;');
  5917. Add('const');
  5918. Add(' cA: longint = 1;');
  5919. Add(' cB = 2;');
  5920. Add(' procedure Sub;');
  5921. Add(' const');
  5922. Add(' csA = 3;');
  5923. Add(' cB: double = 4;');
  5924. Add(' begin');
  5925. Add(' cb:=cb+csa;');
  5926. Add(' ca:=ca+csa+5;');
  5927. Add(' end;');
  5928. Add('begin');
  5929. Add(' ca:=ca+cb+6;');
  5930. Add('end;');
  5931. Add('begin');
  5932. ConvertProgram;
  5933. CheckSource('TestLocalConst',
  5934. LinesToStr([
  5935. 'var cA = 1;',
  5936. 'var cB = 2;',
  5937. 'var csA = 3;',
  5938. 'var cB$1 = 4;',
  5939. 'this.DoIt = function () {',
  5940. ' function Sub() {',
  5941. ' cB$1 = cB$1 + 3;',
  5942. ' cA = cA + 3 + 5;',
  5943. ' };',
  5944. ' cA = cA + 2 + 6;',
  5945. '};'
  5946. ]),
  5947. LinesToStr([
  5948. ]));
  5949. end;
  5950. procedure TTestModule.TestVarExternal;
  5951. begin
  5952. StartProgram(false);
  5953. Add('var');
  5954. Add(' NaN: double; external name ''Global.NaN'';');
  5955. Add(' d: double;');
  5956. Add('begin');
  5957. Add(' d:=NaN;');
  5958. ConvertProgram;
  5959. CheckSource('TestVarExternal',
  5960. LinesToStr([
  5961. 'this.d = 0.0;'
  5962. ]),
  5963. LinesToStr([
  5964. '$mod.d = Global.NaN;'
  5965. ]));
  5966. end;
  5967. procedure TTestModule.TestVarExternalOtherUnit;
  5968. begin
  5969. AddModuleWithIntfImplSrc('unit2.pas',
  5970. LinesToStr([
  5971. 'var NaN: double; external name ''Global.NaN'';',
  5972. 'var iV: longint;'
  5973. ]),
  5974. '');
  5975. StartUnit(true);
  5976. Add('interface');
  5977. Add('uses unit2;');
  5978. Add('implementation');
  5979. Add('var');
  5980. Add(' d: double;');
  5981. Add(' i: longint; external name ''$i'';');
  5982. Add('begin');
  5983. Add(' d:=nan;');
  5984. Add(' d:=uNit2.nan;');
  5985. Add(' d:=test1.d;');
  5986. Add(' i:=iv;');
  5987. Add(' i:=uNit2.iv;');
  5988. Add(' i:=test1.i;');
  5989. ConvertUnit;
  5990. CheckSource('TestVarExternalOtherUnit',
  5991. LinesToStr([
  5992. 'var $impl = $mod.$impl;',
  5993. '']),
  5994. LinesToStr([ // this.$init
  5995. '$impl.d = Global.NaN;',
  5996. '$impl.d = Global.NaN;',
  5997. '$impl.d = $impl.d;',
  5998. '$i = pas.unit2.iV;',
  5999. '$i = pas.unit2.iV;',
  6000. '$i = $i;',
  6001. '']),
  6002. LinesToStr([ // implementation
  6003. '$impl.d = 0.0;',
  6004. '']) );
  6005. end;
  6006. procedure TTestModule.TestVarAbsoluteFail;
  6007. begin
  6008. StartProgram(false);
  6009. Add([
  6010. 'var',
  6011. ' a: longint;',
  6012. ' b: longword absolute a;',
  6013. 'begin']);
  6014. SetExpectedPasResolverError('Invalid variable modifier "absolute"',nInvalidVariableModifier);
  6015. ConvertProgram;
  6016. end;
  6017. procedure TTestModule.TestConstExternal;
  6018. begin
  6019. StartProgram(false);
  6020. Add([
  6021. 'const',
  6022. ' PI: double; external name ''Global.PI'';',
  6023. ' Tau = 2*pi;',
  6024. 'var d: double;',
  6025. 'begin',
  6026. ' d:=pi;',
  6027. ' d:=tau+pi;']);
  6028. ConvertProgram;
  6029. CheckSource('TestConstExternal',
  6030. LinesToStr([
  6031. 'this.Tau = 2*Global.PI;',
  6032. 'this.d = 0.0;'
  6033. ]),
  6034. LinesToStr([
  6035. '$mod.d = Global.PI;',
  6036. '$mod.d = $mod.Tau + Global.PI;'
  6037. ]));
  6038. end;
  6039. procedure TTestModule.TestDouble;
  6040. begin
  6041. StartProgram(false);
  6042. Add([
  6043. 'type',
  6044. ' TDateTime = double;',
  6045. 'const',
  6046. ' a = TDateTime(2.7);',
  6047. ' b = a + TDateTime(1.7);',
  6048. ' c = 0.9 + 0.1;',
  6049. ' f0_1 = 0.1;',
  6050. ' f0_3 = 0.3;',
  6051. ' fn0_1 = -0.1;',
  6052. ' fn0_3 = -0.3;',
  6053. ' fn0_003 = -0.003;',
  6054. ' fn0_123456789 = -0.123456789;',
  6055. ' fn300_0 = -300.0;',
  6056. ' fn123456_0 = -123456.0;',
  6057. ' fn1234567_8 = -1234567.8;',
  6058. ' fn12345678_9 = -12345678.9;',
  6059. ' f1_0En12 = 1E-12;',
  6060. ' fn1_0En12 = -1E-12;',
  6061. ' maxdouble = 1.7e+308;',
  6062. ' mindouble = -1.7e+308;',
  6063. ' MinSafeIntDouble = -$1fffffffffffff;',
  6064. ' MinSafeIntDouble2 = -$20000000000000-1;',
  6065. ' MaxSafeIntDouble = $1fffffffffffff;',
  6066. ' DZeroResolution = 1E-12;',
  6067. ' Minus1 = -1E-12;',
  6068. ' EPS = 1E-9;',
  6069. ' DELTA = 0.001;',
  6070. ' Big = 129.789E+100;',
  6071. ' Test0_15 = 0.15;',
  6072. ' Test999 = 2.9999999999999;',
  6073. ' Test111999 = 211199999999999000.0;',
  6074. ' TestMinus111999 = -211199999999999000.0;',
  6075. 'var',
  6076. ' d: double = b;',
  6077. 'begin',
  6078. ' d:=1.0;',
  6079. ' d:=1.0/3.0;',
  6080. ' d:=1/3;',
  6081. ' d:=5.0E-324;',
  6082. ' d:=1.7E308;',
  6083. ' d:=001.00E00;',
  6084. ' d:=002.00E001;',
  6085. ' d:=003.000E000;',
  6086. ' d:=-004.00E-00;',
  6087. ' d:=-005.00E-001;',
  6088. ' d:=10**3;',
  6089. ' d:=10 mod 3;',
  6090. ' d:=10 div 3;',
  6091. ' d:=c;',
  6092. ' d:=f0_1;',
  6093. ' d:=f0_3;',
  6094. ' d:=fn0_1;',
  6095. ' d:=fn0_3;',
  6096. ' d:=fn0_003;',
  6097. ' d:=fn0_123456789;',
  6098. ' d:=fn300_0;',
  6099. ' d:=fn123456_0;',
  6100. ' d:=fn1234567_8;',
  6101. ' d:=fn12345678_9;',
  6102. ' d:=f1_0En12;',
  6103. ' d:=fn1_0En12;',
  6104. ' d:=maxdouble;',
  6105. ' d:=mindouble;',
  6106. ' d:=MinSafeIntDouble;',
  6107. ' d:=double(MinSafeIntDouble);',
  6108. ' d:=MinSafeIntDouble2;',
  6109. ' d:=double(MinSafeIntDouble2);',
  6110. ' d:=MaxSafeIntDouble;',
  6111. ' d:=default(double);',
  6112. '']);
  6113. ConvertProgram;
  6114. CheckSource('TestDouble',
  6115. LinesToStr([
  6116. 'this.a = 2.7;',
  6117. 'this.b = 2.7 + 1.7;',
  6118. 'this.c = 0.9 + 0.1;',
  6119. 'this.f0_1 = 0.1;',
  6120. 'this.f0_3 = 0.3;',
  6121. 'this.fn0_1 = -0.1;',
  6122. 'this.fn0_3 = -0.3;',
  6123. 'this.fn0_003 = -0.003;',
  6124. 'this.fn0_123456789 = -0.123456789;',
  6125. 'this.fn300_0 = -300.0;',
  6126. 'this.fn123456_0 = -123456.0;',
  6127. 'this.fn1234567_8 = -1234567.8;',
  6128. 'this.fn12345678_9 = -12345678.9;',
  6129. 'this.f1_0En12 = 1E-12;',
  6130. 'this.fn1_0En12 = -1E-12;',
  6131. 'this.maxdouble = 1.7e+308;',
  6132. 'this.mindouble = -1.7e+308;',
  6133. 'this.MinSafeIntDouble = -0x1fffffffffffff;',
  6134. 'this.MinSafeIntDouble2 = -0x20000000000000 - 1;',
  6135. 'this.MaxSafeIntDouble = 0x1fffffffffffff;',
  6136. 'this.DZeroResolution = 1E-12;',
  6137. 'this.Minus1 = -1E-12;',
  6138. 'this.EPS = 1E-9;',
  6139. 'this.DELTA = 0.001;',
  6140. 'this.Big = 129.789E+100;',
  6141. 'this.Test0_15 = 0.15;',
  6142. 'this.Test999 = 2.9999999999999;',
  6143. 'this.Test111999 = 211199999999999000.0;',
  6144. 'this.TestMinus111999 = -211199999999999000.0;',
  6145. 'this.d = 4.4;'
  6146. ]),
  6147. LinesToStr([
  6148. '$mod.d = 1.0;',
  6149. '$mod.d = 1.0 / 3.0;',
  6150. '$mod.d = 1 / 3;',
  6151. '$mod.d = 5.0E-324;',
  6152. '$mod.d = 1.7E308;',
  6153. '$mod.d = 1.00E0;',
  6154. '$mod.d = 2.00E1;',
  6155. '$mod.d = 3.000E0;',
  6156. '$mod.d = -4.00E-0;',
  6157. '$mod.d = -5.00E-1;',
  6158. '$mod.d = Math.pow(10, 3);',
  6159. '$mod.d = 10 % 3;',
  6160. '$mod.d = Math.floor(10 / 3);',
  6161. '$mod.d = 1;',
  6162. '$mod.d = 0.1;',
  6163. '$mod.d = 0.3;',
  6164. '$mod.d = -0.1;',
  6165. '$mod.d = -0.3;',
  6166. '$mod.d = -0.003;',
  6167. '$mod.d = -0.123456789;',
  6168. '$mod.d = -300;',
  6169. '$mod.d = -123456;',
  6170. '$mod.d = -1234567.8;',
  6171. '$mod.d = -1.23456789E7;',
  6172. '$mod.d = 1E-12;',
  6173. '$mod.d = -1E-12;',
  6174. '$mod.d = 1.7E308;',
  6175. '$mod.d = -1.7E308;',
  6176. '$mod.d = -9007199254740991;',
  6177. '$mod.d = -9007199254740991;',
  6178. '$mod.d = -9.007199254740992E15;',
  6179. '$mod.d = -9.007199254740992E15;',
  6180. '$mod.d = 9007199254740991;',
  6181. '$mod.d = 0.0;',
  6182. '']));
  6183. end;
  6184. procedure TTestModule.TestInteger;
  6185. begin
  6186. StartProgram(false);
  6187. Add([
  6188. 'const',
  6189. ' MinInt = low(NativeInt);',
  6190. ' MaxInt = high(NativeInt);',
  6191. 'type',
  6192. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  6193. 'const',
  6194. ' a = low(TMyInt)+High(TMyInt);',
  6195. 'var',
  6196. ' i: TMyInt;',
  6197. 'begin',
  6198. ' i:=-MinInt;',
  6199. ' i:=default(TMyInt);',
  6200. ' i:=low(i)+high(i);',
  6201. '']);
  6202. ConvertProgram;
  6203. CheckSource('TestIntegerRange',
  6204. LinesToStr([
  6205. 'this.MinInt = -9007199254740991;',
  6206. 'this.MaxInt = 9007199254740991;',
  6207. 'this.a = -9007199254740991 + 9007199254740991;',
  6208. 'this.i = 0;',
  6209. '']),
  6210. LinesToStr([
  6211. '$mod.i = - -9007199254740991;',
  6212. '$mod.i = -9007199254740991;',
  6213. '$mod.i = -9007199254740991 + 9007199254740991;',
  6214. '']));
  6215. end;
  6216. procedure TTestModule.TestIntegerRange;
  6217. begin
  6218. StartProgram(false);
  6219. Add([
  6220. 'const',
  6221. ' MinInt = -1;',
  6222. ' MaxInt = +1;',
  6223. 'type',
  6224. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  6225. ' TInt2 = 1..3;',
  6226. 'const',
  6227. ' a = low(TMyInt)+High(TMyInt);',
  6228. ' b = low(TInt2)+High(TInt2);',
  6229. ' s1 = [1];',
  6230. ' s2 = [1,2];',
  6231. ' s3 = [1..3];',
  6232. ' s4 = [low(shortint)..high(shortint)];',
  6233. ' s5 = [succ(low(shortint))..pred(high(shortint))];',
  6234. ' s6 = 1 in s2;',
  6235. 'var',
  6236. ' i: TMyInt;',
  6237. ' i2: TInt2;',
  6238. 'begin',
  6239. ' i:=i2;',
  6240. ' i:=default(TMyInt);',
  6241. ' if i=i2 then ;']);
  6242. ConvertProgram;
  6243. CheckSource('TestIntegerRange',
  6244. LinesToStr([
  6245. 'this.MinInt = -1;',
  6246. 'this.MaxInt = +1;',
  6247. 'this.a = -1 + 1;',
  6248. 'this.b = 1 + 3;',
  6249. 'this.s1 = rtl.createSet(1);',
  6250. 'this.s2 = rtl.createSet(1, 2);',
  6251. 'this.s3 = rtl.createSet(null, 1, 3);',
  6252. 'this.s4 = rtl.createSet(null, -128, 127);',
  6253. 'this.s5 = rtl.createSet(null, -128 + 1, 127 - 1);',
  6254. 'this.s6 = 1 in $mod.s2;',
  6255. 'this.i = 0;',
  6256. 'this.i2 = 0;',
  6257. '']),
  6258. LinesToStr([
  6259. '$mod.i = $mod.i2;',
  6260. '$mod.i = -1;',
  6261. 'if ($mod.i === $mod.i2) ;',
  6262. '']));
  6263. end;
  6264. procedure TTestModule.TestIntegerTypecasts;
  6265. begin
  6266. StartProgram(false);
  6267. Add([
  6268. 'var',
  6269. ' i: nativeint;',
  6270. ' b: byte;',
  6271. ' sh: shortint;',
  6272. ' w: word;',
  6273. ' sm: smallint;',
  6274. ' lw: longword;',
  6275. ' li: longint;',
  6276. 'begin',
  6277. ' b:=byte(i);',
  6278. ' sh:=shortint(i);',
  6279. ' w:=word(i);',
  6280. ' sm:=smallint(i);',
  6281. ' lw:=longword(i);',
  6282. ' li:=longint(i);',
  6283. '']);
  6284. ConvertProgram;
  6285. CheckSource('TestIntegerTypecasts',
  6286. LinesToStr([
  6287. 'this.i = 0;',
  6288. 'this.b = 0;',
  6289. 'this.sh = 0;',
  6290. 'this.w = 0;',
  6291. 'this.sm = 0;',
  6292. 'this.lw = 0;',
  6293. 'this.li = 0;',
  6294. '']),
  6295. LinesToStr([
  6296. '$mod.b = $mod.i & 255;',
  6297. '$mod.sh = (($mod.i & 255) << 24) >> 24;',
  6298. '$mod.w = $mod.i & 65535;',
  6299. '$mod.sm = (($mod.i & 65535) << 16) >> 16;',
  6300. '$mod.lw = $mod.i >>> 0;',
  6301. '$mod.li = $mod.i & 0xFFFFFFFF;',
  6302. '']));
  6303. end;
  6304. procedure TTestModule.TestInteger_BitwiseShrNativeInt;
  6305. begin
  6306. StartProgram(false);
  6307. Add([
  6308. 'var',
  6309. ' i,j: nativeint;',
  6310. 'begin',
  6311. ' i:=i shr 0;',
  6312. ' i:=i shr 1;',
  6313. ' i:=i shr 3;',
  6314. ' i:=i shr 54;',
  6315. ' i:=j shr i;',
  6316. '']);
  6317. ConvertProgram;
  6318. CheckResolverUnexpectedHints;
  6319. CheckSource('TestInteger_BitwiseShrNativeInt',
  6320. LinesToStr([
  6321. 'this.i = 0;',
  6322. 'this.j = 0;',
  6323. '']),
  6324. LinesToStr([
  6325. '$mod.i = $mod.i;',
  6326. '$mod.i = Math.floor($mod.i / 2);',
  6327. '$mod.i = Math.floor($mod.i / 8);',
  6328. '$mod.i = 0;',
  6329. '$mod.i = rtl.shr($mod.j, $mod.i);',
  6330. '']));
  6331. end;
  6332. procedure TTestModule.TestInteger_BitwiseShlNativeInt;
  6333. begin
  6334. StartProgram(false);
  6335. Add([
  6336. 'var',
  6337. ' i: nativeint;',
  6338. 'begin',
  6339. ' i:=i shl 0;',
  6340. ' i:=i shl 54;',
  6341. ' i:=123456789012 shl 1;',
  6342. ' i:=i shl 1;',
  6343. '']);
  6344. ConvertProgram;
  6345. CheckResolverUnexpectedHints;
  6346. CheckSource('TestInteger_BitwiseShrNativeInt',
  6347. LinesToStr([
  6348. 'this.i = 0;',
  6349. '']),
  6350. LinesToStr([
  6351. '$mod.i = $mod.i;',
  6352. '$mod.i = 0;',
  6353. '$mod.i = 246913578024;',
  6354. '$mod.i = rtl.shl($mod.i, 1);',
  6355. '']));
  6356. end;
  6357. procedure TTestModule.TestCurrency;
  6358. begin
  6359. StartProgram(false);
  6360. Add([
  6361. 'type',
  6362. ' TCoin = currency;',
  6363. 'const',
  6364. ' a = TCoin(2.7);',
  6365. ' b = a + TCoin(1.7);',
  6366. ' MinSafeIntCurrency: TCoin = -92233720368.5477;',
  6367. ' MaxSafeIntCurrency: TCoin = 92233720368.5477;',
  6368. 'var',
  6369. ' c: TCoin = b;',
  6370. ' i: nativeint;',
  6371. ' d: double;',
  6372. ' j: jsvalue;',
  6373. 'function DoIt(c: currency): currency; begin end;',
  6374. 'function GetIt(d: double): double; begin end;',
  6375. 'procedure Write(v: jsvalue); begin end;',
  6376. 'begin',
  6377. ' c:=1.0;',
  6378. ' c:=0.1;',
  6379. ' c:=1.0/3.0;',
  6380. ' c:=1/3;',
  6381. ' c:=a;',
  6382. ' d:=c;',
  6383. ' c:=d;',
  6384. ' c:=currency(c);',
  6385. ' c:=currency(d);',
  6386. ' d:=double(c);',
  6387. ' c:=i;',
  6388. ' c:=currency(i);',
  6389. //' i:=c;', not allowed
  6390. ' i:=nativeint(c);',
  6391. ' c:=c+a;',
  6392. ' c:=-c-a;',
  6393. ' c:=d+c;',
  6394. ' c:=c+d;',
  6395. ' c:=d-c;',
  6396. ' c:=c-d;',
  6397. ' c:=c*a;',
  6398. ' c:=a*c;',
  6399. ' c:=d*c;',
  6400. ' c:=c*d;',
  6401. ' c:=c/a;',
  6402. ' c:=a/c;',
  6403. ' c:=d/c;',
  6404. ' c:=c/d;',
  6405. ' c:=c**a;',
  6406. ' c:=a**c;',
  6407. ' c:=d**c;',
  6408. ' c:=c**d;',
  6409. ' if c=c then ;',
  6410. ' if c=a then ;',
  6411. ' if a=c then ;',
  6412. ' if d=c then ;',
  6413. ' if c=d then ;',
  6414. ' c:=DoIt(c);',
  6415. ' c:=DoIt(i);',
  6416. ' c:=DoIt(d);',
  6417. ' c:=GetIt(c);',
  6418. ' j:=c;',
  6419. ' Write(c);',
  6420. ' c:=default(currency);',
  6421. ' j:=str(c);',
  6422. ' j:=str(c:0:3);',
  6423. '']);
  6424. ConvertProgram;
  6425. CheckSource('TestCurrency',
  6426. LinesToStr([
  6427. 'this.a = 27000;',
  6428. 'this.b = $mod.a + 17000;',
  6429. 'this.MinSafeIntCurrency = -92233720368.5477;',
  6430. 'this.MaxSafeIntCurrency = 92233720368.5477;',
  6431. 'this.c = $mod.b;',
  6432. 'this.i = 0;',
  6433. 'this.d = 0.0;',
  6434. 'this.j = undefined;',
  6435. 'this.DoIt = function (c) {',
  6436. ' var Result = 0;',
  6437. ' return Result;',
  6438. '};',
  6439. 'this.GetIt = function (d) {',
  6440. ' var Result = 0.0;',
  6441. ' return Result;',
  6442. '};',
  6443. 'this.Write = function (v) {',
  6444. '};',
  6445. '']),
  6446. LinesToStr([
  6447. '$mod.c = 10000;',
  6448. '$mod.c = 1000;',
  6449. '$mod.c = Math.floor((1.0 / 3.0) * 10000);',
  6450. '$mod.c = Math.floor((1 / 3) * 10000);',
  6451. '$mod.c = $mod.a;',
  6452. '$mod.d = $mod.c / 10000;',
  6453. '$mod.c = Math.floor($mod.d * 10000);',
  6454. '$mod.c = $mod.c;',
  6455. '$mod.c = $mod.d * 10000;',
  6456. '$mod.d = $mod.c / 10000;',
  6457. '$mod.c = $mod.i * 10000;',
  6458. '$mod.c = $mod.i * 10000;',
  6459. '$mod.i = Math.floor($mod.c / 10000);',
  6460. '$mod.c = $mod.c + $mod.a;',
  6461. '$mod.c = -$mod.c - $mod.a;',
  6462. '$mod.c = ($mod.d * 10000) + $mod.c;',
  6463. '$mod.c = $mod.c + ($mod.d * 10000);',
  6464. '$mod.c = ($mod.d * 10000) - $mod.c;',
  6465. '$mod.c = $mod.c - ($mod.d * 10000);',
  6466. '$mod.c = ($mod.c * $mod.a) / 10000;',
  6467. '$mod.c = ($mod.a * $mod.c) / 10000;',
  6468. '$mod.c = $mod.d * $mod.c;',
  6469. '$mod.c = $mod.c * $mod.d;',
  6470. '$mod.c = Math.floor(($mod.c / $mod.a) * 10000);',
  6471. '$mod.c = Math.floor(($mod.a / $mod.c) * 10000);',
  6472. '$mod.c = Math.floor($mod.d / $mod.c);',
  6473. '$mod.c = Math.floor($mod.c / $mod.d);',
  6474. '$mod.c = Math.floor(Math.pow($mod.c / 10000, $mod.a / 10000) * 10000);',
  6475. '$mod.c = Math.floor(Math.pow($mod.a / 10000, $mod.c / 10000) * 10000);',
  6476. '$mod.c = Math.floor(Math.pow($mod.d, $mod.c / 10000) * 10000);',
  6477. '$mod.c = Math.floor(Math.pow($mod.c / 10000, $mod.d) * 10000);',
  6478. 'if ($mod.c === $mod.c) ;',
  6479. 'if ($mod.c === $mod.a) ;',
  6480. 'if ($mod.a === $mod.c) ;',
  6481. 'if (($mod.d * 10000) === $mod.c) ;',
  6482. 'if ($mod.c === ($mod.d * 10000)) ;',
  6483. '$mod.c = $mod.DoIt($mod.c);',
  6484. '$mod.c = $mod.DoIt($mod.i * 10000);',
  6485. '$mod.c = $mod.DoIt($mod.d * 10000);',
  6486. '$mod.c = Math.floor($mod.GetIt($mod.c / 10000) * 10000);',
  6487. '$mod.j = $mod.c / 10000;',
  6488. '$mod.Write($mod.c / 10000);',
  6489. '$mod.c = 0;',
  6490. '$mod.j = rtl.floatToStr($mod.c / 10000);',
  6491. '$mod.j = rtl.floatToStr($mod.c / 10000, 0, 3);',
  6492. '']));
  6493. end;
  6494. procedure TTestModule.TestForBoolDo;
  6495. begin
  6496. StartProgram(false);
  6497. Add([
  6498. 'var b: boolean;',
  6499. 'begin',
  6500. ' for b:=false to true do ;',
  6501. ' for b:=b downto false do ;',
  6502. ' for b in boolean do ;',
  6503. '']);
  6504. ConvertProgram;
  6505. CheckSource('TestForBoolDo',
  6506. LinesToStr([ // statements
  6507. 'this.b = false;']),
  6508. LinesToStr([ // this.$main
  6509. 'for (var $l1 = 0; $l1 <= 1; $l1++) $mod.b = $l1 !== 0;',
  6510. 'for (var $l2 = +$mod.b; $l2 >= 0; $l2--) $mod.b = $l2 !== 0;',
  6511. 'for (var $l3 = 0; $l3 <= 1; $l3++) $mod.b = $l3 !== 0;',
  6512. '']));
  6513. end;
  6514. procedure TTestModule.TestForIntDo;
  6515. begin
  6516. StartProgram(false);
  6517. Add([
  6518. 'var i: longint;',
  6519. 'begin',
  6520. ' for i:=3 to 5 do ;',
  6521. ' for i:=i downto 2 do ;',
  6522. ' for i in byte do ;',
  6523. '']);
  6524. ConvertProgram;
  6525. CheckSource('TestForIntDo',
  6526. LinesToStr([ // statements
  6527. 'this.i = 0;']),
  6528. LinesToStr([ // this.$main
  6529. 'for ($mod.i = 3; $mod.i <= 5; $mod.i++) ;',
  6530. 'for (var $l1 = $mod.i; $l1 >= 2; $l1--) $mod.i = $l1;',
  6531. 'for (var $l2 = 0; $l2 <= 255; $l2++) $mod.i = $l2;',
  6532. '']));
  6533. end;
  6534. procedure TTestModule.TestForIntInDo;
  6535. begin
  6536. StartProgram(false);
  6537. Add([
  6538. 'type',
  6539. ' TSetOfInt = set of byte;',
  6540. ' TIntRg = 3..7;',
  6541. ' TSetOfIntRg = set of TIntRg;',
  6542. 'var',
  6543. ' i,i2: longint;',
  6544. ' a1: array of byte;',
  6545. ' a2: array[1..3] of byte;',
  6546. ' soi: TSetOfInt;',
  6547. ' soir: TSetOfIntRg;',
  6548. ' ir: TIntRg;',
  6549. 'begin',
  6550. ' for i in byte do ;',
  6551. ' for i in a1 do ;',
  6552. ' for i in a2 do ;',
  6553. ' for i in [11..13] do ;',
  6554. ' for i in TSetOfInt do ;',
  6555. ' for i in TIntRg do ;',
  6556. ' for i in soi do i2:=i;',
  6557. ' for i in TSetOfIntRg do ;',
  6558. ' for i in soir do ;',
  6559. ' for ir in TIntRg do ;',
  6560. ' for ir in TSetOfIntRg do ;',
  6561. ' for ir in soir do ;',
  6562. '']);
  6563. ConvertProgram;
  6564. CheckSource('TestForIntInDo',
  6565. LinesToStr([ // statements
  6566. 'this.i = 0;',
  6567. 'this.i2 = 0;',
  6568. 'this.a1 = [];',
  6569. 'this.a2 = rtl.arraySetLength(null, 0, 3);',
  6570. 'this.soi = {};',
  6571. 'this.soir = {};',
  6572. 'this.ir = 0;',
  6573. '']),
  6574. LinesToStr([ // this.$main
  6575. 'for (var $l1 = 0; $l1 <= 255; $l1++) $mod.i = $l1;',
  6576. 'for (var $in2 = $mod.a1, $l3 = 0, $end4 = rtl.length($in2) - 1; $l3 <= $end4; $l3++) $mod.i = $in2[$l3];',
  6577. 'for (var $in5 = $mod.a2, $l6 = 0, $end7 = rtl.length($in5) - 1; $l6 <= $end7; $l6++) $mod.i = $in5[$l6];',
  6578. 'for (var $l8 = 11; $l8 <= 13; $l8++) $mod.i = $l8;',
  6579. 'for (var $l9 = 0; $l9 <= 255; $l9++) $mod.i = $l9;',
  6580. 'for (var $l10 = 3; $l10 <= 7; $l10++) $mod.i = $l10;',
  6581. 'for (var $l11 in $mod.soi) {',
  6582. ' $mod.i = +$l11;',
  6583. ' $mod.i2 = $mod.i;',
  6584. '};',
  6585. 'for (var $l12 = 3; $l12 <= 7; $l12++) $mod.i = $l12;',
  6586. 'for (var $l13 in $mod.soir) $mod.i = +$l13;',
  6587. 'for (var $l14 = 3; $l14 <= 7; $l14++) $mod.ir = $l14;',
  6588. 'for (var $l15 = 3; $l15 <= 7; $l15++) $mod.ir = $l15;',
  6589. 'for (var $l16 in $mod.soir) $mod.ir = +$l16;',
  6590. '']));
  6591. end;
  6592. procedure TTestModule.TestCharConst;
  6593. begin
  6594. StartProgram(false);
  6595. Add([
  6596. 'const',
  6597. ' a = #$00F3;',
  6598. ' c: char = ''1'';',
  6599. 'begin',
  6600. ' c:=#0;',
  6601. ' c:=#1;',
  6602. ' c:=#9;',
  6603. ' c:=#10;',
  6604. ' c:=#13;',
  6605. ' c:=#31;',
  6606. ' c:=#32;',
  6607. ' c:=#$A;',
  6608. ' c:=#$0A;',
  6609. ' c:=#$b;',
  6610. ' c:=#$0b;',
  6611. ' c:=^A;',
  6612. ' c:=''"'';',
  6613. ' c:=default(char);',
  6614. ' c:=#$00E4;', // ä
  6615. ' c:=''ä'';',
  6616. ' c:=#$E4;', // ä
  6617. ' c:=#$D800;', // invalid UTF-16
  6618. ' c:=#$DFFF;', // invalid UTF-16
  6619. ' c:=#$FFFF;', // last UCS-2
  6620. ' c:=high(c);', // last UCS-2
  6621. '']);
  6622. ConvertProgram;
  6623. CheckSource('TestCharConst',
  6624. LinesToStr([
  6625. 'this.a="ó";',
  6626. 'this.c="1";'
  6627. ]),
  6628. LinesToStr([
  6629. '$mod.c="\x00";',
  6630. '$mod.c="\x01";',
  6631. '$mod.c="\t";',
  6632. '$mod.c="\n";',
  6633. '$mod.c="\r";',
  6634. '$mod.c="\x1F";',
  6635. '$mod.c=" ";',
  6636. '$mod.c="\n";',
  6637. '$mod.c="\n";',
  6638. '$mod.c="\x0B";',
  6639. '$mod.c="\x0B";',
  6640. '$mod.c="\x01";',
  6641. '$mod.c=''"'';',
  6642. '$mod.c="\x00";',
  6643. '$mod.c = "ä";',
  6644. '$mod.c = "ä";',
  6645. '$mod.c = "ä";',
  6646. '$mod.c="\uD800";',
  6647. '$mod.c="\uDFFF";',
  6648. '$mod.c="\uFFFF";',
  6649. '$mod.c="\uFFFF";',
  6650. '']));
  6651. end;
  6652. procedure TTestModule.TestChar_Compare;
  6653. begin
  6654. StartProgram(false);
  6655. Add('var');
  6656. Add(' c: char;');
  6657. Add(' b: boolean;');
  6658. Add('begin');
  6659. Add(' b:=c=''1'';');
  6660. Add(' b:=''2''=c;');
  6661. Add(' b:=''3''=''4'';');
  6662. Add(' b:=c<>''5'';');
  6663. Add(' b:=''6''<>c;');
  6664. Add(' b:=c>''7'';');
  6665. Add(' b:=''8''>c;');
  6666. Add(' b:=c>=''9'';');
  6667. Add(' b:=''A''>=c;');
  6668. Add(' b:=c<''B'';');
  6669. Add(' b:=''C''<c;');
  6670. Add(' b:=c<=''D'';');
  6671. Add(' b:=''E''<=c;');
  6672. ConvertProgram;
  6673. CheckSource('TestChar_Compare',
  6674. LinesToStr([
  6675. 'this.c="";',
  6676. 'this.b = false;'
  6677. ]),
  6678. LinesToStr([
  6679. '$mod.b = $mod.c === "1";',
  6680. '$mod.b = "2" === $mod.c;',
  6681. '$mod.b = "3" === "4";',
  6682. '$mod.b = $mod.c !== "5";',
  6683. '$mod.b = "6" !== $mod.c;',
  6684. '$mod.b = $mod.c > "7";',
  6685. '$mod.b = "8" > $mod.c;',
  6686. '$mod.b = $mod.c >= "9";',
  6687. '$mod.b = "A" >= $mod.c;',
  6688. '$mod.b = $mod.c < "B";',
  6689. '$mod.b = "C" < $mod.c;',
  6690. '$mod.b = $mod.c <= "D";',
  6691. '$mod.b = "E" <= $mod.c;',
  6692. '']));
  6693. end;
  6694. procedure TTestModule.TestChar_BuiltInProcs;
  6695. begin
  6696. StartProgram(false);
  6697. Add([
  6698. 'var',
  6699. ' c: char;',
  6700. ' i: longint;',
  6701. ' s: string;',
  6702. 'begin',
  6703. ' i:=ord(c);',
  6704. ' i:=ord(s[i]);',
  6705. ' c:=chr(i);',
  6706. ' c:=pred(c);',
  6707. ' c:=succ(c);',
  6708. ' c:=low(c);',
  6709. ' c:=high(c);',
  6710. ' i:=byte(c);',
  6711. ' i:=word(c);',
  6712. ' i:=longint(c);',
  6713. '']);
  6714. ConvertProgram;
  6715. CheckSource('TestChar_BuiltInProcs',
  6716. LinesToStr([
  6717. 'this.c = "";',
  6718. 'this.i = 0;',
  6719. 'this.s = "";'
  6720. ]),
  6721. LinesToStr([
  6722. '$mod.i = $mod.c.charCodeAt();',
  6723. '$mod.i = $mod.s.charCodeAt($mod.i-1);',
  6724. '$mod.c = String.fromCharCode($mod.i);',
  6725. '$mod.c = String.fromCharCode($mod.c.charCodeAt() - 1);',
  6726. '$mod.c = String.fromCharCode($mod.c.charCodeAt() + 1);',
  6727. '$mod.c = "\x00";',
  6728. '$mod.c = "\uFFFF";',
  6729. '$mod.i = $mod.c.charCodeAt() & 255;',
  6730. '$mod.i = $mod.c.charCodeAt();',
  6731. '$mod.i = $mod.c.charCodeAt() & 0xFFFFFFFF;',
  6732. '']));
  6733. end;
  6734. procedure TTestModule.TestStringConst;
  6735. begin
  6736. StartProgram(false);
  6737. Add([
  6738. '{$H+}',
  6739. 'const',
  6740. ' a = #$00F3#$017C;', // first <256, then >=256
  6741. ' b = string(''a'');',
  6742. ' c = string(''ä'');',
  6743. ' d = UnicodeString(''b'');',
  6744. ' e = UnicodeString(''ö'');',
  6745. 'var',
  6746. ' s: string = ''abc'';',
  6747. 'begin',
  6748. ' s:='''';',
  6749. ' s:=#13#10;',
  6750. ' s:=#9''foo'';',
  6751. ' s:=#$A9;',
  6752. ' s:=''foo''#13''bar'';',
  6753. ' s:=''"'';',
  6754. ' s:=''"''''"'';',
  6755. ' s:=#$20AC;', // euro
  6756. ' s:=#$10437;', // outside BMP
  6757. ' s:=default(string);',
  6758. ' s:=concat(s);',
  6759. ' s:=concat(s,''a'',s)',
  6760. '']);
  6761. ConvertProgram;
  6762. CheckSource('TestStringConst',
  6763. LinesToStr([
  6764. 'this.a = "óż";',
  6765. 'this.b = "a";',
  6766. 'this.c = "ä";',
  6767. 'this.d = "b";',
  6768. 'this.e = "ö";',
  6769. 'this.s="abc";',
  6770. '']),
  6771. LinesToStr([
  6772. '$mod.s="";',
  6773. '$mod.s="\r\n";',
  6774. '$mod.s="\tfoo";',
  6775. '$mod.s="©";',
  6776. '$mod.s="foo\rbar";',
  6777. '$mod.s=''"'';',
  6778. '$mod.s=''"\''"'';',
  6779. '$mod.s="€";',
  6780. '$mod.s="'#$F0#$90#$90#$B7'";',
  6781. '$mod.s="";',
  6782. '$mod.s = $mod.s;',
  6783. '$mod.s = $mod.s.concat("a", $mod.s);',
  6784. '']));
  6785. end;
  6786. procedure TTestModule.TestStringConstSurrogate;
  6787. begin
  6788. StartProgram(false);
  6789. Add([
  6790. 'var',
  6791. ' s: string;',
  6792. 'begin',
  6793. ' s:=''😊'';', // 1F60A
  6794. '']);
  6795. ConvertProgram;
  6796. CheckSource('TestStringConstSurrogate',
  6797. LinesToStr([
  6798. 'this.s="";'
  6799. ]),
  6800. LinesToStr([
  6801. '$mod.s="😊";'
  6802. ]));
  6803. end;
  6804. procedure TTestModule.TestString_Length;
  6805. begin
  6806. StartProgram(false);
  6807. Add('const c = ''foo'';');
  6808. Add('var');
  6809. Add(' s: string;');
  6810. Add(' i: longint;');
  6811. Add('begin');
  6812. Add(' i:=length(s);');
  6813. Add(' i:=length(s+s);');
  6814. Add(' i:=length(''abc'');');
  6815. Add(' i:=length(c);');
  6816. ConvertProgram;
  6817. CheckSource('TestString_Length',
  6818. LinesToStr([
  6819. 'this.c = "foo";',
  6820. 'this.s = "";',
  6821. 'this.i = 0;',
  6822. '']),
  6823. LinesToStr([
  6824. '$mod.i = $mod.s.length;',
  6825. '$mod.i = ($mod.s+$mod.s).length;',
  6826. '$mod.i = "abc".length;',
  6827. '$mod.i = $mod.c.length;',
  6828. '']));
  6829. end;
  6830. procedure TTestModule.TestString_Compare;
  6831. begin
  6832. StartProgram(false);
  6833. Add('var');
  6834. Add(' s, t: string;');
  6835. Add(' b: boolean;');
  6836. Add('begin');
  6837. Add(' b:=s=t;');
  6838. Add(' b:=s<>t;');
  6839. Add(' b:=s>t;');
  6840. Add(' b:=s>=t;');
  6841. Add(' b:=s<t;');
  6842. Add(' b:=s<=t;');
  6843. ConvertProgram;
  6844. CheckSource('TestString_Compare',
  6845. LinesToStr([ // statements
  6846. 'this.s = "";',
  6847. 'this.t = "";',
  6848. 'this.b =false;'
  6849. ]),
  6850. LinesToStr([ // this.$main
  6851. '$mod.b = $mod.s === $mod.t;',
  6852. '$mod.b = $mod.s !== $mod.t;',
  6853. '$mod.b = $mod.s > $mod.t;',
  6854. '$mod.b = $mod.s >= $mod.t;',
  6855. '$mod.b = $mod.s < $mod.t;',
  6856. '$mod.b = $mod.s <= $mod.t;',
  6857. '']));
  6858. end;
  6859. procedure TTestModule.TestString_SetLength;
  6860. begin
  6861. StartProgram(false);
  6862. Add([
  6863. 'procedure DoIt(var s: string);',
  6864. 'begin',
  6865. ' SetLength(s,2);',
  6866. 'end;',
  6867. 'var s: string;',
  6868. 'begin',
  6869. ' SetLength(s,3);',
  6870. '']);
  6871. ConvertProgram;
  6872. CheckSource('TestString_SetLength',
  6873. LinesToStr([ // statements
  6874. 'this.DoIt = function (s) {',
  6875. ' s.set(rtl.strSetLength(s.get(), 2));',
  6876. '};',
  6877. 'this.s = "";',
  6878. '']),
  6879. LinesToStr([ // this.$main
  6880. '$mod.s = rtl.strSetLength($mod.s, 3);'
  6881. ]));
  6882. end;
  6883. procedure TTestModule.TestString_CharAt;
  6884. begin
  6885. StartProgram(false);
  6886. Add([
  6887. 'var',
  6888. ' s: string;',
  6889. ' c: char;',
  6890. ' b: boolean;',
  6891. 'begin',
  6892. ' b:= s[1] = c;',
  6893. ' b:= c = s[1];',
  6894. ' b:= c <> s[1];',
  6895. ' b:= c > s[1];',
  6896. ' b:= c >= s[1];',
  6897. ' b:= c < s[2];',
  6898. ' b:= c <= s[1];',
  6899. ' s[1] := c;',
  6900. ' s[2+3] := c;']);
  6901. ConvertProgram;
  6902. CheckSource('TestString_CharAt',
  6903. LinesToStr([ // statements
  6904. 'this.s = "";',
  6905. 'this.c = "";',
  6906. 'this.b = false;'
  6907. ]),
  6908. LinesToStr([ // this.$main
  6909. '$mod.b = $mod.s.charAt(0) === $mod.c;',
  6910. '$mod.b = $mod.c === $mod.s.charAt(0);',
  6911. '$mod.b = $mod.c !== $mod.s.charAt(0);',
  6912. '$mod.b = $mod.c > $mod.s.charAt(0);',
  6913. '$mod.b = $mod.c >= $mod.s.charAt(0);',
  6914. '$mod.b = $mod.c < $mod.s.charAt(1);',
  6915. '$mod.b = $mod.c <= $mod.s.charAt(0);',
  6916. '$mod.s = rtl.setCharAt($mod.s, 0, $mod.c);',
  6917. '$mod.s = rtl.setCharAt($mod.s, (2 + 3) - 1, $mod.c);',
  6918. '']));
  6919. end;
  6920. procedure TTestModule.TestStringHMinusFail;
  6921. begin
  6922. StartProgram(false);
  6923. Add([
  6924. '{$H-}',
  6925. 'var s: string;',
  6926. 'begin']);
  6927. ConvertProgram;
  6928. CheckHint(mtWarning,nWarnIllegalCompilerDirectiveX,'Warning: test1.pp(3,6) : Illegal compiler directive "H-"');
  6929. end;
  6930. procedure TTestModule.TestStr;
  6931. begin
  6932. StartProgram(false);
  6933. Add('var');
  6934. Add(' b: boolean;');
  6935. Add(' i: longint;');
  6936. Add(' d: double;');
  6937. Add(' s: string;');
  6938. Add('begin');
  6939. Add(' str(b,s);');
  6940. Add(' str(i,s);');
  6941. Add(' str(d,s);');
  6942. Add(' str(i:3,s);');
  6943. Add(' str(d:3:2,s);');
  6944. Add(' Str(12.456:12:1,s);');
  6945. Add(' Str(12.456:12,s);');
  6946. Add(' s:=str(b);');
  6947. Add(' s:=str(i);');
  6948. Add(' s:=str(d);');
  6949. Add(' s:=str(i,i);');
  6950. Add(' s:=str(i:3);');
  6951. Add(' s:=str(d:3:2);');
  6952. Add(' s:=str(i:4,i);');
  6953. Add(' s:=str(i,i:5);');
  6954. Add(' s:=str(i:4,i:5);');
  6955. Add(' s:=str(s,s);');
  6956. Add(' s:=str(s,''foo'');');
  6957. ConvertProgram;
  6958. CheckSource('TestStr',
  6959. LinesToStr([ // statements
  6960. 'this.b = false;',
  6961. 'this.i = 0;',
  6962. 'this.d = 0.0;',
  6963. 'this.s = "";',
  6964. '']),
  6965. LinesToStr([ // this.$main
  6966. '$mod.s = ""+$mod.b;',
  6967. '$mod.s = ""+$mod.i;',
  6968. '$mod.s = rtl.floatToStr($mod.d);',
  6969. '$mod.s = rtl.spaceLeft(""+$mod.i,3);',
  6970. '$mod.s = rtl.floatToStr($mod.d,3,2);',
  6971. '$mod.s = rtl.floatToStr(12.456,12,1);',
  6972. '$mod.s = rtl.floatToStr(12.456,12);',
  6973. '$mod.s = ""+$mod.b;',
  6974. '$mod.s = ""+$mod.i;',
  6975. '$mod.s = rtl.floatToStr($mod.d);',
  6976. '$mod.s = ""+$mod.i+$mod.i;',
  6977. '$mod.s = rtl.spaceLeft(""+$mod.i,3);',
  6978. '$mod.s = rtl.floatToStr($mod.d,3,2);',
  6979. '$mod.s = rtl.spaceLeft("" + $mod.i, 4) + $mod.i;',
  6980. '$mod.s = "" + $mod.i + rtl.spaceLeft("" + $mod.i, 5);',
  6981. '$mod.s = rtl.spaceLeft("" + $mod.i, 4) + rtl.spaceLeft("" + $mod.i, 5);',
  6982. '$mod.s = $mod.s + $mod.s;',
  6983. '$mod.s = $mod.s + "foo";',
  6984. '']));
  6985. end;
  6986. procedure TTestModule.TestBaseType_AnsiStringFail;
  6987. begin
  6988. StartProgram(false);
  6989. Add('var s: AnsiString');
  6990. SetExpectedPasResolverError('identifier not found "AnsiString"',PasResolveEval.nIdentifierNotFound);
  6991. ConvertProgram;
  6992. end;
  6993. procedure TTestModule.TestBaseType_WideStringFail;
  6994. begin
  6995. StartProgram(false);
  6996. Add('var s: WideString');
  6997. SetExpectedPasResolverError('identifier not found "WideString"',PasResolveEval.nIdentifierNotFound);
  6998. ConvertProgram;
  6999. end;
  7000. procedure TTestModule.TestBaseType_ShortStringFail;
  7001. begin
  7002. StartProgram(false);
  7003. Add('var s: ShortString');
  7004. SetExpectedPasResolverError('identifier not found "ShortString"',PasResolveEval.nIdentifierNotFound);
  7005. ConvertProgram;
  7006. end;
  7007. procedure TTestModule.TestBaseType_RawByteStringFail;
  7008. begin
  7009. StartProgram(false);
  7010. Add('var s: RawByteString');
  7011. SetExpectedPasResolverError('identifier not found "RawByteString"',PasResolveEval.nIdentifierNotFound);
  7012. ConvertProgram;
  7013. end;
  7014. procedure TTestModule.TestTypeShortstring_Fail;
  7015. begin
  7016. StartProgram(false);
  7017. Add('type t = string[12];');
  7018. Add('var s: t;');
  7019. Add('begin');
  7020. SetExpectedPasResolverError('illegal qualifier "["',nIllegalQualifier);
  7021. ConvertProgram;
  7022. end;
  7023. procedure TTestModule.TestCharSet_Custom;
  7024. begin
  7025. StartProgram(false);
  7026. Add([
  7027. 'type',
  7028. ' TCharRg = ''a''..''z'';',
  7029. ' TSetOfCharRg = set of TCharRg;',
  7030. ' TCharRg2 = ''m''..''p'';',
  7031. 'const',
  7032. ' crg: TCharRg = ''b'';',
  7033. 'var',
  7034. ' c: char;',
  7035. ' crg2: TCharRg2;',
  7036. ' s: TSetOfCharRg;',
  7037. 'begin',
  7038. ' c:=crg;',
  7039. ' crg:=c;',
  7040. ' crg2:=crg;',
  7041. ' if c=crg then ;',
  7042. ' if crg=c then ;',
  7043. ' if crg=crg2 then ;',
  7044. ' if c in s then ;',
  7045. ' if crg2 in s then ;',
  7046. ' c:=default(TCharRg);',
  7047. '']);
  7048. ConvertProgram;
  7049. CheckSource('TestCharSet_Custom',
  7050. LinesToStr([ // statements
  7051. 'this.crg = "b";',
  7052. 'this.c = "";',
  7053. 'this.crg2 = "m";',
  7054. 'this.s = {};',
  7055. '']),
  7056. LinesToStr([ // this.$main
  7057. '$mod.c = $mod.crg;',
  7058. '$mod.crg = $mod.c;',
  7059. '$mod.crg2 = $mod.crg;',
  7060. 'if ($mod.c === $mod.crg) ;',
  7061. 'if ($mod.crg === $mod.c) ;',
  7062. 'if ($mod.crg === $mod.crg2) ;',
  7063. 'if ($mod.c.charCodeAt() in $mod.s) ;',
  7064. 'if ($mod.crg2.charCodeAt() in $mod.s) ;',
  7065. '$mod.c = "a";',
  7066. '']));
  7067. end;
  7068. procedure TTestModule.TestForCharDo;
  7069. begin
  7070. StartProgram(false);
  7071. Add([
  7072. 'var c: char;',
  7073. 'begin',
  7074. ' for c:=''a'' to ''c'' do ;',
  7075. ' for c:=c downto ''a'' do ;',
  7076. ' for c:=''Б'' to ''Я'' do ;',
  7077. '']);
  7078. ConvertProgram;
  7079. CheckSource('TestForCharDo',
  7080. LinesToStr([ // statements
  7081. 'this.c = "";']),
  7082. LinesToStr([ // this.$main
  7083. 'for (var $l1 = 97; $l1 <= 99; $l1++) $mod.c = String.fromCharCode($l1);',
  7084. 'for (var $l2 = $mod.c.charCodeAt(); $l2 >= 97; $l2--) $mod.c = String.fromCharCode($l2);',
  7085. 'for (var $l3 = 1041; $l3 <= 1071; $l3++) $mod.c = String.fromCharCode($l3);',
  7086. '']));
  7087. end;
  7088. procedure TTestModule.TestForCharInDo;
  7089. begin
  7090. StartProgram(false);
  7091. Add([
  7092. 'type',
  7093. ' TSetOfChar = set of char;',
  7094. ' TCharRg = ''a''..''z'';',
  7095. ' TSetOfCharRg = set of TCharRg;',
  7096. 'const Foo = ''foo'';',
  7097. 'var',
  7098. ' c,c2: char;',
  7099. ' s: string;',
  7100. ' a1: array of char;',
  7101. ' a2: array[1..3] of char;',
  7102. ' soc: TSetOfChar;',
  7103. ' socr: TSetOfCharRg;',
  7104. ' cr: TCharRg;',
  7105. 'begin',
  7106. ' for c in foo do ;',
  7107. ' for c in s do ;',
  7108. ' for c in char do ;',
  7109. ' for c in a1 do ;',
  7110. ' for c in a2 do ;',
  7111. ' for c in [''1''..''3''] do ;',
  7112. ' for c in TSetOfChar do ;',
  7113. ' for c in TCharRg do ;',
  7114. ' for c in soc do c2:=c;',
  7115. ' for c in TSetOfCharRg do ;',
  7116. ' for c in socr do ;',
  7117. ' for cr in TCharRg do ;',
  7118. ' for cr in TSetOfCharRg do ;',
  7119. ' for cr in socr do ;',
  7120. '']);
  7121. ConvertProgram;
  7122. CheckSource('TestForCharInDo',
  7123. LinesToStr([ // statements
  7124. 'this.Foo = "foo";',
  7125. 'this.c = "";',
  7126. 'this.c2 = "";',
  7127. 'this.s = "";',
  7128. 'this.a1 = [];',
  7129. 'this.a2 = rtl.arraySetLength(null, "", 3);',
  7130. 'this.soc = {};',
  7131. 'this.socr = {};',
  7132. 'this.cr = "a";',
  7133. '']),
  7134. LinesToStr([ // this.$main
  7135. 'for (var $in1 = $mod.Foo, $l2 = 0, $end3 = $in1.length - 1; $l2 <= $end3; $l2++) $mod.c = $in1.charAt($l2);',
  7136. 'for (var $in4 = $mod.s, $l5 = 0, $end6 = $in4.length - 1; $l5 <= $end6; $l5++) $mod.c = $in4.charAt($l5);',
  7137. 'for (var $l7 = 0; $l7 <= 65535; $l7++) $mod.c = String.fromCharCode($l7);',
  7138. 'for (var $in8 = $mod.a1, $l9 = 0, $end10 = rtl.length($in8) - 1; $l9 <= $end10; $l9++) $mod.c = $in8[$l9];',
  7139. 'for (var $in11 = $mod.a2, $l12 = 0, $end13 = rtl.length($in11) - 1; $l12 <= $end13; $l12++) $mod.c = $in11[$l12];',
  7140. 'for (var $l14 = 49; $l14 <= 51; $l14++) $mod.c = String.fromCharCode($l14);',
  7141. 'for (var $l15 = 0; $l15 <= 65535; $l15++) $mod.c = String.fromCharCode($l15);',
  7142. 'for (var $l16 = 97; $l16 <= 122; $l16++) $mod.c = String.fromCharCode($l16);',
  7143. 'for (var $l17 in $mod.soc) {',
  7144. ' $mod.c = String.fromCharCode($l17);',
  7145. ' $mod.c2 = $mod.c;',
  7146. '};',
  7147. 'for (var $l18 = 97; $l18 <= 122; $l18++) $mod.c = String.fromCharCode($l18);',
  7148. 'for (var $l19 in $mod.socr) $mod.c = String.fromCharCode($l19);',
  7149. 'for (var $l20 = 97; $l20 <= 122; $l20++) $mod.cr = String.fromCharCode($l20);',
  7150. 'for (var $l21 = 97; $l21 <= 122; $l21++) $mod.cr = String.fromCharCode($l21);',
  7151. 'for (var $l22 in $mod.socr) $mod.cr = String.fromCharCode($l22);',
  7152. '']));
  7153. end;
  7154. procedure TTestModule.TestProcTwoArgs;
  7155. begin
  7156. StartProgram(false);
  7157. Add('procedure Test(a,b: longint);');
  7158. Add('begin');
  7159. Add('end;');
  7160. Add('begin');
  7161. ConvertProgram;
  7162. CheckSource('TestProcTwoArgs',
  7163. LinesToStr([ // statements
  7164. 'this.Test = function (a,b) {',
  7165. '};'
  7166. ]),
  7167. LinesToStr([ // this.$main
  7168. ''
  7169. ]));
  7170. end;
  7171. procedure TTestModule.TestProc_DefaultValue;
  7172. begin
  7173. StartProgram(false);
  7174. Add('procedure p1(i: longint = 1);');
  7175. Add('begin');
  7176. Add('end;');
  7177. Add('procedure p2(i: longint = 1; c: char = ''a'');');
  7178. Add('begin');
  7179. Add('end;');
  7180. Add('procedure p3(d: double = 1.0; b: boolean = false; s: string = ''abc'');');
  7181. Add('begin');
  7182. Add('end;');
  7183. Add('begin');
  7184. Add(' p1;');
  7185. Add(' p1();');
  7186. Add(' p1(11);');
  7187. Add(' p2;');
  7188. Add(' p2();');
  7189. Add(' p2(12);');
  7190. Add(' p2(13,''b'');');
  7191. Add(' p3();');
  7192. ConvertProgram;
  7193. CheckSource('TestProc_DefaultValue',
  7194. LinesToStr([ // statements
  7195. 'this.p1 = function (i) {',
  7196. '};',
  7197. 'this.p2 = function (i,c) {',
  7198. '};',
  7199. 'this.p3 = function (d,b,s) {',
  7200. '};'
  7201. ]),
  7202. LinesToStr([ // this.$main
  7203. ' $mod.p1(1);',
  7204. ' $mod.p1(1);',
  7205. ' $mod.p1(11);',
  7206. ' $mod.p2(1,"a");',
  7207. ' $mod.p2(1,"a");',
  7208. ' $mod.p2(12,"a");',
  7209. ' $mod.p2(13,"b");',
  7210. ' $mod.p3(1.0,false,"abc");'
  7211. ]));
  7212. end;
  7213. procedure TTestModule.TestFunctionInt;
  7214. begin
  7215. StartProgram(false);
  7216. Add('function MyTest(Bar: longint): longint;');
  7217. Add('begin');
  7218. Add(' Result:=2*bar');
  7219. Add('end;');
  7220. Add('begin');
  7221. ConvertProgram;
  7222. CheckSource('TestFunctionInt',
  7223. LinesToStr([ // statements
  7224. 'this.MyTest = function (Bar) {',
  7225. ' var Result = 0;',
  7226. ' Result = 2*Bar;',
  7227. ' return Result;',
  7228. '};'
  7229. ]),
  7230. LinesToStr([ // this.$main
  7231. ''
  7232. ]));
  7233. end;
  7234. procedure TTestModule.TestFunctionString;
  7235. begin
  7236. StartProgram(false);
  7237. Add('function Test(Bar: string): string;');
  7238. Add('begin');
  7239. Add(' Result:=bar+BAR');
  7240. Add('end;');
  7241. Add('begin');
  7242. ConvertProgram;
  7243. CheckSource('TestFunctionString',
  7244. LinesToStr([ // statements
  7245. 'this.Test = function (Bar) {',
  7246. ' var Result = "";',
  7247. ' Result = Bar+Bar;',
  7248. ' return Result;',
  7249. '};'
  7250. ]),
  7251. LinesToStr([ // this.$main
  7252. ''
  7253. ]));
  7254. end;
  7255. procedure TTestModule.TestIfThen;
  7256. begin
  7257. StartProgram(false);
  7258. Add([
  7259. 'var b: boolean;',
  7260. 'begin',
  7261. ' if b then ;',
  7262. ' if b then else ;']);
  7263. ConvertProgram;
  7264. CheckSource('TestIfThen',
  7265. LinesToStr([ // statements
  7266. 'this.b = false;',
  7267. '']),
  7268. LinesToStr([ // this.$main
  7269. 'if ($mod.b) ;',
  7270. 'if ($mod.b) ;',
  7271. '']));
  7272. end;
  7273. procedure TTestModule.TestForLoop;
  7274. begin
  7275. StartProgram(false);
  7276. Add('var');
  7277. Add(' vI, vJ, vN: longint;');
  7278. Add('begin');
  7279. Add(' VJ:=0;');
  7280. Add(' VN:=3;');
  7281. Add(' for VI:=1 to VN do');
  7282. Add(' begin');
  7283. Add(' VJ:=VJ+VI;');
  7284. Add(' end;');
  7285. ConvertProgram;
  7286. CheckSource('TestForLoop',
  7287. LinesToStr([ // statements
  7288. 'this.vI = 0;',
  7289. 'this.vJ = 0;',
  7290. 'this.vN = 0;'
  7291. ]),
  7292. LinesToStr([ // this.$main
  7293. ' $mod.vJ = 0;',
  7294. ' $mod.vN = 3;',
  7295. ' for (var $l1 = 1, $end2 = $mod.vN; $l1 <= $end2; $l1++) {',
  7296. ' $mod.vI = $l1;',
  7297. ' $mod.vJ = $mod.vJ + $mod.vI;',
  7298. ' };',
  7299. '']));
  7300. end;
  7301. procedure TTestModule.TestForLoopInsideFunction;
  7302. begin
  7303. StartProgram(false);
  7304. Add('function SumNumbers(Count: longint): longint;');
  7305. Add('var');
  7306. Add(' vI, vJ: longint;');
  7307. Add('begin');
  7308. Add(' vj:=0;');
  7309. Add(' for vi:=1 to count do');
  7310. Add(' begin');
  7311. Add(' vj:=vj+vi;');
  7312. Add(' end;');
  7313. Add('end;');
  7314. Add('begin');
  7315. Add(' sumnumbers(3);');
  7316. ConvertProgram;
  7317. CheckSource('TestForLoopInsideFunction',
  7318. LinesToStr([ // statements
  7319. 'this.SumNumbers = function (Count) {',
  7320. ' var Result = 0;',
  7321. ' var vI = 0;',
  7322. ' var vJ = 0;',
  7323. ' vJ = 0;',
  7324. ' for (var $l1 = 1, $end2 = Count; $l1 <= $end2; $l1++) {',
  7325. ' vI = $l1;',
  7326. ' vJ = vJ + vI;',
  7327. ' };',
  7328. ' return Result;',
  7329. '};'
  7330. ]),
  7331. LinesToStr([ // $mod.$main
  7332. ' $mod.SumNumbers(3);'
  7333. ]));
  7334. end;
  7335. procedure TTestModule.TestForLoop_ReadVarAfter;
  7336. begin
  7337. StartProgram(false);
  7338. Add('var');
  7339. Add(' vI: longint;');
  7340. Add('begin');
  7341. Add(' for vi:=1 to 2 do ;');
  7342. Add(' if vi=3 then ;');
  7343. ConvertProgram;
  7344. CheckSource('TestForLoop',
  7345. LinesToStr([ // statements
  7346. 'this.vI = 0;'
  7347. ]),
  7348. LinesToStr([ // this.$main
  7349. ' for ($mod.vI = 1; $mod.vI <= 2; $mod.vI++) ;',
  7350. ' if ($mod.vI===3) ;'
  7351. ]));
  7352. end;
  7353. procedure TTestModule.TestForLoop_Nested;
  7354. begin
  7355. StartProgram(false);
  7356. Add('function SumNumbers(Count: longint): longint;');
  7357. Add('var');
  7358. Add(' vI, vJ, vK: longint;');
  7359. Add('begin');
  7360. Add(' VK:=0;');
  7361. Add(' for VI:=1 to count do');
  7362. Add(' begin');
  7363. Add(' for vj:=1 to vi do');
  7364. Add(' begin');
  7365. Add(' vk:=VK+VI;');
  7366. Add(' end;');
  7367. Add(' end;');
  7368. Add('end;');
  7369. Add('begin');
  7370. Add(' sumnumbers(3);');
  7371. ConvertProgram;
  7372. CheckSource('TestForLoopInFunction',
  7373. LinesToStr([ // statements
  7374. 'this.SumNumbers = function (Count) {',
  7375. ' var Result = 0;',
  7376. ' var vI = 0;',
  7377. ' var vJ = 0;',
  7378. ' var vK = 0;',
  7379. ' vK = 0;',
  7380. ' for (var $l1 = 1, $end2 = Count; $l1 <= $end2; $l1++) {',
  7381. ' vI = $l1;',
  7382. ' for (var $l3 = 1, $end4 = vI; $l3 <= $end4; $l3++) {',
  7383. ' vJ = $l3;',
  7384. ' vK = vK + vI;',
  7385. ' };',
  7386. ' };',
  7387. ' return Result;',
  7388. '};'
  7389. ]),
  7390. LinesToStr([ // $mod.$main
  7391. ' $mod.SumNumbers(3);'
  7392. ]));
  7393. end;
  7394. procedure TTestModule.TestRepeatUntil;
  7395. begin
  7396. StartProgram(false);
  7397. Add('var');
  7398. Add(' vI, vJ, vN: longint;');
  7399. Add('begin');
  7400. Add(' vn:=3;');
  7401. Add(' vj:=0;');
  7402. Add(' VI:=0;');
  7403. Add(' repeat');
  7404. Add(' VI:=vi+1;');
  7405. Add(' vj:=VJ+vI;');
  7406. Add(' until vi>=vn');
  7407. ConvertProgram;
  7408. CheckSource('TestRepeatUntil',
  7409. LinesToStr([ // statements
  7410. 'this.vI = 0;',
  7411. 'this.vJ = 0;',
  7412. 'this.vN = 0;'
  7413. ]),
  7414. LinesToStr([ // $mod.$main
  7415. ' $mod.vN = 3;',
  7416. ' $mod.vJ = 0;',
  7417. ' $mod.vI = 0;',
  7418. ' do{',
  7419. ' $mod.vI = $mod.vI + 1;',
  7420. ' $mod.vJ = $mod.vJ + $mod.vI;',
  7421. ' }while(!($mod.vI>=$mod.vN));'
  7422. ]));
  7423. end;
  7424. procedure TTestModule.TestAsmBlock;
  7425. begin
  7426. StartProgram(false);
  7427. Add([
  7428. 'var',
  7429. ' vI: longint;',
  7430. 'begin',
  7431. ' vi:=1;',
  7432. ' asm',
  7433. ' if (vI===1) {',
  7434. ' vI=2;',
  7435. //' console.log(''end;'');', ToDo
  7436. ' }',
  7437. ' if (vI===2){ vI=3; }',
  7438. ' end;',
  7439. ' VI:=4;']);
  7440. ConvertProgram;
  7441. CheckSource('TestAsmBlock',
  7442. LinesToStr([ // statements
  7443. 'this.vI = 0;'
  7444. ]),
  7445. LinesToStr([ // $mod.$main
  7446. '$mod.vI = 1;',
  7447. 'if (vI===1) {',
  7448. ' vI=2;',
  7449. '}',
  7450. 'if (vI===2){ vI=3; }',
  7451. ';',
  7452. '$mod.vI = 4;'
  7453. ]));
  7454. end;
  7455. procedure TTestModule.TestAsmPas_Impl;
  7456. begin
  7457. StartUnit(false);
  7458. Add('interface');
  7459. Add('const cIntf: longint = 1;');
  7460. Add('var vIntf: longint;');
  7461. Add('implementation');
  7462. Add('const cImpl: longint = 2;');
  7463. Add('var vImpl: longint;');
  7464. Add('procedure DoIt;');
  7465. Add('const cLoc: longint = 3;');
  7466. Add('var vLoc: longint;');
  7467. Add('begin;');
  7468. Add(' asm');
  7469. //Add(' pas(vIntf)=pas(cIntf);');
  7470. //Add(' pas(vImpl)=pas(cImpl);');
  7471. //Add(' pas(vLoc)=pas(cLoc);');
  7472. Add(' end;');
  7473. Add('end;');
  7474. ConvertUnit;
  7475. CheckSource('TestAsmPas_Impl',
  7476. LinesToStr([
  7477. 'var $impl = $mod.$impl;',
  7478. 'this.cIntf = 1;',
  7479. 'this.vIntf = 0;',
  7480. '']),
  7481. '', // this.$init
  7482. LinesToStr([ // implementation
  7483. '$impl.cImpl = 2;',
  7484. '$impl.vImpl = 0;',
  7485. 'var cLoc = 3;',
  7486. '$impl.DoIt = function () {',
  7487. ' var vLoc = 0;',
  7488. '};',
  7489. '']) );
  7490. end;
  7491. procedure TTestModule.TestTryFinally;
  7492. begin
  7493. StartProgram(false);
  7494. Add('var i: longint;');
  7495. Add('begin');
  7496. Add(' try');
  7497. Add(' i:=0; i:=2 div i;');
  7498. Add(' finally');
  7499. Add(' i:=3');
  7500. Add(' end;');
  7501. ConvertProgram;
  7502. CheckSource('TestTryFinally',
  7503. LinesToStr([ // statements
  7504. 'this.i = 0;'
  7505. ]),
  7506. LinesToStr([ // $mod.$main
  7507. 'try {',
  7508. ' $mod.i = 0;',
  7509. ' $mod.i = Math.floor(2 / $mod.i);',
  7510. '} finally {',
  7511. ' $mod.i = 3;',
  7512. '};'
  7513. ]));
  7514. end;
  7515. procedure TTestModule.TestTryExcept;
  7516. begin
  7517. StartProgram(false);
  7518. Add('type');
  7519. Add(' TObject = class end;');
  7520. Add(' Exception = class Msg: string; end;');
  7521. Add(' EInvalidCast = class(Exception) end;');
  7522. Add('var vI: longint;');
  7523. Add('begin');
  7524. Add(' try');
  7525. Add(' vi:=1;');
  7526. Add(' except');
  7527. Add(' vi:=2');
  7528. Add(' end;');
  7529. Add(' try');
  7530. Add(' vi:=3;');
  7531. Add(' except');
  7532. Add(' raise;');
  7533. Add(' end;');
  7534. Add(' try');
  7535. Add(' VI:=4;');
  7536. Add(' except');
  7537. Add(' on einvalidcast do');
  7538. Add(' raise;');
  7539. Add(' on E: exception do');
  7540. Add(' if e.msg='''' then');
  7541. Add(' raise e;');
  7542. Add(' else');
  7543. Add(' vi:=5');
  7544. Add(' end;');
  7545. Add(' try');
  7546. Add(' VI:=6;');
  7547. Add(' except');
  7548. Add(' on einvalidcast do ;');
  7549. Add(' end;');
  7550. ConvertProgram;
  7551. CheckSource('TestTryExcept',
  7552. LinesToStr([ // statements
  7553. 'rtl.createClass($mod, "TObject", null, function () {',
  7554. ' this.$init = function () {',
  7555. ' };',
  7556. ' this.$final = function () {',
  7557. ' };',
  7558. '});',
  7559. 'rtl.createClass($mod, "Exception", $mod.TObject, function () {',
  7560. ' this.$init = function () {',
  7561. ' $mod.TObject.$init.call(this);',
  7562. ' this.Msg = "";',
  7563. ' };',
  7564. '});',
  7565. 'rtl.createClass($mod, "EInvalidCast", $mod.Exception, function () {',
  7566. '});',
  7567. 'this.vI = 0;'
  7568. ]),
  7569. LinesToStr([ // $mod.$main
  7570. 'try {',
  7571. ' $mod.vI = 1;',
  7572. '} catch ($e) {',
  7573. ' $mod.vI = 2;',
  7574. '};',
  7575. 'try {',
  7576. ' $mod.vI = 3;',
  7577. '} catch ($e) {',
  7578. ' throw $e;',
  7579. '};',
  7580. 'try {',
  7581. ' $mod.vI = 4;',
  7582. '} catch ($e) {',
  7583. ' if ($mod.EInvalidCast.isPrototypeOf($e)){',
  7584. ' throw $e',
  7585. ' } else if ($mod.Exception.isPrototypeOf($e)) {',
  7586. ' var E = $e;',
  7587. ' if (E.Msg === "") throw E;',
  7588. ' } else {',
  7589. ' $mod.vI = 5;',
  7590. ' }',
  7591. '};',
  7592. 'try {',
  7593. ' $mod.vI = 6;',
  7594. '} catch ($e) {',
  7595. ' if ($mod.EInvalidCast.isPrototypeOf($e)){' ,
  7596. ' } else throw $e',
  7597. '};',
  7598. '']));
  7599. end;
  7600. procedure TTestModule.TestTryExcept_ReservedWords;
  7601. begin
  7602. StartProgram(false);
  7603. Add([
  7604. 'type',
  7605. ' TObject = class end;',
  7606. ' Exception = class',
  7607. ' Symbol: string;',
  7608. ' end;',
  7609. 'var &try: longint;',
  7610. 'begin',
  7611. ' try',
  7612. ' &try:=4;',
  7613. ' except',
  7614. ' on Error: exception do',
  7615. ' if errOR.symBol='''' then',
  7616. ' raise ERRor;',
  7617. ' end;',
  7618. '']);
  7619. ConvertProgram;
  7620. CheckSource('TestTryExcept_ReservedWords',
  7621. LinesToStr([ // statements
  7622. 'rtl.createClass($mod, "TObject", null, function () {',
  7623. ' this.$init = function () {',
  7624. ' };',
  7625. ' this.$final = function () {',
  7626. ' };',
  7627. '});',
  7628. 'rtl.createClass($mod, "Exception", $mod.TObject, function () {',
  7629. ' this.$init = function () {',
  7630. ' $mod.TObject.$init.call(this);',
  7631. ' this.Symbol = "";',
  7632. ' };',
  7633. '});',
  7634. 'this.Try = 0;',
  7635. '']),
  7636. LinesToStr([ // $mod.$main
  7637. 'try {',
  7638. ' $mod.Try = 4;',
  7639. '} catch ($e) {',
  7640. ' if ($mod.Exception.isPrototypeOf($e)) {',
  7641. ' var error = $e;',
  7642. ' if (error.Symbol === "") throw error;',
  7643. ' } else throw $e',
  7644. '};',
  7645. '']));
  7646. end;
  7647. procedure TTestModule.TestIfThenRaiseElse;
  7648. begin
  7649. StartProgram(false);
  7650. Add([
  7651. 'type',
  7652. ' TObject = class',
  7653. ' constructor Create;',
  7654. ' end;',
  7655. 'constructor TObject.Create;',
  7656. 'begin',
  7657. 'end;',
  7658. 'var b: boolean;',
  7659. 'begin',
  7660. ' if b then',
  7661. ' raise TObject.Create',
  7662. ' else',
  7663. ' b:=false;',
  7664. '']);
  7665. ConvertProgram;
  7666. CheckSource('TestIfThenRaiseElse',
  7667. LinesToStr([ // statements
  7668. 'rtl.createClass($mod, "TObject", null, function () {',
  7669. ' this.$init = function () {',
  7670. ' };',
  7671. ' this.$final = function () {',
  7672. ' };',
  7673. ' this.Create = function () {',
  7674. ' return this;',
  7675. ' };',
  7676. '});',
  7677. 'this.b = false;',
  7678. '']),
  7679. LinesToStr([ // $mod.$main
  7680. 'if ($mod.b) {',
  7681. ' throw $mod.TObject.$create("Create")}',
  7682. ' else $mod.b = false;',
  7683. '']));
  7684. end;
  7685. procedure TTestModule.TestCaseOf;
  7686. begin
  7687. StartProgram(false);
  7688. Add([
  7689. 'const e: longint; external name ''$e'';',
  7690. 'var vI: longint;',
  7691. 'begin',
  7692. ' case vi of',
  7693. ' 1: ;',
  7694. ' 2: vi:=3;',
  7695. ' e: ;',
  7696. ' else',
  7697. ' VI:=4',
  7698. ' end;']);
  7699. ConvertProgram;
  7700. CheckSource('TestCaseOf',
  7701. LinesToStr([ // statements
  7702. 'this.vI = 0;'
  7703. ]),
  7704. LinesToStr([ // $mod.$main
  7705. 'var $tmp1 = $mod.vI;',
  7706. 'if ($tmp1 === 1) {}',
  7707. 'else if ($tmp1 === 2) {',
  7708. ' $mod.vI = 3}',
  7709. ' else if ($tmp1 === $e) {}',
  7710. 'else {',
  7711. ' $mod.vI = 4;',
  7712. '};'
  7713. ]));
  7714. end;
  7715. procedure TTestModule.TestCaseOf_UseSwitch;
  7716. begin
  7717. StartProgram(false);
  7718. Converter.UseSwitchStatement:=true;
  7719. Add('var Vi: longint;');
  7720. Add('begin');
  7721. Add(' case vi of');
  7722. Add(' 1: ;');
  7723. Add(' 2: VI:=3;');
  7724. Add(' else');
  7725. Add(' vi:=4');
  7726. Add(' end;');
  7727. ConvertProgram;
  7728. CheckSource('TestCaseOf_UseSwitch',
  7729. LinesToStr([ // statements
  7730. 'this.Vi = 0;'
  7731. ]),
  7732. LinesToStr([ // $mod.$main
  7733. 'switch ($mod.Vi) {',
  7734. 'case 1:',
  7735. ' break;',
  7736. 'case 2:',
  7737. ' $mod.Vi = 3;',
  7738. ' break;',
  7739. 'default:',
  7740. ' $mod.Vi = 4;',
  7741. '};'
  7742. ]));
  7743. end;
  7744. procedure TTestModule.TestCaseOfNoElse;
  7745. begin
  7746. StartProgram(false);
  7747. Add('var Vi: longint;');
  7748. Add('begin');
  7749. Add(' case vi of');
  7750. Add(' 1: begin vi:=2; VI:=3; end;');
  7751. Add(' end;');
  7752. ConvertProgram;
  7753. CheckSource('TestCaseOfNoElse',
  7754. LinesToStr([ // statements
  7755. 'this.Vi = 0;'
  7756. ]),
  7757. LinesToStr([ // $mod.$main
  7758. 'var $tmp1 = $mod.Vi;',
  7759. 'if ($tmp1 === 1) {',
  7760. ' $mod.Vi = 2;',
  7761. ' $mod.Vi = 3;',
  7762. '};'
  7763. ]));
  7764. end;
  7765. procedure TTestModule.TestCaseOfNoElse_UseSwitch;
  7766. begin
  7767. StartProgram(false);
  7768. Converter.UseSwitchStatement:=true;
  7769. Add('var vI: longint;');
  7770. Add('begin');
  7771. Add(' case vi of');
  7772. Add(' 1: begin VI:=2; vi:=3; end;');
  7773. Add(' end;');
  7774. ConvertProgram;
  7775. CheckSource('TestCaseOfNoElse_UseSwitch',
  7776. LinesToStr([ // statements
  7777. 'this.vI = 0;'
  7778. ]),
  7779. LinesToStr([ // $mod.$main
  7780. 'switch ($mod.vI) {',
  7781. 'case 1:',
  7782. ' $mod.vI = 2;',
  7783. ' $mod.vI = 3;',
  7784. ' break;',
  7785. '};'
  7786. ]));
  7787. end;
  7788. procedure TTestModule.TestCaseOfRange;
  7789. begin
  7790. StartProgram(false);
  7791. Add('var vI: longint;');
  7792. Add('begin');
  7793. Add(' case vi of');
  7794. Add(' 1..3: vi:=14;');
  7795. Add(' 4,5: vi:=16;');
  7796. Add(' 6..7,9..10: ;');
  7797. Add(' else ;');
  7798. Add(' end;');
  7799. ConvertProgram;
  7800. CheckSource('TestCaseOfRange',
  7801. LinesToStr([ // statements
  7802. 'this.vI = 0;'
  7803. ]),
  7804. LinesToStr([ // $mod.$main
  7805. 'var $tmp1 = $mod.vI;',
  7806. 'if (($tmp1 >= 1) && ($tmp1 <= 3)){',
  7807. ' $mod.vI = 14',
  7808. '} else if (($tmp1 === 4) || ($tmp1 === 5)){',
  7809. ' $mod.vI = 16',
  7810. '} else if ((($tmp1 >= 6) && ($tmp1 <= 7)) || (($tmp1 >= 9) && ($tmp1 <= 10))) ;'
  7811. ]));
  7812. end;
  7813. procedure TTestModule.TestCaseOfString;
  7814. begin
  7815. StartProgram(false);
  7816. Add([
  7817. 'var s,h: string;',
  7818. 'begin',
  7819. ' case s of',
  7820. ' ''foo'': s:=h;',
  7821. ' ''a''..''z'': h:=s;',
  7822. ' ''ў'', ''ё'': ;',
  7823. ' ''Б''..''Я'': ;',
  7824. ' end;',
  7825. '']);
  7826. ConvertProgram;
  7827. CheckSource('TestCaseOfString',
  7828. LinesToStr([ // statements
  7829. 'this.s = "";',
  7830. 'this.h = "";',
  7831. '']),
  7832. LinesToStr([ // $mod.$main
  7833. 'var $tmp1 = $mod.s;',
  7834. 'if ($tmp1 === "foo") {',
  7835. ' $mod.s = $mod.h}',
  7836. ' else if (($tmp1.length === 1) && ($tmp1 >= "a") && ($tmp1 <= "z")) {',
  7837. ' $mod.h = $mod.s}',
  7838. ' else if (($tmp1 === "ў") || ($tmp1 === "ё")) {}',
  7839. ' else if (($tmp1.length === 1) && ($tmp1 >= "Б") && ($tmp1 <= "Я")) ;',
  7840. '']));
  7841. end;
  7842. procedure TTestModule.TestCaseOfChar;
  7843. begin
  7844. StartProgram(false);
  7845. Add([
  7846. 'var s,h: char;',
  7847. 'begin',
  7848. ' case s of',
  7849. ' ''a''..''z'': h:=s;',
  7850. ' ''ä'': ;',
  7851. ' ''ў'', ''ё'': ;',
  7852. ' ''Б''..''Я'': ;',
  7853. ' end;',
  7854. '']);
  7855. ConvertProgram;
  7856. CheckSource('TestCaseOfString',
  7857. LinesToStr([ // statements
  7858. 'this.s = "";',
  7859. 'this.h = "";',
  7860. '']),
  7861. LinesToStr([ // $mod.$main
  7862. 'var $tmp1 = $mod.s;',
  7863. 'if (($tmp1 >= "a") && ($tmp1 <= "z")) {',
  7864. ' $mod.h = $mod.s}',
  7865. ' else if ($tmp1 === "ä") {}',
  7866. ' else if (($tmp1 === "ў") || ($tmp1 === "ё")) {}',
  7867. ' else if (($tmp1 >= "Б") && ($tmp1 <= "Я")) ;',
  7868. '']));
  7869. end;
  7870. procedure TTestModule.TestCaseOfExternalClassConst;
  7871. begin
  7872. StartProgram(false);
  7873. Add([
  7874. '{$modeswitch externalclass}',
  7875. 'type',
  7876. ' TBird = class external name ''Bird''',
  7877. ' const e: longint;',
  7878. ' end;',
  7879. 'var vI: longint;',
  7880. 'begin',
  7881. ' case vi of',
  7882. ' 1: vi:=3;',
  7883. ' TBird.e: ;',
  7884. ' end;']);
  7885. ConvertProgram;
  7886. CheckSource('TestCaseOfExternalClassConst',
  7887. LinesToStr([ // statements
  7888. 'this.vI = 0;'
  7889. ]),
  7890. LinesToStr([ // $mod.$main
  7891. 'var $tmp1 = $mod.vI;',
  7892. 'if ($tmp1 === 1) {',
  7893. ' $mod.vI = 3}',
  7894. ' else if ($tmp1 === Bird.e) ;'
  7895. ]));
  7896. end;
  7897. procedure TTestModule.TestDebugger;
  7898. begin
  7899. StartProgram(false);
  7900. Add([
  7901. 'procedure DoIt;',
  7902. 'begin',
  7903. ' deBugger;',
  7904. ' DeBugger();',
  7905. 'end;',
  7906. 'begin',
  7907. ' Debugger;']);
  7908. ConvertProgram;
  7909. CheckSource('TestDebugger',
  7910. LinesToStr([ // statements
  7911. 'this.DoIt = function () {',
  7912. ' debugger;',
  7913. ' debugger;',
  7914. '};',
  7915. '']),
  7916. LinesToStr([ // $mod.$main
  7917. 'debugger;',
  7918. '']));
  7919. end;
  7920. procedure TTestModule.TestArray_Dynamic;
  7921. begin
  7922. StartProgram(false);
  7923. Add(['type',
  7924. ' TArrayInt = array of longint;',
  7925. 'var',
  7926. ' Arr: TArrayInt;',
  7927. ' i: longint;',
  7928. ' b: boolean;',
  7929. 'begin',
  7930. ' SetLength(arr,3);',
  7931. ' arr[0]:=4;',
  7932. ' arr[1]:=length(arr)+arr[0];',
  7933. ' arr[i]:=5;',
  7934. ' arr[arr[i]]:=arr[6];',
  7935. ' i:=low(arr);',
  7936. ' i:=high(arr);',
  7937. ' b:=Assigned(arr);',
  7938. ' Arr:=default(TArrayInt);']);
  7939. ConvertProgram;
  7940. CheckSource('TestArray_Dynamic',
  7941. LinesToStr([ // statements
  7942. 'this.Arr = [];',
  7943. 'this.i = 0;',
  7944. 'this.b = false;'
  7945. ]),
  7946. LinesToStr([ // $mod.$main
  7947. '$mod.Arr = rtl.arraySetLength($mod.Arr,0,3);',
  7948. '$mod.Arr[0] = 4;',
  7949. '$mod.Arr[1] = rtl.length($mod.Arr) + $mod.Arr[0];',
  7950. '$mod.Arr[$mod.i] = 5;',
  7951. '$mod.Arr[$mod.Arr[$mod.i]] = $mod.Arr[6];',
  7952. '$mod.i = 0;',
  7953. '$mod.i = rtl.length($mod.Arr) - 1;',
  7954. '$mod.b = rtl.length($mod.Arr) > 0;',
  7955. '$mod.Arr = [];',
  7956. '']));
  7957. end;
  7958. procedure TTestModule.TestArray_Dynamic_Nil;
  7959. begin
  7960. StartProgram(false);
  7961. Add('type');
  7962. Add(' TArrayInt = array of longint;');
  7963. Add('var');
  7964. Add(' Arr: TArrayInt;');
  7965. Add('procedure DoIt(const i: TArrayInt; j: TArrayInt); begin end;');
  7966. Add('begin');
  7967. Add(' arr:=nil;');
  7968. Add(' if arr=nil then;');
  7969. Add(' if nil=arr then;');
  7970. Add(' if arr<>nil then;');
  7971. Add(' if nil<>arr then;');
  7972. Add(' DoIt(nil,nil);');
  7973. ConvertProgram;
  7974. CheckSource('TestArray_Dynamic',
  7975. LinesToStr([ // statements
  7976. 'this.Arr = [];',
  7977. 'this.DoIt = function(i,j){',
  7978. '};'
  7979. ]),
  7980. LinesToStr([ // $mod.$main
  7981. '$mod.Arr = [];',
  7982. 'if (rtl.length($mod.Arr) === 0) ;',
  7983. 'if (rtl.length($mod.Arr) === 0) ;',
  7984. 'if (rtl.length($mod.Arr) > 0) ;',
  7985. 'if (rtl.length($mod.Arr) > 0) ;',
  7986. '$mod.DoIt([],[]);',
  7987. '']));
  7988. end;
  7989. procedure TTestModule.TestArray_DynMultiDimensional;
  7990. begin
  7991. StartProgram(false);
  7992. Add('type');
  7993. Add(' TArrayInt = array of longint;');
  7994. Add(' TArrayArrayInt = array of TArrayInt;');
  7995. Add('var');
  7996. Add(' Arr: TArrayInt;');
  7997. Add(' Arr2: TArrayArrayInt;');
  7998. Add(' i: longint;');
  7999. Add('begin');
  8000. Add(' arr2:=nil;');
  8001. Add(' if arr2=nil then;');
  8002. Add(' if nil=arr2 then;');
  8003. Add(' i:=low(arr2);');
  8004. Add(' i:=low(arr2[1]);');
  8005. Add(' i:=high(arr2);');
  8006. Add(' i:=high(arr2[2]);');
  8007. Add(' arr2[3]:=arr;');
  8008. Add(' arr2[4][5]:=i;');
  8009. Add(' i:=arr2[6][7];');
  8010. Add(' arr2[8,9]:=i;');
  8011. Add(' i:=arr2[10,11];');
  8012. Add(' SetLength(arr2,14);');
  8013. Add(' SetLength(arr2[15],16);');
  8014. ConvertProgram;
  8015. CheckSource('TestArray_Dynamic',
  8016. LinesToStr([ // statements
  8017. 'this.Arr = [];',
  8018. 'this.Arr2 = [];',
  8019. 'this.i = 0;'
  8020. ]),
  8021. LinesToStr([ // $mod.$main
  8022. '$mod.Arr2 = [];',
  8023. 'if (rtl.length($mod.Arr2) === 0) ;',
  8024. 'if (rtl.length($mod.Arr2) === 0) ;',
  8025. '$mod.i = 0;',
  8026. '$mod.i = 0;',
  8027. '$mod.i = rtl.length($mod.Arr2) - 1;',
  8028. '$mod.i = rtl.length($mod.Arr2[2]) - 1;',
  8029. '$mod.Arr2[3] = $mod.Arr;',
  8030. '$mod.Arr2[4][5] = $mod.i;',
  8031. '$mod.i = $mod.Arr2[6][7];',
  8032. '$mod.Arr2[8][9] = $mod.i;',
  8033. '$mod.i = $mod.Arr2[10][11];',
  8034. '$mod.Arr2 = rtl.arraySetLength($mod.Arr2, [], 14);',
  8035. '$mod.Arr2[15] = rtl.arraySetLength($mod.Arr2[15], 0, 16);',
  8036. '']));
  8037. end;
  8038. procedure TTestModule.TestArray_StaticInt;
  8039. begin
  8040. StartProgram(false);
  8041. Add('type');
  8042. Add(' TArrayInt = array[2..4] of longint;');
  8043. Add('var');
  8044. Add(' Arr: TArrayInt;');
  8045. Add(' Arr2: TArrayInt = (5,6,7);');
  8046. Add(' i: longint;');
  8047. Add(' b: boolean;');
  8048. Add('begin');
  8049. Add(' arr[2]:=4;');
  8050. Add(' arr[3]:=arr[2]+arr[3];');
  8051. Add(' arr[i]:=5;');
  8052. Add(' arr[arr[i]]:=arr[high(arr)];');
  8053. Add(' i:=low(arr);');
  8054. Add(' i:=high(arr);');
  8055. Add(' b:=arr[2]=arr[3];');
  8056. Add(' arr:=default(TArrayInt);');
  8057. ConvertProgram;
  8058. CheckSource('TestArray_StaticInt',
  8059. LinesToStr([ // statements
  8060. 'this.Arr = rtl.arraySetLength(null,0,3);',
  8061. 'this.Arr2 = [5, 6, 7];',
  8062. 'this.i = 0;',
  8063. 'this.b = false;'
  8064. ]),
  8065. LinesToStr([ // $mod.$main
  8066. '$mod.Arr[0] = 4;',
  8067. '$mod.Arr[1] = $mod.Arr[0] + $mod.Arr[1];',
  8068. '$mod.Arr[$mod.i-2] = 5;',
  8069. '$mod.Arr[$mod.Arr[$mod.i-2]-2] = $mod.Arr[2];',
  8070. '$mod.i = 2;',
  8071. '$mod.i = 4;',
  8072. '$mod.b = $mod.Arr[0] === $mod.Arr[1];',
  8073. '$mod.Arr = rtl.arraySetLength(null,0,3).slice(0);',
  8074. '']));
  8075. end;
  8076. procedure TTestModule.TestArray_StaticBool;
  8077. begin
  8078. StartProgram(false);
  8079. Add('type');
  8080. Add(' TBools = array[boolean] of boolean;');
  8081. Add(' TBool2 = array[true..true] of boolean;');
  8082. Add('var');
  8083. Add(' Arr: TBools;');
  8084. Add(' Arr2: TBool2;');
  8085. Add(' Arr3: TBools = (true,false);');
  8086. Add(' b: boolean;');
  8087. Add('begin');
  8088. Add(' b:=low(arr);');
  8089. Add(' b:=high(arr);');
  8090. Add(' arr[true]:=false;');
  8091. Add(' arr[false]:=arr[b] or arr[true];');
  8092. Add(' arr[b]:=true;');
  8093. Add(' arr[arr[b]]:=arr[high(arr)];');
  8094. Add(' b:=arr[false]=arr[true];');
  8095. Add(' b:=low(arr2);');
  8096. Add(' b:=high(arr2);');
  8097. Add(' arr2[true]:=true;');
  8098. Add(' arr2[true]:=arr2[true] and arr2[b];');
  8099. Add(' arr2[b]:=false;');
  8100. ConvertProgram;
  8101. CheckSource('TestArray_StaticBool',
  8102. LinesToStr([ // statements
  8103. 'this.Arr = rtl.arraySetLength(null,false,2);',
  8104. 'this.Arr2 = rtl.arraySetLength(null,false,1);',
  8105. 'this.Arr3 = [true, false];',
  8106. 'this.b = false;'
  8107. ]),
  8108. LinesToStr([ // $mod.$main
  8109. '$mod.b = false;',
  8110. '$mod.b = true;',
  8111. '$mod.Arr[1] = false;',
  8112. '$mod.Arr[0] = $mod.Arr[+$mod.b] || $mod.Arr[1];',
  8113. '$mod.Arr[+$mod.b] = true;',
  8114. '$mod.Arr[+$mod.Arr[+$mod.b]] = $mod.Arr[1];',
  8115. '$mod.b = $mod.Arr[0] === $mod.Arr[1];',
  8116. '$mod.b = true;',
  8117. '$mod.b = true;',
  8118. '$mod.Arr2[0] = true;',
  8119. '$mod.Arr2[0] = $mod.Arr2[0] && $mod.Arr2[1-$mod.b];',
  8120. '$mod.Arr2[1-$mod.b] = false;',
  8121. '']));
  8122. end;
  8123. procedure TTestModule.TestArray_StaticChar;
  8124. begin
  8125. StartProgram(false);
  8126. Add([
  8127. 'type',
  8128. ' TChars = array[char] of char;',
  8129. ' TChars2 = array[''a''..''z''] of char;',
  8130. 'var',
  8131. ' Arr: TChars;',
  8132. ' Arr2: TChars2;',
  8133. ' Arr3: array[2..4] of char = (''p'',''a'',''s'');',
  8134. ' Arr4: array[11..13] of char = ''pas'';',
  8135. ' Arr5: array[21..22] of char = ''äö'';',
  8136. ' Arr6: array[31..32] of char = ''ä''+''ö'';',
  8137. ' c: char;',
  8138. ' b: boolean;',
  8139. 'begin',
  8140. ' c:=low(arr);',
  8141. ' c:=high(arr);',
  8142. ' arr[''B'']:=''a'';',
  8143. ' arr[''D'']:=arr[c];',
  8144. ' arr[c]:=arr[''d''];',
  8145. ' arr[arr[c]]:=arr[high(arr)];',
  8146. ' b:=arr[low(arr)]=arr[''e''];',
  8147. ' c:=low(arr2);',
  8148. ' c:=high(arr2);',
  8149. ' arr2[''b'']:=''f'';',
  8150. ' arr2[''a'']:=arr2[c];',
  8151. ' arr2[c]:=arr2[''g''];']);
  8152. ConvertProgram;
  8153. CheckSource('TestArray_StaticChar',
  8154. LinesToStr([ // statements
  8155. 'this.Arr = rtl.arraySetLength(null, "", 65536);',
  8156. 'this.Arr2 = rtl.arraySetLength(null, "", 26);',
  8157. 'this.Arr3 = ["p", "a", "s"];',
  8158. 'this.Arr4 = ["p", "a", "s"];',
  8159. 'this.Arr5 = ["ä", "ö"];',
  8160. 'this.Arr6 = ["ä", "ö"];',
  8161. 'this.c = "";',
  8162. 'this.b = false;',
  8163. '']),
  8164. LinesToStr([ // $mod.$main
  8165. '$mod.c = "\x00";',
  8166. '$mod.c = "\uFFFF";',
  8167. '$mod.Arr[66] = "a";',
  8168. '$mod.Arr[68] = $mod.Arr[$mod.c.charCodeAt()];',
  8169. '$mod.Arr[$mod.c.charCodeAt()] = $mod.Arr[100];',
  8170. '$mod.Arr[$mod.Arr[$mod.c.charCodeAt()].charCodeAt()] = $mod.Arr[65535];',
  8171. '$mod.b = $mod.Arr[0] === $mod.Arr[101];',
  8172. '$mod.c = "a";',
  8173. '$mod.c = "z";',
  8174. '$mod.Arr2[1] = "f";',
  8175. '$mod.Arr2[0] = $mod.Arr2[$mod.c.charCodeAt() - 97];',
  8176. '$mod.Arr2[$mod.c.charCodeAt() - 97] = $mod.Arr2[6];',
  8177. '']));
  8178. end;
  8179. procedure TTestModule.TestArray_StaticMultiDim;
  8180. begin
  8181. StartProgram(false);
  8182. Add([
  8183. 'type',
  8184. ' TArrayInt = array[1..3] of longint;',
  8185. ' TArrayArrayInt = array[5..6] of TArrayInt;',
  8186. 'var',
  8187. ' Arr: TArrayInt;',
  8188. ' Arr2: TArrayArrayInt;',
  8189. ' Arr3: array[boolean] of TArrayInt = ((11,12,13),(21,22,23));',
  8190. ' i: longint;',
  8191. 'begin',
  8192. ' i:=low(arr);',
  8193. ' i:=low(arr2);',
  8194. ' i:=low(arr2[5]);',
  8195. ' i:=high(arr);',
  8196. ' i:=high(arr2);',
  8197. ' i:=high(arr2[6]);',
  8198. ' arr2[5]:=arr;',
  8199. ' arr2[6][2]:=i;',
  8200. ' i:=arr2[6][3];',
  8201. ' arr2[6,3]:=i;',
  8202. ' i:=arr2[5,2];',
  8203. ' arr2:=arr2;',// clone multi dim static array
  8204. //' arr3:=arr3;',// clone anonymous multi dim static array
  8205. '']);
  8206. ConvertProgram;
  8207. CheckSource('TestArray_StaticMultiDim',
  8208. LinesToStr([ // statements
  8209. 'this.TArrayArrayInt$clone = function (a) {',
  8210. ' var r = [];',
  8211. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  8212. ' return r;',
  8213. '};',
  8214. 'this.Arr = rtl.arraySetLength(null, 0, 3);',
  8215. 'this.Arr2 = rtl.arraySetLength(null, 0, 2, 3);',
  8216. 'this.Arr3 = [[11, 12, 13], [21, 22, 23]];',
  8217. 'this.i = 0;'
  8218. ]),
  8219. LinesToStr([ // $mod.$main
  8220. '$mod.i = 1;',
  8221. '$mod.i = 5;',
  8222. '$mod.i = 1;',
  8223. '$mod.i = 3;',
  8224. '$mod.i = 6;',
  8225. '$mod.i = 3;',
  8226. '$mod.Arr2[0] = $mod.Arr.slice(0);',
  8227. '$mod.Arr2[1][1] = $mod.i;',
  8228. '$mod.i = $mod.Arr2[1][2];',
  8229. '$mod.Arr2[1][2] = $mod.i;',
  8230. '$mod.i = $mod.Arr2[0][1];',
  8231. '$mod.Arr2 = $mod.TArrayArrayInt$clone($mod.Arr2);',
  8232. '']));
  8233. end;
  8234. procedure TTestModule.TestArray_StaticInFunction;
  8235. begin
  8236. StartProgram(false);
  8237. Add([
  8238. 'const TArrayInt = 3;',
  8239. 'const TArrayArrayInt = 4;',
  8240. 'procedure DoIt;',
  8241. 'type',
  8242. ' TArrayInt = array[1..3] of longint;',
  8243. ' TArrayArrayInt = array[5..6] of TArrayInt;',
  8244. 'var',
  8245. ' Arr: TArrayInt;',
  8246. ' Arr2: TArrayArrayInt;',
  8247. ' Arr3: array[boolean] of TArrayInt = ((11,12,13),(21,22,23));',
  8248. ' i: longint;',
  8249. 'begin',
  8250. ' arr2[5]:=arr;',
  8251. ' arr2:=arr2;',// clone multi dim static array
  8252. 'end;',
  8253. 'begin',
  8254. '']);
  8255. ConvertProgram;
  8256. CheckSource('TestArray_StaticInFunction',
  8257. LinesToStr([ // statements
  8258. 'this.TArrayInt = 3;',
  8259. 'this.TArrayArrayInt = 4;',
  8260. 'var TArrayArrayInt$1$clone = function (a) {',
  8261. ' var r = [];',
  8262. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  8263. ' return r;',
  8264. '};',
  8265. 'this.DoIt = function () {',
  8266. ' var Arr = rtl.arraySetLength(null, 0, 3);',
  8267. ' var Arr2 = rtl.arraySetLength(null, 0, 2, 3);',
  8268. ' var Arr3 = [[11, 12, 13], [21, 22, 23]];',
  8269. ' var i = 0;',
  8270. ' Arr2[0] = Arr.slice(0);',
  8271. ' Arr2 = TArrayArrayInt$1$clone(Arr2);',
  8272. '};',
  8273. '']),
  8274. LinesToStr([ // $mod.$main
  8275. '']));
  8276. end;
  8277. procedure TTestModule.TestArrayOfRecord;
  8278. begin
  8279. StartProgram(false);
  8280. Add([
  8281. 'type',
  8282. ' TRec = record',
  8283. ' Int: longint;',
  8284. ' end;',
  8285. ' TArrayRec = array of TRec;',
  8286. 'procedure DoIt(vd: TRec; const vc: TRec; var vv: TRec);',
  8287. 'begin',
  8288. 'end;',
  8289. 'var',
  8290. ' Arr: TArrayRec;',
  8291. ' r: TRec;',
  8292. ' i: longint;',
  8293. 'begin',
  8294. ' SetLength(arr,3);',
  8295. ' arr[0].int:=4;',
  8296. ' arr[1].int:=length(arr)+arr[2].int;',
  8297. ' arr[arr[i].int].int:=arr[5].int;',
  8298. ' arr[7]:=r;',
  8299. ' r:=arr[8];',
  8300. ' i:=low(arr);',
  8301. ' i:=high(arr);',
  8302. ' DoIt(Arr[9],Arr[10],Arr[11]);']);
  8303. ConvertProgram;
  8304. CheckSource('TestArrayOfRecord',
  8305. LinesToStr([ // statements
  8306. 'rtl.recNewT($mod, "TRec", function () {',
  8307. ' this.Int = 0;',
  8308. ' this.$eq = function (b) {',
  8309. ' return this.Int === b.Int;',
  8310. ' };',
  8311. ' this.$assign = function (s) {',
  8312. ' this.Int = s.Int;',
  8313. ' return this;',
  8314. ' };',
  8315. '});',
  8316. 'this.DoIt = function (vd, vc, vv) {',
  8317. '};',
  8318. 'this.Arr = [];',
  8319. 'this.r = $mod.TRec.$new();',
  8320. 'this.i = 0;'
  8321. ]),
  8322. LinesToStr([ // $mod.$main
  8323. '$mod.Arr = rtl.arraySetLength($mod.Arr,$mod.TRec,3);',
  8324. '$mod.Arr[0].Int = 4;',
  8325. '$mod.Arr[1].Int = rtl.length($mod.Arr)+$mod.Arr[2].Int;',
  8326. '$mod.Arr[$mod.Arr[$mod.i].Int].Int = $mod.Arr[5].Int;',
  8327. '$mod.Arr[7].$assign($mod.r);',
  8328. '$mod.r.$assign($mod.Arr[8]);',
  8329. '$mod.i = 0;',
  8330. '$mod.i = rtl.length($mod.Arr)-1;',
  8331. '$mod.DoIt($mod.TRec.$clone($mod.Arr[9]), $mod.Arr[10], $mod.Arr[11]);',
  8332. '']));
  8333. end;
  8334. procedure TTestModule.TestArray_StaticRecord;
  8335. begin
  8336. StartProgram(false);
  8337. Add([
  8338. 'type',
  8339. ' TRec = record',
  8340. ' Int: longint;',
  8341. ' end;',
  8342. ' TArrayRec = array[1..2] of TRec;',
  8343. 'var',
  8344. ' Arr: TArrayRec;',
  8345. 'begin',
  8346. ' arr[1].int:=length(arr)+low(arr)+high(arr);',
  8347. '']);
  8348. ConvertProgram;
  8349. CheckSource('TestArray_StaticRecord',
  8350. LinesToStr([ // statements
  8351. 'rtl.recNewT($mod, "TRec", function () {',
  8352. ' this.Int = 0;',
  8353. ' this.$eq = function (b) {',
  8354. ' return this.Int === b.Int;',
  8355. ' };',
  8356. ' this.$assign = function (s) {',
  8357. ' this.Int = s.Int;',
  8358. ' return this;',
  8359. ' };',
  8360. '});',
  8361. 'this.TArrayRec$clone = function (a) {',
  8362. ' var r = [];',
  8363. ' for (var i = 0; i < 2; i++) r.push($mod.TRec.$clone(a[i]));',
  8364. ' return r;',
  8365. '};',
  8366. 'this.Arr = rtl.arraySetLength(null, $mod.TRec, 2);',
  8367. '']),
  8368. LinesToStr([ // $mod.$main
  8369. '$mod.Arr[0].Int = 2 + 1 + 2;']));
  8370. end;
  8371. procedure TTestModule.TestArrayOfSet;
  8372. begin
  8373. StartProgram(false);
  8374. Add([
  8375. 'type',
  8376. ' TFlag = (big,small);',
  8377. ' TSetOfFlag = set of tflag;',
  8378. ' TArrayFlag = array of TSetOfFlag;',
  8379. 'procedure DoIt(const a: Tarrayflag);',
  8380. 'begin',
  8381. 'end;',
  8382. 'var',
  8383. ' f: TFlag;',
  8384. ' s: TSetOfFlag;',
  8385. ' Arr: TArrayFlag;',
  8386. ' i: longint;',
  8387. 'begin',
  8388. ' SetLength(arr,3);',
  8389. ' arr[0]:=s;',
  8390. ' arr[1]:=[big];',
  8391. ' arr[2]:=[big]+s;',
  8392. ' arr[3]:=s+[big];',
  8393. ' arr[4]:=arr[5];',
  8394. ' s:=arr[6];',
  8395. ' i:=low(arr);',
  8396. ' i:=high(arr);',
  8397. ' DoIt(arr);',
  8398. ' DoIt([s]);',
  8399. ' DoIt([[],s]);',
  8400. ' DoIt([s,[]]);',
  8401. '']);
  8402. ConvertProgram;
  8403. CheckSource('TestArrayOfSet',
  8404. LinesToStr([ // statements
  8405. 'this.TFlag = {',
  8406. ' "0": "big",',
  8407. ' big: 0,',
  8408. ' "1": "small",',
  8409. ' small: 1',
  8410. '};',
  8411. 'this.DoIt = function (a) {',
  8412. '};',
  8413. 'this.f = 0;',
  8414. 'this.s = {};',
  8415. 'this.Arr = [];',
  8416. 'this.i = 0;',
  8417. '']),
  8418. LinesToStr([ // $mod.$main
  8419. '$mod.Arr = rtl.arraySetLength($mod.Arr, {}, 3);',
  8420. '$mod.Arr[0] = rtl.refSet($mod.s);',
  8421. '$mod.Arr[1] = rtl.createSet($mod.TFlag.big);',
  8422. '$mod.Arr[2] = rtl.unionSet(rtl.createSet($mod.TFlag.big), $mod.s);',
  8423. '$mod.Arr[3] = rtl.unionSet($mod.s, rtl.createSet($mod.TFlag.big));',
  8424. '$mod.Arr[4] = rtl.refSet($mod.Arr[5]);',
  8425. '$mod.s = rtl.refSet($mod.Arr[6]);',
  8426. '$mod.i = 0;',
  8427. '$mod.i = rtl.length($mod.Arr) - 1;',
  8428. '$mod.DoIt($mod.Arr);',
  8429. '$mod.DoIt([rtl.refSet($mod.s)]);',
  8430. '$mod.DoIt([{}, rtl.refSet($mod.s)]);',
  8431. '$mod.DoIt([rtl.refSet($mod.s), {}]);',
  8432. '']));
  8433. end;
  8434. procedure TTestModule.TestArray_DynAsParam;
  8435. begin
  8436. StartProgram(false);
  8437. Add([
  8438. 'type integer = longint;',
  8439. 'type TArrInt = array of integer;',
  8440. 'procedure DoIt(vG: TArrInt; const vH: TArrInt; var vI: TArrInt);',
  8441. 'var vJ: TArrInt;',
  8442. 'begin',
  8443. ' vg:=vg;',
  8444. ' vj:=vh;',
  8445. ' vi:=vi;',
  8446. ' doit(vg,vg,vg);',
  8447. ' doit(vh,vh,vj);',
  8448. ' doit(vi,vi,vi);',
  8449. ' doit(vj,vj,vj);',
  8450. 'end;',
  8451. 'var i: TArrInt;',
  8452. 'begin',
  8453. ' doit(i,i,i);']);
  8454. ConvertProgram;
  8455. CheckSource('TestArray_DynAsParams',
  8456. LinesToStr([ // statements
  8457. 'this.DoIt = function (vG,vH,vI) {',
  8458. ' var vJ = [];',
  8459. ' vG = vG;',
  8460. ' vJ = vH;',
  8461. ' vI.set(vI.get());',
  8462. ' $mod.DoIt(vG, vG, {',
  8463. ' get: function () {',
  8464. ' return vG;',
  8465. ' },',
  8466. ' set: function (v) {',
  8467. ' vG = v;',
  8468. ' }',
  8469. ' });',
  8470. ' $mod.DoIt(vH, vH, {',
  8471. ' get: function () {',
  8472. ' return vJ;',
  8473. ' },',
  8474. ' set: function (v) {',
  8475. ' vJ = v;',
  8476. ' }',
  8477. ' });',
  8478. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  8479. ' $mod.DoIt(vJ, vJ, {',
  8480. ' get: function () {',
  8481. ' return vJ;',
  8482. ' },',
  8483. ' set: function (v) {',
  8484. ' vJ = v;',
  8485. ' }',
  8486. ' });',
  8487. '};',
  8488. 'this.i = [];'
  8489. ]),
  8490. LinesToStr([
  8491. '$mod.DoIt($mod.i,$mod.i,{',
  8492. ' p: $mod,',
  8493. ' get: function () {',
  8494. ' return this.p.i;',
  8495. ' },',
  8496. ' set: function (v) {',
  8497. ' this.p.i = v;',
  8498. ' }',
  8499. '});'
  8500. ]));
  8501. end;
  8502. procedure TTestModule.TestArray_StaticAsParam;
  8503. begin
  8504. StartProgram(false);
  8505. Add([
  8506. 'type integer = longint;',
  8507. 'type TArrInt = array[1..2] of integer;',
  8508. 'procedure DoIt(vG: TArrInt; const vH: TArrInt; var vI: TArrInt);',
  8509. 'var vJ: TArrInt;',
  8510. 'begin',
  8511. ' vg:=vg;',
  8512. ' vj:=vh;',
  8513. ' vi:=vi;',
  8514. ' doit(vg,vg,vg);',
  8515. ' doit(vh,vh,vj);',
  8516. ' doit(vi,vi,vi);',
  8517. ' doit(vj,vj,vj);',
  8518. 'end;',
  8519. 'var i: TArrInt;',
  8520. 'begin',
  8521. ' doit(i,i,i);']);
  8522. ConvertProgram;
  8523. CheckSource('TestArray_StaticAsParams',
  8524. LinesToStr([ // statements
  8525. 'this.DoIt = function (vG,vH,vI) {',
  8526. ' var vJ = rtl.arraySetLength(null, 0, 2);',
  8527. ' vG = vG.slice(0);',
  8528. ' vJ = vH.slice(0);',
  8529. ' vI.set(vI.get().slice(0));',
  8530. ' $mod.DoIt(vG.slice(0), vG, {',
  8531. ' get: function () {',
  8532. ' return vG;',
  8533. ' },',
  8534. ' set: function (v) {',
  8535. ' vG = v;',
  8536. ' }',
  8537. ' });',
  8538. ' $mod.DoIt(vH.slice(0), vH, {',
  8539. ' get: function () {',
  8540. ' return vJ;',
  8541. ' },',
  8542. ' set: function (v) {',
  8543. ' vJ = v;',
  8544. ' }',
  8545. ' });',
  8546. ' $mod.DoIt(vI.get().slice(0), vI.get(), vI);',
  8547. ' $mod.DoIt(vJ.slice(0), vJ, {',
  8548. ' get: function () {',
  8549. ' return vJ;',
  8550. ' },',
  8551. ' set: function (v) {',
  8552. ' vJ = v;',
  8553. ' }',
  8554. ' });',
  8555. '};',
  8556. 'this.i = rtl.arraySetLength(null, 0, 2);'
  8557. ]),
  8558. LinesToStr([
  8559. '$mod.DoIt($mod.i.slice(0),$mod.i,{',
  8560. ' p: $mod,',
  8561. ' get: function () {',
  8562. ' return this.p.i;',
  8563. ' },',
  8564. ' set: function (v) {',
  8565. ' this.p.i = v;',
  8566. ' }',
  8567. '});'
  8568. ]));
  8569. end;
  8570. procedure TTestModule.TestArrayElement_AsParams;
  8571. begin
  8572. StartProgram(false);
  8573. Add('type integer = longint;');
  8574. Add('type TArrayInt = array of integer;');
  8575. Add('procedure DoIt(vG: Integer; const vH: Integer; var vI: Integer);');
  8576. Add('var vJ: tarrayint;');
  8577. Add('begin');
  8578. Add(' vi:=vi;');
  8579. Add(' doit(vi,vi,vi);');
  8580. Add(' doit(vj[1+1],vj[1+2],vj[1+3]);');
  8581. Add('end;');
  8582. Add('var a: TArrayInt;');
  8583. Add('begin');
  8584. Add(' doit(a[1+4],a[1+5],a[1+6]);');
  8585. ConvertProgram;
  8586. CheckSource('TestArrayElement_AsParams',
  8587. LinesToStr([ // statements
  8588. 'this.DoIt = function (vG,vH,vI) {',
  8589. ' var vJ = [];',
  8590. ' vI.set(vI.get());',
  8591. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  8592. ' $mod.DoIt(vJ[1+1], vJ[1+2], {',
  8593. ' a:1+3,',
  8594. ' p:vJ,',
  8595. ' get: function () {',
  8596. ' return this.p[this.a];',
  8597. ' },',
  8598. ' set: function (v) {',
  8599. ' this.p[this.a] = v;',
  8600. ' }',
  8601. ' });',
  8602. '};',
  8603. 'this.a = [];'
  8604. ]),
  8605. LinesToStr([
  8606. '$mod.DoIt($mod.a[1+4],$mod.a[1+5],{',
  8607. ' a: 1+6,',
  8608. ' p: $mod.a,',
  8609. ' get: function () {',
  8610. ' return this.p[this.a];',
  8611. ' },',
  8612. ' set: function (v) {',
  8613. ' this.p[this.a] = v;',
  8614. ' }',
  8615. '});'
  8616. ]));
  8617. end;
  8618. procedure TTestModule.TestArrayElementFromFuncResult_AsParams;
  8619. begin
  8620. StartProgram(false);
  8621. Add('type Integer = longint;');
  8622. Add('type TArrayInt = array of integer;');
  8623. Add('function GetArr(vB: integer = 0): tarrayint;');
  8624. Add('begin');
  8625. Add('end;');
  8626. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  8627. Add('begin');
  8628. Add('end;');
  8629. Add('begin');
  8630. Add(' doit(getarr[1+1],getarr[1+2],getarr[1+3]);');
  8631. Add(' doit(getarr()[2+1],getarr()[2+2],getarr()[2+3]);');
  8632. Add(' doit(getarr(7)[3+1],getarr(8)[3+2],getarr(9)[3+3]);');
  8633. ConvertProgram;
  8634. CheckSource('TestArrayElementFromFuncResult_AsParams',
  8635. LinesToStr([ // statements
  8636. 'this.GetArr = function (vB) {',
  8637. ' var Result = [];',
  8638. ' return Result;',
  8639. '};',
  8640. 'this.DoIt = function (vG,vH,vI) {',
  8641. '};'
  8642. ]),
  8643. LinesToStr([
  8644. '$mod.DoIt($mod.GetArr(0)[1+1],$mod.GetArr(0)[1+2],{',
  8645. ' a: 1+3,',
  8646. ' p: $mod.GetArr(0),',
  8647. ' get: function () {',
  8648. ' return this.p[this.a];',
  8649. ' },',
  8650. ' set: function (v) {',
  8651. ' this.p[this.a] = v;',
  8652. ' }',
  8653. '});',
  8654. '$mod.DoIt($mod.GetArr(0)[2+1],$mod.GetArr(0)[2+2],{',
  8655. ' a: 2+3,',
  8656. ' p: $mod.GetArr(0),',
  8657. ' get: function () {',
  8658. ' return this.p[this.a];',
  8659. ' },',
  8660. ' set: function (v) {',
  8661. ' this.p[this.a] = v;',
  8662. ' }',
  8663. '});',
  8664. '$mod.DoIt($mod.GetArr(7)[3+1],$mod.GetArr(8)[3+2],{',
  8665. ' a: 3+3,',
  8666. ' p: $mod.GetArr(9),',
  8667. ' get: function () {',
  8668. ' return this.p[this.a];',
  8669. ' },',
  8670. ' set: function (v) {',
  8671. ' this.p[this.a] = v;',
  8672. ' }',
  8673. '});',
  8674. '']));
  8675. end;
  8676. procedure TTestModule.TestArrayEnumTypeRange;
  8677. begin
  8678. StartProgram(false);
  8679. Add([
  8680. 'type',
  8681. ' TEnum = (red,blue);',
  8682. ' TEnumArray = array[TEnum] of longint;',
  8683. 'var',
  8684. ' e: TEnum;',
  8685. ' i: longint;',
  8686. ' a: TEnumArray;',
  8687. ' numbers: TEnumArray = (1,2);',
  8688. ' names: array[TEnum] of string = (''red'',''blue'');',
  8689. 'begin',
  8690. ' e:=low(a);',
  8691. ' e:=high(a);',
  8692. ' i:=a[red];',
  8693. ' a[e]:=a[e];']);
  8694. ConvertProgram;
  8695. CheckSource('TestArrayEnumTypeRange',
  8696. LinesToStr([ // statements
  8697. ' this.TEnum = {',
  8698. ' "0": "red",',
  8699. ' red: 0,',
  8700. ' "1": "blue",',
  8701. ' blue: 1',
  8702. '};',
  8703. 'this.e = 0;',
  8704. 'this.i = 0;',
  8705. 'this.a = rtl.arraySetLength(null,0,2);',
  8706. 'this.numbers = [1, 2];',
  8707. 'this.names = ["red", "blue"];',
  8708. '']),
  8709. LinesToStr([ // $mod.$main
  8710. '$mod.e = $mod.TEnum.red;',
  8711. '$mod.e = $mod.TEnum.blue;',
  8712. '$mod.i = $mod.a[$mod.TEnum.red];',
  8713. '$mod.a[$mod.e] = $mod.a[$mod.e];',
  8714. '']));
  8715. end;
  8716. procedure TTestModule.TestArray_SetLengthOutArg;
  8717. begin
  8718. StartProgram(false);
  8719. Add([
  8720. 'type TArrInt = array of longint;',
  8721. 'procedure DoIt(out a: TArrInt);',
  8722. 'begin',
  8723. ' SetLength(a,2);',
  8724. 'end;',
  8725. 'begin',
  8726. '']);
  8727. ConvertProgram;
  8728. CheckSource('TestArray_SetLengthOutArg',
  8729. LinesToStr([ // statements
  8730. 'this.DoIt = function (a) {',
  8731. ' a.set(rtl.arraySetLength(a.get(), 0, 2));',
  8732. '};',
  8733. '']),
  8734. LinesToStr([
  8735. '']));
  8736. end;
  8737. procedure TTestModule.TestArray_SetLengthProperty;
  8738. begin
  8739. StartProgram(false);
  8740. Add('type');
  8741. Add(' TArrInt = array of longint;');
  8742. Add(' TObject = class');
  8743. Add(' function GetColors: TArrInt; external name ''GetColors'';');
  8744. Add(' procedure SetColors(const Value: TArrInt); external name ''SetColors'';');
  8745. Add(' property Colors: TArrInt read GetColors write SetColors;');
  8746. Add(' end;');
  8747. Add('var Obj: TObject;');
  8748. Add('begin');
  8749. Add(' SetLength(Obj.Colors,2);');
  8750. ConvertProgram;
  8751. CheckSource('TestArray_SetLengthProperty',
  8752. LinesToStr([ // statements
  8753. 'rtl.createClass($mod, "TObject", null, function () {',
  8754. ' this.$init = function () {',
  8755. ' };',
  8756. ' this.$final = function () {',
  8757. ' };',
  8758. '});',
  8759. 'this.Obj = null;',
  8760. '']),
  8761. LinesToStr([
  8762. '$mod.Obj.SetColors(rtl.arraySetLength($mod.Obj.GetColors(), 0, 2));',
  8763. '']));
  8764. end;
  8765. procedure TTestModule.TestArray_SetLengthMultiDim;
  8766. begin
  8767. StartProgram(false);
  8768. Add([
  8769. 'type',
  8770. ' TArrArrInt = array of array of longint;',
  8771. ' TArrStaInt = array of array[1..2] of longint;',
  8772. 'var',
  8773. ' a: TArrArrInt;',
  8774. ' b: TArrStaInt;',
  8775. 'begin',
  8776. ' SetLength(a,2);',
  8777. ' SetLength(a,3,4);',
  8778. ' SetLength(b,5);',
  8779. '']);
  8780. ConvertProgram;
  8781. CheckSource('TestArray_SetLengthMultiDim',
  8782. LinesToStr([ // statements
  8783. 'this.a = [];',
  8784. 'this.b = [];',
  8785. '']),
  8786. LinesToStr([
  8787. '$mod.a = rtl.arraySetLength($mod.a, [], 2);',
  8788. '$mod.a = rtl.arraySetLength($mod.a, 0, 3, 4);',
  8789. '$mod.b = rtl.arraySetLength($mod.b, 0, 5, 2);',
  8790. '']));
  8791. end;
  8792. procedure TTestModule.TestArray_OpenArrayOfString;
  8793. begin
  8794. StartProgram(false);
  8795. Add('procedure DoIt(const a: array of String);');
  8796. Add('var');
  8797. Add(' i: longint;');
  8798. Add(' s: string;');
  8799. Add('begin');
  8800. Add(' for i:=low(a) to high(a) do s:=a[length(a)-i-1];');
  8801. Add('end;');
  8802. Add('var s: string;');
  8803. Add('begin');
  8804. Add(' DoIt([]);');
  8805. Add(' DoIt([s,''foo'','''',s+s]);');
  8806. ConvertProgram;
  8807. CheckSource('TestArray_OpenArrayOfString',
  8808. LinesToStr([ // statements
  8809. 'this.DoIt = function (a) {',
  8810. ' var i = 0;',
  8811. ' var s = "";',
  8812. ' for (var $l1 = 0, $end2 = rtl.length(a) - 1; $l1 <= $end2; $l1++) {',
  8813. ' i = $l1;',
  8814. ' s = a[rtl.length(a) - i - 1];',
  8815. ' };',
  8816. '};',
  8817. 'this.s = "";',
  8818. '']),
  8819. LinesToStr([
  8820. '$mod.DoIt([]);',
  8821. '$mod.DoIt([$mod.s, "foo", "", $mod.s + $mod.s]);',
  8822. '']));
  8823. end;
  8824. procedure TTestModule.TestArray_Concat;
  8825. begin
  8826. StartProgram(false);
  8827. Add([
  8828. 'type',
  8829. ' integer = longint;',
  8830. ' TFlag = (big,small);',
  8831. ' TFlags = set of TFlag;',
  8832. ' TRec = record',
  8833. ' i: integer;',
  8834. ' end;',
  8835. ' TArrInt = array of integer;',
  8836. ' TArrRec = array of TRec;',
  8837. ' TArrFlag = array of TFlag;',
  8838. ' TArrSet = array of TFlags;',
  8839. ' TArrJSValue = array of jsvalue;',
  8840. 'var',
  8841. ' ArrInt: tarrint;',
  8842. ' ArrRec: tarrrec;',
  8843. ' ArrFlag: tarrflag;',
  8844. ' ArrSet: tarrset;',
  8845. ' ArrJSValue: tarrjsvalue;',
  8846. 'begin',
  8847. ' arrint:=concat(arrint);',
  8848. ' arrint:=concat(arrint,arrint);',
  8849. ' arrint:=concat(arrint,arrint,arrint);',
  8850. ' arrrec:=concat(arrrec);',
  8851. ' arrrec:=concat(arrrec,arrrec);',
  8852. ' arrrec:=concat(arrrec,arrrec,arrrec);',
  8853. ' arrset:=concat(arrset);',
  8854. ' arrset:=concat(arrset,arrset);',
  8855. ' arrset:=concat(arrset,arrset,arrset);',
  8856. ' arrjsvalue:=concat(arrjsvalue);',
  8857. ' arrjsvalue:=concat(arrjsvalue,arrjsvalue);',
  8858. ' arrjsvalue:=concat(arrjsvalue,arrjsvalue,arrjsvalue);',
  8859. ' arrint:=concat([1],arrint);',
  8860. ' arrflag:=concat([big]);',
  8861. ' arrflag:=concat([big],arrflag);',
  8862. ' arrflag:=concat(arrflag,[small]);',
  8863. '']);
  8864. ConvertProgram;
  8865. CheckSource('TestArray_Concat',
  8866. LinesToStr([ // statements
  8867. 'this.TFlag = {',
  8868. ' "0": "big",',
  8869. ' big: 0,',
  8870. ' "1": "small",',
  8871. ' small: 1',
  8872. '};',
  8873. 'rtl.recNewT($mod, "TRec", function () {',
  8874. ' this.i = 0;',
  8875. ' this.$eq = function (b) {',
  8876. ' return this.i === b.i;',
  8877. ' };',
  8878. ' this.$assign = function (s) {',
  8879. ' this.i = s.i;',
  8880. ' return this;',
  8881. ' };',
  8882. '});',
  8883. 'this.ArrInt = [];',
  8884. 'this.ArrRec = [];',
  8885. 'this.ArrFlag = [];',
  8886. 'this.ArrSet = [];',
  8887. 'this.ArrJSValue = [];',
  8888. '']),
  8889. LinesToStr([ // $mod.$main
  8890. '$mod.ArrInt = $mod.ArrInt;',
  8891. '$mod.ArrInt = rtl.arrayConcatN($mod.ArrInt, $mod.ArrInt);',
  8892. '$mod.ArrInt = rtl.arrayConcatN($mod.ArrInt, $mod.ArrInt, $mod.ArrInt);',
  8893. '$mod.ArrRec = $mod.ArrRec;',
  8894. '$mod.ArrRec = rtl.arrayConcat($mod.TRec, $mod.ArrRec, $mod.ArrRec);',
  8895. '$mod.ArrRec = rtl.arrayConcat($mod.TRec, $mod.ArrRec, $mod.ArrRec, $mod.ArrRec);',
  8896. '$mod.ArrSet = $mod.ArrSet;',
  8897. '$mod.ArrSet = rtl.arrayConcat("refSet", $mod.ArrSet, $mod.ArrSet);',
  8898. '$mod.ArrSet = rtl.arrayConcat("refSet", $mod.ArrSet, $mod.ArrSet, $mod.ArrSet);',
  8899. '$mod.ArrJSValue = $mod.ArrJSValue;',
  8900. '$mod.ArrJSValue = rtl.arrayConcatN($mod.ArrJSValue, $mod.ArrJSValue);',
  8901. '$mod.ArrJSValue = rtl.arrayConcatN($mod.ArrJSValue, $mod.ArrJSValue, $mod.ArrJSValue);',
  8902. '$mod.ArrInt = rtl.arrayConcatN([1], $mod.ArrInt);',
  8903. '$mod.ArrFlag = [$mod.TFlag.big];',
  8904. '$mod.ArrFlag = rtl.arrayConcatN([$mod.TFlag.big], $mod.ArrFlag);',
  8905. '$mod.ArrFlag = rtl.arrayConcatN($mod.ArrFlag, [$mod.TFlag.small]);',
  8906. '']));
  8907. end;
  8908. procedure TTestModule.TestArray_Copy;
  8909. begin
  8910. StartProgram(false);
  8911. Add([
  8912. 'type',
  8913. ' integer = longint;',
  8914. ' TFlag = (big,small);',
  8915. ' TFlags = set of TFlag;',
  8916. ' TRec = record',
  8917. ' i: integer;',
  8918. ' end;',
  8919. ' TArrInt = array of integer;',
  8920. ' TArrRec = array of TRec;',
  8921. ' TArrSet = array of TFlags;',
  8922. ' TArrJSValue = array of jsvalue;',
  8923. 'var',
  8924. ' ArrInt: tarrint;',
  8925. ' ArrRec: tarrrec;',
  8926. ' ArrSet: tarrset;',
  8927. ' ArrJSValue: tarrjsvalue;',
  8928. 'begin',
  8929. ' arrint:=copy(arrint);',
  8930. ' arrint:=copy(arrint,2);',
  8931. ' arrint:=copy(arrint,3,4);',
  8932. ' arrint:=copy([1,1],1,2);',
  8933. ' arrrec:=copy(arrrec);',
  8934. ' arrrec:=copy(arrrec,5);',
  8935. ' arrrec:=copy(arrrec,6,7);',
  8936. ' arrset:=copy(arrset);',
  8937. ' arrset:=copy(arrset,8);',
  8938. ' arrset:=copy(arrset,9,10);',
  8939. ' arrjsvalue:=copy(arrjsvalue);',
  8940. ' arrjsvalue:=copy(arrjsvalue,11);',
  8941. ' arrjsvalue:=copy(arrjsvalue,12,13);',
  8942. ' ']);
  8943. ConvertProgram;
  8944. CheckSource('TestArray_Copy',
  8945. LinesToStr([ // statements
  8946. 'this.TFlag = {',
  8947. ' "0": "big",',
  8948. ' big: 0,',
  8949. ' "1": "small",',
  8950. ' small: 1',
  8951. '};',
  8952. 'rtl.recNewT($mod, "TRec", function () {',
  8953. ' this.i = 0;',
  8954. ' this.$eq = function (b) {',
  8955. ' return this.i === b.i;',
  8956. ' };',
  8957. ' this.$assign = function (s) {',
  8958. ' this.i = s.i;',
  8959. ' return this;',
  8960. ' };',
  8961. '});',
  8962. 'this.ArrInt = [];',
  8963. 'this.ArrRec = [];',
  8964. 'this.ArrSet = [];',
  8965. 'this.ArrJSValue = [];',
  8966. '']),
  8967. LinesToStr([ // $mod.$main
  8968. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 0);',
  8969. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 2);',
  8970. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 3, 4);',
  8971. '$mod.ArrInt = rtl.arrayCopy(0, [1, 1], 1, 2);',
  8972. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 0);',
  8973. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 5);',
  8974. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 6, 7);',
  8975. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 0);',
  8976. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 8);',
  8977. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 9, 10);',
  8978. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 0);',
  8979. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 11);',
  8980. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 12, 13);',
  8981. '']));
  8982. end;
  8983. procedure TTestModule.TestArray_InsertDelete;
  8984. begin
  8985. StartProgram(false);
  8986. Add([
  8987. 'type',
  8988. ' integer = longint;',
  8989. ' TFlag = (big,small);',
  8990. ' TFlags = set of TFlag;',
  8991. ' TRec = record',
  8992. ' i: integer;',
  8993. ' end;',
  8994. ' TArrInt = array of integer;',
  8995. ' TArrRec = array of TRec;',
  8996. ' TArrSet = array of TFlags;',
  8997. ' TArrJSValue = array of jsvalue;',
  8998. ' TArrArrInt = array of TArrInt;',
  8999. 'var',
  9000. ' ArrInt: tarrint;',
  9001. ' ArrRec: tarrrec;',
  9002. ' ArrSet: tarrset;',
  9003. ' ArrJSValue: tarrjsvalue;',
  9004. ' ArrArrInt: TArrArrInt;',
  9005. 'begin',
  9006. ' Insert(1,arrint,2);',
  9007. ' Insert(arrint[3],arrint,4);',
  9008. ' Insert(arrrec[5],arrrec,6);',
  9009. ' Insert(arrset[7],arrset,7);',
  9010. ' Insert(arrjsvalue[8],arrjsvalue,9);',
  9011. ' Insert(10,arrjsvalue,11);',
  9012. ' Insert([23],arrarrint,22);',
  9013. ' Delete(arrint,12,13);',
  9014. ' Delete(arrrec,14,15);',
  9015. ' Delete(arrset,17,18);',
  9016. ' Delete(arrjsvalue,19,10);']);
  9017. ConvertProgram;
  9018. CheckSource('TestArray_InsertDelete',
  9019. LinesToStr([ // statements
  9020. 'this.TFlag = {',
  9021. ' "0": "big",',
  9022. ' big: 0,',
  9023. ' "1": "small",',
  9024. ' small: 1',
  9025. '};',
  9026. 'rtl.recNewT($mod, "TRec", function () {',
  9027. ' this.i = 0;',
  9028. ' this.$eq = function (b) {',
  9029. ' return this.i === b.i;',
  9030. ' };',
  9031. ' this.$assign = function (s) {',
  9032. ' this.i = s.i;',
  9033. ' return this;',
  9034. ' };',
  9035. '});',
  9036. 'this.ArrInt = [];',
  9037. 'this.ArrRec = [];',
  9038. 'this.ArrSet = [];',
  9039. 'this.ArrJSValue = [];',
  9040. 'this.ArrArrInt = [];',
  9041. '']),
  9042. LinesToStr([ // $mod.$main
  9043. '$mod.ArrInt.splice(2, 0, 1);',
  9044. '$mod.ArrInt.splice(4, 0, $mod.ArrInt[3]);',
  9045. '$mod.ArrRec.splice(6, 0, $mod.ArrRec[5]);',
  9046. '$mod.ArrSet.splice(7, 0, $mod.ArrSet[7]);',
  9047. '$mod.ArrJSValue.splice(9, 0, $mod.ArrJSValue[8]);',
  9048. '$mod.ArrJSValue.splice(11, 0, 10);',
  9049. '$mod.ArrArrInt.splice(22, 0, [23]);',
  9050. '$mod.ArrInt.splice(12, 13);',
  9051. '$mod.ArrRec.splice(14, 15);',
  9052. '$mod.ArrSet.splice(17, 18);',
  9053. '$mod.ArrJSValue.splice(19, 10);',
  9054. '']));
  9055. end;
  9056. procedure TTestModule.TestArray_DynArrayConstObjFPC;
  9057. begin
  9058. StartProgram(false);
  9059. Add([
  9060. '{$modeswitch arrayoperators}',
  9061. 'type',
  9062. ' integer = longint;',
  9063. ' TArrInt = array of integer;',
  9064. ' TArrStr = array of string;',
  9065. 'const',
  9066. ' Ints: TArrInt = (1,2,3);',
  9067. ' Aliases: TarrStr = (''foo'',''b'');',
  9068. ' OneInt: TArrInt = (7);',
  9069. ' OneStr: array of integer = (7);',
  9070. ' Chars: array of char = ''aoc'';',
  9071. ' Names: array of string = (''a'',''foo'');',
  9072. ' NameCount = low(Names)+high(Names)+length(Names);',
  9073. 'var i: integer;',
  9074. 'begin',
  9075. ' Ints:=[];',
  9076. ' Ints:=[1,1];',
  9077. ' Ints:=[1]+[2];',
  9078. ' Ints:=[2];',
  9079. ' Ints:=[]+ints;',
  9080. ' Ints:=Ints+[];',
  9081. ' Ints:=Ints+OneInt;',
  9082. ' Ints:=Ints+[1,1];',
  9083. ' Ints:=[i,i]+Ints;',
  9084. ' Ints:=[1]+[i]+[3];',
  9085. '']);
  9086. ConvertProgram;
  9087. CheckSource('TestArray_DynArrayConstObjFPC',
  9088. LinesToStr([ // statements
  9089. 'this.Ints = [1, 2, 3];',
  9090. 'this.Aliases = ["foo", "b"];',
  9091. 'this.OneInt = [7];',
  9092. 'this.OneStr = [7];',
  9093. 'this.Chars = ["a", "o", "c"];',
  9094. 'this.Names = ["a", "foo"];',
  9095. 'this.NameCount = 0 + (rtl.length($mod.Names) - 1) + rtl.length($mod.Names);',
  9096. 'this.i = 0;',
  9097. '']),
  9098. LinesToStr([ // $mod.$main
  9099. '$mod.Ints = [];',
  9100. '$mod.Ints = [1, 1];',
  9101. '$mod.Ints = rtl.arrayConcatN([1], [2]);',
  9102. '$mod.Ints = [2];',
  9103. '$mod.Ints = rtl.arrayConcatN([], $mod.Ints);',
  9104. '$mod.Ints = rtl.arrayConcatN($mod.Ints, []);',
  9105. '$mod.Ints = rtl.arrayConcatN($mod.Ints, $mod.OneInt);',
  9106. '$mod.Ints = rtl.arrayConcatN($mod.Ints, [1, 1]);',
  9107. '$mod.Ints = rtl.arrayConcatN([$mod.i, $mod.i], $mod.Ints);',
  9108. '$mod.Ints = rtl.arrayConcatN(rtl.arrayConcatN([1], [$mod.i]), [3]);',
  9109. '']));
  9110. end;
  9111. procedure TTestModule.TestArray_DynArrayConstDelphi;
  9112. begin
  9113. StartProgram(false);
  9114. // Note: const c = [1,1]; defines a set!
  9115. Add([
  9116. '{$mode delphi}',
  9117. 'type',
  9118. ' integer = longint;',
  9119. ' TArrInt = array of integer;',
  9120. ' TArrStr = array of string;',
  9121. 'const',
  9122. ' Ints: TArrInt = [1,1,2];',
  9123. ' Aliases: TarrStr = [''foo'',''b''];',
  9124. ' OneInt: TArrInt = [7];',
  9125. ' OneStr: array of integer = [7]+[8];',
  9126. ' Chars: array of char = ''aoc'';',
  9127. ' Names: array of string = [''a'',''a''];',
  9128. ' NameCount = low(Names)+high(Names)+length(Names);',
  9129. 'begin',
  9130. '']);
  9131. ConvertProgram;
  9132. CheckSource('TestArray_DynArrayConstDelphi',
  9133. LinesToStr([ // statements
  9134. 'this.Ints = [1, 1, 2];',
  9135. 'this.Aliases = ["foo", "b"];',
  9136. 'this.OneInt = [7];',
  9137. 'this.OneStr = rtl.arrayConcatN([7],[8]);',
  9138. 'this.Chars = ["a", "o", "c"];',
  9139. 'this.Names = ["a", "a"];',
  9140. 'this.NameCount = 0 + (rtl.length($mod.Names) - 1) + rtl.length($mod.Names);',
  9141. '']),
  9142. LinesToStr([ // $mod.$main
  9143. '']));
  9144. end;
  9145. procedure TTestModule.TestArray_ArrayLitAsParam;
  9146. begin
  9147. StartProgram(false);
  9148. Add([
  9149. '{$modeswitch arrayoperators}',
  9150. 'type',
  9151. ' integer = longint;',
  9152. ' TArrInt = array of integer;',
  9153. ' TArrSet = array of (red,green,blue);',
  9154. 'procedure DoOpenInt(a: array of integer); forward;',
  9155. 'procedure DoInt(a: TArrInt);',
  9156. 'begin',
  9157. ' DoInt(a+[1]);',
  9158. ' DoInt([1]+a);',
  9159. ' DoOpenInt(a);',
  9160. ' DoOpenInt(a+[1]);',
  9161. ' DoOpenInt([1]+a);',
  9162. 'end;',
  9163. 'procedure DoOpenInt(a: array of integer);',
  9164. 'begin',
  9165. ' DoOpenInt(a+[1]);',
  9166. ' DoOpenInt([1]+a);',
  9167. ' DoInt(a);',
  9168. ' DoInt(a+[1]);',
  9169. ' DoInt([1]+a);',
  9170. 'end;',
  9171. 'procedure DoSet(a: TArrSet);',
  9172. 'begin',
  9173. ' DoSet(a+[red]);',
  9174. ' DoSet([blue]+a);',
  9175. 'end;',
  9176. 'var',
  9177. ' i: TArrInt;',
  9178. ' s: TArrSet;',
  9179. 'begin',
  9180. ' DoInt([1]);',
  9181. ' DoInt([1]+[2]);',
  9182. ' DoInt(i+[1]);',
  9183. ' DoInt([1]+i);',
  9184. ' DoOpenInt([1]);',
  9185. ' DoOpenInt([1]+[2]);',
  9186. ' DoOpenInt(i+[1]);',
  9187. ' DoOpenInt([1]+i);',
  9188. ' DoSet([red]);',
  9189. ' DoSet([blue]+[green]);',
  9190. ' DoSet(s+[blue]);',
  9191. ' DoSet([red]+s);',
  9192. '']);
  9193. ConvertProgram;
  9194. CheckSource('TestArray_ArrayLitAsParam',
  9195. LinesToStr([ // statements
  9196. 'this.TArrSet$a = {',
  9197. ' "0": "red",',
  9198. ' red: 0,',
  9199. ' "1": "green",',
  9200. ' green: 1,',
  9201. ' "2": "blue",',
  9202. ' blue: 2',
  9203. '};',
  9204. 'this.DoInt = function (a) {',
  9205. ' $mod.DoInt(rtl.arrayConcatN(a, [1]));',
  9206. ' $mod.DoInt(rtl.arrayConcatN([1], a));',
  9207. ' $mod.DoOpenInt(a);',
  9208. ' $mod.DoOpenInt(rtl.arrayConcatN(a, [1]));',
  9209. ' $mod.DoOpenInt(rtl.arrayConcatN([1], a));',
  9210. '};',
  9211. 'this.DoOpenInt = function (a) {',
  9212. ' $mod.DoOpenInt(rtl.arrayConcatN(a, [1]));',
  9213. ' $mod.DoOpenInt(rtl.arrayConcatN([1], a));',
  9214. ' $mod.DoInt(a);',
  9215. ' $mod.DoInt(rtl.arrayConcatN(a, [1]));',
  9216. ' $mod.DoInt(rtl.arrayConcatN([1], a));',
  9217. '};',
  9218. 'this.DoSet = function (a) {',
  9219. ' $mod.DoSet(rtl.arrayConcatN(a, [$mod.TArrSet$a.red]));',
  9220. ' $mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.blue], a));',
  9221. '};',
  9222. 'this.i = [];',
  9223. 'this.s = [];',
  9224. '']),
  9225. LinesToStr([ // $mod.$main
  9226. '$mod.DoInt([1]);',
  9227. '$mod.DoInt(rtl.arrayConcatN([1], [2]));',
  9228. '$mod.DoInt(rtl.arrayConcatN($mod.i, [1]));',
  9229. '$mod.DoInt(rtl.arrayConcatN([1], $mod.i));',
  9230. '$mod.DoOpenInt([1]);',
  9231. '$mod.DoOpenInt(rtl.arrayConcatN([1], [2]));',
  9232. '$mod.DoOpenInt(rtl.arrayConcatN($mod.i, [1]));',
  9233. '$mod.DoOpenInt(rtl.arrayConcatN([1], $mod.i));',
  9234. '$mod.DoSet([$mod.TArrSet$a.red]);',
  9235. '$mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.blue], [$mod.TArrSet$a.green]));',
  9236. '$mod.DoSet(rtl.arrayConcatN($mod.s, [$mod.TArrSet$a.blue]));',
  9237. '$mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.red], $mod.s));',
  9238. '']));
  9239. end;
  9240. procedure TTestModule.TestArray_ArrayLitMultiDimAsParam;
  9241. begin
  9242. StartProgram(false);
  9243. Add([
  9244. '{$modeswitch arrayoperators}',
  9245. 'type',
  9246. ' integer = longint;',
  9247. ' TArrInt = array of integer;',
  9248. ' TArrArrInt = array of TArrInt;',
  9249. 'procedure DoInt(a: TArrArrInt);',
  9250. 'begin',
  9251. ' DoInt(a+[[1]]);',
  9252. ' DoInt([[1]]+a);',
  9253. ' DoInt(a);',
  9254. 'end;',
  9255. 'var',
  9256. ' i: TArrInt;',
  9257. ' a: TArrArrInt;',
  9258. 'begin',
  9259. ' a:=[[1]];',
  9260. ' a:=[i];',
  9261. ' a:=a+[i];',
  9262. ' a:=[i]+a;',
  9263. ' a:=[[1]+i];',
  9264. ' a:=[[1]+[2]];',
  9265. ' a:=[i+[2]];',
  9266. ' DoInt([[1]]);',
  9267. ' DoInt([[1]+[2],[3,4],[5]]);',
  9268. ' DoInt([i+[1]]+a);',
  9269. ' DoInt([i]+a);',
  9270. '']);
  9271. ConvertProgram;
  9272. CheckSource('TestArray_ArrayLitMultiDimAsParam',
  9273. LinesToStr([ // statements
  9274. 'this.DoInt = function (a) {',
  9275. ' $mod.DoInt(rtl.arrayConcatN(a, [[1]]));',
  9276. ' $mod.DoInt(rtl.arrayConcatN([[1]], a));',
  9277. ' $mod.DoInt(a);',
  9278. '};',
  9279. 'this.i = [];',
  9280. 'this.a = [];',
  9281. '']),
  9282. LinesToStr([ // $mod.$main
  9283. '$mod.a = [[1]];',
  9284. '$mod.a = [$mod.i];',
  9285. '$mod.a = rtl.arrayConcatN($mod.a, [$mod.i]);',
  9286. '$mod.a = rtl.arrayConcatN([$mod.i], $mod.a);',
  9287. '$mod.a = [rtl.arrayConcatN([1], $mod.i)];',
  9288. '$mod.a = [rtl.arrayConcatN([1], [2])];',
  9289. '$mod.a = [rtl.arrayConcatN($mod.i, [2])];',
  9290. '$mod.DoInt([[1]]);',
  9291. '$mod.DoInt([rtl.arrayConcatN([1], [2]), [3, 4], [5]]);',
  9292. '$mod.DoInt(rtl.arrayConcatN([rtl.arrayConcatN($mod.i, [1])], $mod.a));',
  9293. '$mod.DoInt(rtl.arrayConcatN([$mod.i], $mod.a));',
  9294. '']));
  9295. end;
  9296. procedure TTestModule.TestArray_ArrayLitStaticAsParam;
  9297. begin
  9298. StartProgram(false);
  9299. Add([
  9300. '{$modeswitch arrayoperators}',
  9301. 'type',
  9302. ' integer = longint;',
  9303. ' TArrInt = array[1..2] of integer;',
  9304. ' TArrArrInt = array of TArrInt;',
  9305. 'procedure DoInt(a: TArrArrInt);',
  9306. 'begin',
  9307. ' DoInt(a+[[1,2]]);',
  9308. ' DoInt([[1,2]]+a);',
  9309. ' DoInt(a);',
  9310. 'end;',
  9311. 'var',
  9312. ' i: TArrInt;',
  9313. ' a: TArrArrInt;',
  9314. 'begin',
  9315. ' a:=[[1,1]];',
  9316. ' a:=[i];',
  9317. ' a:=a+[i];',
  9318. ' a:=[i]+a;',
  9319. ' DoInt([[1,1]]);',
  9320. ' DoInt([[1,2],[3,4]]);',
  9321. '']);
  9322. ConvertProgram;
  9323. CheckSource('TestArray_ArrayLitStaticAsParam',
  9324. LinesToStr([ // statements
  9325. 'this.DoInt = function (a) {',
  9326. ' $mod.DoInt(rtl.arrayConcatN(a, [[1, 2]]));',
  9327. ' $mod.DoInt(rtl.arrayConcatN([[1, 2]], a));',
  9328. ' $mod.DoInt(a);',
  9329. '};',
  9330. 'this.i = rtl.arraySetLength(null, 0, 2);',
  9331. 'this.a = [];',
  9332. '']),
  9333. LinesToStr([ // $mod.$main
  9334. '$mod.a = [[1, 1]];',
  9335. '$mod.a = [$mod.i.slice(0)];',
  9336. '$mod.a = rtl.arrayConcatN($mod.a, [$mod.i.slice(0)]);',
  9337. '$mod.a = rtl.arrayConcatN([$mod.i.slice(0)], $mod.a);',
  9338. '$mod.DoInt([[1, 1]]);',
  9339. '$mod.DoInt([[1, 2], [3, 4]]);',
  9340. '']));
  9341. end;
  9342. procedure TTestModule.TestArray_ForInArrOfString;
  9343. begin
  9344. StartProgram(false);
  9345. Add([
  9346. 'type',
  9347. 'type',
  9348. ' TMonthNameArray = array [1..12] of string;',
  9349. ' TMonthNames = TMonthNameArray;',
  9350. ' TObject = class',
  9351. ' private',
  9352. ' function GetLongMonthNames: TMonthNames; virtual; abstract;',
  9353. ' public',
  9354. ' Property LongMonthNames : TMonthNames Read GetLongMonthNames;',
  9355. ' end;',
  9356. 'var f: TObject;',
  9357. ' Month: string;',
  9358. 'begin',
  9359. ' for Month in f.LongMonthNames do ;',
  9360. '']);
  9361. ConvertProgram;
  9362. CheckSource('TestArray_ForInArrOfString',
  9363. LinesToStr([ // statements
  9364. 'rtl.createClass($mod, "TObject", null, function () {',
  9365. ' this.$init = function () {',
  9366. ' };',
  9367. ' this.$final = function () {',
  9368. ' };',
  9369. '});',
  9370. 'this.f = null;',
  9371. 'this.Month = "";',
  9372. '']),
  9373. LinesToStr([ // $mod.$main
  9374. 'for (var $in1 = $mod.f.GetLongMonthNames(), $l2 = 0, $end3 = rtl.length($in1) - 1; $l2 <= $end3; $l2++) $mod.Month = $in1[$l2];',
  9375. '']));
  9376. end;
  9377. procedure TTestModule.TestExternalClass_TypeCastArrayToExternalClass;
  9378. begin
  9379. StartProgram(false);
  9380. Add([
  9381. '{$modeswitch externalclass}',
  9382. 'type',
  9383. ' TJSObject = class external name ''Object''',
  9384. ' end;',
  9385. ' TJSArray = class external name ''Array''',
  9386. ' class function isArray(Value: JSValue) : boolean;',
  9387. ' function concat() : TJSArray; varargs;',
  9388. ' end;',
  9389. 'var',
  9390. ' aObj: TJSArray;',
  9391. ' a: array of longint;',
  9392. ' o: TJSObject;',
  9393. 'begin',
  9394. ' if TJSArray.isArray(65) then ;',
  9395. ' aObj:=TJSArray(a).concat(a);',
  9396. ' o:=TJSObject(a);']);
  9397. ConvertProgram;
  9398. CheckSource('TestExternalClass_TypeCastArrayToExternalClass',
  9399. LinesToStr([ // statements
  9400. 'this.aObj = null;',
  9401. 'this.a = [];',
  9402. 'this.o = null;',
  9403. '']),
  9404. LinesToStr([ // $mod.$main
  9405. 'if (Array.isArray(65)) ;',
  9406. '$mod.aObj = $mod.a.concat($mod.a);',
  9407. '$mod.o = $mod.a;',
  9408. '']));
  9409. end;
  9410. procedure TTestModule.TestExternalClass_TypeCastArrayFromExternalClass;
  9411. begin
  9412. StartProgram(false);
  9413. Add([
  9414. '{$modeswitch externalclass}',
  9415. 'type',
  9416. ' TArrStr = array of string;',
  9417. ' TJSArray = class external name ''Array''',
  9418. ' end;',
  9419. ' TJSObject = class external name ''Object''',
  9420. ' end;',
  9421. 'var',
  9422. ' aObj: TJSArray;',
  9423. ' a: TArrStr;',
  9424. ' jo: TJSObject;',
  9425. 'begin',
  9426. ' a:=TArrStr(aObj);',
  9427. ' TArrStr(aObj)[1]:=TArrStr(aObj)[2];',
  9428. ' a:=TarrStr(jo);',
  9429. '']);
  9430. ConvertProgram;
  9431. CheckSource('TestExternalClass_TypeCastArrayFromExternalClass',
  9432. LinesToStr([ // statements
  9433. 'this.aObj = null;',
  9434. 'this.a = [];',
  9435. 'this.jo = null;',
  9436. '']),
  9437. LinesToStr([ // $mod.$main
  9438. '$mod.a = $mod.aObj;',
  9439. '$mod.aObj[1] = $mod.aObj[2];',
  9440. '$mod.a = $mod.jo;',
  9441. '']));
  9442. end;
  9443. procedure TTestModule.TestArrayOfConst_TVarRec;
  9444. begin
  9445. StartProgram(true,[supTVarRec]);
  9446. Add([
  9447. 'procedure Say(args: array of const);',
  9448. 'var',
  9449. ' i: longint;',
  9450. ' v: TVarRec;',
  9451. 'begin',
  9452. ' for i:=low(args) to high(args) do begin',
  9453. ' v:=args[i];',
  9454. ' case v.vtype of',
  9455. ' vtInteger: if length(args)=args[i].vInteger then ;',
  9456. ' end;',
  9457. ' end;',
  9458. ' for v in args do ;',
  9459. ' args:=nil;',
  9460. ' SetLength(args,2);',
  9461. 'end;',
  9462. 'begin']);
  9463. ConvertProgram;
  9464. CheckSource('TestArrayOfConst_TVarRec',
  9465. LinesToStr([ // statements
  9466. 'this.Say = function (args) {',
  9467. ' var i = 0;',
  9468. ' var v = pas.system.TVarRec.$new();',
  9469. ' for (var $l1 = 0, $end2 = rtl.length(args) - 1; $l1 <= $end2; $l1++) {',
  9470. ' i = $l1;',
  9471. ' v.$assign(args[i]);',
  9472. ' var $tmp3 = v.VType;',
  9473. ' if ($tmp3 === 0) if (rtl.length(args) === args[i].VJSValue) ;',
  9474. ' };',
  9475. ' for (var $in4 = args, $l5 = 0, $end6 = rtl.length($in4) - 1; $l5 <= $end6; $l5++) v = $in4[$l5];',
  9476. ' args = [];',
  9477. ' args = rtl.arraySetLength(args, pas.system.TVarRec, 2);',
  9478. '};',
  9479. '']),
  9480. LinesToStr([ // $mod.$main
  9481. ]));
  9482. end;
  9483. procedure TTestModule.TestArrayOfConst_PassBaseTypes;
  9484. begin
  9485. StartProgram(true,[supTVarRec]);
  9486. Add([
  9487. 'procedure Say(args: array of const);',
  9488. 'begin',
  9489. ' Say(args);',
  9490. 'end;',
  9491. 'var',
  9492. ' p: Pointer;',
  9493. ' j: jsvalue;',
  9494. ' c: currency;',
  9495. 'begin',
  9496. ' Say([]);',
  9497. ' Say([1]);',
  9498. ' Say([''c'',''foo'',nil,true,1.3,p,j,c]);',
  9499. '']);
  9500. ConvertProgram;
  9501. CheckSource('TestArrayOfConst_PassBaseTypes',
  9502. LinesToStr([ // statements
  9503. 'this.Say = function (args) {',
  9504. ' $mod.Say(args);',
  9505. '};',
  9506. 'this.p = null;',
  9507. 'this.j = undefined;',
  9508. 'this.c = 0;',
  9509. '']),
  9510. LinesToStr([ // $mod.$main
  9511. '$mod.Say([]);',
  9512. '$mod.Say(pas.system.VarRecs(0, 1));',
  9513. '$mod.Say(pas.system.VarRecs(',
  9514. ' 9,',
  9515. ' "c",',
  9516. ' 18,',
  9517. ' "foo",',
  9518. ' 5,',
  9519. ' null,',
  9520. ' 1,',
  9521. ' true,',
  9522. ' 3,',
  9523. ' 1.3,',
  9524. ' 5,',
  9525. ' $mod.p,',
  9526. ' 20,',
  9527. ' $mod.j,',
  9528. ' 12,',
  9529. ' $mod.c',
  9530. ' ));',
  9531. '']));
  9532. end;
  9533. procedure TTestModule.TestArrayOfConst_PassObj;
  9534. begin
  9535. StartProgram(true,[supTVarRec]);
  9536. Add([
  9537. '{$interfaces corba}',
  9538. 'type',
  9539. ' TObject = class',
  9540. ' end;',
  9541. ' TClass = class of TObject;',
  9542. ' IUnknown = interface',
  9543. ' end;',
  9544. 'procedure Say(args: array of const);',
  9545. 'begin',
  9546. 'end;',
  9547. 'var',
  9548. ' o: TObject;',
  9549. ' c: TClass;',
  9550. ' i: IUnknown;',
  9551. 'begin',
  9552. ' Say([o,c,TObject]);',
  9553. ' Say([nil,i]);',
  9554. '']);
  9555. ConvertProgram;
  9556. CheckSource('TestArrayOfConst_PassObj',
  9557. LinesToStr([ // statements
  9558. 'rtl.createClass($mod, "TObject", null, function () {',
  9559. ' this.$init = function () {',
  9560. ' };',
  9561. ' this.$final = function () {',
  9562. ' };',
  9563. '});',
  9564. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  9565. 'this.Say = function (args) {',
  9566. '};',
  9567. 'this.o = null;',
  9568. 'this.c = null;',
  9569. 'this.i = null;',
  9570. '']),
  9571. LinesToStr([ // $mod.$main
  9572. '$mod.Say(pas.system.VarRecs(',
  9573. ' 7,',
  9574. ' $mod.o,',
  9575. ' 8,',
  9576. ' $mod.c,',
  9577. ' 8,',
  9578. ' $mod.TObject',
  9579. '));',
  9580. '$mod.Say(pas.system.VarRecs(5, null, 14, $mod.i));',
  9581. '']));
  9582. end;
  9583. procedure TTestModule.TestRecord_Empty;
  9584. begin
  9585. StartProgram(false);
  9586. Add([
  9587. 'type',
  9588. ' TRecA = record',
  9589. ' end;',
  9590. 'var a,b: TRecA;',
  9591. 'begin',
  9592. ' if a=b then ;']);
  9593. ConvertProgram;
  9594. CheckSource('TestRecord_Empty',
  9595. LinesToStr([ // statements
  9596. 'rtl.recNewT($mod, "TRecA", function () {',
  9597. ' this.$eq = function (b) {',
  9598. ' return true;',
  9599. ' };',
  9600. ' this.$assign = function (s) {',
  9601. ' return this;',
  9602. ' };',
  9603. '});',
  9604. 'this.a = $mod.TRecA.$new();',
  9605. 'this.b = $mod.TRecA.$new();',
  9606. '']),
  9607. LinesToStr([ // $mod.$main
  9608. 'if ($mod.a.$eq($mod.b)) ;'
  9609. ]));
  9610. end;
  9611. procedure TTestModule.TestRecord_Var;
  9612. begin
  9613. StartProgram(false);
  9614. Add('type');
  9615. Add(' TRecA = record');
  9616. Add(' Bold: longint;');
  9617. Add(' end;');
  9618. Add('var Rec: TRecA;');
  9619. Add('begin');
  9620. Add(' rec.bold:=123');
  9621. ConvertProgram;
  9622. CheckSource('TestRecord_Var',
  9623. LinesToStr([ // statements
  9624. 'rtl.recNewT($mod, "TRecA", function () {',
  9625. ' this.Bold = 0;',
  9626. ' this.$eq = function (b) {',
  9627. ' return this.Bold === b.Bold;',
  9628. ' };',
  9629. ' this.$assign = function (s) {',
  9630. ' this.Bold = s.Bold;',
  9631. ' return this;',
  9632. ' };',
  9633. '});',
  9634. 'this.Rec = $mod.TRecA.$new();',
  9635. '']),
  9636. LinesToStr([ // $mod.$main
  9637. '$mod.Rec.Bold = 123;'
  9638. ]));
  9639. end;
  9640. procedure TTestModule.TestRecord_VarExternal;
  9641. begin
  9642. StartProgram(false);
  9643. Add([
  9644. '{$modeswitch externalclass}',
  9645. 'type',
  9646. ' TRecA = record',
  9647. ' i: byte;',
  9648. ' length_: longint external name ''length'';',
  9649. ' end;',
  9650. 'var Rec: TRecA;',
  9651. 'begin',
  9652. ' rec.length_ := rec.length_',
  9653. '']);
  9654. ConvertProgram;
  9655. CheckSource('TestRecord_VarExternal',
  9656. LinesToStr([ // statements
  9657. 'rtl.recNewT($mod, "TRecA", function () {',
  9658. ' this.i = 0;',
  9659. ' this.$eq = function (b) {',
  9660. ' return (this.i === b.i) && (this.length === b.length);',
  9661. ' };',
  9662. ' this.$assign = function (s) {',
  9663. ' this.i = s.i;',
  9664. ' this.length = s.length;',
  9665. ' return this;',
  9666. ' };',
  9667. '});',
  9668. 'this.Rec = $mod.TRecA.$new();',
  9669. '']),
  9670. LinesToStr([ // $mod.$main
  9671. '$mod.Rec.length = $mod.Rec.length;'
  9672. ]));
  9673. end;
  9674. procedure TTestModule.TestRecord_WithDo;
  9675. begin
  9676. StartProgram(false);
  9677. Add('type');
  9678. Add(' TRec = record');
  9679. Add(' vI: longint;');
  9680. Add(' end;');
  9681. Add('var');
  9682. Add(' Int: longint;');
  9683. Add(' r: TRec;');
  9684. Add('begin');
  9685. Add(' with r do');
  9686. Add(' int:=vi;');
  9687. Add(' with r do begin');
  9688. Add(' int:=vi;');
  9689. Add(' vi:=int;');
  9690. Add(' end;');
  9691. ConvertProgram;
  9692. CheckSource('TestWithRecordDo',
  9693. LinesToStr([ // statements
  9694. 'rtl.recNewT($mod, "TRec", function () {',
  9695. ' this.vI = 0;',
  9696. ' this.$eq = function (b) {',
  9697. ' return this.vI === b.vI;',
  9698. ' };',
  9699. ' this.$assign = function (s) {',
  9700. ' this.vI = s.vI;',
  9701. ' return this;',
  9702. ' };',
  9703. '});',
  9704. 'this.Int = 0;',
  9705. 'this.r = $mod.TRec.$new();',
  9706. '']),
  9707. LinesToStr([ // $mod.$main
  9708. 'var $with1 = $mod.r;',
  9709. '$mod.Int = $with1.vI;',
  9710. 'var $with2 = $mod.r;',
  9711. '$mod.Int = $with2.vI;',
  9712. '$with2.vI = $mod.Int;'
  9713. ]));
  9714. end;
  9715. procedure TTestModule.TestRecord_Assign;
  9716. begin
  9717. StartProgram(false);
  9718. Add('type');
  9719. Add(' TEnum = (red,green);');
  9720. Add(' TEnums = set of TEnum;');
  9721. Add(' TSmallRec = record');
  9722. Add(' N: longint;');
  9723. Add(' end;');
  9724. Add(' TBigRec = record');
  9725. Add(' Int: longint;');
  9726. Add(' D: double;');
  9727. Add(' Arr: array of longint;');
  9728. Add(' Arr2: array[1..2] of longint;');
  9729. Add(' Small: TSmallRec;');
  9730. Add(' Enums: TEnums;');
  9731. Add(' end;');
  9732. Add('var');
  9733. Add(' r, s: TBigRec;');
  9734. Add('begin');
  9735. Add(' r:=s;');
  9736. Add(' r:=default(TBigRec);');
  9737. Add(' r:=default(s);');
  9738. ConvertProgram;
  9739. CheckSource('TestRecord_Assign',
  9740. LinesToStr([ // statements
  9741. 'this.TEnum = {',
  9742. ' "0": "red",',
  9743. ' red: 0,',
  9744. ' "1": "green",',
  9745. ' green: 1',
  9746. '};',
  9747. 'rtl.recNewT($mod, "TSmallRec", function () {',
  9748. ' this.N = 0;',
  9749. ' this.$eq = function (b) {',
  9750. ' return this.N === b.N;',
  9751. ' };',
  9752. ' this.$assign = function (s) {',
  9753. ' this.N = s.N;',
  9754. ' return this;',
  9755. ' };',
  9756. '});',
  9757. 'rtl.recNewT($mod, "TBigRec", function () {',
  9758. ' this.Int = 0;',
  9759. ' this.D = 0.0;',
  9760. ' this.Arr = [];',
  9761. ' this.$new = function () {',
  9762. ' var r = Object.create(this);',
  9763. ' r.Arr2 = rtl.arraySetLength(null, 0, 2);',
  9764. ' r.Small = $mod.TSmallRec.$new();',
  9765. ' r.Enums = {};',
  9766. ' return r;',
  9767. ' };',
  9768. ' this.$eq = function (b) {',
  9769. ' 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);',
  9770. ' };',
  9771. ' this.$assign = function (s) {',
  9772. ' this.Int = s.Int;',
  9773. ' this.D = s.D;',
  9774. ' this.Arr = s.Arr;',
  9775. ' this.Arr2 = s.Arr2.slice(0);',
  9776. ' this.Small.$assign(s.Small);',
  9777. ' this.Enums = rtl.refSet(s.Enums);',
  9778. ' return this;',
  9779. ' };',
  9780. '});',
  9781. 'this.r = $mod.TBigRec.$new();',
  9782. 'this.s = $mod.TBigRec.$new();',
  9783. '']),
  9784. LinesToStr([ // $mod.$main
  9785. '$mod.r.$assign($mod.s);',
  9786. '$mod.r.$assign($mod.TBigRec.$new());',
  9787. '$mod.r.$assign($mod.TBigRec.$new());',
  9788. '']));
  9789. end;
  9790. procedure TTestModule.TestRecord_AsParams;
  9791. begin
  9792. StartProgram(false);
  9793. Add([
  9794. 'type',
  9795. ' integer = longint;',
  9796. ' TRecord = record',
  9797. ' i: integer;',
  9798. ' end;',
  9799. 'procedure DoIt(vD: TRecord; const vC: TRecord; var vV: TRecord; var U);',
  9800. 'var vL: TRecord;',
  9801. 'begin',
  9802. ' vd:=vd;',
  9803. ' vd.i:=vd.i;',
  9804. ' vl:=vc;',
  9805. ' vv:=vv;',
  9806. ' vv.i:=vv.i;',
  9807. ' U:=vl;',
  9808. ' U:=vd;',
  9809. ' U:=vc;',
  9810. ' U:=vv;',
  9811. ' vl:=TRecord(U);',
  9812. ' vd:=TRecord(U);',
  9813. ' vv:=TRecord(U);',
  9814. ' doit(vd,vd,vd,vd);',
  9815. ' doit(vc,vc,vl,vl);',
  9816. ' doit(vv,vv,vv,vv);',
  9817. ' doit(vl,vl,vl,vl);',
  9818. ' TRecord(U).i:=3;',
  9819. 'end;',
  9820. 'var i: TRecord;',
  9821. 'begin',
  9822. ' doit(i,i,i,i);',
  9823. '']);
  9824. ConvertProgram;
  9825. CheckSource('TestRecord_AsParams',
  9826. LinesToStr([ // statements
  9827. 'rtl.recNewT($mod, "TRecord", function () {',
  9828. ' this.i = 0;',
  9829. ' this.$eq = function (b) {',
  9830. ' return this.i === b.i;',
  9831. ' };',
  9832. ' this.$assign = function (s) {',
  9833. ' this.i = s.i;',
  9834. ' return this;',
  9835. ' };',
  9836. '});',
  9837. 'this.DoIt = function (vD, vC, vV, U) {',
  9838. ' var vL = $mod.TRecord.$new();',
  9839. ' vD.$assign(vD);',
  9840. ' vD.i = vD.i;',
  9841. ' vL.$assign(vC);',
  9842. ' vV.$assign(vV);',
  9843. ' vV.i = vV.i;',
  9844. ' U.$assign(vL);',
  9845. ' U.$assign(vD);',
  9846. ' U.$assign(vC);',
  9847. ' U.$assign(vV);',
  9848. ' vL.$assign(U);',
  9849. ' vD.$assign(U);',
  9850. ' vV.$assign(U);',
  9851. ' $mod.DoIt($mod.TRecord.$clone(vD), vD, vD, vD);',
  9852. ' $mod.DoIt($mod.TRecord.$clone(vC), vC, vL, vL);',
  9853. ' $mod.DoIt($mod.TRecord.$clone(vV), vV, vV, vV);',
  9854. ' $mod.DoIt($mod.TRecord.$clone(vL), vL, vL, vL);',
  9855. ' U.i = 3;',
  9856. '};',
  9857. 'this.i = $mod.TRecord.$new();'
  9858. ]),
  9859. LinesToStr([
  9860. '$mod.DoIt($mod.TRecord.$clone($mod.i), $mod.i, $mod.i, $mod.i);',
  9861. '']));
  9862. end;
  9863. procedure TTestModule.TestRecordElement_AsParams;
  9864. begin
  9865. StartProgram(false);
  9866. Add('type');
  9867. Add(' integer = longint;');
  9868. Add(' TRecord = record');
  9869. Add(' i: integer;');
  9870. Add(' end;');
  9871. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  9872. Add('var vJ: TRecord;');
  9873. Add('begin');
  9874. Add(' doit(vj.i,vj.i,vj.i);');
  9875. Add('end;');
  9876. Add('var r: TRecord;');
  9877. Add('begin');
  9878. Add(' doit(r.i,r.i,r.i);');
  9879. ConvertProgram;
  9880. CheckSource('TestRecordElement_AsParams',
  9881. LinesToStr([ // statements
  9882. 'rtl.recNewT($mod, "TRecord", function () {',
  9883. ' this.i = 0;',
  9884. ' this.$eq = function (b) {',
  9885. ' return this.i === b.i;',
  9886. ' };',
  9887. ' this.$assign = function (s) {',
  9888. ' this.i = s.i;',
  9889. ' return this;',
  9890. ' };',
  9891. '});',
  9892. 'this.DoIt = function (vG,vH,vI) {',
  9893. ' var vJ = $mod.TRecord.$new();',
  9894. ' $mod.DoIt(vJ.i, vJ.i, {',
  9895. ' p: vJ,',
  9896. ' get: function () {',
  9897. ' return this.p.i;',
  9898. ' },',
  9899. ' set: function (v) {',
  9900. ' this.p.i = v;',
  9901. ' }',
  9902. ' });',
  9903. '};',
  9904. 'this.r = $mod.TRecord.$new();'
  9905. ]),
  9906. LinesToStr([
  9907. '$mod.DoIt($mod.r.i,$mod.r.i,{',
  9908. ' p: $mod.r,',
  9909. ' get: function () {',
  9910. ' return this.p.i;',
  9911. ' },',
  9912. ' set: function (v) {',
  9913. ' this.p.i = v;',
  9914. ' }',
  9915. '});'
  9916. ]));
  9917. end;
  9918. procedure TTestModule.TestRecordElementFromFuncResult_AsParams;
  9919. begin
  9920. StartProgram(false);
  9921. Add('type');
  9922. Add(' integer = longint;');
  9923. Add(' TRecord = record');
  9924. Add(' i: integer;');
  9925. Add(' end;');
  9926. Add('function GetRec(vB: integer = 0): TRecord;');
  9927. Add('begin');
  9928. Add('end;');
  9929. Add('procedure DoIt(vG: integer; const vH: integer);');
  9930. Add('begin');
  9931. Add('end;');
  9932. Add('begin');
  9933. Add(' doit(getrec.i,getrec.i);');
  9934. Add(' doit(getrec().i,getrec().i);');
  9935. Add(' doit(getrec(1).i,getrec(2).i);');
  9936. ConvertProgram;
  9937. CheckSource('TestRecordElementFromFuncResult_AsParams',
  9938. LinesToStr([ // statements
  9939. 'rtl.recNewT($mod, "TRecord", function () {',
  9940. ' this.i = 0;',
  9941. ' this.$eq = function (b) {',
  9942. ' return this.i === b.i;',
  9943. ' };',
  9944. ' this.$assign = function (s) {',
  9945. ' this.i = s.i;',
  9946. ' return this;',
  9947. ' };',
  9948. '});',
  9949. 'this.GetRec = function (vB) {',
  9950. ' var Result = $mod.TRecord.$new();',
  9951. ' return Result;',
  9952. '};',
  9953. 'this.DoIt = function (vG, vH) {',
  9954. '};',
  9955. '']),
  9956. LinesToStr([
  9957. '$mod.DoIt($mod.GetRec(0).i,$mod.GetRec(0).i);',
  9958. '$mod.DoIt($mod.GetRec(0).i,$mod.GetRec(0).i);',
  9959. '$mod.DoIt($mod.GetRec(1).i,$mod.GetRec(2).i);',
  9960. '']));
  9961. end;
  9962. procedure TTestModule.TestRecordElementFromWith_AsParams;
  9963. begin
  9964. StartProgram(false);
  9965. Add('type');
  9966. Add(' integer = longint;');
  9967. Add(' TRecord = record');
  9968. Add(' i: integer;');
  9969. Add(' end;');
  9970. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  9971. Add('begin');
  9972. Add('end;');
  9973. Add('var r: trecord;');
  9974. Add('begin');
  9975. Add(' with r do ');
  9976. Add(' doit(i,i,i);');
  9977. ConvertProgram;
  9978. CheckSource('TestRecordElementFromWith_AsParams',
  9979. LinesToStr([ // statements
  9980. 'rtl.recNewT($mod, "TRecord", function () {',
  9981. ' this.i = 0;',
  9982. ' this.$eq = function (b) {',
  9983. ' return this.i === b.i;',
  9984. ' };',
  9985. ' this.$assign = function (s) {',
  9986. ' this.i = s.i;',
  9987. ' return this;',
  9988. ' };',
  9989. '});',
  9990. 'this.DoIt = function (vG,vH,vI) {',
  9991. '};',
  9992. 'this.r = $mod.TRecord.$new();'
  9993. ]),
  9994. LinesToStr([
  9995. 'var $with1 = $mod.r;',
  9996. '$mod.DoIt($with1.i,$with1.i,{',
  9997. ' p: $with1,',
  9998. ' get: function () {',
  9999. ' return this.p.i;',
  10000. ' },',
  10001. ' set: function (v) {',
  10002. ' this.p.i = v;',
  10003. ' }',
  10004. '});',
  10005. '']));
  10006. end;
  10007. procedure TTestModule.TestRecord_Equal;
  10008. begin
  10009. StartProgram(false);
  10010. Add('type');
  10011. Add(' integer = longint;');
  10012. Add(' TFlag = (red,blue);');
  10013. Add(' TFlags = set of TFlag;');
  10014. Add(' TProc = procedure;');
  10015. Add(' TRecord = record');
  10016. Add(' i: integer;');
  10017. Add(' Event: TProc;');
  10018. Add(' f: TFlags;');
  10019. Add(' end;');
  10020. Add(' TNested = record');
  10021. Add(' r: TRecord;');
  10022. Add(' end;');
  10023. Add('var');
  10024. Add(' b: boolean;');
  10025. Add(' r,s: trecord;');
  10026. Add('begin');
  10027. Add(' b:=r=s;');
  10028. Add(' b:=r<>s;');
  10029. ConvertProgram;
  10030. CheckSource('TestRecord_Equal',
  10031. LinesToStr([ // statements
  10032. 'this.TFlag = {',
  10033. ' "0": "red",',
  10034. ' red: 0,',
  10035. ' "1": "blue",',
  10036. ' blue: 1',
  10037. '};',
  10038. 'rtl.recNewT($mod, "TRecord", function () {',
  10039. ' this.i = 0;',
  10040. ' this.Event = null;',
  10041. ' this.$new = function () {',
  10042. ' var r = Object.create(this);',
  10043. ' r.f = {};',
  10044. ' return r;',
  10045. ' };',
  10046. ' this.$eq = function (b) {',
  10047. ' return (this.i === b.i) && rtl.eqCallback(this.Event, b.Event) && rtl.eqSet(this.f, b.f);',
  10048. ' };',
  10049. ' this.$assign = function (s) {',
  10050. ' this.i = s.i;',
  10051. ' this.Event = s.Event;',
  10052. ' this.f = rtl.refSet(s.f);',
  10053. ' return this;',
  10054. ' };',
  10055. '});',
  10056. 'rtl.recNewT($mod, "TNested", function () {',
  10057. ' this.$new = function () {',
  10058. ' var r = Object.create(this);',
  10059. ' r.r = $mod.TRecord.$new();',
  10060. ' return r;',
  10061. ' };',
  10062. ' this.$eq = function (b) {',
  10063. ' return this.r.$eq(b.r);',
  10064. ' };',
  10065. ' this.$assign = function (s) {',
  10066. ' this.r.$assign(s.r);',
  10067. ' return this;',
  10068. ' };',
  10069. '});',
  10070. 'this.b = false;',
  10071. 'this.r = $mod.TRecord.$new();',
  10072. 'this.s = $mod.TRecord.$new();',
  10073. '']),
  10074. LinesToStr([
  10075. '$mod.b = $mod.r.$eq($mod.s);',
  10076. '$mod.b = !$mod.r.$eq($mod.s);',
  10077. '']));
  10078. end;
  10079. procedure TTestModule.TestRecord_JSValue;
  10080. begin
  10081. StartProgram(false);
  10082. Add([
  10083. 'type',
  10084. ' TRecord = record',
  10085. ' i: longint;',
  10086. ' end;',
  10087. 'procedure Fly(d: jsvalue; const c: jsvalue);',
  10088. 'begin',
  10089. 'end;',
  10090. 'var',
  10091. ' Jv: jsvalue;',
  10092. ' Rec: trecord;',
  10093. 'begin',
  10094. ' rec:=trecord(jv);',
  10095. ' jv:=rec;',
  10096. ' Fly(rec,rec);',
  10097. ' Fly(@rec,@rec);',
  10098. '']);
  10099. ConvertProgram;
  10100. CheckSource('TestRecord_JSValue',
  10101. LinesToStr([ // statements
  10102. 'rtl.recNewT($mod, "TRecord", function () {',
  10103. ' this.i = 0;',
  10104. ' this.$eq = function (b) {',
  10105. ' return this.i === b.i;',
  10106. ' };',
  10107. ' this.$assign = function (s) {',
  10108. ' this.i = s.i;',
  10109. ' return this;',
  10110. ' };',
  10111. '});',
  10112. 'this.Fly = function (d, c) {',
  10113. '};',
  10114. 'this.Jv = undefined;',
  10115. 'this.Rec = $mod.TRecord.$new();',
  10116. '']),
  10117. LinesToStr([
  10118. '$mod.Rec.$assign(rtl.getObject($mod.Jv));',
  10119. '$mod.Jv = $mod.Rec;',
  10120. '$mod.Fly($mod.TRecord.$clone($mod.Rec), $mod.Rec);',
  10121. '$mod.Fly($mod.Rec, $mod.Rec);',
  10122. '']));
  10123. end;
  10124. procedure TTestModule.TestRecord_VariantFail;
  10125. begin
  10126. StartProgram(false);
  10127. Add([
  10128. 'type',
  10129. ' TRec = record',
  10130. ' case word of',
  10131. ' 0: (b0, b1: Byte);',
  10132. ' 1: (i: word);',
  10133. ' end;',
  10134. 'begin']);
  10135. SetExpectedPasResolverError('variant record is not supported',
  10136. nXIsNotSupported);
  10137. ConvertProgram;
  10138. end;
  10139. procedure TTestModule.TestRecord_FieldArray;
  10140. begin
  10141. StartProgram(false);
  10142. Add([
  10143. 'type',
  10144. ' TArrInt = array[3..4] of longint;',
  10145. ' TArrArrInt = array[3..4] of longint;',
  10146. ' TRec = record',
  10147. ' a: array of longint;',
  10148. ' s: array[1..2] of longint;',
  10149. ' m: array[1..2,3..4] of longint;',
  10150. ' o: TArrArrInt;',
  10151. ' end;',
  10152. 'begin']);
  10153. ConvertProgram;
  10154. CheckSource('TestRecord_FieldArray',
  10155. LinesToStr([ // statements
  10156. 'rtl.recNewT($mod, "TRec", function () {',
  10157. ' this.a = [];',
  10158. ' this.$new = function () {',
  10159. ' var r = Object.create(this);',
  10160. ' r.s = rtl.arraySetLength(null, 0, 2);',
  10161. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  10162. ' r.o = rtl.arraySetLength(null, 0, 2);',
  10163. ' return r;',
  10164. ' };',
  10165. ' this.$eq = function (b) {',
  10166. ' return (this.a === b.a) && rtl.arrayEq(this.s, b.s) && rtl.arrayEq(this.m, b.m) && rtl.arrayEq(this.o, b.o);',
  10167. ' };',
  10168. ' this.$assign = function (s) {',
  10169. ' this.a = s.a;',
  10170. ' this.s = s.s.slice(0);',
  10171. ' this.m = s.m.slice(0);',
  10172. ' this.o = s.o.slice(0);',
  10173. ' return this;',
  10174. ' };',
  10175. '});',
  10176. '']),
  10177. LinesToStr([ // $mod.$main
  10178. '']));
  10179. end;
  10180. procedure TTestModule.TestRecord_Const;
  10181. begin
  10182. StartProgram(false);
  10183. Add([
  10184. 'type',
  10185. ' TArrInt = array[3..4] of longint;',
  10186. ' TPoint = record x,y: longint; end;',
  10187. ' TRec = record',
  10188. ' i: longint;',
  10189. ' a: array of longint;',
  10190. ' s: array[1..2] of longint;',
  10191. ' m: array[1..2,3..4] of longint;',
  10192. ' p: TPoint;',
  10193. ' end;',
  10194. ' TPoints = array of TPoint;',
  10195. 'const',
  10196. ' r: TRec = (',
  10197. ' i:1;',
  10198. ' a:(2,3);',
  10199. ' s:(4,5);',
  10200. ' m:( (11,12), (13,14) );',
  10201. ' p: (x:21; y:22)',
  10202. ' );',
  10203. ' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
  10204. 'begin']);
  10205. ConvertProgram;
  10206. CheckSource('TestRecord_Const',
  10207. LinesToStr([ // statements
  10208. 'rtl.recNewT($mod, "TPoint", function () {',
  10209. ' this.x = 0;',
  10210. ' this.y = 0;',
  10211. ' this.$eq = function (b) {',
  10212. ' return (this.x === b.x) && (this.y === b.y);',
  10213. ' };',
  10214. ' this.$assign = function (s) {',
  10215. ' this.x = s.x;',
  10216. ' this.y = s.y;',
  10217. ' return this;',
  10218. ' };',
  10219. '});',
  10220. 'rtl.recNewT($mod, "TRec", function () {',
  10221. ' this.i = 0;',
  10222. ' this.a = [];',
  10223. ' this.$new = function () {',
  10224. ' var r = Object.create(this);',
  10225. ' r.s = rtl.arraySetLength(null, 0, 2);',
  10226. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  10227. ' r.p = $mod.TPoint.$new();',
  10228. ' return r;',
  10229. ' };',
  10230. ' this.$eq = function (b) {',
  10231. ' 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);',
  10232. ' };',
  10233. ' this.$assign = function (s) {',
  10234. ' this.i = s.i;',
  10235. ' this.a = s.a;',
  10236. ' this.s = s.s.slice(0);',
  10237. ' this.m = s.m.slice(0);',
  10238. ' this.p.$assign(s.p);',
  10239. ' return this;',
  10240. ' };',
  10241. '});',
  10242. 'this.r = $mod.TRec.$clone({',
  10243. ' i: 1,',
  10244. ' a: [2, 3],',
  10245. ' s: [4, 5],',
  10246. ' m: [[11, 12], [13, 14]],',
  10247. ' p: $mod.TPoint.$clone({',
  10248. ' x: 21,',
  10249. ' y: 22',
  10250. ' })',
  10251. '});',
  10252. 'this.p = [$mod.TPoint.$clone({',
  10253. ' x: 1,',
  10254. ' y: 2',
  10255. '}), $mod.TPoint.$clone({',
  10256. ' x: 3,',
  10257. ' y: 4',
  10258. '})];',
  10259. '']),
  10260. LinesToStr([ // $mod.$main
  10261. '']));
  10262. end;
  10263. procedure TTestModule.TestRecord_TypecastFail;
  10264. begin
  10265. StartProgram(false);
  10266. Add([
  10267. 'type',
  10268. ' TPoint = record x,y: longint; end;',
  10269. ' TRec = record l: longint end;',
  10270. 'var p: TPoint;',
  10271. 'begin',
  10272. ' if TRec(p).l=2 then ;']);
  10273. SetExpectedPasResolverError('Illegal type conversion: "TPoint" to "record TRec"',
  10274. nIllegalTypeConversionTo);
  10275. ConvertProgram;
  10276. end;
  10277. procedure TTestModule.TestRecord_InFunction;
  10278. begin
  10279. StartProgram(false);
  10280. Add([
  10281. 'var TPoint: longint = 3;',
  10282. 'procedure DoIt;',
  10283. 'type',
  10284. ' TPoint = record x,y: longint; end;',
  10285. ' TPoints = array of TPoint;',
  10286. 'var',
  10287. ' r: TPoint;',
  10288. ' p: TPoints;',
  10289. 'begin',
  10290. ' SetLength(p,2);',
  10291. 'end;',
  10292. 'begin']);
  10293. ConvertProgram;
  10294. CheckSource('TestRecord_InFunction',
  10295. LinesToStr([ // statements
  10296. 'this.TPoint = 3;',
  10297. 'var TPoint$1 = rtl.recNewT(null, "", function () {',
  10298. ' this.x = 0;',
  10299. ' this.y = 0;',
  10300. ' this.$eq = function (b) {',
  10301. ' return (this.x === b.x) && (this.y === b.y);',
  10302. ' };',
  10303. ' this.$assign = function (s) {',
  10304. ' this.x = s.x;',
  10305. ' this.y = s.y;',
  10306. ' return this;',
  10307. ' };',
  10308. '});',
  10309. 'this.DoIt = function () {',
  10310. ' var r = TPoint$1.$new();',
  10311. ' var p = [];',
  10312. ' p = rtl.arraySetLength(p, TPoint$1, 2);',
  10313. '};',
  10314. '']),
  10315. LinesToStr([ // $mod.$main
  10316. '']));
  10317. end;
  10318. procedure TTestModule.TestRecord_AnonymousFail;
  10319. begin
  10320. StartProgram(false);
  10321. Add([
  10322. 'var',
  10323. ' r: record x: word end;',
  10324. 'begin']);
  10325. SetExpectedPasResolverError('not yet implemented: :TPasRecordType [20190408224556] anonymous record type',
  10326. nNotYetImplemented);
  10327. ConvertProgram;
  10328. end;
  10329. procedure TTestModule.TestAdvRecord_Function;
  10330. begin
  10331. StartProgram(false);
  10332. Parser.Options:=Parser.Options+[po_cassignments];
  10333. Add([
  10334. '{$modeswitch AdvancedRecords}',
  10335. 'type',
  10336. ' TPoint = record',
  10337. ' x,y: word;',
  10338. ' function Add(const apt: TPoint): TPoint;',
  10339. ' end;',
  10340. 'function TPoint.Add(const apt: TPoint): TPoint;',
  10341. 'begin',
  10342. ' Result:=Self;',
  10343. ' Result.x+=apt.x;',
  10344. ' Result.y:=Result.y+apt.y;',
  10345. ' Self:=apt;',
  10346. 'end;',
  10347. 'var p,q: TPoint;',
  10348. 'begin',
  10349. ' p.add(q);',
  10350. ' p:=default(TPoint);',
  10351. ' p:=q;',
  10352. '']);
  10353. ConvertProgram;
  10354. CheckSource('TestAdvRecord_Function',
  10355. LinesToStr([ // statements
  10356. 'rtl.recNewT($mod, "TPoint", function () {',
  10357. ' this.x = 0;',
  10358. ' this.y = 0;',
  10359. ' this.$eq = function (b) {',
  10360. ' return (this.x === b.x) && (this.y === b.y);',
  10361. ' };',
  10362. ' this.$assign = function (s) {',
  10363. ' this.x = s.x;',
  10364. ' this.y = s.y;',
  10365. ' return this;',
  10366. ' };',
  10367. ' this.Add = function (apt) {',
  10368. ' var Result = $mod.TPoint.$new();',
  10369. ' Result.$assign(this);',
  10370. ' Result.x += apt.x;',
  10371. ' Result.y = Result.y + apt.y;',
  10372. ' this.$assign(apt);',
  10373. ' return Result;',
  10374. ' };',
  10375. '});',
  10376. 'this.p = $mod.TPoint.$new();',
  10377. 'this.q = $mod.TPoint.$new();',
  10378. '']),
  10379. LinesToStr([ // $mod.$main
  10380. '$mod.p.Add($mod.q);',
  10381. '$mod.p.$assign($mod.TPoint.$new());',
  10382. '$mod.p.$assign($mod.q);',
  10383. '']));
  10384. end;
  10385. procedure TTestModule.TestAdvRecord_Property;
  10386. begin
  10387. StartProgram(false);
  10388. Add([
  10389. '{$modeswitch AdvancedRecords}',
  10390. 'type',
  10391. ' TPoint = record',
  10392. ' x,y: word;',
  10393. ' strict private',
  10394. ' function GetSize: longword;',
  10395. ' procedure SetSize(Value: longword);',
  10396. ' public',
  10397. ' property Size: longword read GetSize write SetSize;',
  10398. ' property Left: word read x write y;',
  10399. ' end;',
  10400. 'procedure SetSize(Value: longword); begin end;',// check auto rename
  10401. 'function TPoint.GetSize: longword;',
  10402. 'begin',
  10403. ' x:=y;',
  10404. ' Size:=Size;',
  10405. ' Left:=Left;',
  10406. 'end;',
  10407. 'procedure TPoint.SetSize(Value: longword);',
  10408. 'begin',
  10409. 'end;',
  10410. 'var p,q: TPoint;',
  10411. 'begin',
  10412. ' p.Size:=q.Size;',
  10413. ' p.Left:=q.Left;',
  10414. '']);
  10415. ConvertProgram;
  10416. CheckSource('TestAdvRecord_Property',
  10417. LinesToStr([ // statements
  10418. 'rtl.recNewT($mod, "TPoint", function () {',
  10419. ' this.x = 0;',
  10420. ' this.y = 0;',
  10421. ' this.$eq = function (b) {',
  10422. ' return (this.x === b.x) && (this.y === b.y);',
  10423. ' };',
  10424. ' this.$assign = function (s) {',
  10425. ' this.x = s.x;',
  10426. ' this.y = s.y;',
  10427. ' return this;',
  10428. ' };',
  10429. ' this.GetSize = function () {',
  10430. ' var Result = 0;',
  10431. ' this.x = this.y;',
  10432. ' this.SetSize(this.GetSize());',
  10433. ' this.y = this.x;',
  10434. ' return Result;',
  10435. ' };',
  10436. ' this.SetSize = function (Value) {',
  10437. ' };',
  10438. '});',
  10439. 'this.SetSize = function (Value) {',
  10440. '};',
  10441. 'this.p = $mod.TPoint.$new();',
  10442. 'this.q = $mod.TPoint.$new();',
  10443. '']),
  10444. LinesToStr([ // $mod.$main
  10445. '$mod.p.SetSize($mod.q.GetSize());',
  10446. '$mod.p.y = $mod.q.x;',
  10447. '']));
  10448. end;
  10449. procedure TTestModule.TestAdvRecord_PropertyDefault;
  10450. begin
  10451. StartProgram(false);
  10452. Add([
  10453. '{$modeswitch AdvancedRecords}',
  10454. 'type',
  10455. ' TPoint = record',
  10456. ' strict private',
  10457. ' function GetItems(Index: word): word;',
  10458. ' procedure SetItems(Index: word; Value: word);',
  10459. ' public',
  10460. ' property Items[Index: word]: word read GetItems write SetItems; default;',
  10461. ' end;',
  10462. 'function TPoint.GetItems(Index: word): word;',
  10463. 'begin',
  10464. ' Items[index]:=Items[index];',
  10465. ' self.Items[index]:=self.Items[index];',
  10466. 'end;',
  10467. 'procedure TPoint.SetItems(Index: word; Value: word);',
  10468. 'begin',
  10469. 'end;',
  10470. 'var p: TPoint;',
  10471. 'begin',
  10472. ' p[1]:=p[2];',
  10473. ' p.Items[3]:=p.Items[4];',
  10474. '']);
  10475. ConvertProgram;
  10476. CheckSource('TestAdvRecord_PropertyDefault',
  10477. LinesToStr([ // statements
  10478. 'rtl.recNewT($mod, "TPoint", function () {',
  10479. ' this.$eq = function (b) {',
  10480. ' return true;',
  10481. ' };',
  10482. ' this.$assign = function (s) {',
  10483. ' return this;',
  10484. ' };',
  10485. ' this.GetItems = function (Index) {',
  10486. ' var Result = 0;',
  10487. ' this.SetItems(Index, this.GetItems(Index));',
  10488. ' this.SetItems(Index, this.GetItems(Index));',
  10489. ' return Result;',
  10490. ' };',
  10491. ' this.SetItems = function (Index, Value) {',
  10492. ' };',
  10493. '});',
  10494. 'this.p = $mod.TPoint.$new();',
  10495. '']),
  10496. LinesToStr([ // $mod.$main
  10497. '$mod.p.SetItems(1, $mod.p.GetItems(2));',
  10498. '$mod.p.SetItems(3, $mod.p.GetItems(4));',
  10499. '']));
  10500. end;
  10501. procedure TTestModule.TestAdvRecord_Property_ClassMethod;
  10502. begin
  10503. StartProgram(false);
  10504. Add([
  10505. '{$modeswitch AdvancedRecords}',
  10506. 'type',
  10507. ' TRec = record',
  10508. ' class var Fx: longint;',
  10509. ' class var Fy: longint;',
  10510. ' class function GetInt: longint; static;',
  10511. ' class procedure SetInt(Value: longint); static;',
  10512. ' class procedure DoIt; static;',
  10513. ' class property IntA: longint read Fx write Fy;',
  10514. ' class property IntB: longint read GetInt write SetInt;',
  10515. ' end;',
  10516. 'class function trec.getint: longint;',
  10517. 'begin',
  10518. ' result:=fx;',
  10519. 'end;',
  10520. 'class procedure trec.setint(value: longint);',
  10521. 'begin',
  10522. 'end;',
  10523. 'class procedure trec.doit;',
  10524. 'begin',
  10525. ' IntA:=IntA+1;',
  10526. ' IntB:=IntB+1;',
  10527. 'end;',
  10528. 'var r: trec;',
  10529. 'begin',
  10530. ' trec.inta:=trec.inta+1;',
  10531. ' if trec.intb=2 then;',
  10532. ' trec.intb:=trec.intb+2;',
  10533. ' trec.setint(trec.inta);',
  10534. ' r.inta:=r.inta+1;',
  10535. ' if r.intb=2 then;',
  10536. ' r.intb:=r.intb+2;',
  10537. ' r.setint(r.inta);']);
  10538. ConvertProgram;
  10539. CheckSource('TestAdvRecord_Property_ClassMethod',
  10540. LinesToStr([ // statements
  10541. 'rtl.recNewT($mod, "TRec", function () {',
  10542. ' this.Fx = 0;',
  10543. ' this.Fy = 0;',
  10544. ' this.$eq = function (b) {',
  10545. ' return true;',
  10546. ' };',
  10547. ' this.$assign = function (s) {',
  10548. ' return this;',
  10549. ' };',
  10550. ' this.GetInt = function () {',
  10551. ' var Result = 0;',
  10552. ' Result = this.Fx;',
  10553. ' return Result;',
  10554. ' };',
  10555. ' this.SetInt = function (Value) {',
  10556. ' };',
  10557. ' this.DoIt = function () {',
  10558. ' $mod.TRec.Fy = this.Fx + 1;',
  10559. ' this.SetInt(this.GetInt() + 1);',
  10560. ' };',
  10561. '}, true);',
  10562. 'this.r = $mod.TRec.$new();',
  10563. '']),
  10564. LinesToStr([ // $mod.$main
  10565. '$mod.TRec.Fy = $mod.TRec.Fx + 1;',
  10566. 'if ($mod.TRec.GetInt() === 2) ;',
  10567. '$mod.TRec.SetInt($mod.TRec.GetInt() + 2);',
  10568. '$mod.TRec.SetInt($mod.TRec.Fx);',
  10569. '$mod.TRec.Fy = $mod.r.Fx + 1;',
  10570. 'if ($mod.r.GetInt() === 2) ;',
  10571. '$mod.r.SetInt($mod.r.GetInt() + 2);',
  10572. '$mod.r.SetInt($mod.r.Fx);',
  10573. '']));
  10574. end;
  10575. procedure TTestModule.TestAdvRecord_Const;
  10576. begin
  10577. StartProgram(false);
  10578. Add([
  10579. '{$modeswitch AdvancedRecords}',
  10580. 'type',
  10581. ' TArrInt = array[3..4] of longint;',
  10582. ' TPoint = record',
  10583. ' x,y: longint;',
  10584. ' class var Count: nativeint;',
  10585. ' end;',
  10586. ' TRec = record',
  10587. ' i: longint;',
  10588. ' a: array of longint;',
  10589. ' s: array[1..2] of longint;',
  10590. ' m: array[1..2,3..4] of longint;',
  10591. ' p: TPoint;',
  10592. ' end;',
  10593. ' TPoints = array of TPoint;',
  10594. 'const',
  10595. ' r: TRec = (',
  10596. ' i:1;',
  10597. ' a:(2,3);',
  10598. ' s:(4,5);',
  10599. ' m:( (11,12), (13,14) );',
  10600. ' p: (x:21)',
  10601. ' );',
  10602. ' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
  10603. 'begin']);
  10604. ConvertProgram;
  10605. CheckSource('TestAdvRecord_Const',
  10606. LinesToStr([ // statements
  10607. 'rtl.recNewT($mod, "TPoint", function () {',
  10608. ' this.x = 0;',
  10609. ' this.y = 0;',
  10610. ' this.Count = 0;',
  10611. ' this.$eq = function (b) {',
  10612. ' return (this.x === b.x) && (this.y === b.y);',
  10613. ' };',
  10614. ' this.$assign = function (s) {',
  10615. ' this.x = s.x;',
  10616. ' this.y = s.y;',
  10617. ' return this;',
  10618. ' };',
  10619. '}, true);',
  10620. 'rtl.recNewT($mod, "TRec", function () {',
  10621. ' this.i = 0;',
  10622. ' this.a = [];',
  10623. ' this.$new = function () {',
  10624. ' var r = Object.create(this);',
  10625. ' r.s = rtl.arraySetLength(null, 0, 2);',
  10626. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  10627. ' r.p = $mod.TPoint.$new();',
  10628. ' return r;',
  10629. ' };',
  10630. ' this.$eq = function (b) {',
  10631. ' 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);',
  10632. ' };',
  10633. ' this.$assign = function (s) {',
  10634. ' this.i = s.i;',
  10635. ' this.a = s.a;',
  10636. ' this.s = s.s.slice(0);',
  10637. ' this.m = s.m.slice(0);',
  10638. ' this.p.$assign(s.p);',
  10639. ' return this;',
  10640. ' };',
  10641. '});',
  10642. 'this.r = $mod.TRec.$clone({',
  10643. ' i: 1,',
  10644. ' a: [2, 3],',
  10645. ' s: [4, 5],',
  10646. ' m: [[11, 12], [13, 14]],',
  10647. ' p: $mod.TPoint.$clone({',
  10648. ' x: 21,',
  10649. ' y: 0',
  10650. ' })',
  10651. '});',
  10652. 'this.p = [$mod.TPoint.$clone({',
  10653. ' x: 1,',
  10654. ' y: 2',
  10655. '}), $mod.TPoint.$clone({',
  10656. ' x: 3,',
  10657. ' y: 4',
  10658. '})];',
  10659. '']),
  10660. LinesToStr([ // $mod.$main
  10661. '']));
  10662. end;
  10663. procedure TTestModule.TestAdvRecord_ExternalField;
  10664. begin
  10665. StartProgram(false);
  10666. Add([
  10667. '{$modeswitch AdvancedRecords}',
  10668. '{$modeswitch externalclass}',
  10669. 'type',
  10670. ' TCar = record',
  10671. ' public',
  10672. ' Intern: longint external name ''$Intern'';',
  10673. ' Intern2: longint external name ''$Intern2'';',
  10674. ' Bracket: longint external name ''["A B"]'';',
  10675. ' procedure DoIt;',
  10676. ' end;',
  10677. 'implementation',
  10678. 'procedure tcar.doit;',
  10679. 'begin',
  10680. ' Intern:=Intern+1;',
  10681. ' Intern2:=Intern2+2;',
  10682. ' Bracket:=Bracket+3;',
  10683. 'end;',
  10684. 'var Rec: TCar = (intern: 11; intern2: 12; bracket: 13);',
  10685. 'begin',
  10686. ' Rec.intern:=Rec.intern+1;',
  10687. ' Rec.intern2:=Rec.intern2+2;',
  10688. ' Rec.Bracket:=Rec.Bracket+3;',
  10689. ' with Rec do begin',
  10690. ' intern:=intern+1;',
  10691. ' intern2:=intern2+2;',
  10692. ' Bracket:=Bracket+3;',
  10693. ' end;']);
  10694. ConvertProgram;
  10695. CheckSource('TestAdvRecord_ExternalField',
  10696. LinesToStr([ // statements
  10697. 'rtl.recNewT($mod, "TCar", function () {',
  10698. ' this.$eq = function (b) {',
  10699. ' return (this.$Intern === b.$Intern) && (this.$Intern2 === b.$Intern2) && (this["A B"] === b["A B"]);',
  10700. ' };',
  10701. ' this.$assign = function (s) {',
  10702. ' this.$Intern = s.$Intern;',
  10703. ' this.$Intern2 = s.$Intern2;',
  10704. ' this["A B"] = s["A B"];',
  10705. ' return this;',
  10706. ' };',
  10707. ' this.DoIt = function () {',
  10708. ' this.$Intern = this.$Intern + 1;',
  10709. ' this.$Intern2 = this.$Intern2 + 2;',
  10710. ' this["A B"] = this["A B"] + 3;',
  10711. ' };',
  10712. '});',
  10713. 'this.Rec = $mod.TCar.$clone({',
  10714. ' $Intern: 11,',
  10715. ' $Intern2: 12,',
  10716. ' "A B": 13',
  10717. '});',
  10718. '']),
  10719. LinesToStr([ // $mod.$main
  10720. '$mod.Rec.$Intern = $mod.Rec.$Intern + 1;',
  10721. '$mod.Rec.$Intern2 = $mod.Rec.$Intern2 + 2;',
  10722. '$mod.Rec["A B"] = $mod.Rec["A B"] + 3;',
  10723. 'var $with1 = $mod.Rec;',
  10724. '$with1.$Intern = $with1.$Intern + 1;',
  10725. '$with1.$Intern2 = $with1.$Intern2 + 2;',
  10726. '$with1["A B"] = $with1["A B"] + 3;',
  10727. '']));
  10728. end;
  10729. procedure TTestModule.TestAdvRecord_SubRecord;
  10730. begin
  10731. StartProgram(false);
  10732. Add([
  10733. '{$modeswitch AdvancedRecords}',
  10734. 'type',
  10735. ' TRec = record',
  10736. ' type',
  10737. ' TPoint = record',
  10738. ' x,y: longint;',
  10739. ' class var Count: nativeint;',
  10740. ' procedure DoIt;',
  10741. ' class procedure DoThat; static;',
  10742. ' end;',
  10743. ' var',
  10744. ' i: longint;',
  10745. ' p: TPoint;',
  10746. ' procedure DoSome;',
  10747. ' end;',
  10748. 'const',
  10749. ' r: TRec = (',
  10750. ' i:1;',
  10751. ' p: (x:21;y:22)',
  10752. ' );',
  10753. 'procedure TRec.DoSome;',
  10754. 'begin',
  10755. ' p.x:=p.y+1;',
  10756. ' p.Count:=p.Count+2;',
  10757. 'end;',
  10758. 'procedure TRec.TPoint.DoIt;',
  10759. 'begin',
  10760. ' Count:=Count+3;',
  10761. 'end;',
  10762. 'class procedure TRec.TPoint.DoThat;',
  10763. 'begin',
  10764. ' Count:=Count+4;',
  10765. 'end;',
  10766. 'begin']);
  10767. ConvertProgram;
  10768. CheckSource('TestAdvRecord_SubRecord',
  10769. LinesToStr([ // statements
  10770. 'rtl.recNewT($mod, "TRec", function () {',
  10771. ' rtl.recNewT(this, "TPoint", function () {',
  10772. ' this.x = 0;',
  10773. ' this.y = 0;',
  10774. ' this.Count = 0;',
  10775. ' this.$eq = function (b) {',
  10776. ' return (this.x === b.x) && (this.y === b.y);',
  10777. ' };',
  10778. ' this.$assign = function (s) {',
  10779. ' this.x = s.x;',
  10780. ' this.y = s.y;',
  10781. ' return this;',
  10782. ' };',
  10783. ' this.DoIt = function () {',
  10784. ' $mod.TRec.TPoint.Count = this.Count + 3;',
  10785. ' };',
  10786. ' this.DoThat = function () {',
  10787. ' $mod.TRec.TPoint.Count = this.Count + 4;',
  10788. ' };',
  10789. ' }, true);',
  10790. ' this.i = 0;',
  10791. ' this.$new = function () {',
  10792. ' var r = Object.create(this);',
  10793. ' r.p = this.TPoint.$new();',
  10794. ' return r;',
  10795. ' };',
  10796. ' this.$eq = function (b) {',
  10797. ' return (this.i === b.i) && this.p.$eq(b.p);',
  10798. ' };',
  10799. ' this.$assign = function (s) {',
  10800. ' this.i = s.i;',
  10801. ' this.p.$assign(s.p);',
  10802. ' return this;',
  10803. ' };',
  10804. ' this.DoSome = function () {',
  10805. ' this.p.x = this.p.y + 1;',
  10806. ' this.TPoint.Count = this.p.Count + 2;',
  10807. ' };',
  10808. '}, true);',
  10809. 'this.r = $mod.TRec.$clone({',
  10810. ' i: 1,',
  10811. ' p: $mod.TRec.TPoint.$clone({',
  10812. ' x: 21,',
  10813. ' y: 22',
  10814. ' })',
  10815. '});',
  10816. '']),
  10817. LinesToStr([ // $mod.$main
  10818. '']));
  10819. end;
  10820. procedure TTestModule.TestAdvRecord_SubClass;
  10821. begin
  10822. StartProgram(false);
  10823. Add([
  10824. '{$modeswitch AdvancedRecords}',
  10825. 'type',
  10826. ' TObject = class end;',
  10827. ' TPoint = record',
  10828. ' type',
  10829. ' TBird = class',
  10830. ' procedure DoIt;',
  10831. ' class procedure Glob;',
  10832. ' end;',
  10833. ' procedure DoIt(b: TBird);',
  10834. ' end;',
  10835. 'procedure TPoint.TBird.DoIt;',
  10836. 'begin',
  10837. ' doit;',
  10838. ' self.doit;',
  10839. ' glob;',
  10840. ' self.glob;',
  10841. 'end;',
  10842. 'class procedure TPoint.TBird.Glob;',
  10843. 'begin',
  10844. ' glob;',
  10845. ' self.glob;',
  10846. 'end;',
  10847. 'procedure TPoint.DoIt(b: TBird);',
  10848. 'begin',
  10849. ' b.doit;',
  10850. ' b.glob;',
  10851. ' TBird.glob;',
  10852. 'end;',
  10853. 'begin',
  10854. '']);
  10855. ConvertProgram;
  10856. CheckSource('TestAdvRecord_SubClass',
  10857. LinesToStr([ // statements
  10858. 'rtl.createClass($mod, "TObject", null, function () {',
  10859. ' this.$init = function () {',
  10860. ' };',
  10861. ' this.$final = function () {',
  10862. ' };',
  10863. '});',
  10864. 'rtl.recNewT($mod, "TPoint", function () {',
  10865. ' rtl.createClass(this, "TBird", $mod.TObject, function () {',
  10866. ' this.DoIt = function () {',
  10867. ' this.DoIt();',
  10868. ' this.DoIt();',
  10869. ' this.$class.Glob();',
  10870. ' this.$class.Glob();',
  10871. ' };',
  10872. ' this.Glob = function () {',
  10873. ' this.Glob();',
  10874. ' this.Glob();',
  10875. ' };',
  10876. ' });',
  10877. ' this.$eq = function (b) {',
  10878. ' return true;',
  10879. ' };',
  10880. ' this.$assign = function (s) {',
  10881. ' return this;',
  10882. ' };',
  10883. ' this.DoIt = function (b) {',
  10884. ' b.DoIt();',
  10885. ' b.$class.Glob();',
  10886. ' this.TBird.Glob();',
  10887. ' };',
  10888. '}, true);',
  10889. '']),
  10890. LinesToStr([ // $mod.$main
  10891. '']));
  10892. end;
  10893. procedure TTestModule.TestAdvRecord_SubInterfaceFail;
  10894. begin
  10895. StartProgram(false);
  10896. Add([
  10897. '{$modeswitch AdvancedRecords}',
  10898. 'type',
  10899. ' IUnknown = interface end;',
  10900. ' TPoint = record',
  10901. ' type IBird = interface end;',
  10902. ' end;',
  10903. 'begin',
  10904. '']);
  10905. SetExpectedPasResolverError('not yet implemented: IBird:TPasClassType [20190105143752] interface inside record',
  10906. nNotYetImplemented);
  10907. ParseProgram;
  10908. end;
  10909. procedure TTestModule.TestAdvRecord_Constructor;
  10910. begin
  10911. StartProgram(false);
  10912. Add([
  10913. '{$modeswitch AdvancedRecords}',
  10914. 'type',
  10915. ' TPoint = record',
  10916. ' x,y: longint;',
  10917. ' constructor Create(ax: longint; ay: longint = -1);',
  10918. ' end;',
  10919. 'constructor tpoint.create(ax,ay: longint);',
  10920. 'begin',
  10921. ' x:=ax;',
  10922. ' self.y:=ay;',
  10923. 'end;',
  10924. 'var r: TPoint;',
  10925. 'begin',
  10926. ' r:=TPoint.Create(1,2);',
  10927. ' with TPoint do r:=Create(1,2);',
  10928. ' r.Create(3);',
  10929. ' r:=r.Create(4);',
  10930. '']);
  10931. ConvertProgram;
  10932. CheckSource('TestAdvRecord_Constructor',
  10933. LinesToStr([ // statements
  10934. 'rtl.recNewT($mod, "TPoint", function () {',
  10935. ' this.x = 0;',
  10936. ' this.y = 0;',
  10937. ' this.$eq = function (b) {',
  10938. ' return (this.x === b.x) && (this.y === b.y);',
  10939. ' };',
  10940. ' this.$assign = function (s) {',
  10941. ' this.x = s.x;',
  10942. ' this.y = s.y;',
  10943. ' return this;',
  10944. ' };',
  10945. ' this.Create = function (ax, ay) {',
  10946. ' this.x = ax;',
  10947. ' this.y = ay;',
  10948. ' return this;',
  10949. ' };',
  10950. '}, true);',
  10951. 'this.r = $mod.TPoint.$new();',
  10952. '']),
  10953. LinesToStr([ // $mod.$main
  10954. '$mod.r.$assign($mod.TPoint.$new().Create(1, 2));',
  10955. 'var $with1 = $mod.TPoint;',
  10956. '$mod.r.$assign($with1.$new().Create(1, 2));',
  10957. '$mod.r.Create(3, -1);',
  10958. '$mod.r.$assign($mod.r.Create(4, -1));',
  10959. '']));
  10960. end;
  10961. procedure TTestModule.TestAdvRecord_ClassConstructor_Program;
  10962. begin
  10963. StartProgram(false);
  10964. Add([
  10965. '{$modeswitch AdvancedRecords}',
  10966. 'type',
  10967. ' TPoint = record',
  10968. ' class var x: longint;',
  10969. ' class procedure Fly; static;',
  10970. ' class constructor Init;',
  10971. ' end;',
  10972. 'var count: word;',
  10973. 'class procedure Tpoint.Fly;',
  10974. 'begin',
  10975. 'end;',
  10976. 'class constructor tpoint.init;',
  10977. 'begin',
  10978. ' count:=count+1;',
  10979. ' x:=3;',
  10980. ' tpoint.x:=4;',
  10981. ' fly;',
  10982. ' tpoint.fly;',
  10983. 'end;',
  10984. 'var r: TPoint;',
  10985. 'begin',
  10986. ' r.x:=10;',
  10987. '']);
  10988. ConvertProgram;
  10989. CheckSource('TestAdvRecord_ClassConstructor_Program',
  10990. LinesToStr([ // statements
  10991. 'rtl.recNewT($mod, "TPoint", function () {',
  10992. ' this.x = 0;',
  10993. ' this.$eq = function (b) {',
  10994. ' return true;',
  10995. ' };',
  10996. ' this.$assign = function (s) {',
  10997. ' return this;',
  10998. ' };',
  10999. ' this.Fly = function () {',
  11000. ' };',
  11001. '}, true);',
  11002. 'this.count = 0;',
  11003. 'this.r = $mod.TPoint.$new();',
  11004. '']),
  11005. LinesToStr([ // $mod.$main
  11006. '(function () {',
  11007. ' $mod.count = $mod.count + 1;',
  11008. ' $mod.TPoint.x = 3;',
  11009. ' $mod.TPoint.x = 4;',
  11010. ' $mod.TPoint.Fly();',
  11011. ' $mod.TPoint.Fly();',
  11012. '})();',
  11013. '$mod.TPoint.x = 10;',
  11014. '']));
  11015. end;
  11016. procedure TTestModule.TestAdvRecord_ClassConstructor_Unit;
  11017. begin
  11018. StartUnit(false);
  11019. Add([
  11020. 'interface',
  11021. '{$modeswitch AdvancedRecords}',
  11022. 'type',
  11023. ' TPoint = record',
  11024. ' class var x: longint;',
  11025. ' class procedure Fly; static;',
  11026. ' class constructor Init;',
  11027. ' end;',
  11028. 'implementation',
  11029. 'var count: word;',
  11030. 'class procedure Tpoint.Fly;',
  11031. 'begin',
  11032. 'end;',
  11033. 'class constructor tpoint.init;',
  11034. 'begin',
  11035. ' count:=count+1;',
  11036. ' x:=3;',
  11037. ' tpoint.x:=4;',
  11038. ' fly;',
  11039. ' tpoint.fly;',
  11040. 'end;',
  11041. '']);
  11042. ConvertUnit;
  11043. CheckSource('TestAdvRecord_ClassConstructor_Unit',
  11044. LinesToStr([ // statements
  11045. 'var $impl = $mod.$impl;',
  11046. 'rtl.recNewT($mod, "TPoint", function () {',
  11047. ' this.x = 0;',
  11048. ' this.$eq = function (b) {',
  11049. ' return true;',
  11050. ' };',
  11051. ' this.$assign = function (s) {',
  11052. ' return this;',
  11053. ' };',
  11054. ' this.Fly = function () {',
  11055. ' };',
  11056. '}, true);',
  11057. '']),
  11058. LinesToStr([ // $mod.$init
  11059. '(function () {',
  11060. ' $impl.count = $impl.count + 1;',
  11061. ' $mod.TPoint.x = 3;',
  11062. ' $mod.TPoint.x = 4;',
  11063. ' $mod.TPoint.Fly();',
  11064. ' $mod.TPoint.Fly();',
  11065. '})();',
  11066. '']),
  11067. LinesToStr([ // $mod.$main
  11068. '$impl.count = 0;',
  11069. '']));
  11070. end;
  11071. procedure TTestModule.TestClass_TObjectDefaultConstructor;
  11072. begin
  11073. StartProgram(false);
  11074. Add(['type',
  11075. ' TObject = class',
  11076. ' public',
  11077. ' constructor Create;',
  11078. ' destructor Destroy;',
  11079. ' end;',
  11080. ' TBird = TObject;',
  11081. 'constructor tobject.create;',
  11082. 'begin end;',
  11083. 'destructor tobject.destroy;',
  11084. 'begin end;',
  11085. 'var Obj: tobject;',
  11086. 'begin',
  11087. ' obj:=tobject.create;',
  11088. ' obj:=tobject.create();',
  11089. ' obj:=tbird.create;',
  11090. ' obj:=tbird.create();',
  11091. ' obj:=obj.create();',
  11092. ' obj.destroy;',
  11093. '']);
  11094. ConvertProgram;
  11095. CheckSource('TestClass_TObjectDefaultConstructor',
  11096. LinesToStr([ // statements
  11097. 'rtl.createClass($mod,"TObject",null,function(){',
  11098. ' this.$init = function () {',
  11099. ' };',
  11100. ' this.$final = function () {',
  11101. ' };',
  11102. ' this.Create = function(){',
  11103. ' return this;',
  11104. ' };',
  11105. ' this.Destroy = function(){',
  11106. ' };',
  11107. '});',
  11108. 'this.Obj = null;'
  11109. ]),
  11110. LinesToStr([ // $mod.$main
  11111. '$mod.Obj = $mod.TObject.$create("Create");',
  11112. '$mod.Obj = $mod.TObject.$create("Create");',
  11113. '$mod.Obj = $mod.TObject.$create("Create");',
  11114. '$mod.Obj = $mod.TObject.$create("Create");',
  11115. '$mod.Obj = $mod.Obj.Create();',
  11116. '$mod.Obj.$destroy("Destroy");',
  11117. '']));
  11118. end;
  11119. procedure TTestModule.TestClass_TObjectConstructorWithParams;
  11120. begin
  11121. StartProgram(false);
  11122. Add('type');
  11123. Add(' TObject = class');
  11124. Add(' public');
  11125. Add(' constructor Create(Par: longint);');
  11126. Add(' end;');
  11127. Add('constructor tobject.create(par: longint);');
  11128. Add('begin end;');
  11129. Add('var Obj: tobject;');
  11130. Add('begin');
  11131. Add(' obj:=tobject.create(3);');
  11132. ConvertProgram;
  11133. CheckSource('TestClass_TObjectConstructorWithParams',
  11134. LinesToStr([ // statements
  11135. 'rtl.createClass($mod,"TObject",null,function(){',
  11136. ' this.$init = function () {',
  11137. ' };',
  11138. ' this.$final = function () {',
  11139. ' };',
  11140. ' this.Create = function(Par){',
  11141. ' return this;',
  11142. ' };',
  11143. '});',
  11144. 'this.Obj = null;'
  11145. ]),
  11146. LinesToStr([ // $mod.$main
  11147. '$mod.Obj = $mod.TObject.$create("Create",[3]);'
  11148. ]));
  11149. end;
  11150. procedure TTestModule.TestClass_TObjectConstructorWithDefaultParam;
  11151. begin
  11152. StartProgram(false);
  11153. Add('type');
  11154. Add(' TObject = class');
  11155. Add(' public');
  11156. Add(' constructor Create;');
  11157. Add(' end;');
  11158. Add(' TTest = class(TObject)');
  11159. Add(' public');
  11160. Add(' constructor Create(const Par: longint = 1);');
  11161. Add(' end;');
  11162. Add('constructor tobject.create;');
  11163. Add('begin end;');
  11164. Add('constructor ttest.create(const par: longint);');
  11165. Add('begin end;');
  11166. Add('var t: ttest;');
  11167. Add('begin');
  11168. Add(' t:=ttest.create;');
  11169. Add(' t:=ttest.create(2);');
  11170. ConvertProgram;
  11171. CheckSource('TestClass_TObjectConstructorWithDefaultParam',
  11172. LinesToStr([ // statements
  11173. 'rtl.createClass($mod,"TObject",null,function(){',
  11174. ' this.$init = function () {',
  11175. ' };',
  11176. ' this.$final = function () {',
  11177. ' };',
  11178. ' this.Create = function(){',
  11179. ' return this;',
  11180. ' };',
  11181. '});',
  11182. 'rtl.createClass($mod, "TTest", $mod.TObject, function () {',
  11183. ' this.Create$1 = function (Par) {',
  11184. ' return this;',
  11185. ' };',
  11186. '});',
  11187. 'this.t = null;'
  11188. ]),
  11189. LinesToStr([ // $mod.$main
  11190. '$mod.t = $mod.TTest.$create("Create$1", [1]);',
  11191. '$mod.t = $mod.TTest.$create("Create$1", [2]);'
  11192. ]));
  11193. end;
  11194. procedure TTestModule.TestClass_Var;
  11195. begin
  11196. StartProgram(false);
  11197. Add([
  11198. 'type',
  11199. ' TObject = class',
  11200. ' public',
  11201. ' vI: longint;',
  11202. ' constructor Create(Par: longint);',
  11203. ' end;',
  11204. 'constructor tobject.create(par: longint);',
  11205. 'begin',
  11206. ' vi:=par+3',
  11207. 'end;',
  11208. 'var Obj: tobject;',
  11209. 'begin',
  11210. ' obj:=tobject.create(4);',
  11211. ' obj.vi:=obj.VI+5;']);
  11212. ConvertProgram;
  11213. CheckSource('TestClass_Var',
  11214. LinesToStr([ // statements
  11215. 'rtl.createClass($mod,"TObject",null,function(){',
  11216. ' this.$init = function () {',
  11217. ' this.vI = 0;',
  11218. ' };',
  11219. ' this.$final = function () {',
  11220. ' };',
  11221. ' this.Create = function(Par){',
  11222. ' this.vI = Par+3;',
  11223. ' return this;',
  11224. ' };',
  11225. '});',
  11226. 'this.Obj = null;'
  11227. ]),
  11228. LinesToStr([ // $mod.$main
  11229. '$mod.Obj = $mod.TObject.$create("Create",[4]);',
  11230. '$mod.Obj.vI = $mod.Obj.vI + 5;'
  11231. ]));
  11232. end;
  11233. procedure TTestModule.TestClass_Method;
  11234. begin
  11235. StartProgram(false);
  11236. Add('type');
  11237. Add(' TObject = class');
  11238. Add(' public');
  11239. Add(' vI: longint;');
  11240. Add(' Sub: TObject;');
  11241. Add(' constructor Create;');
  11242. Add(' function GetIt(Par: longint): tobject;');
  11243. Add(' end;');
  11244. Add('constructor tobject.create; begin end;');
  11245. Add('function tobject.getit(par: longint): tobject;');
  11246. Add('begin');
  11247. Add(' Self.vi:=par+3;');
  11248. Add(' Result:=self.sub;');
  11249. Add('end;');
  11250. Add('var Obj: tobject;');
  11251. Add('begin');
  11252. Add(' obj:=tobject.create;');
  11253. Add(' obj.getit(4);');
  11254. Add(' obj.sub.sub:=nil;');
  11255. Add(' obj.sub.getit(5);');
  11256. Add(' obj.sub.getit(6).SUB:=nil;');
  11257. Add(' obj.sub.getit(7).GETIT(8);');
  11258. Add(' obj.sub.getit(9).SuB.getit(10);');
  11259. ConvertProgram;
  11260. CheckSource('TestClass_Method',
  11261. LinesToStr([ // statements
  11262. 'rtl.createClass($mod,"TObject",null,function(){',
  11263. ' this.$init = function () {',
  11264. ' this.vI = 0;',
  11265. ' this.Sub = null;',
  11266. ' };',
  11267. ' this.$final = function () {',
  11268. ' this.Sub = undefined;',
  11269. ' };',
  11270. ' this.Create = function(){',
  11271. ' return this;',
  11272. ' };',
  11273. ' this.GetIt = function(Par){',
  11274. ' var Result = null;',
  11275. ' this.vI = Par + 3;',
  11276. ' Result = this.Sub;',
  11277. ' return Result;',
  11278. ' };',
  11279. '});',
  11280. 'this.Obj = null;'
  11281. ]),
  11282. LinesToStr([ // $mod.$main
  11283. '$mod.Obj = $mod.TObject.$create("Create");',
  11284. '$mod.Obj.GetIt(4);',
  11285. '$mod.Obj.Sub.Sub=null;',
  11286. '$mod.Obj.Sub.GetIt(5);',
  11287. '$mod.Obj.Sub.GetIt(6).Sub=null;',
  11288. '$mod.Obj.Sub.GetIt(7).GetIt(8);',
  11289. '$mod.Obj.Sub.GetIt(9).Sub.GetIt(10);'
  11290. ]));
  11291. end;
  11292. procedure TTestModule.TestClass_Implementation;
  11293. begin
  11294. StartUnit(false);
  11295. Add([
  11296. 'interface',
  11297. 'type',
  11298. ' TObject = class',
  11299. ' constructor Create;',
  11300. ' end;',
  11301. 'implementation',
  11302. 'type',
  11303. ' TIntClass = class',
  11304. ' constructor Create; reintroduce;',
  11305. ' class procedure DoGlob;',
  11306. ' end;',
  11307. 'constructor tintclass.create;',
  11308. 'begin',
  11309. ' inherited;',
  11310. ' inherited create;',
  11311. ' doglob;',
  11312. 'end;',
  11313. 'class procedure tintclass.doglob;',
  11314. 'begin',
  11315. 'end;',
  11316. 'constructor tobject.create;',
  11317. 'var',
  11318. ' iC: tintclass;',
  11319. 'begin',
  11320. ' ic:=tintclass.create;',
  11321. ' tintclass.doglob;',
  11322. ' ic.doglob;',
  11323. 'end;',
  11324. 'initialization',
  11325. ' tintclass.doglob;',
  11326. '']);
  11327. ConvertUnit;
  11328. CheckSource('TestClass_Implementation',
  11329. LinesToStr([ // statements
  11330. 'var $impl = $mod.$impl;',
  11331. 'rtl.createClass($mod, "TObject", null, function () {',
  11332. ' this.$init = function () {',
  11333. ' };',
  11334. ' this.$final = function () {',
  11335. ' };',
  11336. ' this.Create = function () {',
  11337. ' var iC = null;',
  11338. ' iC = $impl.TIntClass.$create("Create$1");',
  11339. ' $impl.TIntClass.DoGlob();',
  11340. ' iC.$class.DoGlob();',
  11341. ' return this;',
  11342. ' };',
  11343. '});',
  11344. '']),
  11345. LinesToStr([ // $mod.$main
  11346. '$impl.TIntClass.DoGlob();',
  11347. '']),
  11348. LinesToStr([
  11349. 'rtl.createClass($impl, "TIntClass", $mod.TObject, function () {',
  11350. ' this.Create$1 = function () {',
  11351. ' $mod.TObject.Create.call(this);',
  11352. ' $mod.TObject.Create.call(this);',
  11353. ' this.$class.DoGlob();',
  11354. ' return this;',
  11355. ' };',
  11356. ' this.DoGlob = function () {',
  11357. ' };',
  11358. '});',
  11359. '']));
  11360. end;
  11361. procedure TTestModule.TestClass_Inheritance;
  11362. begin
  11363. StartProgram(false);
  11364. Add('type');
  11365. Add(' TObject = class');
  11366. Add(' public');
  11367. Add(' constructor Create;');
  11368. Add(' end;');
  11369. Add(' TClassA = class');
  11370. Add(' end;');
  11371. Add(' TClassB = class(TObject)');
  11372. Add(' procedure ProcB;');
  11373. Add(' end;');
  11374. Add('constructor tobject.create; begin end;');
  11375. Add('procedure tclassb.procb; begin end;');
  11376. Add('var');
  11377. Add(' oO: TObject;');
  11378. Add(' oA: TClassA;');
  11379. Add(' oB: TClassB;');
  11380. Add('begin');
  11381. Add(' oO:=tobject.Create;');
  11382. Add(' oA:=tclassa.Create;');
  11383. Add(' ob:=tclassb.Create;');
  11384. Add(' if oo is tclassa then ;');
  11385. Add(' ob:=oo as tclassb;');
  11386. Add(' (oo as tclassb).procb;');
  11387. ConvertProgram;
  11388. CheckSource('TestClass_Inheritance',
  11389. LinesToStr([ // statements
  11390. 'rtl.createClass($mod,"TObject",null,function(){',
  11391. ' this.$init = function () {',
  11392. ' };',
  11393. ' this.$final = function () {',
  11394. ' };',
  11395. ' this.Create = function () {',
  11396. ' return this;',
  11397. ' };',
  11398. '});',
  11399. 'rtl.createClass($mod,"TClassA",$mod.TObject,function(){',
  11400. '});',
  11401. 'rtl.createClass($mod,"TClassB",$mod.TObject,function(){',
  11402. ' this.ProcB = function () {',
  11403. ' };',
  11404. '});',
  11405. 'this.oO = null;',
  11406. 'this.oA = null;',
  11407. 'this.oB = null;'
  11408. ]),
  11409. LinesToStr([ // $mod.$main
  11410. '$mod.oO = $mod.TObject.$create("Create");',
  11411. '$mod.oA = $mod.TClassA.$create("Create");',
  11412. '$mod.oB = $mod.TClassB.$create("Create");',
  11413. 'if ($mod.TClassA.isPrototypeOf($mod.oO));',
  11414. '$mod.oB = rtl.as($mod.oO, $mod.TClassB);',
  11415. 'rtl.as($mod.oO, $mod.TClassB).ProcB();'
  11416. ]));
  11417. end;
  11418. procedure TTestModule.TestClass_TypeAlias;
  11419. begin
  11420. StartProgram(false);
  11421. Add([
  11422. '{$interfaces corba}',
  11423. 'type',
  11424. ' IObject = interface',
  11425. ' end;',
  11426. ' IBird = type IObject;',
  11427. ' TObject = class',
  11428. ' end;',
  11429. ' TBird = type TObject;',
  11430. 'var',
  11431. ' oObj: TObject;',
  11432. ' oBird: TBird;',
  11433. ' IntfObj: IObject;',
  11434. ' IntfBird: IBird;',
  11435. 'begin',
  11436. ' oObj:=oBird;',
  11437. '']);
  11438. ConvertProgram;
  11439. CheckSource('TestClass_TypeAlias',
  11440. LinesToStr([ // statements
  11441. 'rtl.createInterface($mod, "IObject", "{B92D5841-6F2A-306A-8000-000000000000}", [], null);',
  11442. 'rtl.createInterface($mod, "IBird", "{4B0D080B-C0F6-387B-AE88-F10981585074}", [], $mod.IObject);',
  11443. 'rtl.createClass($mod, "TObject", null, function () {',
  11444. ' this.$init = function () {',
  11445. ' };',
  11446. ' this.$final = function () {',
  11447. ' };',
  11448. '});',
  11449. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  11450. '});',
  11451. 'this.oObj = null;',
  11452. 'this.oBird = null;',
  11453. 'this.IntfObj = null;',
  11454. 'this.IntfBird = null;',
  11455. '']),
  11456. LinesToStr([ // $mod.$main
  11457. '$mod.oObj = $mod.oBird;',
  11458. '']));
  11459. end;
  11460. procedure TTestModule.TestClass_AbstractMethod;
  11461. begin
  11462. StartProgram(false);
  11463. Add('type');
  11464. Add(' TObject = class');
  11465. Add(' public');
  11466. Add(' procedure DoIt; virtual; abstract;');
  11467. Add(' end;');
  11468. Add('begin');
  11469. ConvertProgram;
  11470. CheckSource('TestClass_AbstractMethod',
  11471. LinesToStr([ // statements
  11472. 'rtl.createClass($mod,"TObject",null,function(){',
  11473. ' this.$init = function () {',
  11474. ' };',
  11475. ' this.$final = function () {',
  11476. ' };',
  11477. '});'
  11478. ]),
  11479. LinesToStr([ // this.$main
  11480. ''
  11481. ]));
  11482. end;
  11483. procedure TTestModule.TestClass_CallInherited_ProcNoParams;
  11484. begin
  11485. StartProgram(false);
  11486. Add([
  11487. 'type',
  11488. ' TObject = class',
  11489. ' procedure DoAbstract; virtual; abstract;',
  11490. ' procedure DoVirtual; virtual;',
  11491. ' procedure DoIt;',
  11492. ' end;',
  11493. ' TA = class',
  11494. ' procedure doabstract; override;',
  11495. ' procedure dovirtual; override;',
  11496. ' procedure DoSome;',
  11497. ' end;',
  11498. 'procedure tobject.dovirtual;',
  11499. 'begin',
  11500. ' inherited; // call non existing ancestor -> ignore silently',
  11501. 'end;',
  11502. 'procedure tobject.doit;',
  11503. 'begin',
  11504. 'end;',
  11505. 'procedure ta.doabstract;',
  11506. 'begin',
  11507. ' inherited dovirtual; // call TObject.DoVirtual',
  11508. 'end;',
  11509. 'procedure ta.dovirtual;',
  11510. 'begin',
  11511. ' inherited; // call TObject.DoVirtual',
  11512. ' inherited dovirtual; // call TObject.DoVirtual',
  11513. ' inherited dovirtual(); // call TObject.DoVirtual',
  11514. ' doit;',
  11515. ' doit();',
  11516. 'end;',
  11517. 'procedure ta.dosome;',
  11518. 'begin',
  11519. ' inherited; // call non existing ancestor method -> silently ignore',
  11520. 'end;',
  11521. 'begin']);
  11522. ConvertProgram;
  11523. CheckSource('TestClass_CallInherited_ProcNoParams',
  11524. LinesToStr([ // statements
  11525. 'rtl.createClass($mod,"TObject",null,function(){',
  11526. ' this.$init = function () {',
  11527. ' };',
  11528. ' this.$final = function () {',
  11529. ' };',
  11530. ' this.DoVirtual = function () {',
  11531. ' };',
  11532. ' this.DoIt = function () {',
  11533. ' };',
  11534. '});',
  11535. 'rtl.createClass($mod, "TA", $mod.TObject, function () {',
  11536. ' this.DoAbstract = function () {',
  11537. ' $mod.TObject.DoVirtual.call(this);',
  11538. ' };',
  11539. ' this.DoVirtual = function () {',
  11540. ' $mod.TObject.DoVirtual.call(this);',
  11541. ' $mod.TObject.DoVirtual.call(this);',
  11542. ' $mod.TObject.DoVirtual.call(this);',
  11543. ' this.DoIt();',
  11544. ' this.DoIt();',
  11545. ' };',
  11546. ' this.DoSome = function () {',
  11547. ' };',
  11548. '});'
  11549. ]),
  11550. LinesToStr([ // this.$main
  11551. ''
  11552. ]));
  11553. end;
  11554. procedure TTestModule.TestClass_CallInherited_WithParams;
  11555. begin
  11556. StartProgram(false);
  11557. Add([
  11558. 'type',
  11559. ' TObject = class',
  11560. ' procedure DoAbstract(pA: longint; pB: longint = 0); virtual; abstract;',
  11561. ' procedure DoVirtual(pA: longint; pB: longint = 0); virtual;',
  11562. ' procedure DoIt(pA: longint; pB: longint = 0);',
  11563. ' procedure DoIt2(pA: longint = 1; pB: longint = 2);',
  11564. ' function GetIt(pA: longint = 1; pB: longint = 2): longint;',
  11565. ' end;',
  11566. ' TClassA = class',
  11567. ' procedure DoAbstract(pA: longint; pB: longint = 0); override;',
  11568. ' procedure DoVirtual(pA: longint; pB: longint = 0); override;',
  11569. ' function GetIt(pA: longint = 1; pB: longint = 2): longint;',
  11570. ' end;',
  11571. 'procedure tobject.dovirtual(pa: longint; pb: longint = 0);',
  11572. 'begin',
  11573. 'end;',
  11574. 'procedure tobject.doit(pa: longint; pb: longint = 0);',
  11575. 'begin',
  11576. 'end;',
  11577. 'procedure tobject.doit2(pa: longint; pb: longint = 0);',
  11578. 'begin',
  11579. 'end;',
  11580. 'function tobject.getit(pa: longint; pb: longint = 0): longint;',
  11581. 'begin',
  11582. 'end;',
  11583. 'procedure tclassa.doabstract(pa: longint; pb: longint = 0);',
  11584. 'begin',
  11585. ' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)',
  11586. ' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)',
  11587. 'end;',
  11588. 'procedure tclassa.dovirtual(pa: longint; pb: longint = 0);',
  11589. 'begin',
  11590. ' inherited; // call TObject.DoVirtual(pA,pB)',
  11591. ' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)',
  11592. ' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)',
  11593. ' doit(pa,pb);',
  11594. ' doit(pa);',
  11595. ' doit2(pa);',
  11596. ' doit2;',
  11597. 'end;',
  11598. 'function tclassa.getit(pa: longint; pb: longint = 0): longint;',
  11599. 'begin',
  11600. ' pa:=inherited;',
  11601. 'end;',
  11602. 'begin']);
  11603. ConvertProgram;
  11604. CheckSource('TestClass_CallInherited_WithParams',
  11605. LinesToStr([ // statements
  11606. 'rtl.createClass($mod,"TObject",null,function(){',
  11607. ' this.$init = function () {',
  11608. ' };',
  11609. ' this.$final = function () {',
  11610. ' };',
  11611. ' this.DoVirtual = function (pA,pB) {',
  11612. ' };',
  11613. ' this.DoIt = function (pA,pB) {',
  11614. ' };',
  11615. ' this.DoIt2 = function (pA,pB) {',
  11616. ' };',
  11617. ' this.GetIt = function (pA, pB) {',
  11618. ' var Result = 0;',
  11619. ' return Result;',
  11620. ' };',
  11621. '});',
  11622. 'rtl.createClass($mod, "TClassA", $mod.TObject, function () {',
  11623. ' this.DoAbstract = function (pA,pB) {',
  11624. ' $mod.TObject.DoVirtual.call(this,pA,pB);',
  11625. ' $mod.TObject.DoVirtual.call(this,pA,0);',
  11626. ' };',
  11627. ' this.DoVirtual = function (pA,pB) {',
  11628. ' $mod.TObject.DoVirtual.apply(this, arguments);',
  11629. ' $mod.TObject.DoVirtual.call(this,pA,pB);',
  11630. ' $mod.TObject.DoVirtual.call(this,pA,0);',
  11631. ' this.DoIt(pA,pB);',
  11632. ' this.DoIt(pA,0);',
  11633. ' this.DoIt2(pA,2);',
  11634. ' this.DoIt2(1,2);',
  11635. ' };',
  11636. ' this.GetIt$1 = function (pA, pB) {',
  11637. ' var Result = 0;',
  11638. ' pA = $mod.TObject.GetIt.apply(this, arguments);',
  11639. ' return Result;',
  11640. ' };',
  11641. '});'
  11642. ]),
  11643. LinesToStr([ // this.$main
  11644. ''
  11645. ]));
  11646. end;
  11647. procedure TTestModule.TestClasS_CallInheritedConstructor;
  11648. begin
  11649. StartProgram(false);
  11650. Add('type');
  11651. Add(' TObject = class');
  11652. Add(' constructor Create; virtual;');
  11653. Add(' constructor CreateWithB(b: boolean);');
  11654. Add(' end;');
  11655. Add(' TA = class');
  11656. Add(' constructor Create; override;');
  11657. Add(' constructor CreateWithC(c: char);');
  11658. Add(' procedure DoIt;');
  11659. Add(' class function DoSome: TObject;');
  11660. Add(' end;');
  11661. Add('constructor tobject.create;');
  11662. Add('begin');
  11663. Add(' inherited; // call non existing ancestor -> ignore silently');
  11664. Add('end;');
  11665. Add('constructor tobject.createwithb(b: boolean);');
  11666. Add('begin');
  11667. Add(' inherited; // call non existing ancestor -> ignore silently');
  11668. Add(' create; // normal call');
  11669. Add('end;');
  11670. Add('constructor ta.create;');
  11671. Add('begin');
  11672. Add(' inherited; // normal call TObject.Create');
  11673. Add(' inherited create; // normal call TObject.Create');
  11674. Add(' inherited createwithb(false); // normal call TObject.CreateWithB');
  11675. Add('end;');
  11676. Add('constructor ta.createwithc(c: char);');
  11677. Add('begin');
  11678. Add(' inherited create; // call TObject.Create');
  11679. Add(' inherited createwithb(true); // call TObject.CreateWithB');
  11680. Add(' doit;');
  11681. Add(' doit();');
  11682. Add(' dosome;');
  11683. Add('end;');
  11684. Add('procedure ta.doit;');
  11685. Add('begin');
  11686. Add(' create; // normal call');
  11687. Add(' createwithb(false); // normal call');
  11688. Add(' createwithc(''c''); // normal call');
  11689. Add('end;');
  11690. Add('class function ta.dosome: TObject;');
  11691. Add('begin');
  11692. Add(' Result:=create; // constructor');
  11693. Add(' Result:=createwithb(true); // constructor');
  11694. Add(' Result:=createwithc(''c''); // constructor');
  11695. Add('end;');
  11696. Add('begin');
  11697. ConvertProgram;
  11698. CheckSource('TestClass_CallInheritedConstructor',
  11699. LinesToStr([ // statements
  11700. 'rtl.createClass($mod,"TObject",null,function(){',
  11701. ' this.$init = function () {',
  11702. ' };',
  11703. ' this.$final = function () {',
  11704. ' };',
  11705. ' this.Create = function () {',
  11706. ' return this;',
  11707. ' };',
  11708. ' this.CreateWithB = function (b) {',
  11709. ' this.Create();',
  11710. ' return this;',
  11711. ' };',
  11712. '});',
  11713. 'rtl.createClass($mod, "TA", $mod.TObject, function () {',
  11714. ' this.Create = function () {',
  11715. ' $mod.TObject.Create.call(this);',
  11716. ' $mod.TObject.Create.call(this);',
  11717. ' $mod.TObject.CreateWithB.call(this, false);',
  11718. ' return this;',
  11719. ' };',
  11720. ' this.CreateWithC = function (c) {',
  11721. ' $mod.TObject.Create.call(this);',
  11722. ' $mod.TObject.CreateWithB.call(this, true);',
  11723. ' this.DoIt();',
  11724. ' this.DoIt();',
  11725. ' this.$class.DoSome();',
  11726. ' return this;',
  11727. ' };',
  11728. ' this.DoIt = function () {',
  11729. ' this.Create();',
  11730. ' this.CreateWithB(false);',
  11731. ' this.CreateWithC("c");',
  11732. ' };',
  11733. ' this.DoSome = function () {',
  11734. ' var Result = null;',
  11735. ' Result = this.$create("Create");',
  11736. ' Result = this.$create("CreateWithB", [true]);',
  11737. ' Result = this.$create("CreateWithC", ["c"]);',
  11738. ' return Result;',
  11739. ' };',
  11740. '});'
  11741. ]),
  11742. LinesToStr([ // this.$main
  11743. ''
  11744. ]));
  11745. end;
  11746. procedure TTestModule.TestClass_ClassVar_Assign;
  11747. begin
  11748. StartProgram(false);
  11749. Add([
  11750. 'type',
  11751. ' TObject = class',
  11752. ' public',
  11753. ' class var vI: longint;',
  11754. ' class var Sub: TObject;',
  11755. ' constructor Create;',
  11756. ' class function GetIt(var Par: longint): tobject;',
  11757. ' end;',
  11758. 'constructor tobject.create;',
  11759. 'begin',
  11760. ' vi:=vi+1;',
  11761. ' Self.vi:=Self.vi+1;',
  11762. ' inc(vi);',
  11763. 'end;',
  11764. 'class function tobject.getit(var par: longint): tobject;',
  11765. 'begin',
  11766. ' vi:=vi+3;',
  11767. ' Self.vi:=Self.vi+4;',
  11768. ' inc(vi);',
  11769. ' Result:=self.sub;',
  11770. ' GetIt(vi);',
  11771. 'end;',
  11772. 'var Obj: tobject;',
  11773. 'begin',
  11774. ' obj:=tobject.create;',
  11775. ' tobject.vi:=3;',
  11776. ' if tobject.vi=4 then ;',
  11777. ' tobject.sub:=nil;',
  11778. ' obj.sub:=nil;',
  11779. ' obj.sub.sub:=nil;']);
  11780. ConvertProgram;
  11781. CheckSource('TestClass_ClassVar_Assign',
  11782. LinesToStr([ // statements
  11783. 'rtl.createClass($mod,"TObject",null,function(){',
  11784. ' this.vI = 0;',
  11785. ' this.Sub = null;',
  11786. ' this.$init = function () {',
  11787. ' };',
  11788. ' this.$final = function () {',
  11789. ' };',
  11790. ' this.Create = function(){',
  11791. ' $mod.TObject.vI = this.vI+1;',
  11792. ' $mod.TObject.vI = this.vI+1;',
  11793. ' $mod.TObject.vI += 1;',
  11794. ' return this;',
  11795. ' };',
  11796. ' this.GetIt = function(Par){',
  11797. ' var Result = null;',
  11798. ' $mod.TObject.vI = this.vI + 3;',
  11799. ' $mod.TObject.vI = this.vI + 4;',
  11800. ' $mod.TObject.vI += 1;',
  11801. ' Result = this.Sub;',
  11802. ' this.GetIt({',
  11803. ' p: $mod.TObject,',
  11804. ' get: function () {',
  11805. ' return this.p.vI;',
  11806. ' },',
  11807. ' set: function (v) {',
  11808. ' this.p.vI = v;',
  11809. ' }',
  11810. ' });',
  11811. ' return Result;',
  11812. ' };',
  11813. '});',
  11814. 'this.Obj = null;'
  11815. ]),
  11816. LinesToStr([ // $mod.$main
  11817. '$mod.Obj = $mod.TObject.$create("Create");',
  11818. '$mod.TObject.vI = 3;',
  11819. 'if ($mod.TObject.vI === 4);',
  11820. '$mod.TObject.Sub=null;',
  11821. '$mod.TObject.Sub=null;',
  11822. '$mod.TObject.Sub=null;',
  11823. '']));
  11824. end;
  11825. procedure TTestModule.TestClass_CallClassMethod;
  11826. begin
  11827. StartProgram(false);
  11828. Add('type');
  11829. Add(' TObject = class');
  11830. Add(' public');
  11831. Add(' class var vI: longint;');
  11832. Add(' class var Sub: TObject;');
  11833. Add(' constructor Create;');
  11834. Add(' function GetMore(Par: longint): longint;');
  11835. Add(' class function GetIt(Par: longint): tobject;');
  11836. Add(' end;');
  11837. Add('constructor tobject.create;');
  11838. Add('begin');
  11839. Add(' sub:=getit(3);');
  11840. Add(' vi:=getmore(4);');
  11841. Add(' sub:=Self.getit(5);');
  11842. Add(' vi:=Self.getmore(6);');
  11843. Add('end;');
  11844. Add('function tobject.getmore(par: longint): longint;');
  11845. Add('begin');
  11846. Add(' sub:=getit(11);');
  11847. Add(' vi:=getmore(12);');
  11848. Add(' sub:=self.getit(13);');
  11849. Add(' vi:=self.getmore(14);');
  11850. Add('end;');
  11851. Add('class function tobject.getit(par: longint): tobject;');
  11852. Add('begin');
  11853. Add(' sub:=getit(21);');
  11854. Add(' vi:=sub.getmore(22);');
  11855. Add(' sub:=self.getit(23);');
  11856. Add(' vi:=self.sub.getmore(24);');
  11857. Add('end;');
  11858. Add('var Obj: tobject;');
  11859. Add('begin');
  11860. Add(' obj:=tobject.create;');
  11861. Add(' tobject.getit(5);');
  11862. Add(' obj.getit(6);');
  11863. Add(' obj.sub.getit(7);');
  11864. Add(' obj.sub.getit(8).SUB:=nil;');
  11865. Add(' obj.sub.getit(9).GETIT(10);');
  11866. Add(' obj.sub.getit(11).SuB.getit(12);');
  11867. ConvertProgram;
  11868. CheckSource('TestClass_CallClassMethod',
  11869. LinesToStr([ // statements
  11870. 'rtl.createClass($mod,"TObject",null,function(){',
  11871. ' this.vI = 0;',
  11872. ' this.Sub = null;',
  11873. ' this.$init = function () {',
  11874. ' };',
  11875. ' this.$final = function () {',
  11876. ' };',
  11877. ' this.Create = function(){',
  11878. ' $mod.TObject.Sub = this.$class.GetIt(3);',
  11879. ' $mod.TObject.vI = this.GetMore(4);',
  11880. ' $mod.TObject.Sub = this.$class.GetIt(5);',
  11881. ' $mod.TObject.vI = this.GetMore(6);',
  11882. ' return this;',
  11883. ' };',
  11884. ' this.GetMore = function(Par){',
  11885. ' var Result = 0;',
  11886. ' $mod.TObject.Sub = this.$class.GetIt(11);',
  11887. ' $mod.TObject.vI = this.GetMore(12);',
  11888. ' $mod.TObject.Sub = this.$class.GetIt(13);',
  11889. ' $mod.TObject.vI = this.GetMore(14);',
  11890. ' return Result;',
  11891. ' };',
  11892. ' this.GetIt = function(Par){',
  11893. ' var Result = null;',
  11894. ' $mod.TObject.Sub = this.GetIt(21);',
  11895. ' $mod.TObject.vI = this.Sub.GetMore(22);',
  11896. ' $mod.TObject.Sub = this.GetIt(23);',
  11897. ' $mod.TObject.vI = this.Sub.GetMore(24);',
  11898. ' return Result;',
  11899. ' };',
  11900. '});',
  11901. 'this.Obj = null;'
  11902. ]),
  11903. LinesToStr([ // $mod.$main
  11904. '$mod.Obj = $mod.TObject.$create("Create");',
  11905. '$mod.TObject.GetIt(5);',
  11906. '$mod.Obj.$class.GetIt(6);',
  11907. '$mod.Obj.Sub.$class.GetIt(7);',
  11908. '$mod.TObject.Sub=null;',
  11909. '$mod.Obj.Sub.$class.GetIt(9).$class.GetIt(10);',
  11910. '$mod.Obj.Sub.$class.GetIt(11).Sub.$class.GetIt(12);',
  11911. '']));
  11912. end;
  11913. procedure TTestModule.TestClass_Property;
  11914. begin
  11915. StartProgram(false);
  11916. Add('type');
  11917. Add(' TObject = class');
  11918. Add(' Fx: longint;');
  11919. Add(' Fy: longint;');
  11920. Add(' function GetInt: longint;');
  11921. Add(' procedure SetInt(Value: longint);');
  11922. Add(' procedure DoIt;');
  11923. Add(' property IntA: longint read Fx write Fy;');
  11924. Add(' property IntB: longint read GetInt write SetInt;');
  11925. Add(' end;');
  11926. Add('function tobject.getint: longint;');
  11927. Add('begin');
  11928. Add(' result:=fx;');
  11929. Add('end;');
  11930. Add('procedure tobject.setint(value: longint);');
  11931. Add('begin');
  11932. Add(' if value=fy then exit;');
  11933. Add(' fy:=value;');
  11934. Add('end;');
  11935. Add('procedure tobject.doit;');
  11936. Add('begin');
  11937. Add(' IntA:=IntA+1;');
  11938. Add(' Self.IntA:=Self.IntA+1;');
  11939. Add(' IntB:=IntB+1;');
  11940. Add(' Self.IntB:=Self.IntB+1;');
  11941. Add('end;');
  11942. Add('var Obj: tobject;');
  11943. Add('begin');
  11944. Add(' obj.inta:=obj.inta+1;');
  11945. Add(' if obj.intb=2 then;');
  11946. Add(' obj.intb:=obj.intb+2;');
  11947. Add(' obj.setint(obj.inta);');
  11948. ConvertProgram;
  11949. CheckSource('TestClass_Property',
  11950. LinesToStr([ // statements
  11951. 'rtl.createClass($mod, "TObject", null, function () {',
  11952. ' this.$init = function () {',
  11953. ' this.Fx = 0;',
  11954. ' this.Fy = 0;',
  11955. ' };',
  11956. ' this.$final = function () {',
  11957. ' };',
  11958. ' this.GetInt = function () {',
  11959. ' var Result = 0;',
  11960. ' Result = this.Fx;',
  11961. ' return Result;',
  11962. ' };',
  11963. ' this.SetInt = function (Value) {',
  11964. ' if (Value === this.Fy) return;',
  11965. ' this.Fy = Value;',
  11966. ' };',
  11967. ' this.DoIt = function () {',
  11968. ' this.Fy = this.Fx + 1;',
  11969. ' this.Fy = this.Fx + 1;',
  11970. ' this.SetInt(this.GetInt() + 1);',
  11971. ' this.SetInt(this.GetInt() + 1);',
  11972. ' };',
  11973. '});',
  11974. 'this.Obj = null;'
  11975. ]),
  11976. LinesToStr([ // $mod.$main
  11977. '$mod.Obj.Fy = $mod.Obj.Fx + 1;',
  11978. 'if ($mod.Obj.GetInt() === 2);',
  11979. '$mod.Obj.SetInt($mod.Obj.GetInt() + 2);',
  11980. '$mod.Obj.SetInt($mod.Obj.Fx);'
  11981. ]));
  11982. end;
  11983. procedure TTestModule.TestClass_Property_ClassMethod;
  11984. begin
  11985. StartProgram(false);
  11986. Add([
  11987. 'type',
  11988. ' TObject = class',
  11989. ' class var Fx: longint;',
  11990. ' class var Fy: longint;',
  11991. ' class function GetInt: longint;',
  11992. ' class procedure SetInt(Value: longint);',
  11993. ' end;',
  11994. ' TBird = class',
  11995. ' class procedure DoIt;',
  11996. ' class property IntA: longint read Fx write Fy;',
  11997. ' class property IntB: longint read GetInt write SetInt;',
  11998. ' end;',
  11999. 'class function tobject.getint: longint;',
  12000. 'begin',
  12001. ' result:=fx;',
  12002. 'end;',
  12003. 'class procedure tobject.setint(value: longint);',
  12004. 'begin',
  12005. 'end;',
  12006. 'class procedure tbird.doit;',
  12007. 'begin',
  12008. ' FX:=3;',
  12009. ' IntA:=IntA+1;',
  12010. ' Self.IntA:=Self.IntA+1;',
  12011. ' IntB:=IntB+1;',
  12012. ' Self.IntB:=Self.IntB+1;',
  12013. ' with Self do begin',
  12014. ' FX:=11;',
  12015. ' IntA:=IntA+12;',
  12016. ' IntB:=IntB+13;',
  12017. ' end;',
  12018. 'end;',
  12019. 'var Obj: tbird;',
  12020. 'begin',
  12021. ' tbird.fx:=tbird.fx+1;',
  12022. ' tbird.inta:=tbird.inta+1;',
  12023. ' if tbird.intb=2 then;',
  12024. ' tbird.intb:=tbird.intb+2;',
  12025. ' tbird.setint(tbird.inta);',
  12026. ' obj.inta:=obj.inta+1;',
  12027. ' if obj.intb=2 then;',
  12028. ' obj.intb:=obj.intb+2;',
  12029. ' obj.setint(obj.inta);',
  12030. ' with Tbird do begin',
  12031. ' FX:=FY+1;',
  12032. ' inta:=inta+2;',
  12033. ' intb:=intb+3;',
  12034. ' end;',
  12035. ' with Obj do begin',
  12036. ' FX:=FY+1;',
  12037. ' inta:=inta+2;',
  12038. ' intb:=intb+3;',
  12039. ' end;',
  12040. '']);
  12041. ConvertProgram;
  12042. CheckSource('TestClass_Property_ClassMethod',
  12043. LinesToStr([ // statements
  12044. 'rtl.createClass($mod, "TObject", null, function () {',
  12045. ' this.Fx = 0;',
  12046. ' this.Fy = 0;',
  12047. ' this.$init = function () {',
  12048. ' };',
  12049. ' this.$final = function () {',
  12050. ' };',
  12051. ' this.GetInt = function () {',
  12052. ' var Result = 0;',
  12053. ' Result = this.Fx;',
  12054. ' return Result;',
  12055. ' };',
  12056. ' this.SetInt = function (Value) {',
  12057. ' };',
  12058. '});',
  12059. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  12060. ' this.DoIt = function () {',
  12061. ' $mod.TObject.Fx = 3;',
  12062. ' $mod.TObject.Fy = this.Fx + 1;',
  12063. ' $mod.TObject.Fy = this.Fx + 1;',
  12064. ' this.SetInt(this.GetInt() + 1);',
  12065. ' this.SetInt(this.GetInt() + 1);',
  12066. ' $mod.TObject.Fx = 11;',
  12067. ' $mod.TObject.Fy = this.Fx + 12;',
  12068. ' this.SetInt(this.GetInt() + 13);',
  12069. ' };',
  12070. '});',
  12071. 'this.Obj = null;'
  12072. ]),
  12073. LinesToStr([ // $mod.$main
  12074. '$mod.TObject.Fx = $mod.TBird.Fx + 1;',
  12075. '$mod.TObject.Fy = $mod.TBird.Fx + 1;',
  12076. 'if ($mod.TBird.GetInt() === 2);',
  12077. '$mod.TBird.SetInt($mod.TBird.GetInt() + 2);',
  12078. '$mod.TBird.SetInt($mod.TBird.Fx);',
  12079. '$mod.TObject.Fy = $mod.Obj.Fx + 1;',
  12080. 'if ($mod.Obj.$class.GetInt() === 2);',
  12081. '$mod.Obj.$class.SetInt($mod.Obj.$class.GetInt() + 2);',
  12082. '$mod.Obj.$class.SetInt($mod.Obj.Fx);',
  12083. 'var $with1 = $mod.TBird;',
  12084. '$mod.TObject.Fx = $with1.Fy + 1;',
  12085. '$mod.TObject.Fy = $with1.Fx + 2;',
  12086. '$with1.SetInt($with1.GetInt() + 3);',
  12087. 'var $with2 = $mod.Obj;',
  12088. '$mod.TObject.Fx = $with2.Fy + 1;',
  12089. '$mod.TObject.Fy = $with2.Fx + 2;',
  12090. '$with2.$class.SetInt($with2.$class.GetInt() + 3);',
  12091. '']));
  12092. end;
  12093. procedure TTestModule.TestClass_Property_Indexed;
  12094. begin
  12095. StartProgram(false);
  12096. Add('type');
  12097. Add(' TObject = class');
  12098. Add(' FItems: array of longint;');
  12099. Add(' function GetItems(Index: longint): longint;');
  12100. Add(' procedure SetItems(Index: longint; Value: longint);');
  12101. Add(' procedure DoIt;');
  12102. Add(' property Items[Index: longint]: longint read getitems write setitems;');
  12103. Add(' end;');
  12104. Add('function tobject.getitems(index: longint): longint;');
  12105. Add('begin');
  12106. Add(' Result:=fitems[index];');
  12107. Add('end;');
  12108. Add('procedure tobject.setitems(index: longint; value: longint);');
  12109. Add('begin');
  12110. Add(' fitems[index]:=value;');
  12111. Add('end;');
  12112. Add('procedure tobject.doit;');
  12113. Add('begin');
  12114. Add(' items[1]:=2;');
  12115. Add(' items[3]:=items[4];');
  12116. Add(' self.items[5]:=self.items[6];');
  12117. Add(' items[items[7]]:=items[items[8]];');
  12118. Add('end;');
  12119. Add('var Obj: tobject;');
  12120. Add('begin');
  12121. Add(' obj.Items[11]:=obj.Items[12];');
  12122. ConvertProgram;
  12123. CheckSource('TestClass_Property_Indexed',
  12124. LinesToStr([ // statements
  12125. 'rtl.createClass($mod, "TObject", null, function () {',
  12126. ' this.$init = function () {',
  12127. ' this.FItems = [];',
  12128. ' };',
  12129. ' this.$final = function () {',
  12130. ' this.FItems = undefined;',
  12131. ' };',
  12132. ' this.GetItems = function (Index) {',
  12133. ' var Result = 0;',
  12134. ' Result = this.FItems[Index];',
  12135. ' return Result;',
  12136. ' };',
  12137. ' this.SetItems = function (Index, Value) {',
  12138. ' this.FItems[Index] = Value;',
  12139. ' };',
  12140. ' this.DoIt = function () {',
  12141. ' this.SetItems(1, 2);',
  12142. ' this.SetItems(3,this.GetItems(4));',
  12143. ' this.SetItems(5,this.GetItems(6));',
  12144. ' this.SetItems(this.GetItems(7), this.GetItems(this.GetItems(8)));',
  12145. ' };',
  12146. '});',
  12147. 'this.Obj = null;'
  12148. ]),
  12149. LinesToStr([ // $mod.$main
  12150. '$mod.Obj.SetItems(11,$mod.Obj.GetItems(12));'
  12151. ]));
  12152. end;
  12153. procedure TTestModule.TestClass_Property_IndexSpec;
  12154. begin
  12155. StartProgram(false);
  12156. Add([
  12157. 'type',
  12158. ' TEnum = (red, blue);',
  12159. ' TObject = class',
  12160. ' function GetIntBool(Index: longint): boolean; virtual; abstract;',
  12161. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  12162. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  12163. ' procedure SetEnumBool(Index: TEnum; b: boolean); virtual; abstract;',
  12164. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  12165. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  12166. ' property B1: boolean index 1 read GetIntBool write SetIntBool;',
  12167. ' property B2: boolean index TEnum.blue read GetEnumBool write SetEnumBool;',
  12168. ' property B3: boolean index ord(red) read GetIntBool write SetIntBool;',
  12169. ' property I1[A: String]: boolean index ord(blue) read GetStrIntBool write SetStrIntBool;',
  12170. ' end;',
  12171. 'procedure DoIt(b: boolean); begin end;',
  12172. 'var',
  12173. ' o: TObject;',
  12174. 'begin',
  12175. ' o.B1:=o.B1;',
  12176. ' o.B2:=o.B2;',
  12177. ' o.B3:=o.B3;',
  12178. ' o.I1[''a'']:=o.I1[''b''];',
  12179. ' doit(o.b1);',
  12180. ' doit(o.b2);',
  12181. ' doit(o.i1[''c'']);',
  12182. '']);
  12183. ConvertProgram;
  12184. CheckSource('TestClass_Property_IndexSpec',
  12185. LinesToStr([ // statements
  12186. 'this.TEnum = {',
  12187. ' "0": "red",',
  12188. ' red: 0,',
  12189. ' "1": "blue",',
  12190. ' blue: 1',
  12191. '};',
  12192. 'rtl.createClass($mod, "TObject", null, function () {',
  12193. ' this.$init = function () {',
  12194. ' };',
  12195. ' this.$final = function () {',
  12196. ' };',
  12197. '});',
  12198. 'this.DoIt = function (b) {',
  12199. '};',
  12200. 'this.o = null;',
  12201. '']),
  12202. LinesToStr([ // $mod.$main
  12203. '$mod.o.SetIntBool(1, $mod.o.GetIntBool(1));',
  12204. '$mod.o.SetEnumBool($mod.TEnum.blue, $mod.o.GetEnumBool($mod.TEnum.blue));',
  12205. '$mod.o.SetIntBool(0, $mod.o.GetIntBool(0));',
  12206. '$mod.o.SetStrIntBool("a", 1, $mod.o.GetStrIntBool("b", 1));',
  12207. '$mod.DoIt($mod.o.GetIntBool(1));',
  12208. '$mod.DoIt($mod.o.GetEnumBool($mod.TEnum.blue));',
  12209. '$mod.DoIt($mod.o.GetStrIntBool("c", 1));',
  12210. '']));
  12211. end;
  12212. procedure TTestModule.TestClass_PropertyOfTypeArray;
  12213. begin
  12214. StartProgram(false);
  12215. Add('type');
  12216. Add(' TArray = array of longint;');
  12217. Add(' TObject = class');
  12218. Add(' FItems: TArray;');
  12219. Add(' function GetItems: tarray;');
  12220. Add(' procedure SetItems(Value: tarray);');
  12221. Add(' property Items: tarray read getitems write setitems;');
  12222. Add(' end;');
  12223. Add('function tobject.getitems: tarray;');
  12224. Add('begin');
  12225. Add(' Result:=fitems;');
  12226. Add('end;');
  12227. Add('procedure tobject.setitems(value: tarray);');
  12228. Add('begin');
  12229. Add(' fitems:=value;');
  12230. Add(' fitems:=nil;');
  12231. Add(' Items:=nil;');
  12232. Add(' Items:=Items;');
  12233. Add(' Items[1]:=2;');
  12234. Add(' fitems[3]:=Items[4];');
  12235. Add(' Items[5]:=Items[6];');
  12236. Add(' Self.Items[7]:=8;');
  12237. Add(' Self.Items[9]:=Self.Items[10];');
  12238. Add(' Items[Items[11]]:=Items[Items[12]];');
  12239. Add('end;');
  12240. Add('var Obj: tobject;');
  12241. Add('begin');
  12242. Add(' obj.items:=nil;');
  12243. Add(' obj.items:=obj.items;');
  12244. Add(' obj.items[11]:=obj.items[12];');
  12245. ConvertProgram;
  12246. CheckSource('TestClass_PropertyOfTypeArray',
  12247. LinesToStr([ // statements
  12248. 'rtl.createClass($mod, "TObject", null, function () {',
  12249. ' this.$init = function () {',
  12250. ' this.FItems = [];',
  12251. ' };',
  12252. ' this.$final = function () {',
  12253. ' this.FItems = undefined;',
  12254. ' };',
  12255. ' this.GetItems = function () {',
  12256. ' var Result = [];',
  12257. ' Result = this.FItems;',
  12258. ' return Result;',
  12259. ' };',
  12260. ' this.SetItems = function (Value) {',
  12261. ' this.FItems = Value;',
  12262. ' this.FItems = [];',
  12263. ' this.SetItems([]);',
  12264. ' this.SetItems(this.GetItems());',
  12265. ' this.GetItems()[1] = 2;',
  12266. ' this.FItems[3] = this.GetItems()[4];',
  12267. ' this.GetItems()[5] = this.GetItems()[6];',
  12268. ' this.GetItems()[7] = 8;',
  12269. ' this.GetItems()[9] = this.GetItems()[10];',
  12270. ' this.GetItems()[this.GetItems()[11]] = this.GetItems()[this.GetItems()[12]];',
  12271. ' };',
  12272. '});',
  12273. 'this.Obj = null;'
  12274. ]),
  12275. LinesToStr([ // $mod.$main
  12276. '$mod.Obj.SetItems([]);',
  12277. '$mod.Obj.SetItems($mod.Obj.GetItems());',
  12278. '$mod.Obj.GetItems()[11] = $mod.Obj.GetItems()[12];'
  12279. ]));
  12280. end;
  12281. procedure TTestModule.TestClass_PropertyDefault;
  12282. begin
  12283. StartProgram(false);
  12284. Add([
  12285. 'type',
  12286. ' TArray = array of longint;',
  12287. ' TObject = class',
  12288. ' FItems: TArray;',
  12289. ' function GetItems(Index: longint): longint;',
  12290. ' procedure SetItems(Index, Value: longint);',
  12291. ' property Items[Index: longint]: longint read getitems write setitems; default;',
  12292. ' end;',
  12293. 'function tobject.getitems(index: longint): longint;',
  12294. 'begin',
  12295. 'end;',
  12296. 'procedure tobject.setitems(index, value: longint);',
  12297. 'begin',
  12298. ' Self[1]:=2;',
  12299. ' Self[3]:=Self[index];',
  12300. ' Self[index]:=Self[Self[value]];',
  12301. ' Self[Self[4]]:=value;',
  12302. 'end;',
  12303. 'var Obj: tobject;',
  12304. 'begin',
  12305. ' obj[11]:=12;',
  12306. ' obj[13]:=obj[14];',
  12307. ' obj[obj[15]]:=obj[obj[15]];',
  12308. ' TObject(obj)[16]:=TObject(obj)[17];']);
  12309. ConvertProgram;
  12310. CheckSource('TestClass_PropertyDefault',
  12311. LinesToStr([ // statements
  12312. 'rtl.createClass($mod, "TObject", null, function () {',
  12313. ' this.$init = function () {',
  12314. ' this.FItems = [];',
  12315. ' };',
  12316. ' this.$final = function () {',
  12317. ' this.FItems = undefined;',
  12318. ' };',
  12319. ' this.GetItems = function (Index) {',
  12320. ' var Result = 0;',
  12321. ' return Result;',
  12322. ' };',
  12323. ' this.SetItems = function (Index, Value) {',
  12324. ' this.SetItems(1, 2);',
  12325. ' this.SetItems(3, this.GetItems(Index));',
  12326. ' this.SetItems(Index, this.GetItems(this.GetItems(Value)));',
  12327. ' this.SetItems(this.GetItems(4), Value);',
  12328. ' };',
  12329. '});',
  12330. 'this.Obj = null;'
  12331. ]),
  12332. LinesToStr([ // $mod.$main
  12333. '$mod.Obj.SetItems(11, 12);',
  12334. '$mod.Obj.SetItems(13, $mod.Obj.GetItems(14));',
  12335. '$mod.Obj.SetItems($mod.Obj.GetItems(15), $mod.Obj.GetItems($mod.Obj.GetItems(15)));',
  12336. '$mod.Obj.SetItems(16, $mod.Obj.GetItems(17));',
  12337. '']));
  12338. end;
  12339. procedure TTestModule.TestClass_PropertyDefault2;
  12340. begin
  12341. StartProgram(false);
  12342. Add([
  12343. 'type',
  12344. ' TObject = class end;',
  12345. ' TAlphaList = class',
  12346. ' function GetAlphas(Index: boolean): Pointer; virtual; abstract;',
  12347. ' procedure SetAlphas(Index: boolean; Value: Pointer); virtual; abstract;',
  12348. ' property Alphas[Index: boolean]: Pointer read getAlphas write setAlphas; default;',
  12349. ' end;',
  12350. ' TBetaList = class',
  12351. ' function GetBetas(Index: longint): Pointer; virtual; abstract;',
  12352. ' procedure SetBetas(Index: longint; Value: Pointer); virtual; abstract;',
  12353. ' property Betas[Index: longint]: Pointer read getBetas write setBetas; default;',
  12354. ' end;',
  12355. ' TBird = class',
  12356. ' procedure DoIt;',
  12357. ' end;',
  12358. 'procedure TBird.DoIt;',
  12359. 'var',
  12360. ' List: TAlphaList;',
  12361. 'begin',
  12362. ' if TBetaList(List[true])[3]=nil then ;',
  12363. ' TBetaList(List[false])[5]:=nil;',
  12364. 'end;',
  12365. 'var',
  12366. ' List: TAlphaList;',
  12367. 'begin',
  12368. ' if TBetaList(List[true])[3]=nil then ;',
  12369. ' TBetaList(List[false])[5]:=nil;',
  12370. '']);
  12371. ConvertProgram;
  12372. CheckSource('TestClass_PropertyDefault2',
  12373. LinesToStr([ // statements
  12374. 'rtl.createClass($mod, "TObject", null, function () {',
  12375. ' this.$init = function () {',
  12376. ' };',
  12377. ' this.$final = function () {',
  12378. ' };',
  12379. '});',
  12380. 'rtl.createClass($mod, "TAlphaList", $mod.TObject, function () {',
  12381. '});',
  12382. 'rtl.createClass($mod, "TBetaList", $mod.TObject, function () {',
  12383. '});',
  12384. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  12385. ' this.DoIt = function () {',
  12386. ' var List = null;',
  12387. ' if (List.GetAlphas(true).GetBetas(3) === null) ;',
  12388. ' List.GetAlphas(false).SetBetas(5, null);',
  12389. ' };',
  12390. '});',
  12391. 'this.List = null;',
  12392. '']),
  12393. LinesToStr([ // $mod.$main
  12394. 'if ($mod.List.GetAlphas(true).GetBetas(3) === null) ;',
  12395. '$mod.List.GetAlphas(false).SetBetas(5, null);',
  12396. '']));
  12397. end;
  12398. procedure TTestModule.TestClass_PropertyOverride;
  12399. begin
  12400. StartProgram(false);
  12401. Add('type');
  12402. Add(' integer = longint;');
  12403. Add(' TObject = class');
  12404. Add(' FItem: integer;');
  12405. Add(' function GetItem: integer; external name ''GetItem'';');
  12406. Add(' procedure SetItem(Value: integer); external name ''SetItem'';');
  12407. Add(' property Item: integer read getitem write setitem;');
  12408. Add(' end;');
  12409. Add(' TCar = class');
  12410. Add(' FBag: integer;');
  12411. Add(' function GetBag: integer; external name ''GetBag'';');
  12412. Add(' property Item read getbag;');
  12413. Add(' end;');
  12414. Add('var');
  12415. Add(' Obj: tobject;');
  12416. Add(' Car: tcar;');
  12417. Add('begin');
  12418. Add(' Obj.Item:=Obj.Item;');
  12419. Add(' Car.Item:=Car.Item;');
  12420. ConvertProgram;
  12421. CheckSource('TestClass_PropertyOverride',
  12422. LinesToStr([ // statements
  12423. 'rtl.createClass($mod, "TObject", null, function () {',
  12424. ' this.$init = function () {',
  12425. ' this.FItem = 0;',
  12426. ' };',
  12427. ' this.$final = function () {',
  12428. ' };',
  12429. '});',
  12430. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  12431. ' this.$init = function () {',
  12432. ' $mod.TObject.$init.call(this);',
  12433. ' this.FBag = 0;',
  12434. ' };',
  12435. '});',
  12436. 'this.Obj = null;',
  12437. 'this.Car = null;',
  12438. '']),
  12439. LinesToStr([ // $mod.$main
  12440. '$mod.Obj.SetItem($mod.Obj.GetItem());',
  12441. '$mod.Car.SetItem($mod.Car.GetBag());',
  12442. '']));
  12443. end;
  12444. procedure TTestModule.TestClass_PropertyIncVisibility;
  12445. begin
  12446. AddModuleWithIntfImplSrc('unit1.pp',
  12447. LinesToStr([
  12448. 'type',
  12449. ' TNumber = longint;',
  12450. ' TInteger = longint;',
  12451. ' TObject = class',
  12452. ' private',
  12453. ' function GetItems(Index: TNumber): TInteger; virtual; abstract;',
  12454. ' procedure SetItems(Index: TInteger; Value: TNumber); virtual; abstract;',
  12455. ' protected',
  12456. ' property Items[Index: TNumber]: longint read GetItems write SetItems;',
  12457. ' end;']),
  12458. LinesToStr([
  12459. '']));
  12460. StartProgram(true);
  12461. Add([
  12462. 'uses unit1;',
  12463. 'type',
  12464. ' TBird = class',
  12465. ' public',
  12466. ' property Items;',
  12467. ' end;',
  12468. 'procedure DoIt(i: TInteger);',
  12469. 'begin',
  12470. 'end;',
  12471. 'var b: TBird;',
  12472. 'begin',
  12473. ' b.Items[1]:=2;',
  12474. ' b.Items[3]:=b.Items[4];',
  12475. ' DoIt(b.Items[5]);',
  12476. '']);
  12477. ConvertProgram;
  12478. CheckSource('TestClass_PropertyIncVisibility',
  12479. LinesToStr([ // statements
  12480. 'rtl.createClass($mod, "TBird", pas.unit1.TObject, function () {',
  12481. '});',
  12482. 'this.DoIt = function (i) {',
  12483. '};',
  12484. 'this.b = null;'
  12485. ]),
  12486. LinesToStr([ // $mod.$main
  12487. '$mod.b.SetItems(1, 2);',
  12488. '$mod.b.SetItems(3, $mod.b.GetItems(4));',
  12489. '$mod.DoIt($mod.b.GetItems(5));'
  12490. ]));
  12491. end;
  12492. procedure TTestModule.TestClass_Assigned;
  12493. begin
  12494. StartProgram(false);
  12495. Add('type');
  12496. Add(' TObject = class');
  12497. Add(' end;');
  12498. Add('var');
  12499. Add(' Obj: tobject;');
  12500. Add(' b: boolean;');
  12501. Add('begin');
  12502. Add(' if Assigned(obj) then ;');
  12503. Add(' b:=Assigned(obj) or false;');
  12504. ConvertProgram;
  12505. CheckSource('TestClass_Assigned',
  12506. LinesToStr([ // statements
  12507. 'rtl.createClass($mod, "TObject", null, function () {',
  12508. ' this.$init = function () {',
  12509. ' };',
  12510. ' this.$final = function () {',
  12511. ' };',
  12512. '});',
  12513. 'this.Obj = null;',
  12514. 'this.b = false;'
  12515. ]),
  12516. LinesToStr([ // $mod.$main
  12517. 'if ($mod.Obj != null);',
  12518. '$mod.b = ($mod.Obj != null) || false;'
  12519. ]));
  12520. end;
  12521. procedure TTestModule.TestClass_WithClassDoCreate;
  12522. begin
  12523. StartProgram(false);
  12524. Add('type');
  12525. Add(' TObject = class');
  12526. Add(' aBool: boolean;');
  12527. Add(' Arr: array of boolean;');
  12528. Add(' constructor Create;');
  12529. Add(' end;');
  12530. Add('constructor TObject.Create; begin end;');
  12531. Add('var');
  12532. Add(' Obj: tobject;');
  12533. Add(' b: boolean;');
  12534. Add('begin');
  12535. Add(' with tobject.create do begin');
  12536. Add(' b:=abool;');
  12537. Add(' abool:=b;');
  12538. Add(' b:=arr[1];');
  12539. Add(' arr[2]:=b;');
  12540. Add(' end;');
  12541. Add(' with tobject do');
  12542. Add(' obj:=create;');
  12543. Add(' with obj do begin');
  12544. Add(' create;');
  12545. Add(' b:=abool;');
  12546. Add(' abool:=b;');
  12547. Add(' b:=arr[3];');
  12548. Add(' arr[4]:=b;');
  12549. Add(' end;');
  12550. ConvertProgram;
  12551. CheckSource('TestClass_WithClassDoCreate',
  12552. LinesToStr([ // statements
  12553. 'rtl.createClass($mod, "TObject", null, function () {',
  12554. ' this.$init = function () {',
  12555. ' this.aBool = false;',
  12556. ' this.Arr = [];',
  12557. ' };',
  12558. ' this.$final = function () {',
  12559. ' this.Arr = undefined;',
  12560. ' };',
  12561. ' this.Create = function () {',
  12562. ' return this;',
  12563. ' };',
  12564. '});',
  12565. 'this.Obj = null;',
  12566. 'this.b = false;'
  12567. ]),
  12568. LinesToStr([ // $mod.$main
  12569. 'var $with1 = $mod.TObject.$create("Create");',
  12570. '$mod.b = $with1.aBool;',
  12571. '$with1.aBool = $mod.b;',
  12572. '$mod.b = $with1.Arr[1];',
  12573. '$with1.Arr[2] = $mod.b;',
  12574. 'var $with2 = $mod.TObject;',
  12575. '$mod.Obj = $with2.$create("Create");',
  12576. 'var $with3 = $mod.Obj;',
  12577. '$with3.Create();',
  12578. '$mod.b = $with3.aBool;',
  12579. '$with3.aBool = $mod.b;',
  12580. '$mod.b = $with3.Arr[3];',
  12581. '$with3.Arr[4] = $mod.b;',
  12582. '']));
  12583. end;
  12584. procedure TTestModule.TestClass_WithClassInstDoProperty;
  12585. begin
  12586. StartProgram(false);
  12587. Add('type');
  12588. Add(' TObject = class');
  12589. Add(' FInt: longint;');
  12590. Add(' constructor Create;');
  12591. Add(' function GetSize: longint;');
  12592. Add(' procedure SetSize(Value: longint);');
  12593. Add(' property Int: longint read FInt write FInt;');
  12594. Add(' property Size: longint read GetSize write SetSize;');
  12595. Add(' end;');
  12596. Add('constructor TObject.Create; begin end;');
  12597. Add('function TObject.GetSize: longint; begin; end;');
  12598. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  12599. Add('var');
  12600. Add(' Obj: tobject;');
  12601. Add(' i: longint;');
  12602. Add('begin');
  12603. Add(' with TObject.Create do begin');
  12604. Add(' i:=int;');
  12605. Add(' int:=i;');
  12606. Add(' i:=size;');
  12607. Add(' size:=i;');
  12608. Add(' end;');
  12609. Add(' with obj do begin');
  12610. Add(' i:=int;');
  12611. Add(' int:=i;');
  12612. Add(' i:=size;');
  12613. Add(' size:=i;');
  12614. Add(' end;');
  12615. ConvertProgram;
  12616. CheckSource('TestClass_WithClassInstDoProperty',
  12617. LinesToStr([ // statements
  12618. 'rtl.createClass($mod, "TObject", null, function () {',
  12619. ' this.$init = function () {',
  12620. ' this.FInt = 0;',
  12621. ' };',
  12622. ' this.$final = function () {',
  12623. ' };',
  12624. ' this.Create = function () {',
  12625. ' return this;',
  12626. ' };',
  12627. ' this.GetSize = function () {',
  12628. ' var Result = 0;',
  12629. ' return Result;',
  12630. ' };',
  12631. ' this.SetSize = function (Value) {',
  12632. ' };',
  12633. '});',
  12634. 'this.Obj = null;',
  12635. 'this.i = 0;'
  12636. ]),
  12637. LinesToStr([ // $mod.$main
  12638. 'var $with1 = $mod.TObject.$create("Create");',
  12639. '$mod.i = $with1.FInt;',
  12640. '$with1.FInt = $mod.i;',
  12641. '$mod.i = $with1.GetSize();',
  12642. '$with1.SetSize($mod.i);',
  12643. 'var $with2 = $mod.Obj;',
  12644. '$mod.i = $with2.FInt;',
  12645. '$with2.FInt = $mod.i;',
  12646. '$mod.i = $with2.GetSize();',
  12647. '$with2.SetSize($mod.i);',
  12648. '']));
  12649. end;
  12650. procedure TTestModule.TestClass_WithClassInstDoPropertyWithParams;
  12651. begin
  12652. StartProgram(false);
  12653. Add('type');
  12654. Add(' TObject = class');
  12655. Add(' constructor Create;');
  12656. Add(' function GetItems(Index: longint): longint;');
  12657. Add(' procedure SetItems(Index, Value: longint);');
  12658. Add(' property Items[Index: longint]: longint read GetItems write SetItems;');
  12659. Add(' end;');
  12660. Add('constructor TObject.Create; begin end;');
  12661. Add('function tobject.getitems(index: longint): longint; begin; end;');
  12662. Add('procedure tobject.setitems(index, value: longint); begin; end;');
  12663. Add('var');
  12664. Add(' Obj: tobject;');
  12665. Add(' i: longint;');
  12666. Add('begin');
  12667. Add(' with TObject.Create do begin');
  12668. Add(' i:=Items[1];');
  12669. Add(' Items[2]:=i;');
  12670. Add(' end;');
  12671. Add(' with obj do begin');
  12672. Add(' i:=Items[3];');
  12673. Add(' Items[4]:=i;');
  12674. Add(' end;');
  12675. ConvertProgram;
  12676. CheckSource('TestClass_WithClassInstDoPropertyWithParams',
  12677. LinesToStr([ // statements
  12678. 'rtl.createClass($mod, "TObject", null, function () {',
  12679. ' this.$init = function () {',
  12680. ' };',
  12681. ' this.$final = function () {',
  12682. ' };',
  12683. ' this.Create = function () {',
  12684. ' return this;',
  12685. ' };',
  12686. ' this.GetItems = function (Index) {',
  12687. ' var Result = 0;',
  12688. ' return Result;',
  12689. ' };',
  12690. ' this.SetItems = function (Index, Value) {',
  12691. ' };',
  12692. '});',
  12693. 'this.Obj = null;',
  12694. 'this.i = 0;'
  12695. ]),
  12696. LinesToStr([ // $mod.$main
  12697. 'var $with1 = $mod.TObject.$create("Create");',
  12698. '$mod.i = $with1.GetItems(1);',
  12699. '$with1.SetItems(2, $mod.i);',
  12700. 'var $with2 = $mod.Obj;',
  12701. '$mod.i = $with2.GetItems(3);',
  12702. '$with2.SetItems(4, $mod.i);',
  12703. '']));
  12704. end;
  12705. procedure TTestModule.TestClass_WithClassInstDoFunc;
  12706. begin
  12707. StartProgram(false);
  12708. Add('type');
  12709. Add(' TObject = class');
  12710. Add(' constructor Create;');
  12711. Add(' function GetSize: longint;');
  12712. Add(' procedure SetSize(Value: longint);');
  12713. Add(' end;');
  12714. Add('constructor TObject.Create; begin end;');
  12715. Add('function TObject.GetSize: longint; begin; end;');
  12716. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  12717. Add('var');
  12718. Add(' Obj: tobject;');
  12719. Add(' i: longint;');
  12720. Add('begin');
  12721. Add(' with TObject.Create do begin');
  12722. Add(' i:=GetSize;');
  12723. Add(' i:=GetSize();');
  12724. Add(' SetSize(i);');
  12725. Add(' end;');
  12726. Add(' with obj do begin');
  12727. Add(' i:=GetSize;');
  12728. Add(' i:=GetSize();');
  12729. Add(' SetSize(i);');
  12730. Add(' end;');
  12731. ConvertProgram;
  12732. CheckSource('TestClass_WithClassInstDoFunc',
  12733. LinesToStr([ // statements
  12734. 'rtl.createClass($mod, "TObject", null, function () {',
  12735. ' this.$init = function () {',
  12736. ' };',
  12737. ' this.$final = function () {',
  12738. ' };',
  12739. ' this.Create = function () {',
  12740. ' return this;',
  12741. ' };',
  12742. ' this.GetSize = function () {',
  12743. ' var Result = 0;',
  12744. ' return Result;',
  12745. ' };',
  12746. ' this.SetSize = function (Value) {',
  12747. ' };',
  12748. '});',
  12749. 'this.Obj = null;',
  12750. 'this.i = 0;'
  12751. ]),
  12752. LinesToStr([ // $mod.$main
  12753. 'var $with1 = $mod.TObject.$create("Create");',
  12754. '$mod.i = $with1.GetSize();',
  12755. '$mod.i = $with1.GetSize();',
  12756. '$with1.SetSize($mod.i);',
  12757. 'var $with2 = $mod.Obj;',
  12758. '$mod.i = $with2.GetSize();',
  12759. '$mod.i = $with2.GetSize();',
  12760. '$with2.SetSize($mod.i);',
  12761. '']));
  12762. end;
  12763. procedure TTestModule.TestClass_TypeCast;
  12764. begin
  12765. StartProgram(false);
  12766. Add('type');
  12767. Add(' TObject = class');
  12768. Add(' Next: TObject;');
  12769. Add(' constructor Create;');
  12770. Add(' end;');
  12771. Add(' TControl = class(TObject)');
  12772. Add(' Arr: array of TObject;');
  12773. Add(' function GetIt(vI: longint = 0): TObject;');
  12774. Add(' end;');
  12775. Add('constructor tobject.create; begin end;');
  12776. Add('function tcontrol.getit(vi: longint = 0): tobject; begin end;');
  12777. Add('var');
  12778. Add(' Obj: tobject;');
  12779. Add('begin');
  12780. Add(' obj:=tcontrol(obj).next;');
  12781. Add(' tcontrol(obj):=nil;');
  12782. Add(' obj:=tcontrol(obj);');
  12783. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit);');
  12784. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit());');
  12785. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit(1));');
  12786. Add(' tcontrol(obj):=tcontrol(tcontrol(tcontrol(obj).getit).arr[2]);');
  12787. ConvertProgram;
  12788. CheckSource('TestClass_TypeCast',
  12789. LinesToStr([ // statements
  12790. 'rtl.createClass($mod, "TObject", null, function () {',
  12791. ' this.$init = function () {',
  12792. ' this.Next = null;',
  12793. ' };',
  12794. ' this.$final = function () {',
  12795. ' this.Next = undefined;',
  12796. ' };',
  12797. ' this.Create = function () {',
  12798. ' return this;',
  12799. ' };',
  12800. '});',
  12801. 'rtl.createClass($mod, "TControl", $mod.TObject, function () {',
  12802. ' this.$init = function () {',
  12803. ' $mod.TObject.$init.call(this);',
  12804. ' this.Arr = [];',
  12805. ' };',
  12806. ' this.$final = function () {',
  12807. ' this.Arr = undefined;',
  12808. ' $mod.TObject.$final.call(this);',
  12809. ' };',
  12810. ' this.GetIt = function (vI) {',
  12811. ' var Result = null;',
  12812. ' return Result;',
  12813. ' };',
  12814. '});',
  12815. 'this.Obj = null;'
  12816. ]),
  12817. LinesToStr([ // $mod.$main
  12818. '$mod.Obj = $mod.Obj.Next;',
  12819. '$mod.Obj = null;',
  12820. '$mod.Obj = $mod.Obj;',
  12821. '$mod.Obj = $mod.Obj.GetIt(0);',
  12822. '$mod.Obj = $mod.Obj.GetIt(0);',
  12823. '$mod.Obj = $mod.Obj.GetIt(1);',
  12824. '$mod.Obj = $mod.Obj.GetIt(0).Arr[2];',
  12825. '']));
  12826. end;
  12827. procedure TTestModule.TestClass_TypeCastUntypedParam;
  12828. begin
  12829. StartProgram(false);
  12830. Add('type');
  12831. Add(' TObject = class end;');
  12832. Add('procedure ProcA(var A);');
  12833. Add('begin');
  12834. Add(' TObject(A):=nil;');
  12835. Add(' TObject(A):=TObject(A);');
  12836. Add(' if TObject(A)=nil then ;');
  12837. Add(' if nil=TObject(A) then ;');
  12838. Add('end;');
  12839. Add('procedure ProcB(out A);');
  12840. Add('begin');
  12841. Add(' TObject(A):=nil;');
  12842. Add(' TObject(A):=TObject(A);');
  12843. Add(' if TObject(A)=nil then ;');
  12844. Add(' if nil=TObject(A) then ;');
  12845. Add('end;');
  12846. Add('procedure ProcC(const A);');
  12847. Add('begin');
  12848. Add(' if TObject(A)=nil then ;');
  12849. Add(' if nil=TObject(A) then ;');
  12850. Add('end;');
  12851. Add('var o: TObject;');
  12852. Add('begin');
  12853. Add(' ProcA(o);');
  12854. Add(' ProcB(o);');
  12855. Add(' ProcC(o);');
  12856. ConvertProgram;
  12857. CheckSource('TestClass_TypeCastUntypedParam',
  12858. LinesToStr([ // statements
  12859. 'rtl.createClass($mod, "TObject", null, function () {',
  12860. ' this.$init = function () {',
  12861. ' };',
  12862. ' this.$final = function () {',
  12863. ' };',
  12864. '});',
  12865. 'this.ProcA = function (A) {',
  12866. ' A.set(null);',
  12867. ' A.set(A.get());',
  12868. ' if (A.get() === null);',
  12869. ' if (null === A.get());',
  12870. '};',
  12871. 'this.ProcB = function (A) {',
  12872. ' A.set(null);',
  12873. ' A.set(A.get());',
  12874. ' if (A.get() === null);',
  12875. ' if (null === A.get());',
  12876. '};',
  12877. 'this.ProcC = function (A) {',
  12878. ' if (A === null);',
  12879. ' if (null === A);',
  12880. '};',
  12881. 'this.o = null;',
  12882. '']),
  12883. LinesToStr([ // $mod.$main
  12884. '$mod.ProcA({',
  12885. ' p: $mod,',
  12886. ' get: function () {',
  12887. ' return this.p.o;',
  12888. ' },',
  12889. ' set: function (v) {',
  12890. ' this.p.o = v;',
  12891. ' }',
  12892. '});',
  12893. '$mod.ProcB({',
  12894. ' p: $mod,',
  12895. ' get: function () {',
  12896. ' return this.p.o;',
  12897. ' },',
  12898. ' set: function (v) {',
  12899. ' this.p.o = v;',
  12900. ' }',
  12901. '});',
  12902. '$mod.ProcC($mod.o);',
  12903. '']));
  12904. end;
  12905. procedure TTestModule.TestClass_Overloads;
  12906. begin
  12907. StartProgram(false);
  12908. Add('type');
  12909. Add(' TObject = class');
  12910. Add(' procedure DoIt;');
  12911. Add(' procedure DoIt(vI: longint);');
  12912. Add(' end;');
  12913. Add('procedure TObject.DoIt;');
  12914. Add('begin');
  12915. Add(' DoIt;');
  12916. Add(' DoIt(1);');
  12917. Add('end;');
  12918. Add('procedure TObject.DoIt(vI: longint); begin end;');
  12919. Add('begin');
  12920. ConvertProgram;
  12921. CheckSource('TestClass_Overloads',
  12922. LinesToStr([ // statements
  12923. 'rtl.createClass($mod, "TObject", null, function () {',
  12924. ' this.$init = function () {',
  12925. ' };',
  12926. ' this.$final = function () {',
  12927. ' };',
  12928. ' this.DoIt = function () {',
  12929. ' this.DoIt();',
  12930. ' this.DoIt$1(1);',
  12931. ' };',
  12932. ' this.DoIt$1 = function (vI) {',
  12933. ' };',
  12934. '});',
  12935. '']),
  12936. LinesToStr([ // $mod.$main
  12937. '']));
  12938. end;
  12939. procedure TTestModule.TestClass_OverloadsAncestor;
  12940. begin
  12941. StartProgram(false);
  12942. Add('type');
  12943. Add(' TObject = class;');
  12944. Add(' TObject = class');
  12945. Add(' procedure DoIt(vA: longint);');
  12946. Add(' procedure DoIt(vA, vB: longint);');
  12947. Add(' end;');
  12948. Add(' TCar = class;');
  12949. Add(' TCar = class');
  12950. Add(' procedure DoIt(vA: longint);');
  12951. Add(' procedure DoIt(vA, vB: longint);');
  12952. Add(' end;');
  12953. Add('procedure tobject.doit(va: longint);');
  12954. Add('begin');
  12955. Add(' doit(1);');
  12956. Add(' doit(1,2);');
  12957. Add('end;');
  12958. Add('procedure tobject.doit(va, vb: longint); begin end;');
  12959. Add('procedure tcar.doit(va: longint);');
  12960. Add('begin');
  12961. Add(' doit(1);');
  12962. Add(' doit(1,2);');
  12963. Add(' inherited doit(1);');
  12964. Add(' inherited doit(1,2);');
  12965. Add('end;');
  12966. Add('procedure tcar.doit(va, vb: longint); begin end;');
  12967. Add('begin');
  12968. ConvertProgram;
  12969. CheckSource('TestClass_OverloadsAncestor',
  12970. LinesToStr([ // statements
  12971. 'rtl.createClass($mod, "TObject", null, function () {',
  12972. ' this.$init = function () {',
  12973. ' };',
  12974. ' this.$final = function () {',
  12975. ' };',
  12976. ' this.DoIt = function (vA) {',
  12977. ' this.DoIt(1);',
  12978. ' this.DoIt$1(1,2);',
  12979. ' };',
  12980. ' this.DoIt$1 = function (vA, vB) {',
  12981. ' };',
  12982. '});',
  12983. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  12984. ' this.DoIt$2 = function (vA) {',
  12985. ' this.DoIt$2(1);',
  12986. ' this.DoIt$3(1, 2);',
  12987. ' $mod.TObject.DoIt.call(this, 1);',
  12988. ' $mod.TObject.DoIt$1.call(this, 1, 2);',
  12989. ' };',
  12990. ' this.DoIt$3 = function (vA, vB) {',
  12991. ' };',
  12992. '});',
  12993. '']),
  12994. LinesToStr([ // $mod.$main
  12995. '']));
  12996. end;
  12997. procedure TTestModule.TestClass_OverloadConstructor;
  12998. begin
  12999. StartProgram(false);
  13000. Add('type');
  13001. Add(' TObject = class');
  13002. Add(' constructor Create(vA: longint);');
  13003. Add(' constructor Create(vA, vB: longint);');
  13004. Add(' end;');
  13005. Add(' TCar = class');
  13006. Add(' constructor Create(vA: longint);');
  13007. Add(' constructor Create(vA, vB: longint);');
  13008. Add(' end;');
  13009. Add('constructor tobject.create(va: longint);');
  13010. Add('begin');
  13011. Add(' create(1);');
  13012. Add(' create(1,2);');
  13013. Add('end;');
  13014. Add('constructor tobject.create(va, vb: longint); begin end;');
  13015. Add('constructor tcar.create(va: longint);');
  13016. Add('begin');
  13017. Add(' create(1);');
  13018. Add(' create(1,2);');
  13019. Add(' inherited create(1);');
  13020. Add(' inherited create(1,2);');
  13021. Add('end;');
  13022. Add('constructor tcar.create(va, vb: longint); begin end;');
  13023. Add('begin');
  13024. Add(' tobject.create(1);');
  13025. Add(' tobject.create(1,2);');
  13026. Add(' tcar.create(1);');
  13027. Add(' tcar.create(1,2);');
  13028. ConvertProgram;
  13029. CheckSource('TestClass_OverloadConstructor',
  13030. LinesToStr([ // statements
  13031. 'rtl.createClass($mod, "TObject", null, function () {',
  13032. ' this.$init = function () {',
  13033. ' };',
  13034. ' this.$final = function () {',
  13035. ' };',
  13036. ' this.Create = function (vA) {',
  13037. ' this.Create(1);',
  13038. ' this.Create$1(1,2);',
  13039. ' return this;',
  13040. ' };',
  13041. ' this.Create$1 = function (vA, vB) {',
  13042. ' return this;',
  13043. ' };',
  13044. '});',
  13045. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  13046. ' this.Create$2 = function (vA) {',
  13047. ' this.Create$2(1);',
  13048. ' this.Create$3(1, 2);',
  13049. ' $mod.TObject.Create.call(this, 1);',
  13050. ' $mod.TObject.Create$1.call(this, 1, 2);',
  13051. ' return this;',
  13052. ' };',
  13053. ' this.Create$3 = function (vA, vB) {',
  13054. ' return this;',
  13055. ' };',
  13056. '});',
  13057. '']),
  13058. LinesToStr([ // $mod.$main
  13059. '$mod.TObject.$create("Create", [1]);',
  13060. '$mod.TObject.$create("Create$1", [1, 2]);',
  13061. '$mod.TCar.$create("Create$2", [1]);',
  13062. '$mod.TCar.$create("Create$3", [1, 2]);',
  13063. '']));
  13064. end;
  13065. procedure TTestModule.TestClass_OverloadDelphiOverride;
  13066. begin
  13067. StartProgram(false);
  13068. Add([
  13069. '{$mode delphi}',
  13070. 'type',
  13071. ' TObject = class end;',
  13072. ' TBird = class',
  13073. ' function {#a}GetValue: longint; overload; virtual;',
  13074. ' function {#b}GetValue(AValue: longint): longint; overload; virtual;',
  13075. ' end;',
  13076. ' TEagle = class(TBird)',
  13077. ' function {#c}GetValue: longint; overload; override;',
  13078. ' function {#d}GetValue(AValue: longint): longint; overload; override;',
  13079. ' end;',
  13080. 'function TBird.GetValue: longint;',
  13081. 'begin',
  13082. ' if 3={@a}GetValue then ;',
  13083. ' if 4={@b}GetValue(5) then ;',
  13084. 'end;',
  13085. 'function TBird.GetValue(AValue: longint): longint;',
  13086. 'begin',
  13087. 'end;',
  13088. 'function TEagle.GetValue: longint;',
  13089. 'begin',
  13090. ' if 13={@c}GetValue then ;',
  13091. ' if 14={@d}GetValue(15) then ;',
  13092. ' if 15=inherited {@a}GetValue then ;',
  13093. ' if 16=inherited {@b}GetValue(17) then ;',
  13094. 'end;',
  13095. 'function TEagle.GetValue(AValue: longint): longint;',
  13096. 'begin',
  13097. 'end;',
  13098. 'var',
  13099. ' e: TEagle;',
  13100. 'begin',
  13101. ' if 23=e.{@c}GetValue then ;',
  13102. ' if 24=e.{@d}GetValue(25) then ;']);
  13103. ConvertProgram;
  13104. CheckSource('TestClass_OverloadDelphiOverride',
  13105. LinesToStr([ // statements
  13106. 'rtl.createClass($mod, "TObject", null, function () {',
  13107. ' this.$init = function () {',
  13108. ' };',
  13109. ' this.$final = function () {',
  13110. ' };',
  13111. '});',
  13112. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  13113. ' this.GetValue = function () {',
  13114. ' var Result = 0;',
  13115. ' if (3 === this.GetValue()) ;',
  13116. ' if (4 === this.GetValue$1(5)) ;',
  13117. ' return Result;',
  13118. ' };',
  13119. ' this.GetValue$1 = function (AValue) {',
  13120. ' var Result = 0;',
  13121. ' return Result;',
  13122. ' };',
  13123. '});',
  13124. 'rtl.createClass($mod, "TEagle", $mod.TBird, function () {',
  13125. ' this.GetValue = function () {',
  13126. ' var Result = 0;',
  13127. ' if (13 === this.GetValue()) ;',
  13128. ' if (14 === this.GetValue$1(15)) ;',
  13129. ' if (15 === $mod.TBird.GetValue.call(this)) ;',
  13130. ' if (16 === $mod.TBird.GetValue$1.call(this, 17)) ;',
  13131. ' return Result;',
  13132. ' };',
  13133. ' this.GetValue$1 = function (AValue) {',
  13134. ' var Result = 0;',
  13135. ' return Result;',
  13136. ' };',
  13137. '});',
  13138. 'this.e = null;',
  13139. '']),
  13140. LinesToStr([ // $mod.$main
  13141. 'if (23 === $mod.e.GetValue()) ;',
  13142. 'if (24 === $mod.e.GetValue$1(25)) ;',
  13143. '']));
  13144. end;
  13145. procedure TTestModule.TestClass_ReintroducedVar;
  13146. begin
  13147. StartProgram(false);
  13148. Add('type');
  13149. Add(' TObject = class');
  13150. Add(' strict private');
  13151. Add(' Some: longint;');
  13152. Add(' end;');
  13153. Add(' TMobile = class');
  13154. Add(' strict private');
  13155. Add(' Some: string;');
  13156. Add(' end;');
  13157. Add(' TCar = class(tmobile)');
  13158. Add(' procedure Some;');
  13159. Add(' procedure Some(vA: longint);');
  13160. Add(' end;');
  13161. Add('procedure tcar.some;');
  13162. Add('begin');
  13163. Add(' Some;');
  13164. Add(' Some(1);');
  13165. Add('end;');
  13166. Add('procedure tcar.some(va: longint); begin end;');
  13167. Add('begin');
  13168. ConvertProgram;
  13169. CheckSource('TestClass_ReintroducedVar',
  13170. LinesToStr([ // statements
  13171. 'rtl.createClass($mod, "TObject", null, function () {',
  13172. ' this.$init = function () {',
  13173. ' this.Some = 0;',
  13174. ' };',
  13175. ' this.$final = function () {',
  13176. ' };',
  13177. '});',
  13178. 'rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
  13179. ' this.$init = function () {',
  13180. ' $mod.TObject.$init.call(this);',
  13181. ' this.Some$1 = "";',
  13182. ' };',
  13183. '});',
  13184. 'rtl.createClass($mod, "TCar", $mod.TMobile, function () {',
  13185. ' this.Some$2 = function () {',
  13186. ' this.Some$2();',
  13187. ' this.Some$3(1);',
  13188. ' };',
  13189. ' this.Some$3 = function (vA) {',
  13190. ' };',
  13191. '});',
  13192. '']),
  13193. LinesToStr([ // $mod.$main
  13194. '']));
  13195. end;
  13196. procedure TTestModule.TestClass_RaiseDescendant;
  13197. begin
  13198. StartProgram(false);
  13199. Add([
  13200. 'type',
  13201. ' TObject = class',
  13202. ' constructor Create(Msg: string);',
  13203. ' end;',
  13204. ' Exception = class',
  13205. ' end;',
  13206. ' EConvertError = class(Exception)',
  13207. ' end;',
  13208. 'constructor TObject.Create(Msg: string); begin end;',
  13209. 'function AssertConv(Msg: string = ''def''): EConvertError; begin end;',
  13210. 'begin',
  13211. ' raise Exception.Create(''Bar1'');',
  13212. ' raise EConvertError.Create(''Bar2'');',
  13213. ' raise AssertConv(''Bar2'');',
  13214. ' raise AssertConv;',
  13215. '']);
  13216. ConvertProgram;
  13217. CheckSource('TestClass_RaiseDescendant',
  13218. LinesToStr([ // statements
  13219. 'rtl.createClass($mod, "TObject", null, function () {',
  13220. ' this.$init = function () {',
  13221. ' };',
  13222. ' this.$final = function () {',
  13223. ' };',
  13224. ' this.Create = function (Msg) {',
  13225. ' return this;',
  13226. ' };',
  13227. '});',
  13228. 'rtl.createClass($mod, "Exception", $mod.TObject, function () {',
  13229. '});',
  13230. 'rtl.createClass($mod, "EConvertError", $mod.Exception, function () {',
  13231. '});',
  13232. 'this.AssertConv = function (Msg) {',
  13233. ' var Result = null;',
  13234. ' return Result;',
  13235. '};',
  13236. '']),
  13237. LinesToStr([ // $mod.$main
  13238. 'throw $mod.Exception.$create("Create",["Bar1"]);',
  13239. 'throw $mod.EConvertError.$create("Create",["Bar2"]);',
  13240. 'throw $mod.AssertConv("Bar2");',
  13241. 'throw $mod.AssertConv("def");',
  13242. '']));
  13243. end;
  13244. procedure TTestModule.TestClass_ExternalMethod;
  13245. begin
  13246. AddModuleWithIntfImplSrc('unit2.pas',
  13247. LinesToStr([
  13248. 'type',
  13249. ' TObject = class',
  13250. ' public',
  13251. ' procedure Intern; external name ''$DoIntern'';',
  13252. ' end;',
  13253. '']),
  13254. LinesToStr([
  13255. '']));
  13256. StartUnit(true);
  13257. Add('interface');
  13258. Add('uses unit2;');
  13259. Add('type');
  13260. Add(' TCar = class(TObject)');
  13261. Add(' public');
  13262. Add(' procedure Intern2; external name ''$DoIntern2'';');
  13263. Add(' procedure DoIt;');
  13264. Add(' end;');
  13265. Add('implementation');
  13266. Add('procedure tcar.doit;');
  13267. Add('begin');
  13268. Add(' Intern;');
  13269. Add(' Intern();');
  13270. Add(' Intern2;');
  13271. Add(' Intern2();');
  13272. Add('end;');
  13273. Add('var Obj: TCar;');
  13274. Add('begin');
  13275. Add(' obj.intern;');
  13276. Add(' obj.intern();');
  13277. Add(' obj.intern2;');
  13278. Add(' obj.intern2();');
  13279. Add(' obj.doit;');
  13280. Add(' obj.doit();');
  13281. Add(' with obj do begin');
  13282. Add(' Intern;');
  13283. Add(' Intern();');
  13284. Add(' Intern2;');
  13285. Add(' Intern2();');
  13286. Add(' end;');
  13287. ConvertUnit;
  13288. CheckSource('TestClass_ExternalMethod',
  13289. LinesToStr([
  13290. 'var $impl = $mod.$impl;',
  13291. 'rtl.createClass($mod, "TCar", pas.unit2.TObject, function () {',
  13292. ' this.DoIt = function () {',
  13293. ' this.$DoIntern();',
  13294. ' this.$DoIntern();',
  13295. ' this.$DoIntern2();',
  13296. ' this.$DoIntern2();',
  13297. ' };',
  13298. ' });',
  13299. '']),
  13300. LinesToStr([ // this.$init
  13301. '$impl.Obj.$DoIntern();',
  13302. '$impl.Obj.$DoIntern();',
  13303. '$impl.Obj.$DoIntern2();',
  13304. '$impl.Obj.$DoIntern2();',
  13305. '$impl.Obj.DoIt();',
  13306. '$impl.Obj.DoIt();',
  13307. 'var $with1 = $impl.Obj;',
  13308. '$with1.$DoIntern();',
  13309. '$with1.$DoIntern();',
  13310. '$with1.$DoIntern2();',
  13311. '$with1.$DoIntern2();',
  13312. '']),
  13313. LinesToStr([ // implementation
  13314. '$impl.Obj = null;',
  13315. '']) );
  13316. end;
  13317. procedure TTestModule.TestClass_ExternalVirtualNameMismatchFail;
  13318. begin
  13319. StartProgram(false);
  13320. Add('type');
  13321. Add(' TObject = class');
  13322. Add(' procedure DoIt; virtual; external name ''Foo'';');
  13323. Add(' end;');
  13324. Add('begin');
  13325. SetExpectedPasResolverError('Virtual method name must match external',
  13326. nVirtualMethodNameMustMatchExternal);
  13327. ConvertProgram;
  13328. end;
  13329. procedure TTestModule.TestClass_ExternalOverrideFail;
  13330. begin
  13331. StartProgram(false);
  13332. Add('type');
  13333. Add(' TObject = class');
  13334. Add(' procedure DoIt; virtual; external name ''DoIt'';');
  13335. Add(' end;');
  13336. Add(' TCar = class');
  13337. Add(' procedure DoIt; override; external name ''DoIt'';');
  13338. Add(' end;');
  13339. Add('begin');
  13340. SetExpectedPasResolverError('Invalid procedure modifier override,external',
  13341. nInvalidXModifierY);
  13342. ConvertProgram;
  13343. end;
  13344. procedure TTestModule.TestClass_ExternalVar;
  13345. begin
  13346. AddModuleWithIntfImplSrc('unit2.pas',
  13347. LinesToStr([
  13348. '{$modeswitch externalclass}',
  13349. 'type',
  13350. ' TObject = class',
  13351. ' public',
  13352. ' Intern: longint external name ''$Intern'';',
  13353. ' Bracket: longint external name ''["A B"]'';',
  13354. ' end;',
  13355. '']),
  13356. LinesToStr([
  13357. '']));
  13358. StartUnit(true);
  13359. Add([
  13360. 'interface',
  13361. 'uses unit2;',
  13362. '{$modeswitch externalclass}',
  13363. 'type',
  13364. ' TCar = class(tobject)',
  13365. ' public',
  13366. ' Intern2: longint external name ''$Intern2'';',
  13367. ' procedure DoIt;',
  13368. ' end;',
  13369. 'implementation',
  13370. 'procedure tcar.doit;',
  13371. 'begin',
  13372. ' Intern:=Intern+1;',
  13373. ' Intern2:=Intern2+2;',
  13374. ' Bracket:=Bracket+3;',
  13375. 'end;',
  13376. 'var Obj: TCar;',
  13377. 'begin',
  13378. ' obj.intern:=obj.intern+1;',
  13379. ' obj.intern2:=obj.intern2+2;',
  13380. ' obj.Bracket:=obj.Bracket+3;',
  13381. ' with obj do begin',
  13382. ' intern:=intern+1;',
  13383. ' intern2:=intern2+2;',
  13384. ' Bracket:=Bracket+3;',
  13385. ' end;']);
  13386. ConvertUnit;
  13387. CheckSource('TestClass_ExternalVar',
  13388. LinesToStr([
  13389. 'var $impl = $mod.$impl;',
  13390. 'rtl.createClass($mod, "TCar", pas.unit2.TObject, function () {',
  13391. ' this.DoIt = function () {',
  13392. ' this.$Intern = this.$Intern + 1;',
  13393. ' this.$Intern2 = this.$Intern2 + 2;',
  13394. ' this["A B"] = this["A B"] + 3;',
  13395. ' };',
  13396. ' });',
  13397. '']),
  13398. LinesToStr([
  13399. '$impl.Obj.$Intern = $impl.Obj.$Intern + 1;',
  13400. '$impl.Obj.$Intern2 = $impl.Obj.$Intern2 + 2;',
  13401. '$impl.Obj["A B"] = $impl.Obj["A B"] + 3;',
  13402. 'var $with1 = $impl.Obj;',
  13403. '$with1.$Intern = $with1.$Intern + 1;',
  13404. '$with1.$Intern2 = $with1.$Intern2 + 2;',
  13405. '$with1["A B"] = $with1["A B"] + 3;',
  13406. '']),
  13407. LinesToStr([ // implementation
  13408. '$impl.Obj = null;',
  13409. '']));
  13410. end;
  13411. procedure TTestModule.TestClass_Const;
  13412. begin
  13413. StartProgram(false);
  13414. Add('type');
  13415. Add(' integer = longint;');
  13416. Add(' TClass = class of TObject;');
  13417. Add(' TObject = class');
  13418. Add(' public');
  13419. Add(' const cI: integer = 3;');
  13420. Add(' procedure DoIt;');
  13421. Add(' class procedure DoMore;');
  13422. Add(' end;');
  13423. Add('implementation');
  13424. Add('procedure tobject.doit;');
  13425. Add('begin');
  13426. Add(' if cI=4 then;');
  13427. Add(' if 5=cI then;');
  13428. Add(' if Self.cI=6 then;');
  13429. Add(' if 7=Self.cI then;');
  13430. Add(' with Self do begin');
  13431. Add(' if cI=11 then;');
  13432. Add(' if 12=cI then;');
  13433. Add(' end;');
  13434. Add('end;');
  13435. Add('class procedure tobject.domore;');
  13436. Add('begin');
  13437. Add(' if cI=8 then;');
  13438. Add(' if Self.cI=9 then;');
  13439. Add(' if 10=cI then;');
  13440. Add(' if 11=Self.cI then;');
  13441. Add(' with Self do begin');
  13442. Add(' if cI=13 then;');
  13443. Add(' if 14=cI then;');
  13444. Add(' end;');
  13445. Add('end;');
  13446. Add('var');
  13447. Add(' Obj: TObject;');
  13448. Add(' Cla: TClass;');
  13449. Add('begin');
  13450. Add(' if TObject.cI=21 then ;');
  13451. Add(' if Obj.cI=22 then ;');
  13452. Add(' if Cla.cI=23 then ;');
  13453. Add(' with obj do if ci=24 then;');
  13454. Add(' with TObject do if ci=25 then;');
  13455. Add(' with Cla do if ci=26 then;');
  13456. ConvertProgram;
  13457. CheckSource('TestClass_Const',
  13458. LinesToStr([
  13459. 'rtl.createClass($mod, "TObject", null, function () {',
  13460. ' this.cI = 3;',
  13461. ' this.$init = function () {',
  13462. ' };',
  13463. ' this.$final = function () {',
  13464. ' };',
  13465. ' this.DoIt = function () {',
  13466. ' if (this.cI === 4) ;',
  13467. ' if (5 === this.cI) ;',
  13468. ' if (this.cI === 6) ;',
  13469. ' if (7 === this.cI) ;',
  13470. ' if (this.cI === 11) ;',
  13471. ' if (12 === this.cI) ;',
  13472. ' };',
  13473. ' this.DoMore = function () {',
  13474. ' if (this.cI === 8) ;',
  13475. ' if (this.cI === 9) ;',
  13476. ' if (10 === this.cI) ;',
  13477. ' if (11 === this.cI) ;',
  13478. ' if (this.cI === 13) ;',
  13479. ' if (14 === this.cI) ;',
  13480. ' };',
  13481. '});',
  13482. 'this.Obj = null;',
  13483. 'this.Cla = null;',
  13484. '']),
  13485. LinesToStr([
  13486. 'if ($mod.TObject.cI === 21) ;',
  13487. 'if ($mod.Obj.cI === 22) ;',
  13488. 'if ($mod.Cla.cI === 23) ;',
  13489. 'var $with1 = $mod.Obj;',
  13490. 'if ($with1.cI === 24) ;',
  13491. 'var $with2 = $mod.TObject;',
  13492. 'if ($with2.cI === 25) ;',
  13493. 'var $with3 = $mod.Cla;',
  13494. 'if ($with3.cI === 26) ;',
  13495. '']));
  13496. end;
  13497. procedure TTestModule.TestClass_LocalVarSelfFail;
  13498. begin
  13499. StartProgram(false);
  13500. Add([
  13501. 'type',
  13502. ' TObject = class',
  13503. ' constructor Create;',
  13504. ' end;',
  13505. 'constructor tobject.create;',
  13506. 'var self: longint;',
  13507. 'begin',
  13508. 'end',
  13509. 'begin',
  13510. '']);
  13511. SetExpectedPasResolverError('Duplicate identifier "self" at (0)',nDuplicateIdentifier);
  13512. ConvertProgram;
  13513. end;
  13514. procedure TTestModule.TestClass_ArgSelfFail;
  13515. begin
  13516. StartProgram(false);
  13517. Add([
  13518. 'type',
  13519. ' TObject = class',
  13520. ' procedure DoIt(Self: longint);',
  13521. ' end;',
  13522. 'procedure tobject.doit(self: longint);',
  13523. 'begin',
  13524. 'end',
  13525. 'begin',
  13526. '']);
  13527. SetExpectedPasResolverError('Duplicate identifier "Self" at test1.pp(5,24)',nDuplicateIdentifier);
  13528. ConvertProgram;
  13529. end;
  13530. procedure TTestModule.TestClass_NestedProcSelf;
  13531. begin
  13532. StartProgram(false);
  13533. Add([
  13534. 'type',
  13535. ' TObject = class',
  13536. ' Key: longint;',
  13537. ' class var State: longint;',
  13538. ' procedure DoIt;',
  13539. ' function GetSize: longint; virtual; abstract;',
  13540. ' procedure SetSize(Value: longint); virtual; abstract;',
  13541. ' property Size: longint read GetSize write SetSize;',
  13542. ' end;',
  13543. 'procedure tobject.doit;',
  13544. ' procedure Sub;',
  13545. ' begin',
  13546. ' key:=key+2;',
  13547. ' self.key:=self.key+3;',
  13548. ' state:=state+4;',
  13549. ' self.state:=self.state+5;',
  13550. ' tobject.state:=tobject.state+6;',
  13551. ' size:=size+7;',
  13552. ' self.size:=self.size+8;',
  13553. ' end;',
  13554. 'begin',
  13555. ' sub;',
  13556. ' key:=key+12;',
  13557. ' self.key:=self.key+13;',
  13558. ' state:=state+14;',
  13559. ' self.state:=self.state+15;',
  13560. ' tobject.state:=tobject.state+16;',
  13561. ' size:=size+17;',
  13562. ' self.size:=self.size+18;',
  13563. 'end;',
  13564. 'begin',
  13565. '']);
  13566. ConvertProgram;
  13567. CheckSource('TestClass_NestedProcSelf',
  13568. LinesToStr([ // statements
  13569. 'rtl.createClass($mod, "TObject", null, function () {',
  13570. ' this.State = 0;',
  13571. ' this.$init = function () {',
  13572. ' this.Key = 0;',
  13573. ' };',
  13574. ' this.$final = function () {',
  13575. ' };',
  13576. ' this.DoIt = function () {',
  13577. ' var $Self = this;',
  13578. ' function Sub() {',
  13579. ' $Self.Key = $Self.Key + 2;',
  13580. ' $Self.Key = $Self.Key + 3;',
  13581. ' $mod.TObject.State = $Self.State + 4;',
  13582. ' $mod.TObject.State = $Self.State + 5;',
  13583. ' $mod.TObject.State = $mod.TObject.State + 6;',
  13584. ' $Self.SetSize($Self.GetSize() + 7);',
  13585. ' $Self.SetSize($Self.GetSize() + 8);',
  13586. ' };',
  13587. ' Sub();',
  13588. ' $Self.Key = $Self.Key + 12;',
  13589. ' $Self.Key = $Self.Key + 13;',
  13590. ' $mod.TObject.State = $Self.State + 14;',
  13591. ' $mod.TObject.State = $Self.State + 15;',
  13592. ' $mod.TObject.State = $mod.TObject.State + 16;',
  13593. ' $Self.SetSize($Self.GetSize() + 17);',
  13594. ' $Self.SetSize($Self.GetSize() + 18);',
  13595. ' };',
  13596. '});',
  13597. '']),
  13598. LinesToStr([ // $mod.$main
  13599. '']));
  13600. end;
  13601. procedure TTestModule.TestClass_NestedProcSelf2;
  13602. begin
  13603. StartProgram(false);
  13604. Add([
  13605. 'type',
  13606. ' TObject = class',
  13607. ' Key: longint;',
  13608. ' class var State: longint;',
  13609. ' function GetSize: longint; virtual; abstract;',
  13610. ' procedure SetSize(Value: longint); virtual; abstract;',
  13611. ' property Size: longint read GetSize write SetSize;',
  13612. ' end;',
  13613. ' TBird = class',
  13614. ' procedure DoIt;',
  13615. ' end;',
  13616. 'procedure tbird.doit;',
  13617. ' procedure Sub;',
  13618. ' begin',
  13619. ' key:=key+2;',
  13620. ' self.key:=self.key+3;',
  13621. ' state:=state+4;',
  13622. ' self.state:=self.state+5;',
  13623. ' tobject.state:=tobject.state+6;',
  13624. ' size:=size+7;',
  13625. ' self.size:=self.size+8;',
  13626. ' end;',
  13627. 'begin',
  13628. ' sub;',
  13629. ' key:=key+12;',
  13630. ' self.key:=self.key+13;',
  13631. ' state:=state+14;',
  13632. ' self.state:=self.state+15;',
  13633. ' tobject.state:=tobject.state+16;',
  13634. ' size:=size+17;',
  13635. ' self.size:=self.size+18;',
  13636. 'end;',
  13637. 'begin',
  13638. '']);
  13639. ConvertProgram;
  13640. CheckSource('TestClass_NestedProcSelf2',
  13641. LinesToStr([ // statements
  13642. 'rtl.createClass($mod, "TObject", null, function () {',
  13643. ' this.State = 0;',
  13644. ' this.$init = function () {',
  13645. ' this.Key = 0;',
  13646. ' };',
  13647. ' this.$final = function () {',
  13648. ' };',
  13649. '});',
  13650. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  13651. ' this.DoIt = function () {',
  13652. ' var $Self = this;',
  13653. ' function Sub() {',
  13654. ' $Self.Key = $Self.Key + 2;',
  13655. ' $Self.Key = $Self.Key + 3;',
  13656. ' $mod.TObject.State = $Self.State + 4;',
  13657. ' $mod.TObject.State = $Self.State + 5;',
  13658. ' $mod.TObject.State = $mod.TObject.State + 6;',
  13659. ' $Self.SetSize($Self.GetSize() + 7);',
  13660. ' $Self.SetSize($Self.GetSize() + 8);',
  13661. ' };',
  13662. ' Sub();',
  13663. ' $Self.Key = $Self.Key + 12;',
  13664. ' $Self.Key = $Self.Key + 13;',
  13665. ' $mod.TObject.State = $Self.State + 14;',
  13666. ' $mod.TObject.State = $Self.State + 15;',
  13667. ' $mod.TObject.State = $mod.TObject.State + 16;',
  13668. ' $Self.SetSize($Self.GetSize() + 17);',
  13669. ' $Self.SetSize($Self.GetSize() + 18);',
  13670. ' };',
  13671. '});',
  13672. '']),
  13673. LinesToStr([ // $mod.$main
  13674. '']));
  13675. end;
  13676. procedure TTestModule.TestClass_NestedProcClassSelf;
  13677. begin
  13678. StartProgram(false);
  13679. Add([
  13680. 'type',
  13681. ' TObject = class',
  13682. ' class var State: longint;',
  13683. ' class procedure DoIt;',
  13684. ' class function GetSize: longint; virtual; abstract;',
  13685. ' class procedure SetSize(Value: longint); virtual; abstract;',
  13686. ' class property Size: longint read GetSize write SetSize;',
  13687. ' end;',
  13688. 'class procedure tobject.doit;',
  13689. ' procedure Sub;',
  13690. ' begin',
  13691. ' state:=state+2;',
  13692. ' self.state:=self.state+3;',
  13693. ' tobject.state:=tobject.state+4;',
  13694. ' size:=size+5;',
  13695. ' self.size:=self.size+6;',
  13696. ' tobject.size:=tobject.size+7;',
  13697. ' end;',
  13698. 'begin',
  13699. ' sub;',
  13700. ' state:=state+12;',
  13701. ' self.state:=self.state+13;',
  13702. ' tobject.state:=tobject.state+14;',
  13703. ' size:=size+15;',
  13704. ' self.size:=self.size+16;',
  13705. ' tobject.size:=tobject.size+17;',
  13706. 'end;',
  13707. 'begin',
  13708. '']);
  13709. ConvertProgram;
  13710. CheckSource('TestClass_NestedProcClassSelf',
  13711. LinesToStr([ // statements
  13712. 'rtl.createClass($mod, "TObject", null, function () {',
  13713. ' this.State = 0;',
  13714. ' this.$init = function () {',
  13715. ' };',
  13716. ' this.$final = function () {',
  13717. ' };',
  13718. ' this.DoIt = function () {',
  13719. ' var $Self = this;',
  13720. ' function Sub() {',
  13721. ' $mod.TObject.State = $Self.State + 2;',
  13722. ' $mod.TObject.State = $Self.State + 3;',
  13723. ' $mod.TObject.State = $mod.TObject.State + 4;',
  13724. ' $Self.SetSize($Self.GetSize() + 5);',
  13725. ' $Self.SetSize($Self.GetSize() + 6);',
  13726. ' $mod.TObject.SetSize($mod.TObject.GetSize() + 7);',
  13727. ' };',
  13728. ' Sub();',
  13729. ' $mod.TObject.State = $Self.State + 12;',
  13730. ' $mod.TObject.State = $Self.State + 13;',
  13731. ' $mod.TObject.State = $mod.TObject.State + 14;',
  13732. ' $Self.SetSize($Self.GetSize() + 15);',
  13733. ' $Self.SetSize($Self.GetSize() + 16);',
  13734. ' $mod.TObject.SetSize($mod.TObject.GetSize() + 17);',
  13735. ' };',
  13736. '});',
  13737. '']),
  13738. LinesToStr([ // $mod.$main
  13739. '']));
  13740. end;
  13741. procedure TTestModule.TestClass_NestedProcCallInherited;
  13742. begin
  13743. StartProgram(false);
  13744. Add([
  13745. 'type',
  13746. ' TObject = class',
  13747. ' function DoIt(k: boolean): longint; virtual;',
  13748. ' end;',
  13749. ' TBird = class',
  13750. ' function DoIt(k: boolean): longint; override;',
  13751. ' end;',
  13752. 'function tobject.doit(k: boolean): longint;',
  13753. 'begin',
  13754. 'end;',
  13755. 'function tbird.doit(k: boolean): longint;',
  13756. ' procedure Sub;',
  13757. ' begin',
  13758. ' inherited DoIt(true);',
  13759. //' if inherited DoIt(false)=4 then ;',
  13760. ' end;',
  13761. 'begin',
  13762. ' Sub;',
  13763. ' inherited;',
  13764. ' inherited DoIt(true);',
  13765. //' if inherited DoIt(false)=14 then ;',
  13766. 'end;',
  13767. 'begin',
  13768. '']);
  13769. ConvertProgram;
  13770. CheckSource('TestClass_NestedProcCallInherited',
  13771. LinesToStr([ // statements
  13772. 'rtl.createClass($mod, "TObject", null, function () {',
  13773. ' this.$init = function () {',
  13774. ' };',
  13775. ' this.$final = function () {',
  13776. ' };',
  13777. ' this.DoIt = function (k) {',
  13778. ' var Result = 0;',
  13779. ' return Result;',
  13780. ' };',
  13781. '});',
  13782. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  13783. ' this.DoIt = function (k) {',
  13784. ' var $Self = this;',
  13785. ' var Result = 0;',
  13786. ' function Sub() {',
  13787. ' $mod.TObject.DoIt.call($Self, true);',
  13788. ' };',
  13789. ' Sub();',
  13790. ' $mod.TObject.DoIt.apply($Self, arguments);',
  13791. ' $mod.TObject.DoIt.call($Self, true);',
  13792. ' return Result;',
  13793. ' };',
  13794. '});',
  13795. '']),
  13796. LinesToStr([ // $mod.$main
  13797. '']));
  13798. end;
  13799. procedure TTestModule.TestClass_TObjectFree;
  13800. begin
  13801. StartProgram(false);
  13802. Add([
  13803. 'type',
  13804. ' TObject = class',
  13805. ' Obj: tobject;',
  13806. ' procedure Free;',
  13807. ' procedure Release;',
  13808. ' end;',
  13809. 'procedure tobject.free;',
  13810. 'begin',
  13811. 'end;',
  13812. 'procedure tobject.release;',
  13813. 'begin',
  13814. ' free;',
  13815. ' if true then free;',
  13816. 'end;',
  13817. 'function DoIt(o: tobject): tobject;',
  13818. 'var l: tobject;',
  13819. 'begin',
  13820. ' o.free;',
  13821. ' o.free();',
  13822. ' l.free;',
  13823. ' l.free();',
  13824. ' o.obj.free;',
  13825. ' o.obj.free();',
  13826. ' with o do obj.free;',
  13827. ' with o do obj.free();',
  13828. ' result.Free;',
  13829. ' result.Free();',
  13830. 'end;',
  13831. 'var o: tobject;',
  13832. ' a: array of tobject;',
  13833. 'begin',
  13834. ' o.free;',
  13835. ' o.obj.free;',
  13836. ' a[1+2].free;',
  13837. '']);
  13838. ConvertProgram;
  13839. CheckSource('TestClass_TObjectFree',
  13840. LinesToStr([ // statements
  13841. 'rtl.createClass($mod, "TObject", null, function () {',
  13842. ' this.$init = function () {',
  13843. ' this.Obj = null;',
  13844. ' };',
  13845. ' this.$final = function () {',
  13846. ' this.Obj = undefined;',
  13847. ' };',
  13848. ' this.Free = function () {',
  13849. ' };',
  13850. ' this.Release = function () {',
  13851. ' this.Free();',
  13852. ' if (true) this.Free();',
  13853. ' };',
  13854. '});',
  13855. 'this.DoIt = function (o) {',
  13856. ' var Result = null;',
  13857. ' var l = null;',
  13858. ' o = rtl.freeLoc(o);',
  13859. ' o = rtl.freeLoc(o);',
  13860. ' l = rtl.freeLoc(l);',
  13861. ' l = rtl.freeLoc(l);',
  13862. ' rtl.free(o, "Obj");',
  13863. ' rtl.free(o, "Obj");',
  13864. ' rtl.free(o, "Obj");',
  13865. ' rtl.free(o, "Obj");',
  13866. ' Result = rtl.freeLoc(Result);',
  13867. ' Result = rtl.freeLoc(Result);',
  13868. ' return Result;',
  13869. '};',
  13870. 'this.o = null;',
  13871. 'this.a = [];',
  13872. '']),
  13873. LinesToStr([ // $mod.$main
  13874. 'rtl.free($mod, "o");',
  13875. 'rtl.free($mod.o, "Obj");',
  13876. 'rtl.free($mod.a, 1 + 2);',
  13877. '']));
  13878. end;
  13879. procedure TTestModule.TestClass_TObjectFree_VarArg;
  13880. begin
  13881. StartProgram(false);
  13882. Add([
  13883. 'type',
  13884. ' TObject = class',
  13885. ' Obj: tobject;',
  13886. ' procedure Free;',
  13887. ' end;',
  13888. 'procedure tobject.free;',
  13889. 'begin',
  13890. 'end;',
  13891. 'procedure DoIt(var o: tobject);',
  13892. 'begin',
  13893. ' o.free;',
  13894. ' o.free();',
  13895. 'end;',
  13896. 'begin',
  13897. '']);
  13898. ConvertProgram;
  13899. CheckSource('TestClass_TObjectFree_VarArg',
  13900. LinesToStr([ // statements
  13901. 'rtl.createClass($mod, "TObject", null, function () {',
  13902. ' this.$init = function () {',
  13903. ' this.Obj = null;',
  13904. ' };',
  13905. ' this.$final = function () {',
  13906. ' this.Obj = undefined;',
  13907. ' };',
  13908. ' this.Free = function () {',
  13909. ' };',
  13910. '});',
  13911. 'this.DoIt = function (o) {',
  13912. ' o.set(rtl.freeLoc(o.get()));',
  13913. ' o.set(rtl.freeLoc(o.get()));',
  13914. '};',
  13915. '']),
  13916. LinesToStr([ // $mod.$main
  13917. '']));
  13918. end;
  13919. procedure TTestModule.TestClass_TObjectFreeNewInstance;
  13920. begin
  13921. StartProgram(false);
  13922. Add([
  13923. 'type',
  13924. ' TObject = class',
  13925. ' constructor Create;',
  13926. ' procedure Free;',
  13927. ' end;',
  13928. 'constructor TObject.Create; begin end;',
  13929. 'procedure tobject.free; begin end;',
  13930. 'begin',
  13931. ' with tobject.create do free;',
  13932. '']);
  13933. ConvertProgram;
  13934. CheckSource('TestClass_TObjectFreeNewInstance',
  13935. LinesToStr([ // statements
  13936. 'rtl.createClass($mod, "TObject", null, function () {',
  13937. ' this.$init = function () {',
  13938. ' };',
  13939. ' this.$final = function () {',
  13940. ' };',
  13941. ' this.Create = function () {',
  13942. ' return this;',
  13943. ' };',
  13944. ' this.Free = function () {',
  13945. ' };',
  13946. '});',
  13947. '']),
  13948. LinesToStr([ // $mod.$main
  13949. 'var $with1 = $mod.TObject.$create("Create");',
  13950. '$with1=rtl.freeLoc($with1);',
  13951. '']));
  13952. end;
  13953. procedure TTestModule.TestClass_TObjectFreeLowerCase;
  13954. begin
  13955. StartProgram(false);
  13956. Add([
  13957. 'type',
  13958. ' TObject = class',
  13959. ' destructor Destroy;',
  13960. ' procedure Free;',
  13961. ' end;',
  13962. 'destructor TObject.Destroy; begin end;',
  13963. 'procedure tobject.free; begin end;',
  13964. 'var o: tobject;',
  13965. 'begin',
  13966. ' o.free;',
  13967. '']);
  13968. Converter.UseLowerCase:=true;
  13969. ConvertProgram;
  13970. CheckSource('TestClass_TObjectFreeLowerCase',
  13971. LinesToStr([ // statements
  13972. 'rtl.createClass($mod, "tobject", null, function () {',
  13973. ' this.$init = function () {',
  13974. ' };',
  13975. ' this.$final = function () {',
  13976. ' };',
  13977. ' rtl.tObjectDestroy = "destroy";',
  13978. ' this.destroy = function () {',
  13979. ' };',
  13980. ' this.free = function () {',
  13981. ' };',
  13982. '});',
  13983. 'this.o = null;',
  13984. '']),
  13985. LinesToStr([ // $mod.$main
  13986. 'rtl.free($mod, "o");',
  13987. '']));
  13988. end;
  13989. procedure TTestModule.TestClass_TObjectFreeFunctionFail;
  13990. begin
  13991. StartProgram(false);
  13992. Add([
  13993. 'type',
  13994. ' TObject = class',
  13995. ' procedure Free;',
  13996. ' function GetObj: tobject; virtual; abstract;',
  13997. ' end;',
  13998. 'procedure tobject.free;',
  13999. 'begin',
  14000. 'end;',
  14001. 'var o: tobject;',
  14002. 'begin',
  14003. ' o.getobj.free;',
  14004. '']);
  14005. SetExpectedPasResolverError(sFreeNeedsVar,nFreeNeedsVar);
  14006. ConvertProgram;
  14007. end;
  14008. procedure TTestModule.TestClass_TObjectFreePropertyFail;
  14009. begin
  14010. StartProgram(false);
  14011. Add([
  14012. 'type',
  14013. ' TObject = class',
  14014. ' procedure Free;',
  14015. ' FObj: TObject;',
  14016. ' property Obj: tobject read FObj write FObj;',
  14017. ' end;',
  14018. 'procedure tobject.free;',
  14019. 'begin',
  14020. 'end;',
  14021. 'var o: tobject;',
  14022. 'begin',
  14023. ' o.obj.free;',
  14024. '']);
  14025. SetExpectedPasResolverError(sFreeNeedsVar,nFreeNeedsVar);
  14026. ConvertProgram;
  14027. end;
  14028. procedure TTestModule.TestClass_ForIn;
  14029. begin
  14030. StartProgram(false);
  14031. Add([
  14032. 'type',
  14033. ' TObject = class end;',
  14034. ' TItem = TObject;',
  14035. ' TEnumerator = class',
  14036. ' FCurrent: TItem;',
  14037. ' property Current: TItem read FCurrent;',
  14038. ' function MoveNext: boolean;',
  14039. ' end;',
  14040. ' TBird = class',
  14041. ' function GetEnumerator: TEnumerator;',
  14042. ' end;',
  14043. 'function TEnumerator.MoveNext: boolean;',
  14044. 'begin',
  14045. 'end;',
  14046. 'function TBird.GetEnumerator: TEnumerator;',
  14047. 'begin',
  14048. 'end;',
  14049. 'var',
  14050. ' b: TBird;',
  14051. ' i, i2: TItem;',
  14052. 'begin',
  14053. ' for i in b do i2:=i;']);
  14054. ConvertProgram;
  14055. CheckSource('TestClass_ForIn',
  14056. LinesToStr([ // statements
  14057. 'rtl.createClass($mod, "TObject", null, function () {',
  14058. ' this.$init = function () {',
  14059. ' };',
  14060. ' this.$final = function () {',
  14061. ' };',
  14062. '});',
  14063. 'rtl.createClass($mod, "TEnumerator", $mod.TObject, function () {',
  14064. ' this.$init = function () {',
  14065. ' $mod.TObject.$init.call(this);',
  14066. ' this.FCurrent = null;',
  14067. ' };',
  14068. ' this.$final = function () {',
  14069. ' this.FCurrent = undefined;',
  14070. ' $mod.TObject.$final.call(this);',
  14071. ' };',
  14072. ' this.MoveNext = function () {',
  14073. ' var Result = false;',
  14074. ' return Result;',
  14075. ' };',
  14076. '});',
  14077. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  14078. ' this.GetEnumerator = function () {',
  14079. ' var Result = null;',
  14080. ' return Result;',
  14081. ' };',
  14082. '});',
  14083. 'this.b = null;',
  14084. 'this.i = null;',
  14085. 'this.i2 = null;'
  14086. ]),
  14087. LinesToStr([ // $mod.$main
  14088. 'var $in1 = $mod.b.GetEnumerator();',
  14089. 'try {',
  14090. ' while ($in1.MoveNext()){',
  14091. ' $mod.i = $in1.FCurrent;',
  14092. ' $mod.i2 = $mod.i;',
  14093. ' }',
  14094. '} finally {',
  14095. ' $in1 = rtl.freeLoc($in1)',
  14096. '};',
  14097. '']));
  14098. end;
  14099. procedure TTestModule.TestClass_DispatchMessage;
  14100. begin
  14101. StartProgram(false);
  14102. Add([
  14103. 'type',
  14104. ' TObject = class',
  14105. ' {$DispatchField DispInt}',
  14106. ' procedure Dispatch(var Msg); virtual; abstract;',
  14107. ' {$DispatchStrField DispStr}',
  14108. ' procedure DispatchStr(var Msg); virtual; abstract;',
  14109. ' end;',
  14110. ' THopMsg = record',
  14111. ' DispInt: longint;',
  14112. ' end;',
  14113. ' TPutMsg = record',
  14114. ' DispStr: string;',
  14115. ' end;',
  14116. ' TBird = class',
  14117. ' procedure Fly(var Msg); virtual; abstract; message 2;',
  14118. ' procedure Run; overload; virtual; abstract;',
  14119. ' procedure Run(var Msg); overload; message ''Fast'';',
  14120. ' procedure Hop(var Msg: THopMsg); virtual; abstract; message 3;',
  14121. ' procedure Put(var Msg: TPutMsg); virtual; abstract; message ''foo'';',
  14122. ' end;',
  14123. 'procedure TBird.Run(var Msg);',
  14124. 'begin',
  14125. 'end;',
  14126. 'begin',
  14127. '']);
  14128. ConvertProgram;
  14129. CheckSource('TestClass_Message',
  14130. LinesToStr([ // statements
  14131. 'rtl.createClass($mod, "TObject", null, function () {',
  14132. ' this.$init = function () {',
  14133. ' };',
  14134. ' this.$final = function () {',
  14135. ' };',
  14136. '});',
  14137. 'rtl.recNewT($mod, "THopMsg", function () {',
  14138. ' this.DispInt = 0;',
  14139. ' this.$eq = function (b) {',
  14140. ' return this.DispInt === b.DispInt;',
  14141. ' };',
  14142. ' this.$assign = function (s) {',
  14143. ' this.DispInt = s.DispInt;',
  14144. ' return this;',
  14145. ' };',
  14146. '});',
  14147. 'rtl.recNewT($mod, "TPutMsg", function () {',
  14148. ' this.DispStr = "";',
  14149. ' this.$eq = function (b) {',
  14150. ' return this.DispStr === b.DispStr;',
  14151. ' };',
  14152. ' this.$assign = function (s) {',
  14153. ' this.DispStr = s.DispStr;',
  14154. ' return this;',
  14155. ' };',
  14156. '});',
  14157. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  14158. ' this.Run$1 = function (Msg) {',
  14159. ' };',
  14160. ' this.$msgint = {',
  14161. ' "2": "Fly",',
  14162. ' "3": "Hop"',
  14163. ' };',
  14164. ' this.$msgstr = {',
  14165. ' Fast: "Run$1",',
  14166. ' foo: "Put"',
  14167. ' };',
  14168. '});',
  14169. '']),
  14170. LinesToStr([ // $mod.$main
  14171. '']));
  14172. end;
  14173. procedure TTestModule.TestClass_Message_DuplicateIntFail;
  14174. begin
  14175. StartProgram(false);
  14176. Add([
  14177. 'type',
  14178. ' TObject = class',
  14179. ' procedure Fly(var Msg); virtual; abstract; message 3;',
  14180. ' procedure Run(var Msg); virtual; abstract; message 1+2;',
  14181. ' end;',
  14182. 'begin',
  14183. '']);
  14184. SetExpectedPasResolverError('Duplicate message id "3" at test1.pp(5,56)',nDuplicateMessageIdXAtY);
  14185. ConvertProgram;
  14186. end;
  14187. procedure TTestModule.TestClass_DispatchMessage_WrongFieldNameFail;
  14188. begin
  14189. StartProgram(false);
  14190. Add([
  14191. 'type',
  14192. ' TObject = class',
  14193. ' {$dispatchfield Msg}',
  14194. ' procedure Dispatch(var Msg); virtual; abstract;',
  14195. ' end;',
  14196. ' TFlyMsg = record',
  14197. ' FlyId: longint;',
  14198. ' end;',
  14199. ' TBird = class',
  14200. ' procedure Fly(var Msg: TFlyMsg); virtual; abstract; message 3;',
  14201. ' end;',
  14202. 'begin',
  14203. '']);
  14204. ConvertProgram;
  14205. CheckHint(mtWarning,nDispatchRequiresX,'Dispatch requires record field "Msg"');
  14206. end;
  14207. procedure TTestModule.TestClassOf_Create;
  14208. begin
  14209. StartProgram(false);
  14210. Add('type');
  14211. Add(' TObject = class');
  14212. Add(' constructor Create;');
  14213. Add(' end;');
  14214. Add(' TClass = class of TObject;');
  14215. Add('constructor tobject.create; begin end;');
  14216. Add('var');
  14217. Add(' Obj: tobject;');
  14218. Add(' C: tclass;');
  14219. Add('begin');
  14220. Add(' obj:=C.create;');
  14221. Add(' with c do obj:=create;');
  14222. ConvertProgram;
  14223. CheckSource('TestClassOf_Create',
  14224. LinesToStr([ // statements
  14225. 'rtl.createClass($mod, "TObject", null, function () {',
  14226. ' this.$init = function () {',
  14227. ' };',
  14228. ' this.$final = function () {',
  14229. ' };',
  14230. ' this.Create = function () {',
  14231. ' return this;',
  14232. ' };',
  14233. '});',
  14234. 'this.Obj = null;',
  14235. 'this.C = null;'
  14236. ]),
  14237. LinesToStr([ // $mod.$main
  14238. '$mod.Obj = $mod.C.$create("Create");',
  14239. 'var $with1 = $mod.C;',
  14240. '$mod.Obj = $with1.$create("Create");',
  14241. '']));
  14242. end;
  14243. procedure TTestModule.TestClassOf_Call;
  14244. begin
  14245. StartProgram(false);
  14246. Add('type');
  14247. Add(' TObject = class');
  14248. Add(' class procedure DoIt;');
  14249. Add(' end;');
  14250. Add(' TClass = class of TObject;');
  14251. Add('class procedure tobject.doit; begin end;');
  14252. Add('var');
  14253. Add(' C: tclass;');
  14254. Add('begin');
  14255. Add(' c.doit;');
  14256. Add(' with c do doit;');
  14257. ConvertProgram;
  14258. CheckSource('TestClassOf_Call',
  14259. LinesToStr([ // statements
  14260. 'rtl.createClass($mod, "TObject", null, function () {',
  14261. ' this.$init = function () {',
  14262. ' };',
  14263. ' this.$final = function () {',
  14264. ' };',
  14265. ' this.DoIt = function () {',
  14266. ' };',
  14267. '});',
  14268. 'this.C = null;'
  14269. ]),
  14270. LinesToStr([ // $mod.$main
  14271. '$mod.C.DoIt();',
  14272. 'var $with1 = $mod.C;',
  14273. '$with1.DoIt();',
  14274. '']));
  14275. end;
  14276. procedure TTestModule.TestClassOf_Assign;
  14277. begin
  14278. StartProgram(false);
  14279. Add('type');
  14280. Add(' TClass = class of TObject;');
  14281. Add(' TObject = class');
  14282. Add(' ClassType: TClass; ');
  14283. Add(' end;');
  14284. Add('var');
  14285. Add(' Obj: tobject;');
  14286. Add(' C: tclass;');
  14287. Add('begin');
  14288. Add(' c:=nil;');
  14289. Add(' c:=obj.classtype;');
  14290. ConvertProgram;
  14291. CheckSource('TestClassOf_Assign',
  14292. LinesToStr([ // statements
  14293. 'rtl.createClass($mod, "TObject", null, function () {',
  14294. ' this.$init = function () {',
  14295. ' this.ClassType = null;',
  14296. ' };',
  14297. ' this.$final = function () {',
  14298. ' this.ClassType = undefined;',
  14299. ' };',
  14300. '});',
  14301. 'this.Obj = null;',
  14302. 'this.C = null;'
  14303. ]),
  14304. LinesToStr([ // $mod.$main
  14305. '$mod.C = null;',
  14306. '$mod.C = $mod.Obj.ClassType;',
  14307. '']));
  14308. end;
  14309. procedure TTestModule.TestClassOf_Is;
  14310. begin
  14311. StartProgram(false);
  14312. Add('type');
  14313. Add(' TClass = class of TObject;');
  14314. Add(' TObject = class');
  14315. Add(' end;');
  14316. Add(' TCar = class');
  14317. Add(' end;');
  14318. Add(' TCars = class of TCar;');
  14319. Add('var');
  14320. Add(' Obj: tobject;');
  14321. Add(' C: tclass;');
  14322. Add(' Cars: tcars;');
  14323. Add('begin');
  14324. Add(' if c is tcar then ;');
  14325. Add(' if c is tcars then ;');
  14326. ConvertProgram;
  14327. CheckSource('TestClassOf_Is',
  14328. LinesToStr([ // statements
  14329. 'rtl.createClass($mod, "TObject", null, function () {',
  14330. ' this.$init = function () {',
  14331. ' };',
  14332. ' this.$final = function () {',
  14333. ' };',
  14334. '});',
  14335. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  14336. '});',
  14337. 'this.Obj = null;',
  14338. 'this.C = null;',
  14339. 'this.Cars = null;'
  14340. ]),
  14341. LinesToStr([ // $mod.$main
  14342. 'if(rtl.is($mod.C,$mod.TCar));',
  14343. 'if(rtl.is($mod.C,$mod.TCar));',
  14344. '']));
  14345. end;
  14346. procedure TTestModule.TestClassOf_Compare;
  14347. begin
  14348. StartProgram(false);
  14349. Add('type');
  14350. Add(' TClass = class of TObject;');
  14351. Add(' TObject = class');
  14352. Add(' ClassType: TClass; ');
  14353. Add(' end;');
  14354. Add('var');
  14355. Add(' b: boolean;');
  14356. Add(' Obj: tobject;');
  14357. Add(' C: tclass;');
  14358. Add('begin');
  14359. Add(' b:=c=nil;');
  14360. Add(' b:=nil=c;');
  14361. Add(' b:=c=obj.classtype;');
  14362. Add(' b:=obj.classtype=c;');
  14363. Add(' b:=c=TObject;');
  14364. Add(' b:=TObject=c;');
  14365. Add(' b:=c<>nil;');
  14366. Add(' b:=nil<>c;');
  14367. Add(' b:=c<>obj.classtype;');
  14368. Add(' b:=obj.classtype<>c;');
  14369. Add(' b:=c<>TObject;');
  14370. Add(' b:=TObject<>c;');
  14371. ConvertProgram;
  14372. CheckSource('TestClassOf_Compare',
  14373. LinesToStr([ // statements
  14374. 'rtl.createClass($mod, "TObject", null, function () {',
  14375. ' this.$init = function () {',
  14376. ' this.ClassType = null;',
  14377. ' };',
  14378. ' this.$final = function () {',
  14379. ' this.ClassType = undefined;',
  14380. ' };',
  14381. '});',
  14382. 'this.b = false;',
  14383. 'this.Obj = null;',
  14384. 'this.C = null;'
  14385. ]),
  14386. LinesToStr([ // $mod.$main
  14387. '$mod.b = $mod.C === null;',
  14388. '$mod.b = null === $mod.C;',
  14389. '$mod.b = $mod.C === $mod.Obj.ClassType;',
  14390. '$mod.b = $mod.Obj.ClassType === $mod.C;',
  14391. '$mod.b = $mod.C === $mod.TObject;',
  14392. '$mod.b = $mod.TObject === $mod.C;',
  14393. '$mod.b = $mod.C !== null;',
  14394. '$mod.b = null !== $mod.C;',
  14395. '$mod.b = $mod.C !== $mod.Obj.ClassType;',
  14396. '$mod.b = $mod.Obj.ClassType !== $mod.C;',
  14397. '$mod.b = $mod.C !== $mod.TObject;',
  14398. '$mod.b = $mod.TObject !== $mod.C;',
  14399. '']));
  14400. end;
  14401. procedure TTestModule.TestClassOf_ClassVar;
  14402. begin
  14403. StartProgram(false);
  14404. Add('type');
  14405. Add(' TObject = class');
  14406. Add(' class var id: longint;');
  14407. Add(' end;');
  14408. Add(' TClass = class of TObject;');
  14409. Add('var');
  14410. Add(' C: tclass;');
  14411. Add('begin');
  14412. Add(' C.id:=C.id;');
  14413. ConvertProgram;
  14414. CheckSource('TestClassOf_ClassVar',
  14415. LinesToStr([ // statements
  14416. 'rtl.createClass($mod, "TObject", null, function () {',
  14417. ' this.id = 0;',
  14418. ' this.$init = function () {',
  14419. ' };',
  14420. ' this.$final = function () {',
  14421. ' };',
  14422. '});',
  14423. 'this.C = null;'
  14424. ]),
  14425. LinesToStr([ // $mod.$main
  14426. '$mod.TObject.id = $mod.C.id;',
  14427. '']));
  14428. end;
  14429. procedure TTestModule.TestClassOf_ClassMethod;
  14430. begin
  14431. StartProgram(false);
  14432. Add('type');
  14433. Add(' TObject = class');
  14434. Add(' class function DoIt(i: longint = 0): longint;');
  14435. Add(' end;');
  14436. Add(' TClass = class of TObject;');
  14437. Add('class function tobject.doit(i: longint = 0): longint; begin end;');
  14438. Add('var');
  14439. Add(' i: longint;');
  14440. Add(' C: tclass;');
  14441. Add('begin');
  14442. Add(' C.DoIt;');
  14443. Add(' C.DoIt();');
  14444. Add(' i:=C.DoIt;');
  14445. Add(' i:=C.DoIt();');
  14446. ConvertProgram;
  14447. CheckSource('TestClassOf_ClassMethod',
  14448. LinesToStr([ // statements
  14449. 'rtl.createClass($mod, "TObject", null, function () {',
  14450. ' this.$init = function () {',
  14451. ' };',
  14452. ' this.$final = function () {',
  14453. ' };',
  14454. ' this.DoIt = function (i) {',
  14455. ' var Result = 0;',
  14456. ' return Result;',
  14457. ' };',
  14458. '});',
  14459. 'this.i = 0;',
  14460. 'this.C = null;'
  14461. ]),
  14462. LinesToStr([ // $mod.$main
  14463. '$mod.C.DoIt(0);',
  14464. '$mod.C.DoIt(0);',
  14465. '$mod.i = $mod.C.DoIt(0);',
  14466. '$mod.i = $mod.C.DoIt(0);',
  14467. '']));
  14468. end;
  14469. procedure TTestModule.TestClassOf_ClassProperty;
  14470. begin
  14471. StartProgram(false);
  14472. Add([
  14473. 'type',
  14474. ' TObject = class',
  14475. ' class var FA: longint;',
  14476. ' class function GetA: longint;',
  14477. ' class procedure SetA(Value: longint);',
  14478. ' class property pA: longint read fa write fa;',
  14479. ' class property pB: longint read geta write seta;',
  14480. ' end;',
  14481. ' TObjectClass = class of tobject;',
  14482. 'class function tobject.geta: longint; begin end;',
  14483. 'class procedure tobject.seta(value: longint); begin end;',
  14484. 'var',
  14485. ' b: boolean;',
  14486. ' Obj: tobject;',
  14487. ' Cla: tobjectclass;',
  14488. 'begin',
  14489. ' obj.pa:=obj.pa;',
  14490. ' obj.pb:=obj.pb;',
  14491. ' b:=obj.pa=4;',
  14492. ' b:=obj.pb=obj.pb;',
  14493. ' b:=5=obj.pa;',
  14494. ' cla.pa:=6;',
  14495. ' cla.pa:=cla.pa;',
  14496. ' cla.pb:=cla.pb;',
  14497. ' b:=cla.pa=7;',
  14498. ' b:=cla.pb=cla.pb;',
  14499. ' b:=8=cla.pa;',
  14500. ' tobject.pa:=9;',
  14501. ' tobject.pb:=tobject.pb;',
  14502. ' b:=tobject.pa=10;',
  14503. ' b:=11=tobject.pa;',
  14504. '']);
  14505. ConvertProgram;
  14506. CheckSource('TestClassOf_ClassProperty',
  14507. LinesToStr([ // statements
  14508. 'rtl.createClass($mod, "TObject", null, function () {',
  14509. ' this.FA = 0;',
  14510. ' this.$init = function () {',
  14511. ' };',
  14512. ' this.$final = function () {',
  14513. ' };',
  14514. ' this.GetA = function () {',
  14515. ' var Result = 0;',
  14516. ' return Result;',
  14517. ' };',
  14518. ' this.SetA = function (Value) {',
  14519. ' };',
  14520. '});',
  14521. 'this.b = false;',
  14522. 'this.Obj = null;',
  14523. 'this.Cla = null;'
  14524. ]),
  14525. LinesToStr([ // $mod.$main
  14526. '$mod.TObject.FA = $mod.Obj.FA;',
  14527. '$mod.Obj.$class.SetA($mod.Obj.$class.GetA());',
  14528. '$mod.b = $mod.Obj.FA === 4;',
  14529. '$mod.b = $mod.Obj.$class.GetA() === $mod.Obj.$class.GetA();',
  14530. '$mod.b = 5 === $mod.Obj.FA;',
  14531. '$mod.TObject.FA = 6;',
  14532. '$mod.TObject.FA = $mod.Cla.FA;',
  14533. '$mod.Cla.SetA($mod.Cla.GetA());',
  14534. '$mod.b = $mod.Cla.FA === 7;',
  14535. '$mod.b = $mod.Cla.GetA() === $mod.Cla.GetA();',
  14536. '$mod.b = 8 === $mod.Cla.FA;',
  14537. '$mod.TObject.FA = 9;',
  14538. '$mod.TObject.SetA($mod.TObject.GetA());',
  14539. '$mod.b = $mod.TObject.FA === 10;',
  14540. '$mod.b = 11 === $mod.TObject.FA;',
  14541. '']));
  14542. end;
  14543. procedure TTestModule.TestClassOf_ClassMethodSelf;
  14544. begin
  14545. StartProgram(false);
  14546. Add('type');
  14547. Add(' TObject = class');
  14548. Add(' class var GlobalId: longint;');
  14549. Add(' class procedure ProcA;');
  14550. Add(' end;');
  14551. Add('class procedure tobject.proca;');
  14552. Add('var b: boolean;');
  14553. Add('begin');
  14554. Add(' b:=self=nil;');
  14555. Add(' b:=self.globalid=3;');
  14556. Add(' b:=4=self.globalid;');
  14557. Add(' self.globalid:=5;');
  14558. Add(' self.proca;');
  14559. Add('end;');
  14560. Add('begin');
  14561. ConvertProgram;
  14562. CheckSource('TestClassOf_ClassMethodSelf',
  14563. LinesToStr([ // statements
  14564. 'rtl.createClass($mod, "TObject", null, function () {',
  14565. ' this.GlobalId = 0;',
  14566. ' this.$init = function () {',
  14567. ' };',
  14568. ' this.$final = function () {',
  14569. ' };',
  14570. ' this.ProcA = function () {',
  14571. ' var b = false;',
  14572. ' b = this === null;',
  14573. ' b = this.GlobalId === 3;',
  14574. ' b = 4 === this.GlobalId;',
  14575. ' $mod.TObject.GlobalId = 5;',
  14576. ' this.ProcA();',
  14577. ' };',
  14578. '});'
  14579. ]),
  14580. LinesToStr([ // $mod.$main
  14581. '']));
  14582. end;
  14583. procedure TTestModule.TestClassOf_TypeCast;
  14584. begin
  14585. StartProgram(false);
  14586. Add('type');
  14587. Add(' TObject = class');
  14588. Add(' class procedure {#TObject_DoIt}DoIt;');
  14589. Add(' end;');
  14590. Add(' TClass = class of TObject;');
  14591. Add(' TMobile = class');
  14592. Add(' class procedure {#TMobile_DoIt}DoIt;');
  14593. Add(' end;');
  14594. Add(' TMobileClass = class of TMobile;');
  14595. Add(' TCar = class(TMobile)');
  14596. Add(' class procedure {#TCar_DoIt}DoIt;');
  14597. Add(' end;');
  14598. Add(' TCarClass = class of TCar;');
  14599. Add('class procedure TObject.DoIt;');
  14600. Add('begin');
  14601. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  14602. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  14603. Add('end;');
  14604. Add('class procedure TMobile.DoIt;');
  14605. Add('begin');
  14606. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  14607. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  14608. Add(' TCarClass(Self).{@TCar_DoIt}DoIt;');
  14609. Add('end;');
  14610. Add('class procedure TCar.DoIt; begin end;');
  14611. Add('var');
  14612. Add(' ObjC: TClass;');
  14613. Add(' MobileC: TMobileClass;');
  14614. Add(' CarC: TCarClass;');
  14615. Add('begin');
  14616. Add(' ObjC.{@TObject_DoIt}DoIt;');
  14617. Add(' MobileC.{@TMobile_DoIt}DoIt;');
  14618. Add(' CarC.{@TCar_DoIt}DoIt;');
  14619. Add(' TClass(ObjC).{@TObject_DoIt}DoIt;');
  14620. Add(' TMobileClass(ObjC).{@TMobile_DoIt}DoIt;');
  14621. Add(' TCarClass(ObjC).{@TCar_DoIt}DoIt;');
  14622. Add(' TClass(MobileC).{@TObject_DoIt}DoIt;');
  14623. Add(' TMobileClass(MobileC).{@TMobile_DoIt}DoIt;');
  14624. Add(' TCarClass(MobileC).{@TCar_DoIt}DoIt;');
  14625. Add(' TClass(CarC).{@TObject_DoIt}DoIt;');
  14626. Add(' TMobileClass(CarC).{@TMobile_DoIt}DoIt;');
  14627. Add(' TCarClass(CarC).{@TCar_DoIt}DoIt;');
  14628. ConvertProgram;
  14629. CheckSource('TestClassOf_TypeCast',
  14630. LinesToStr([ // statements
  14631. 'rtl.createClass($mod, "TObject", null, function () {',
  14632. ' this.$init = function () {',
  14633. ' };',
  14634. ' this.$final = function () {',
  14635. ' };',
  14636. ' this.DoIt = function () {',
  14637. ' this.DoIt();',
  14638. ' this.DoIt$1();',
  14639. ' };',
  14640. '});',
  14641. 'rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
  14642. ' this.DoIt$1 = function () {',
  14643. ' this.DoIt();',
  14644. ' this.DoIt$1();',
  14645. ' this.DoIt$2();',
  14646. ' };',
  14647. '});',
  14648. 'rtl.createClass($mod, "TCar", $mod.TMobile, function () {',
  14649. ' this.DoIt$2 = function () {',
  14650. ' };',
  14651. '});',
  14652. 'this.ObjC = null;',
  14653. 'this.MobileC = null;',
  14654. 'this.CarC = null;',
  14655. '']),
  14656. LinesToStr([ // $mod.$main
  14657. '$mod.ObjC.DoIt();',
  14658. '$mod.MobileC.DoIt$1();',
  14659. '$mod.CarC.DoIt$2();',
  14660. '$mod.ObjC.DoIt();',
  14661. '$mod.ObjC.DoIt$1();',
  14662. '$mod.ObjC.DoIt$2();',
  14663. '$mod.MobileC.DoIt();',
  14664. '$mod.MobileC.DoIt$1();',
  14665. '$mod.MobileC.DoIt$2();',
  14666. '$mod.CarC.DoIt();',
  14667. '$mod.CarC.DoIt$1();',
  14668. '$mod.CarC.DoIt$2();',
  14669. '']));
  14670. end;
  14671. procedure TTestModule.TestClassOf_ImplicitFunctionCall;
  14672. begin
  14673. StartProgram(false);
  14674. Add('type');
  14675. Add(' TObject = class');
  14676. Add(' function CurNow: longint; ');
  14677. Add(' class function Now: longint; ');
  14678. Add(' end;');
  14679. Add('function TObject.CurNow: longint; begin end;');
  14680. Add('class function TObject.Now: longint; begin end;');
  14681. Add('var');
  14682. Add(' Obj: tobject;');
  14683. Add(' vI: longint;');
  14684. Add('begin');
  14685. Add(' obj.curnow;');
  14686. Add(' vi:=obj.curnow;');
  14687. Add(' tobject.now;');
  14688. Add(' vi:=tobject.now;');
  14689. ConvertProgram;
  14690. CheckSource('TestClassOf_ImplicitFunctionCall',
  14691. LinesToStr([ // statements
  14692. 'rtl.createClass($mod, "TObject", null, function () {',
  14693. ' this.$init = function () {',
  14694. ' };',
  14695. ' this.$final = function () {',
  14696. ' };',
  14697. ' this.CurNow = function () {',
  14698. ' var Result = 0;',
  14699. ' return Result;',
  14700. ' };',
  14701. ' this.Now = function () {',
  14702. ' var Result = 0;',
  14703. ' return Result;',
  14704. ' };',
  14705. '});',
  14706. 'this.Obj = null;',
  14707. 'this.vI = 0;',
  14708. '']),
  14709. LinesToStr([ // $mod.$main
  14710. '$mod.Obj.CurNow();',
  14711. '$mod.vI = $mod.Obj.CurNow();',
  14712. '$mod.TObject.Now();',
  14713. '$mod.vI = $mod.TObject.Now();',
  14714. '']));
  14715. end;
  14716. procedure TTestModule.TestClassOf_Const;
  14717. begin
  14718. StartProgram(false);
  14719. Add([
  14720. 'type',
  14721. ' TObject = class',
  14722. ' end;',
  14723. ' TBird = TObject;',
  14724. ' TBirds = class of TBird;',
  14725. ' TEagles = TBirds;',
  14726. ' THawk = class(TBird);',
  14727. 'const',
  14728. ' Hawk: TEagles = THawk;',
  14729. ' DefaultBirdClasses : Array [1..2] of TEagles = (',
  14730. ' TBird,',
  14731. ' THawk',
  14732. ' );',
  14733. 'begin']);
  14734. ConvertProgram;
  14735. CheckSource('TestClassOf_Const',
  14736. LinesToStr([ // statements
  14737. 'rtl.createClass($mod, "TObject", null, function () {',
  14738. ' this.$init = function () {',
  14739. ' };',
  14740. ' this.$final = function () {',
  14741. ' };',
  14742. '});',
  14743. 'rtl.createClass($mod, "THawk", $mod.TObject, function () {',
  14744. '});',
  14745. 'this.Hawk = $mod.THawk;',
  14746. 'this.DefaultBirdClasses = [$mod.TObject, $mod.THawk];',
  14747. '']),
  14748. LinesToStr([ // $mod.$main
  14749. '']));
  14750. end;
  14751. procedure TTestModule.TestNestedClass_Alias;
  14752. begin
  14753. Converter.Options:=Converter.Options-[coNoTypeInfo];
  14754. StartProgram(false);
  14755. Add([
  14756. 'type',
  14757. ' TObject = class',
  14758. ' type TNested = type longint;',
  14759. ' end;',
  14760. 'type TAlias = type tobject.tnested;',
  14761. 'var i: tobject.tnested = 3;',
  14762. 'var j: TAlias = 4;',
  14763. 'begin',
  14764. ' if typeinfo(TAlias)=nil then ;',
  14765. ' if typeinfo(tobject.tnested)=nil then ;',
  14766. '']);
  14767. ConvertProgram;
  14768. CheckSource('TestNestedClass_Alias',
  14769. LinesToStr([ // statements
  14770. 'rtl.createClass($mod, "TObject", null, function () {',
  14771. ' $mod.$rtti.$inherited("TObject.TNested", rtl.longint, {});',
  14772. ' this.$init = function () {',
  14773. ' };',
  14774. ' this.$final = function () {',
  14775. ' };',
  14776. '});',
  14777. '$mod.$rtti.$inherited("TAlias", $mod.$rtti["TObject.TNested"], {});',
  14778. 'this.i = 3;',
  14779. 'this.j = 4;',
  14780. '']),
  14781. LinesToStr([ // $mod.$main
  14782. 'if ($mod.$rtti["TAlias"] === null) ;',
  14783. 'if ($mod.$rtti["TObject.TNested"] === null) ;',
  14784. '']));
  14785. end;
  14786. procedure TTestModule.TestNestedClass_Record;
  14787. begin
  14788. Converter.Options:=Converter.Options-[coNoTypeInfo];
  14789. StartProgram(false);
  14790. Add([
  14791. 'type',
  14792. ' TObject = class',
  14793. ' type TPoint = record',
  14794. ' x,y: byte;',
  14795. ' end;',
  14796. ' procedure DoIt(t: TPoint);',
  14797. ' end;',
  14798. 'procedure tobject.DoIt(t: TPoint);',
  14799. 'var p: TPoint;',
  14800. 'begin',
  14801. ' t.x:=t.y;',
  14802. ' p:=t;',
  14803. 'end;',
  14804. 'var',
  14805. ' p: tobject.tpoint = (x:2; y:4);',
  14806. ' o: TObject;',
  14807. 'begin',
  14808. ' p:=p;',
  14809. ' o.doit(p);',
  14810. '']);
  14811. ConvertProgram;
  14812. CheckSource('TestNestedClass_Record',
  14813. LinesToStr([ // statements
  14814. 'rtl.createClass($mod, "TObject", null, function () {',
  14815. ' rtl.recNewT(this, "TPoint", function () {',
  14816. ' this.x = 0;',
  14817. ' this.y = 0;',
  14818. ' this.$eq = function (b) {',
  14819. ' return (this.x === b.x) && (this.y === b.y);',
  14820. ' };',
  14821. ' this.$assign = function (s) {',
  14822. ' this.x = s.x;',
  14823. ' this.y = s.y;',
  14824. ' return this;',
  14825. ' };',
  14826. ' var $r = $mod.$rtti.$Record("TObject.TPoint", {});',
  14827. ' $r.addField("x", rtl.byte);',
  14828. ' $r.addField("y", rtl.byte);',
  14829. ' });',
  14830. ' this.$init = function () {',
  14831. ' };',
  14832. ' this.$final = function () {',
  14833. ' };',
  14834. ' this.DoIt = function (t) {',
  14835. ' var p = this.TPoint.$new();',
  14836. ' t.x = t.y;',
  14837. ' p.$assign(t);',
  14838. ' };',
  14839. '});',
  14840. 'this.p = $mod.TObject.TPoint.$clone({',
  14841. ' x: 2,',
  14842. ' y: 4',
  14843. '});',
  14844. 'this.o = null;',
  14845. '']),
  14846. LinesToStr([ // $mod.$main
  14847. '$mod.p.$assign($mod.p);',
  14848. '$mod.o.DoIt($mod.TObject.TPoint.$clone($mod.p));',
  14849. '']));
  14850. end;
  14851. procedure TTestModule.TestNestedClass_Class;
  14852. begin
  14853. Converter.Options:=Converter.Options-[coNoTypeInfo];
  14854. StartProgram(false);
  14855. Add([
  14856. 'type',
  14857. ' TObject = class end;',
  14858. ' TBird = class',
  14859. ' type TLeg = class',
  14860. ' FId: longint;',
  14861. ' constructor Create;',
  14862. ' function Create(i: longint): TLeg;',
  14863. ' end;',
  14864. ' function DoIt(b: TBird): Tleg;',
  14865. ' end;',
  14866. 'constructor tbird.tleg.create;',
  14867. 'begin',
  14868. ' FId:=3;',
  14869. 'end;',
  14870. 'function tbird.tleg.Create(i: longint): TLeg;',
  14871. 'begin',
  14872. ' Create;',
  14873. ' Result:=TLeg.Create;',
  14874. ' Result:=TBird.TLeg.Create;',
  14875. ' Result:=Create(3);',
  14876. ' FId:=i;',
  14877. 'end;',
  14878. 'function tbird.DoIt(b: tbird): tleg;',
  14879. 'begin',
  14880. ' Result.Create;',
  14881. ' Result:=TLeg.Create;',
  14882. ' Result:=TBird.TLeg.Create;',
  14883. ' Result:=Result.Create(3);',
  14884. 'end;',
  14885. 'var',
  14886. ' b: Tbird.tleg;',
  14887. 'begin',
  14888. ' b.Create;',
  14889. ' b:=TBird.TLeg.Create;',
  14890. ' b:=b.Create(3);',
  14891. '']);
  14892. ConvertProgram;
  14893. CheckSource('TestNestedClass_Class',
  14894. LinesToStr([ // statements
  14895. 'rtl.createClass($mod, "TObject", null, function () {',
  14896. ' this.$init = function () {',
  14897. ' };',
  14898. ' this.$final = function () {',
  14899. ' };',
  14900. '});',
  14901. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  14902. ' rtl.createClass(this, "TLeg", $mod.TObject, function () {',
  14903. ' this.$init = function () {',
  14904. ' $mod.TObject.$init.call(this);',
  14905. ' this.FId = 0;',
  14906. ' };',
  14907. ' this.Create = function () {',
  14908. ' this.FId = 3;',
  14909. ' return this;',
  14910. ' };',
  14911. ' this.Create$1 = function (i) {',
  14912. ' var Result = null;',
  14913. ' this.Create();',
  14914. ' Result = $mod.TBird.TLeg.$create("Create");',
  14915. ' Result = $mod.TBird.TLeg.$create("Create");',
  14916. ' Result = this.Create$1(3);',
  14917. ' this.FId = i;',
  14918. ' return Result;',
  14919. ' };',
  14920. ' });',
  14921. ' this.DoIt = function (b) {',
  14922. ' var Result = null;',
  14923. ' Result.Create();',
  14924. ' Result = this.TLeg.$create("Create");',
  14925. ' Result = $mod.TBird.TLeg.$create("Create");',
  14926. ' Result = Result.Create$1(3);',
  14927. ' return Result;',
  14928. ' };',
  14929. '});',
  14930. 'this.b = null;',
  14931. '']),
  14932. LinesToStr([ // $mod.$main
  14933. '$mod.b.Create();',
  14934. '$mod.b = $mod.TBird.TLeg.$create("Create");',
  14935. '$mod.b = $mod.b.Create$1(3);',
  14936. '']));
  14937. end;
  14938. procedure TTestModule.TestExternalClass_Var;
  14939. begin
  14940. StartProgram(false);
  14941. Add([
  14942. '{$modeswitch externalclass}',
  14943. 'type',
  14944. ' TExtA = class external name ''ExtObj''',
  14945. ' Id: longint external name ''$Id'';',
  14946. ' B: longint;',
  14947. ' end;',
  14948. 'var Obj: TExtA;',
  14949. 'begin',
  14950. ' obj.id:=obj.id+1;',
  14951. ' obj.B:=obj.B+1;']);
  14952. ConvertProgram;
  14953. CheckSource('TestExternalClass_Var',
  14954. LinesToStr([ // statements
  14955. 'this.Obj = null;',
  14956. '']),
  14957. LinesToStr([ // $mod.$main
  14958. '$mod.Obj.$Id = $mod.Obj.$Id + 1;',
  14959. '$mod.Obj.B = $mod.Obj.B + 1;',
  14960. '']));
  14961. end;
  14962. procedure TTestModule.TestExternalClass_Const;
  14963. begin
  14964. StartProgram(false);
  14965. Add([
  14966. '{$modeswitch externalclass}',
  14967. 'type',
  14968. ' TExtA = class external name ''ExtObj''',
  14969. ' const Two: longint = 2;',
  14970. ' const Three = 3;',
  14971. ' const Id: longint;',
  14972. ' end;',
  14973. ' TExtB = class external name ''ExtB''',
  14974. ' A: TExtA;',
  14975. ' end;',
  14976. 'var',
  14977. ' A: texta;',
  14978. ' B: textb;',
  14979. ' i: longint;',
  14980. 'begin',
  14981. ' i:=a.two;',
  14982. ' i:=texta.two;',
  14983. ' i:=a.three;',
  14984. ' i:=texta.three;',
  14985. ' i:=a.id;',
  14986. ' i:=texta.id;',
  14987. '']);
  14988. ConvertProgram;
  14989. CheckSource('TestExternalClass_Const',
  14990. LinesToStr([ // statements
  14991. 'this.A = null;',
  14992. 'this.B = null;',
  14993. 'this.i = 0;',
  14994. '']),
  14995. LinesToStr([ // $mod.$main
  14996. '$mod.i = 2;',
  14997. '$mod.i = 2;',
  14998. '$mod.i = 3;',
  14999. '$mod.i = 3;',
  15000. '$mod.i = $mod.A.Id;',
  15001. '$mod.i = ExtObj.Id;',
  15002. '']));
  15003. end;
  15004. procedure TTestModule.TestExternalClass_Dollar;
  15005. begin
  15006. StartProgram(false);
  15007. Add([
  15008. '{$modeswitch externalclass}',
  15009. 'type',
  15010. ' TExtA = class external name ''$''',
  15011. ' Id: longint external name ''$'';',
  15012. ' function Bla(i: longint): longint; external name ''$'';',
  15013. ' end;',
  15014. 'function dollar(k: longint): longint; external name ''$'';',
  15015. 'var Obj: TExtA;',
  15016. 'begin',
  15017. ' dollar(1);',
  15018. ' obj.id:=obj.id+2;',
  15019. ' obj.Bla(3);',
  15020. '']);
  15021. ConvertProgram;
  15022. CheckSource('TestExternalClass_Dollar',
  15023. LinesToStr([ // statements
  15024. 'this.Obj = null;',
  15025. '']),
  15026. LinesToStr([ // $mod.$main
  15027. '$(1);',
  15028. '$mod.Obj.$ = $mod.Obj.$ + 2;',
  15029. '$mod.Obj.$(3);',
  15030. '']));
  15031. end;
  15032. procedure TTestModule.TestExternalClass_DuplicateVarFail;
  15033. begin
  15034. StartProgram(false);
  15035. Add('{$modeswitch externalclass}');
  15036. Add('type');
  15037. Add(' TExtA = class external name ''ExtA''');
  15038. Add(' Id: longint external name ''$Id'';');
  15039. Add(' end;');
  15040. Add(' TExtB = class external ''lib'' name ''ExtB''(TExtA)');
  15041. Add(' Id: longint;');
  15042. Add(' end;');
  15043. Add('begin');
  15044. SetExpectedPasResolverError('Duplicate identifier "Id" at test1.pp(6,5)',nDuplicateIdentifier);
  15045. ConvertProgram;
  15046. end;
  15047. procedure TTestModule.TestExternalClass_Method;
  15048. begin
  15049. StartProgram(false);
  15050. Add('{$modeswitch externalclass}');
  15051. Add('type');
  15052. Add(' TExtA = class external name ''ExtObj''');
  15053. Add(' procedure DoIt(Id: longint = 1); external name ''$Execute'';');
  15054. Add(' procedure DoSome(Id: longint = 1);');
  15055. Add(' end;');
  15056. Add('var Obj: texta;');
  15057. Add('begin');
  15058. Add(' obj.doit;');
  15059. Add(' obj.doit();');
  15060. Add(' obj.doit(2);');
  15061. Add(' with obj do begin');
  15062. Add(' doit;');
  15063. Add(' doit();');
  15064. Add(' doit(3);');
  15065. Add(' end;');
  15066. ConvertProgram;
  15067. CheckSource('TestExternalClass_Method',
  15068. LinesToStr([ // statements
  15069. 'this.Obj = null;',
  15070. '']),
  15071. LinesToStr([ // $mod.$main
  15072. '$mod.Obj.$Execute(1);',
  15073. '$mod.Obj.$Execute(1);',
  15074. '$mod.Obj.$Execute(2);',
  15075. 'var $with1 = $mod.Obj;',
  15076. '$with1.$Execute(1);',
  15077. '$with1.$Execute(1);',
  15078. '$with1.$Execute(3);',
  15079. '']));
  15080. end;
  15081. procedure TTestModule.TestExternalClass_ClassMethod;
  15082. begin
  15083. StartProgram(false);
  15084. Add([
  15085. '{$modeswitch externalclass}',
  15086. 'type',
  15087. ' TExtA = class external name ''ExtObj''',
  15088. ' class procedure DoIt(Id: longint = 1); external name ''$Execute'';',
  15089. ' end;',
  15090. ' TExtB = TExtA;',
  15091. 'begin',
  15092. ' texta.doit;',
  15093. ' texta.doit();',
  15094. ' texta.doit(2);',
  15095. ' with texta do begin',
  15096. ' doit;',
  15097. ' doit();',
  15098. ' doit(3);',
  15099. ' end;',
  15100. ' textb.doit;',
  15101. ' textb.doit();',
  15102. ' textb.doit(4);',
  15103. ' with textb do begin',
  15104. ' doit;',
  15105. ' doit();',
  15106. ' doit(5);',
  15107. ' end;',
  15108. '']);
  15109. ConvertProgram;
  15110. CheckSource('TestExternalClass_ClassMethod',
  15111. LinesToStr([ // statements
  15112. '']),
  15113. LinesToStr([ // $mod.$main
  15114. 'ExtObj.$Execute(1);',
  15115. 'ExtObj.$Execute(1);',
  15116. 'ExtObj.$Execute(2);',
  15117. 'ExtObj.$Execute(1);',
  15118. 'ExtObj.$Execute(1);',
  15119. 'ExtObj.$Execute(3);',
  15120. 'ExtObj.$Execute(1);',
  15121. 'ExtObj.$Execute(1);',
  15122. 'ExtObj.$Execute(4);',
  15123. 'ExtObj.$Execute(1);',
  15124. 'ExtObj.$Execute(1);',
  15125. 'ExtObj.$Execute(5);',
  15126. '']));
  15127. end;
  15128. procedure TTestModule.TestExternalClass_FunctionResultInTypeCast;
  15129. begin
  15130. StartProgram(false);
  15131. Add([
  15132. '{$modeswitch externalclass}',
  15133. 'type',
  15134. ' TBird = class external name ''Array''',
  15135. ' end;',
  15136. 'function GetPtr: Pointer;',
  15137. 'begin',
  15138. 'end;',
  15139. 'procedure Write(const p);',
  15140. 'begin',
  15141. 'end;',
  15142. 'procedure WriteLn; varargs;',
  15143. 'begin',
  15144. 'end;',
  15145. 'begin',
  15146. ' if TBird(GetPtr)=nil then ;',
  15147. ' Write(GetPtr);',
  15148. ' WriteLn(GetPtr);',
  15149. ' Write(TBird(GetPtr));',
  15150. ' WriteLn(TBird(GetPtr));',
  15151. '']);
  15152. ConvertProgram;
  15153. CheckSource('TestFunctionResultInTypeCast',
  15154. LinesToStr([ // statements
  15155. 'this.GetPtr = function () {',
  15156. ' var Result = null;',
  15157. ' return Result;',
  15158. '};',
  15159. 'this.Write = function (p) {',
  15160. '};',
  15161. 'this.WriteLn = function () {',
  15162. '};',
  15163. '']),
  15164. LinesToStr([
  15165. 'if ($mod.GetPtr() === null) ;',
  15166. '$mod.Write($mod.GetPtr());',
  15167. '$mod.WriteLn($mod.GetPtr());',
  15168. '$mod.Write($mod.GetPtr());',
  15169. '$mod.WriteLn($mod.GetPtr());',
  15170. '']));
  15171. end;
  15172. procedure TTestModule.TestExternalClass_NonExternalOverride;
  15173. begin
  15174. StartProgram(false);
  15175. Add('{$modeswitch externalclass}');
  15176. Add('type');
  15177. Add(' TExtA = class external name ''ExtObjA''');
  15178. Add(' procedure ProcA; virtual;');
  15179. Add(' procedure ProcB; virtual;');
  15180. Add(' end;');
  15181. Add(' TExtB = class external name ''ExtObjB'' (TExtA)');
  15182. Add(' end;');
  15183. Add(' TExtC = class (TExtB)');
  15184. Add(' procedure ProcA; override;');
  15185. Add(' end;');
  15186. Add('procedure TExtC.ProcA;');
  15187. Add('begin');
  15188. Add(' ProcA;');
  15189. Add(' Self.ProcA;');
  15190. Add(' ProcB;');
  15191. Add(' Self.ProcB;');
  15192. Add('end;');
  15193. Add('var');
  15194. Add(' A: texta;');
  15195. Add(' B: textb;');
  15196. Add(' C: textc;');
  15197. Add('begin');
  15198. Add(' a.proca;');
  15199. Add(' b.proca;');
  15200. Add(' c.proca;');
  15201. ConvertProgram;
  15202. CheckSource('TestExternalClass_NonExternalOverride',
  15203. LinesToStr([ // statements
  15204. 'rtl.createClassExt($mod, "TExtC", ExtObjB, "", function () {',
  15205. ' this.$init = function () {',
  15206. ' };',
  15207. ' this.$final = function () {',
  15208. ' };',
  15209. ' this.ProcA = function () {',
  15210. ' this.ProcA();',
  15211. ' this.ProcA();',
  15212. ' this.ProcB();',
  15213. ' this.ProcB();',
  15214. ' };',
  15215. '});',
  15216. 'this.A = null;',
  15217. 'this.B = null;',
  15218. 'this.C = null;',
  15219. '']),
  15220. LinesToStr([ // $mod.$main
  15221. '$mod.A.ProcA();',
  15222. '$mod.B.ProcA();',
  15223. '$mod.C.ProcA();',
  15224. '']));
  15225. end;
  15226. procedure TTestModule.TestExternalClass_OverloadHint;
  15227. begin
  15228. StartProgram(false);
  15229. Add([
  15230. '{$modeswitch externalclass}',
  15231. 'type',
  15232. ' TExtA = class external name ''ExtObjA''',
  15233. ' procedure DoIt;',
  15234. ' procedure DoIt(i: longint);',
  15235. ' end;',
  15236. 'begin',
  15237. '']);
  15238. ConvertProgram;
  15239. CheckResolverUnexpectedHints(true);
  15240. CheckSource('TestExternalClass_OverloadHint',
  15241. LinesToStr([ // statements
  15242. '']),
  15243. LinesToStr([ // $mod.$main
  15244. '']));
  15245. end;
  15246. procedure TTestModule.TestExternalClass_SameNamePublishedProperty;
  15247. begin
  15248. StartProgram(false);
  15249. Add([
  15250. '{$modeswitch externalclass}',
  15251. 'type',
  15252. ' JSwiper = class external name ''Swiper''',
  15253. ' constructor New;',
  15254. ' end;',
  15255. ' TObject = class',
  15256. ' private',
  15257. ' FSwiper: JSwiper;',
  15258. ' published',
  15259. ' property Swiper: JSwiper read FSwiper write FSwiper;',
  15260. ' end;',
  15261. 'begin',
  15262. ' JSwiper.new;',
  15263. '']);
  15264. ConvertProgram;
  15265. CheckSource('TestExternalClass_SameNamePublishedProperty',
  15266. LinesToStr([ // statements
  15267. 'rtl.createClass($mod, "TObject", null, function () {',
  15268. ' this.$init = function () {',
  15269. ' this.FSwiper = null;',
  15270. ' };',
  15271. ' this.$final = function () {',
  15272. ' this.FSwiper = undefined;',
  15273. ' };',
  15274. ' var $r = this.$rtti;',
  15275. ' $r.addProperty("Swiper", 0, $mod.$rtti["JSwiper"], "FSwiper", "FSwiper");',
  15276. '});',
  15277. '']),
  15278. LinesToStr([ // $mod.$main
  15279. 'new Swiper();',
  15280. '']));
  15281. end;
  15282. procedure TTestModule.TestExternalClass_Property;
  15283. begin
  15284. StartProgram(false);
  15285. Add([
  15286. '{$modeswitch externalclass}',
  15287. 'type',
  15288. ' TExtA = class external name ''ExtA''',
  15289. ' function getYear: longint;',
  15290. ' procedure setYear(Value: longint);',
  15291. ' property Year: longint read getyear write setyear;',
  15292. ' end;',
  15293. ' TExtB = class (TExtA)',
  15294. ' procedure OtherSetYear(Value: longint);',
  15295. ' property year write othersetyear;',
  15296. ' end;',
  15297. 'procedure textb.othersetyear(value: longint);',
  15298. 'begin',
  15299. ' setYear(Value+4);',
  15300. 'end;',
  15301. 'var',
  15302. ' A: texta;',
  15303. ' B: textb;',
  15304. 'begin',
  15305. ' a.year:=a.year+1;',
  15306. ' b.year:=b.year+2;']);
  15307. ConvertProgram;
  15308. CheckSource('TestExternalClass_NonExternalOverride',
  15309. LinesToStr([ // statements
  15310. 'rtl.createClassExt($mod, "TExtB", ExtA, "", function () {',
  15311. ' this.$init = function () {',
  15312. ' };',
  15313. ' this.$final = function () {',
  15314. ' };',
  15315. ' this.OtherSetYear = function (Value) {',
  15316. ' this.setYear(Value+4);',
  15317. ' };',
  15318. '});',
  15319. 'this.A = null;',
  15320. 'this.B = null;',
  15321. '']),
  15322. LinesToStr([ // $mod.$main
  15323. '$mod.A.setYear($mod.A.getYear()+1);',
  15324. '$mod.B.OtherSetYear($mod.B.getYear()+2);',
  15325. '']));
  15326. end;
  15327. procedure TTestModule.TestExternalClass_PropertyDate;
  15328. begin
  15329. StartProgram(false);
  15330. Add([
  15331. '{$modeswitch externalclass}',
  15332. 'type',
  15333. ' TExtA = class external name ''ExtA''',
  15334. ' end;',
  15335. ' TExtB = class (TExtA)',
  15336. ' FDate: string;',
  15337. ' property Date: string read FDate write FDate;',
  15338. ' property ExtA: string read FDate write FDate;',
  15339. ' end;',
  15340. ' {$M+}',
  15341. ' TObject = class',
  15342. ' FDate: string;',
  15343. ' published',
  15344. ' property Date: string read FDate write FDate;',
  15345. ' property ExtA: string read FDate write FDate;',
  15346. ' end;',
  15347. 'var',
  15348. ' B: textb;',
  15349. ' o: TObject;',
  15350. 'begin',
  15351. ' b.date:=b.exta;',
  15352. ' o.date:=o.exta;']);
  15353. ConvertProgram;
  15354. CheckSource('TestExternalClass_PropertyDate',
  15355. LinesToStr([ // statements
  15356. 'rtl.createClassExt($mod, "TExtB", ExtA, "", function () {',
  15357. ' this.$init = function () {',
  15358. ' this.FDate = "";',
  15359. ' };',
  15360. ' this.$final = function () {',
  15361. ' };',
  15362. '});',
  15363. 'rtl.createClass($mod, "TObject", null, function () {',
  15364. ' this.$init = function () {',
  15365. ' this.FDate = "";',
  15366. ' };',
  15367. ' this.$final = function () {',
  15368. ' };',
  15369. ' var $r = this.$rtti;',
  15370. ' $r.addField("FDate", rtl.string);',
  15371. ' $r.addProperty("Date", 0, rtl.string, "FDate", "FDate");',
  15372. ' $r.addProperty("ExtA", 0, rtl.string, "FDate", "FDate");',
  15373. '});',
  15374. 'this.B = null;',
  15375. 'this.o = null;',
  15376. '']),
  15377. LinesToStr([ // $mod.$main
  15378. '$mod.B.FDate = $mod.B.FDate;',
  15379. '$mod.o.FDate = $mod.o.FDate;',
  15380. '']));
  15381. end;
  15382. procedure TTestModule.TestExternalClass_ClassProperty;
  15383. begin
  15384. StartProgram(false);
  15385. Add('{$modeswitch externalclass}');
  15386. Add('type');
  15387. Add(' TExtA = class external name ''ExtA''');
  15388. Add(' class function getYear: longint;');
  15389. Add(' class procedure setYear(Value: longint);');
  15390. Add(' class property Year: longint read getyear write setyear;');
  15391. Add(' end;');
  15392. Add(' TExtB = class (TExtA)');
  15393. Add(' class function GetCentury: longint;');
  15394. Add(' class procedure SetCentury(Value: longint);');
  15395. Add(' class property Century: longint read getcentury write setcentury;');
  15396. Add(' end;');
  15397. Add('class function textb.getcentury: longint;');
  15398. Add('begin');
  15399. Add('end;');
  15400. Add('class procedure textb.setcentury(value: longint);');
  15401. Add('begin');
  15402. Add(' setyear(value+11);');
  15403. Add(' texta.year:=texta.year+12;');
  15404. Add(' year:=year+13;');
  15405. Add(' textb.century:=textb.century+14;');
  15406. Add(' century:=century+15;');
  15407. Add('end;');
  15408. Add('var');
  15409. Add(' A: texta;');
  15410. Add(' B: textb;');
  15411. Add('begin');
  15412. Add(' texta.year:=texta.year+1;');
  15413. Add(' textb.year:=textb.year+2;');
  15414. Add(' TextA.year:=TextA.year+3;');
  15415. Add(' b.year:=b.year+4;');
  15416. Add(' textb.century:=textb.century+5;');
  15417. Add(' b.century:=b.century+6;');
  15418. ConvertProgram;
  15419. CheckSource('TestExternalClass_ClassProperty',
  15420. LinesToStr([ // statements
  15421. 'rtl.createClassExt($mod, "TExtB", ExtA, "", function () {',
  15422. ' this.$init = function () {',
  15423. ' };',
  15424. ' this.$final = function () {',
  15425. ' };',
  15426. ' this.GetCentury = function () {',
  15427. ' var Result = 0;',
  15428. ' return Result;',
  15429. ' };',
  15430. ' this.SetCentury = function (Value) {',
  15431. ' this.setYear(Value + 11);',
  15432. ' ExtA.setYear(ExtA.getYear() + 12);',
  15433. ' this.setYear(this.getYear() + 13);',
  15434. ' $mod.TExtB.SetCentury($mod.TExtB.GetCentury() + 14);',
  15435. ' this.SetCentury(this.GetCentury() + 15);',
  15436. ' };',
  15437. '});',
  15438. 'this.A = null;',
  15439. 'this.B = null;',
  15440. '']),
  15441. LinesToStr([ // $mod.$main
  15442. 'ExtA.setYear(ExtA.getYear() + 1);',
  15443. '$mod.TExtB.setYear($mod.TExtB.getYear() + 2);',
  15444. 'ExtA.setYear(ExtA.getYear() + 3);',
  15445. '$mod.B.setYear($mod.B.getYear() + 4);',
  15446. '$mod.TExtB.SetCentury($mod.TExtB.GetCentury() + 5);',
  15447. '$mod.B.$class.SetCentury($mod.B.$class.GetCentury() + 6);',
  15448. '']));
  15449. end;
  15450. procedure TTestModule.TestExternalClass_ClassOf;
  15451. begin
  15452. StartProgram(false);
  15453. Add('{$modeswitch externalclass}');
  15454. Add('type');
  15455. Add(' TExtA = class external name ''ExtA''');
  15456. Add(' procedure ProcA; virtual;');
  15457. Add(' procedure ProcB; virtual;');
  15458. Add(' end;');
  15459. Add(' TExtAClass = class of TExtA;');
  15460. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  15461. Add(' end;');
  15462. Add(' TExtBClass = class of TExtB;');
  15463. Add(' TExtC = class (TExtB)');
  15464. Add(' procedure ProcA; override;');
  15465. Add(' end;');
  15466. Add(' TExtCClass = class of TExtC;');
  15467. Add('procedure TExtC.ProcA; begin end;');
  15468. Add('var');
  15469. Add(' A: texta; ClA: TExtAClass;');
  15470. Add(' B: textb; ClB: TExtBClass;');
  15471. Add(' C: textc; ClC: TExtCClass;');
  15472. Add('begin');
  15473. Add(' ClA:=texta;');
  15474. Add(' ClA:=textb;');
  15475. Add(' ClA:=textc;');
  15476. Add(' ClB:=textb;');
  15477. Add(' ClB:=textc;');
  15478. Add(' ClC:=textc;');
  15479. ConvertProgram;
  15480. CheckSource('TestExternalClass_ClassOf',
  15481. LinesToStr([ // statements
  15482. 'rtl.createClassExt($mod, "TExtC", ExtB, "", function () {',
  15483. ' this.$init = function () {',
  15484. ' };',
  15485. ' this.$final = function () {',
  15486. ' };',
  15487. ' this.ProcA = function () {',
  15488. ' };',
  15489. '});',
  15490. 'this.A = null;',
  15491. 'this.ClA = null;',
  15492. 'this.B = null;',
  15493. 'this.ClB = null;',
  15494. 'this.C = null;',
  15495. 'this.ClC = null;',
  15496. '']),
  15497. LinesToStr([ // $mod.$main
  15498. '$mod.ClA = ExtA;',
  15499. '$mod.ClA = ExtB;',
  15500. '$mod.ClA = $mod.TExtC;',
  15501. '$mod.ClB = ExtB;',
  15502. '$mod.ClB = $mod.TExtC;',
  15503. '$mod.ClC = $mod.TExtC;',
  15504. '']));
  15505. end;
  15506. procedure TTestModule.TestExternalClass_ClassOtherUnit;
  15507. begin
  15508. AddModuleWithIntfImplSrc('unit2.pas',
  15509. LinesToStr([
  15510. '{$modeswitch externalclass}',
  15511. 'type',
  15512. ' TExtA = class external name ''ExtA''',
  15513. ' class var Id: longint;',
  15514. ' end;',
  15515. '']),
  15516. '');
  15517. StartUnit(true);
  15518. Add('interface');
  15519. Add('uses unit2;');
  15520. Add('implementation');
  15521. Add('begin');
  15522. Add(' unit2.texta.id:=unit2.texta.id+1;');
  15523. ConvertUnit;
  15524. CheckSource('TestExternalClass_ClassOtherUnit',
  15525. LinesToStr([
  15526. '']),
  15527. LinesToStr([
  15528. 'ExtA.Id = ExtA.Id + 1;',
  15529. '']));
  15530. end;
  15531. procedure TTestModule.TestExternalClass_Is;
  15532. begin
  15533. StartProgram(false);
  15534. Add('{$modeswitch externalclass}');
  15535. Add('type');
  15536. Add(' TExtA = class external name ''ExtA''');
  15537. Add(' end;');
  15538. Add(' TExtAClass = class of TExtA;');
  15539. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  15540. Add(' end;');
  15541. Add(' TExtBClass = class of TExtB;');
  15542. Add(' TExtC = class (TExtB)');
  15543. Add(' end;');
  15544. Add(' TExtCClass = class of TExtC;');
  15545. Add('var');
  15546. Add(' A: texta; ClA: TExtAClass;');
  15547. Add(' B: textb; ClB: TExtBClass;');
  15548. Add(' C: textc; ClC: TExtCClass;');
  15549. Add('begin');
  15550. Add(' if a is textb then ;');
  15551. Add(' if a is textc then ;');
  15552. Add(' if b is textc then ;');
  15553. Add(' if cla is textb then ;');
  15554. Add(' if cla is textc then ;');
  15555. Add(' if clb is textc then ;');
  15556. ConvertProgram;
  15557. CheckSource('TestExternalClass_Is',
  15558. LinesToStr([ // statements
  15559. 'rtl.createClassExt($mod, "TExtC", ExtB, "", function () {',
  15560. ' this.$init = function () {',
  15561. ' };',
  15562. ' this.$final = function () {',
  15563. ' };',
  15564. '});',
  15565. 'this.A = null;',
  15566. 'this.ClA = null;',
  15567. 'this.B = null;',
  15568. 'this.ClB = null;',
  15569. 'this.C = null;',
  15570. 'this.ClC = null;',
  15571. '']),
  15572. LinesToStr([ // $mod.$main
  15573. 'if (rtl.isExt($mod.A, ExtB)) ;',
  15574. 'if ($mod.TExtC.isPrototypeOf($mod.A)) ;',
  15575. 'if ($mod.TExtC.isPrototypeOf($mod.B)) ;',
  15576. 'if (rtl.isExt($mod.ClA, ExtB)) ;',
  15577. 'if (rtl.is($mod.ClA, $mod.TExtC)) ;',
  15578. 'if (rtl.is($mod.ClB, $mod.TExtC)) ;',
  15579. '']));
  15580. end;
  15581. procedure TTestModule.TestExternalClass_As;
  15582. begin
  15583. StartProgram(false);
  15584. Add('{$modeswitch externalclass}');
  15585. Add('type');
  15586. Add(' TExtA = class external name ''ExtA''');
  15587. Add(' end;');
  15588. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  15589. Add(' end;');
  15590. Add(' TExtC = class (TExtB)');
  15591. Add(' end;');
  15592. Add('var');
  15593. Add(' A: texta;');
  15594. Add(' B: textb;');
  15595. Add(' C: textc;');
  15596. Add('begin');
  15597. Add(' b:=a as textb;');
  15598. Add(' c:=a as textc;');
  15599. Add(' c:=b as textc;');
  15600. ConvertProgram;
  15601. CheckSource('TestExternalClass_Is',
  15602. LinesToStr([ // statements
  15603. 'rtl.createClassExt($mod, "TExtC", ExtB, "", function () {',
  15604. ' this.$init = function () {',
  15605. ' };',
  15606. ' this.$final = function () {',
  15607. ' };',
  15608. '});',
  15609. 'this.A = null;',
  15610. 'this.B = null;',
  15611. 'this.C = null;',
  15612. '']),
  15613. LinesToStr([ // $mod.$main
  15614. '$mod.B = rtl.asExt($mod.A, ExtB);',
  15615. '$mod.C = rtl.as($mod.A, $mod.TExtC);',
  15616. '$mod.C = rtl.as($mod.B, $mod.TExtC);',
  15617. '']));
  15618. end;
  15619. procedure TTestModule.TestExternalClass_DestructorFail;
  15620. begin
  15621. StartProgram(false);
  15622. Add('{$modeswitch externalclass}');
  15623. Add('type');
  15624. Add(' TExtA = class external name ''ExtA''');
  15625. Add(' destructor Free;');
  15626. Add(' end;');
  15627. SetExpectedPasResolverError('Pascal element not supported: destructor',
  15628. nPasElementNotSupported);
  15629. ConvertProgram;
  15630. end;
  15631. procedure TTestModule.TestExternalClass_New;
  15632. begin
  15633. StartProgram(false);
  15634. Add('{$modeswitch externalclass}');
  15635. Add('type');
  15636. Add(' TExtA = class external name ''ExtA''');
  15637. Add(' constructor New;');
  15638. Add(' constructor New(i: longint; j: longint = 2);');
  15639. Add(' end;');
  15640. Add('var');
  15641. Add(' A: texta;');
  15642. Add('begin');
  15643. Add(' a:=texta.new;');
  15644. Add(' a:=texta(texta.new);');
  15645. Add(' a:=texta.new();');
  15646. Add(' a:=texta.new(1);');
  15647. Add(' with texta do begin');
  15648. Add(' a:=new;');
  15649. Add(' a:=new();');
  15650. Add(' a:=new(2);');
  15651. Add(' end;');
  15652. Add(' a:=test1.texta.new;');
  15653. Add(' a:=test1.texta.new();');
  15654. Add(' a:=test1.texta.new(3);');
  15655. ConvertProgram;
  15656. CheckSource('TestExternalClass_New',
  15657. LinesToStr([ // statements
  15658. 'this.A = null;',
  15659. '']),
  15660. LinesToStr([ // $mod.$main
  15661. '$mod.A = new ExtA();',
  15662. '$mod.A = new ExtA();',
  15663. '$mod.A = new ExtA();',
  15664. '$mod.A = new ExtA(1,2);',
  15665. '$mod.A = new ExtA();',
  15666. '$mod.A = new ExtA();',
  15667. '$mod.A = new ExtA(2,2);',
  15668. '$mod.A = new ExtA();',
  15669. '$mod.A = new ExtA();',
  15670. '$mod.A = new ExtA(3,2);',
  15671. '']));
  15672. end;
  15673. procedure TTestModule.TestExternalClass_ClassOf_New;
  15674. begin
  15675. StartProgram(false);
  15676. Add('{$modeswitch externalclass}');
  15677. Add('type');
  15678. Add(' TExtAClass = class of TExtA;');
  15679. Add(' TExtA = class external name ''ExtA''');
  15680. Add(' C: TExtAClass;');
  15681. Add(' constructor New;');
  15682. Add(' end;');
  15683. Add('var');
  15684. Add(' A: texta;');
  15685. Add(' C: textaclass;');
  15686. Add('begin');
  15687. Add(' a:=c.new;');
  15688. Add(' a:=c.new();');
  15689. Add(' with C do begin');
  15690. Add(' a:=new;');
  15691. Add(' a:=new();');
  15692. Add(' end;');
  15693. Add(' a:=test1.c.new;');
  15694. Add(' a:=test1.c.new();');
  15695. Add(' a:=A.c.new();');
  15696. ConvertProgram;
  15697. CheckSource('TestExternalClass_ClassOf_New',
  15698. LinesToStr([ // statements
  15699. 'this.A = null;',
  15700. 'this.C = null;',
  15701. '']),
  15702. LinesToStr([ // $mod.$main
  15703. '$mod.A = new $mod.C();',
  15704. '$mod.A = new $mod.C();',
  15705. 'var $with1 = $mod.C;',
  15706. '$mod.A = new $with1();',
  15707. '$mod.A = new $with1();',
  15708. '$mod.A = new $mod.C();',
  15709. '$mod.A = new $mod.C();',
  15710. '$mod.A = new $mod.A.C();',
  15711. '']));
  15712. end;
  15713. procedure TTestModule.TestExternalClass_FuncClassOf_New;
  15714. begin
  15715. StartProgram(false);
  15716. Add([
  15717. '{$modeswitch externalclass}',
  15718. 'type',
  15719. ' TExtAClass = class of TExtA;',
  15720. ' TExtA = class external name ''ExtA''',
  15721. ' constructor New;',
  15722. ' end;',
  15723. 'function GetCreator: TExtAClass;',
  15724. 'begin',
  15725. ' Result:=TExtA;',
  15726. 'end;',
  15727. 'var',
  15728. ' A: texta;',
  15729. 'begin',
  15730. ' a:=getcreator.new;',
  15731. ' a:=getcreator().new;',
  15732. ' a:=getcreator().new();',
  15733. ' a:=getcreator.new();',
  15734. ' with getcreator do begin',
  15735. ' a:=new;',
  15736. ' a:=new();',
  15737. ' end;']);
  15738. ConvertProgram;
  15739. CheckSource('TestExternalClass_FuncClassOf_New',
  15740. LinesToStr([ // statements
  15741. 'this.GetCreator = function () {',
  15742. ' var Result = null;',
  15743. ' Result = ExtA;',
  15744. ' return Result;',
  15745. '};',
  15746. 'this.A = null;',
  15747. '']),
  15748. LinesToStr([ // $mod.$main
  15749. '$mod.A = new ($mod.GetCreator())();',
  15750. '$mod.A = new ($mod.GetCreator())();',
  15751. '$mod.A = new ($mod.GetCreator())();',
  15752. '$mod.A = new ($mod.GetCreator())();',
  15753. 'var $with1 = $mod.GetCreator();',
  15754. '$mod.A = new $with1();',
  15755. '$mod.A = new $with1();',
  15756. '']));
  15757. end;
  15758. procedure TTestModule.TestExternalClass_New_PasClassFail;
  15759. begin
  15760. StartProgram(false);
  15761. Add([
  15762. '{$modeswitch externalclass}',
  15763. 'type',
  15764. ' TExtA = class external name ''ExtA''',
  15765. ' constructor New;',
  15766. ' end;',
  15767. ' TBird = class(TExtA)',
  15768. ' end;',
  15769. 'begin',
  15770. ' TBird.new;',
  15771. '']);
  15772. SetExpectedPasResolverError(sJSNewNotSupported,nJSNewNotSupported);
  15773. ConvertProgram;
  15774. end;
  15775. procedure TTestModule.TestExternalClass_New_PasClassBracketsFail;
  15776. begin
  15777. StartProgram(false);
  15778. Add([
  15779. '{$modeswitch externalclass}',
  15780. 'type',
  15781. ' TExtA = class external name ''ExtA''',
  15782. ' constructor New;',
  15783. ' end;',
  15784. ' TBird = class(TExtA)',
  15785. ' end;',
  15786. 'begin',
  15787. ' TBird.new();',
  15788. '']);
  15789. SetExpectedPasResolverError(sJSNewNotSupported,nJSNewNotSupported);
  15790. ConvertProgram;
  15791. end;
  15792. procedure TTestModule.TestExternalClass_LocalConstSameName;
  15793. begin
  15794. StartProgram(false);
  15795. Add('{$modeswitch externalclass}');
  15796. Add('type');
  15797. Add(' TExtA = class external name ''ExtA''');
  15798. Add(' constructor New;');
  15799. Add(' end;');
  15800. Add('function DoIt: longint;');
  15801. Add('const ExtA: longint = 3;');
  15802. Add('begin');
  15803. Add(' Result:=ExtA;');
  15804. Add('end;');
  15805. Add('var');
  15806. Add(' A: texta;');
  15807. Add('begin');
  15808. Add(' a:=texta.new;');
  15809. ConvertProgram;
  15810. CheckSource('TestExternalClass_LocalConstSameName',
  15811. LinesToStr([ // statements
  15812. 'var ExtA$1 = 3;',
  15813. 'this.DoIt = function () {',
  15814. ' var Result = 0;',
  15815. ' Result = ExtA$1;',
  15816. ' return Result;',
  15817. '};',
  15818. 'this.A = null;',
  15819. '']),
  15820. LinesToStr([ // $mod.$main
  15821. '$mod.A = new ExtA();',
  15822. '']));
  15823. end;
  15824. procedure TTestModule.TestExternalClass_ReintroduceOverload;
  15825. begin
  15826. StartProgram(false);
  15827. Add('{$modeswitch externalclass}');
  15828. Add('type');
  15829. Add(' TExtA = class external name ''ExtA''');
  15830. Add(' procedure DoIt;');
  15831. Add(' end;');
  15832. Add(' TMyA = class(TExtA)');
  15833. Add(' procedure DoIt;');
  15834. Add(' end;');
  15835. Add('procedure TMyA.DoIt; begin end;');
  15836. Add('begin');
  15837. ConvertProgram;
  15838. CheckSource('TestExternalClass_ReintroduceOverload',
  15839. LinesToStr([ // statements
  15840. 'rtl.createClassExt($mod, "TMyA", ExtA, "", function () {',
  15841. ' this.$init = function () {',
  15842. ' };',
  15843. ' this.$final = function () {',
  15844. ' };',
  15845. ' this.DoIt$1 = function () {',
  15846. ' };',
  15847. '});',
  15848. '']),
  15849. LinesToStr([ // $mod.$main
  15850. '']));
  15851. end;
  15852. procedure TTestModule.TestExternalClass_Inherited;
  15853. begin
  15854. StartProgram(false);
  15855. Add('{$modeswitch externalclass}');
  15856. Add('type');
  15857. Add(' TExtA = class external name ''ExtA''');
  15858. Add(' procedure DoIt(i: longint = 1); virtual;');
  15859. Add(' procedure DoSome(j: longint = 2);');
  15860. Add(' end;');
  15861. Add(' TExtB = class external name ''ExtB''(TExtA)');
  15862. Add(' end;');
  15863. Add(' TMyC = class(TExtB)');
  15864. Add(' procedure DoIt(i: longint = 1); override;');
  15865. Add(' procedure DoSome(j: longint = 2); reintroduce;');
  15866. Add(' end;');
  15867. Add('procedure TMyC.DoIt(i: longint);');
  15868. Add('begin');
  15869. Add(' inherited;');
  15870. Add(' inherited DoIt;');
  15871. Add(' inherited DoIt();');
  15872. Add(' inherited DoIt(3);');
  15873. Add(' inherited DoSome;');
  15874. Add(' inherited DoSome();');
  15875. Add(' inherited DoSome(4);');
  15876. Add('end;');
  15877. Add('procedure TMyC.DoSome(j: longint);');
  15878. Add('begin');
  15879. Add(' inherited;');
  15880. Add('end;');
  15881. Add('begin');
  15882. ConvertProgram;
  15883. CheckSource('TestExternalClass_ReintroduceOverload',
  15884. LinesToStr([ // statements
  15885. 'rtl.createClassExt($mod, "TMyC", ExtB, "", function () {',
  15886. ' this.$init = function () {',
  15887. ' };',
  15888. ' this.$final = function () {',
  15889. ' };',
  15890. ' this.DoIt = function (i) {',
  15891. ' ExtB.DoIt.apply(this, arguments);',
  15892. ' ExtB.DoIt.call(this, 1);',
  15893. ' ExtB.DoIt.call(this, 1);',
  15894. ' ExtB.DoIt.call(this, 3);',
  15895. ' ExtB.DoSome.call(this, 2);',
  15896. ' ExtB.DoSome.call(this, 2);',
  15897. ' ExtB.DoSome.call(this, 4);',
  15898. ' };',
  15899. ' this.DoSome$1 = function (j) {',
  15900. ' ExtB.DoSome.apply(this, arguments);',
  15901. ' };',
  15902. '});',
  15903. '']),
  15904. LinesToStr([ // $mod.$main
  15905. '']));
  15906. end;
  15907. procedure TTestModule.TestExternalClass_PascalAncestorFail;
  15908. begin
  15909. StartProgram(false);
  15910. Add('{$modeswitch externalclass}');
  15911. Add('type');
  15912. Add(' TObject = class');
  15913. Add(' end;');
  15914. Add(' TExtA = class external name ''ExtA''(TObject)');
  15915. Add(' end;');
  15916. Add('begin');
  15917. SetExpectedPasResolverError('Ancestor "TObject" is not external',nAncestorIsNotExternal);
  15918. ConvertProgram;
  15919. end;
  15920. procedure TTestModule.TestExternalClass_NewInstance;
  15921. begin
  15922. StartProgram(false);
  15923. Add('{$modeswitch externalclass}');
  15924. Add('type');
  15925. Add(' TExtA = class external name ''ExtA''');
  15926. Add(' end;');
  15927. Add(' TMyB = class(TExtA)');
  15928. Add(' protected');
  15929. Add(' class function NewInstance(fnname: string; const paramarray): TMyB; virtual;');
  15930. Add(' end;');
  15931. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  15932. Add('begin end;');
  15933. Add('begin');
  15934. ConvertProgram;
  15935. CheckSource('TestExternalClass_NewInstance',
  15936. LinesToStr([ // statements
  15937. 'rtl.createClassExt($mod, "TMyB", ExtA, "NewInstance", function () {',
  15938. ' this.$init = function () {',
  15939. ' };',
  15940. ' this.$final = function () {',
  15941. ' };',
  15942. ' this.NewInstance = function (fnname, paramarray) {',
  15943. ' var Result = null;',
  15944. ' return Result;',
  15945. ' };',
  15946. '});',
  15947. '']),
  15948. LinesToStr([ // $mod.$main
  15949. '']));
  15950. end;
  15951. procedure TTestModule.TestExternalClass_NewInstance_NonVirtualFail;
  15952. begin
  15953. StartProgram(false);
  15954. Add('{$modeswitch externalclass}');
  15955. Add('type');
  15956. Add(' TExtA = class external name ''ExtA''');
  15957. Add(' end;');
  15958. Add(' TMyB = class(TExtA)');
  15959. Add(' protected');
  15960. Add(' class function NewInstance(fnname: string; const paramarray): TMyB;');
  15961. Add(' end;');
  15962. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  15963. Add('begin end;');
  15964. Add('begin');
  15965. SetExpectedPasResolverError(sNewInstanceFunctionMustBeVirtual,nNewInstanceFunctionMustBeVirtual);
  15966. ConvertProgram;
  15967. end;
  15968. procedure TTestModule.TestExternalClass_NewInstance_FirstParamNotString_Fail;
  15969. begin
  15970. StartProgram(false);
  15971. Add('{$modeswitch externalclass}');
  15972. Add('type');
  15973. Add(' TExtA = class external name ''ExtA''');
  15974. Add(' end;');
  15975. Add(' TMyB = class(TExtA)');
  15976. Add(' protected');
  15977. Add(' class function NewInstance(fnname: longint; const paramarray): TMyB; virtual;');
  15978. Add(' end;');
  15979. Add('class function TMyB.NewInstance(fnname: longint; const paramarray): TMyB;');
  15980. Add('begin end;');
  15981. Add('begin');
  15982. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Longint", expected "String"',
  15983. nIncompatibleTypeArgNo);
  15984. ConvertProgram;
  15985. end;
  15986. procedure TTestModule.TestExternalClass_NewInstance_SecondParamTyped_Fail;
  15987. begin
  15988. StartProgram(false);
  15989. Add('{$modeswitch externalclass}');
  15990. Add('type');
  15991. Add(' TExtA = class external name ''ExtA''');
  15992. Add(' end;');
  15993. Add(' TMyB = class(TExtA)');
  15994. Add(' protected');
  15995. Add(' class function NewInstance(fnname: string; const paramarray: string): TMyB; virtual;');
  15996. Add(' end;');
  15997. Add('class function TMyB.NewInstance(fnname: string; const paramarray: string): TMyB;');
  15998. Add('begin end;');
  15999. Add('begin');
  16000. SetExpectedPasResolverError('Incompatible type arg no. 2: Got "type", expected "untyped"',
  16001. nIncompatibleTypeArgNo);
  16002. ConvertProgram;
  16003. end;
  16004. procedure TTestModule.TestExternalClass_PascalProperty;
  16005. begin
  16006. StartProgram(false);
  16007. Add('{$modeswitch externalclass}');
  16008. Add('type');
  16009. Add(' TJSElement = class;');
  16010. Add(' TJSNotifyEvent = procedure(Sender: TJSElement) of object;');
  16011. Add(' TJSElement = class external name ''ExtA''');
  16012. Add(' end;');
  16013. Add(' TControl = class(TJSElement)');
  16014. Add(' private');
  16015. Add(' FOnClick: TJSNotifyEvent;');
  16016. Add(' property OnClick: TJSNotifyEvent read FOnClick write FOnClick;');
  16017. Add(' procedure Click(Sender: TJSElement);');
  16018. Add(' end;');
  16019. Add('procedure TControl.Click(Sender: TJSElement);');
  16020. Add('begin');
  16021. Add(' OnClick(Self);');
  16022. Add('end;');
  16023. Add('var');
  16024. Add(' Ctrl: TControl;');
  16025. Add('begin');
  16026. Add(' Ctrl.OnClick:[email protected];');
  16027. Add(' Ctrl.OnClick(Ctrl);');
  16028. ConvertProgram;
  16029. CheckSource('TestExternalClass_PascalProperty',
  16030. LinesToStr([ // statements
  16031. 'rtl.createClassExt($mod, "TControl", ExtA, "", function () {',
  16032. ' this.$init = function () {',
  16033. ' this.FOnClick = null;',
  16034. ' };',
  16035. ' this.$final = function () {',
  16036. ' this.FOnClick = undefined;',
  16037. ' };',
  16038. ' this.Click = function (Sender) {',
  16039. ' this.FOnClick(this);',
  16040. ' };',
  16041. '});',
  16042. 'this.Ctrl = null;',
  16043. '']),
  16044. LinesToStr([ // $mod.$main
  16045. '$mod.Ctrl.FOnClick = rtl.createCallback($mod.Ctrl, "Click");',
  16046. '$mod.Ctrl.FOnClick($mod.Ctrl);',
  16047. '']));
  16048. end;
  16049. procedure TTestModule.TestExternalClass_TypeCastToRootClass;
  16050. begin
  16051. StartProgram(false);
  16052. Add([
  16053. '{$modeswitch externalclass}',
  16054. 'type',
  16055. ' IUnknown = interface end;',
  16056. ' TObject = class',
  16057. ' end;',
  16058. ' TChild = class',
  16059. ' end;',
  16060. ' TExtRootA = class external name ''ExtRootA''',
  16061. ' end;',
  16062. ' TExtChildA = class external name ''ExtChildA''(TExtRootA)',
  16063. ' end;',
  16064. ' TExtRootB = class external name ''ExtRootB''',
  16065. ' end;',
  16066. ' TExtChildB = class external name ''ExtChildB''(TExtRootB)',
  16067. ' end;',
  16068. 'var',
  16069. ' Obj: TObject;',
  16070. ' Child: TChild;',
  16071. ' RootA: TExtRootA;',
  16072. ' ChildA: TExtChildA;',
  16073. ' RootB: TExtRootB;',
  16074. ' ChildB: TExtChildB;',
  16075. ' i: IUnknown;',
  16076. 'begin',
  16077. ' obj:=tobject(roota);',
  16078. ' obj:=tobject(childa);',
  16079. ' child:=tchild(tobject(roota));',
  16080. ' roota:=textroota(obj);',
  16081. ' roota:=textroota(child);',
  16082. ' roota:=textroota(rootb);',
  16083. ' roota:=textroota(childb);',
  16084. ' childa:=textchilda(textroota(obj));',
  16085. ' roota:=TExtRootA(i)',
  16086. '']);
  16087. ConvertProgram;
  16088. CheckSource('TestExternalClass_TypeCastToRootClass',
  16089. LinesToStr([ // statements
  16090. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  16091. 'rtl.createClass($mod, "TObject", null, function () {',
  16092. ' this.$init = function () {',
  16093. ' };',
  16094. ' this.$final = function () {',
  16095. ' };',
  16096. '});',
  16097. 'rtl.createClass($mod, "TChild", $mod.TObject, function () {',
  16098. '});',
  16099. 'this.Obj = null;',
  16100. 'this.Child = null;',
  16101. 'this.RootA = null;',
  16102. 'this.ChildA = null;',
  16103. 'this.RootB = null;',
  16104. 'this.ChildB = null;',
  16105. 'this.i = null;',
  16106. '']),
  16107. LinesToStr([ // $mod.$main
  16108. '$mod.Obj = $mod.RootA;',
  16109. '$mod.Obj = $mod.ChildA;',
  16110. '$mod.Child = $mod.RootA;',
  16111. '$mod.RootA = $mod.Obj;',
  16112. '$mod.RootA = $mod.Child;',
  16113. '$mod.RootA = $mod.RootB;',
  16114. '$mod.RootA = $mod.ChildB;',
  16115. '$mod.ChildA = $mod.Obj;',
  16116. '$mod.RootA = $mod.i;',
  16117. '']));
  16118. end;
  16119. procedure TTestModule.TestExternalClass_TypeCastToJSObject;
  16120. begin
  16121. StartProgram(false);
  16122. Add([
  16123. '{$modeswitch externalclass}',
  16124. 'type',
  16125. ' IUnknown = interface end;',
  16126. ' IBird = interface(IUnknown) end;',
  16127. ' TClass = class of TObject;',
  16128. ' TObject = class',
  16129. ' end;',
  16130. ' TChild = class',
  16131. ' end;',
  16132. ' TJSObject = class external name ''Object''',
  16133. ' end;',
  16134. ' TRec = record end;',
  16135. 'var',
  16136. ' Obj: TObject;',
  16137. ' Child: TChild;',
  16138. ' i: IUnknown;',
  16139. ' Bird: IBird;',
  16140. ' j: TJSObject;',
  16141. ' r: TRec;',
  16142. ' c: TClass;',
  16143. 'begin',
  16144. ' j:=tjsobject(IUnknown);',
  16145. ' j:=tjsobject(IBird);',
  16146. ' j:=tjsobject(TObject);',
  16147. ' j:=tjsobject(TChild);',
  16148. ' j:=tjsobject(TRec);',
  16149. ' j:=tjsobject(Obj);',
  16150. ' j:=tjsobject(Child);',
  16151. ' j:=tjsobject(i);',
  16152. ' j:=tjsobject(Bird);',
  16153. ' j:=tjsobject(r);',
  16154. ' j:=tjsobject(c);',
  16155. '']);
  16156. ConvertProgram;
  16157. CheckSource('TestExternalClass_TypeCastToJSObject',
  16158. LinesToStr([ // statements
  16159. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  16160. 'rtl.createInterface($mod, "IBird", "{4B0D080B-C0F6-396E-AE88-000B87785074}", [], $mod.IUnknown);',
  16161. 'rtl.createClass($mod, "TObject", null, function () {',
  16162. ' this.$init = function () {',
  16163. ' };',
  16164. ' this.$final = function () {',
  16165. ' };',
  16166. '});',
  16167. 'rtl.createClass($mod, "TChild", $mod.TObject, function () {',
  16168. '});',
  16169. 'rtl.recNewT($mod, "TRec", function () {',
  16170. ' this.$eq = function (b) {',
  16171. ' return true;',
  16172. ' };',
  16173. ' this.$assign = function (s) {',
  16174. ' return this;',
  16175. ' };',
  16176. '});',
  16177. 'this.Obj = null;',
  16178. 'this.Child = null;',
  16179. 'this.i = null;',
  16180. 'this.Bird = null;',
  16181. 'this.j = null;',
  16182. 'this.r = $mod.TRec.$new();',
  16183. 'this.c = null;',
  16184. '']),
  16185. LinesToStr([ // $mod.$main
  16186. '$mod.j = $mod.IUnknown;',
  16187. '$mod.j = $mod.IBird;',
  16188. '$mod.j = $mod.TObject;',
  16189. '$mod.j = $mod.TChild;',
  16190. '$mod.j = $mod.TRec;',
  16191. '$mod.j = $mod.Obj;',
  16192. '$mod.j = $mod.Child;',
  16193. '$mod.j = $mod.i;',
  16194. '$mod.j = $mod.Bird;',
  16195. '$mod.j = $mod.r;',
  16196. '$mod.j = $mod.c;',
  16197. '']));
  16198. end;
  16199. procedure TTestModule.TestExternalClass_TypeCastStringToExternalString;
  16200. begin
  16201. StartProgram(false);
  16202. Add('{$modeswitch externalclass}');
  16203. Add('type');
  16204. Add(' TJSString = class external name ''String''');
  16205. Add(' class function fromCharCode() : string; varargs;');
  16206. Add(' function anchor(const aName : string) : string;');
  16207. Add(' end;');
  16208. Add('var');
  16209. Add(' s: string;');
  16210. Add('begin');
  16211. Add(' s:=TJSString.fromCharCode(65,66);');
  16212. Add(' s:=TJSString(s).anchor(s);');
  16213. Add(' s:=TJSString(''foo'').anchor(s);');
  16214. ConvertProgram;
  16215. CheckSource('TestExternalClass_TypeCastStringToExternalString',
  16216. LinesToStr([ // statements
  16217. 'this.s = "";',
  16218. '']),
  16219. LinesToStr([ // $mod.$main
  16220. '$mod.s = String.fromCharCode(65, 66);',
  16221. '$mod.s = $mod.s.anchor($mod.s);',
  16222. '$mod.s = "foo".anchor($mod.s);',
  16223. '']));
  16224. end;
  16225. procedure TTestModule.TestExternalClass_TypeCastToJSFunction;
  16226. begin
  16227. StartProgram(false);
  16228. Add([
  16229. '{$modeswitch externalclass}',
  16230. 'type',
  16231. ' TJSObject = class external name ''Object'' end;',
  16232. ' TJSFunction = class external name ''Function''',
  16233. ' function bind(thisArg: TJSObject): TJSFunction; varargs;',
  16234. ' function call(thisArg: TJSObject): JSValue; varargs;',
  16235. ' end;',
  16236. ' TObject = class',
  16237. ' procedure DoIt(i: longint);',
  16238. ' end;',
  16239. ' TFuncInt = function(o: TObject): longint;',
  16240. 'function GetIt(o: TObject): longint;',
  16241. ' procedure Sub; begin end;',
  16242. 'var',
  16243. ' f: TJSFunction;',
  16244. ' fi: TFuncInt;',
  16245. 'begin',
  16246. ' fi:=TFuncInt(f);',
  16247. ' f:=TJSFunction(fi);',
  16248. ' f:=TJSFunction(@GetIt);',
  16249. ' f:=TJSFunction(@GetIt).bind(nil,3);',
  16250. ' f:=TJSFunction(@Sub);',
  16251. ' f:=TJSFunction(@o.doit);',
  16252. ' f:=TJSFunction(fi).bind(nil,4)',
  16253. 'end;',
  16254. 'procedure TObject.DoIt(i: longint);',
  16255. ' procedure Sub; begin end;',
  16256. 'var f: TJSFunction;',
  16257. 'begin',
  16258. ' f:=TJSFunction(@DoIt);',
  16259. ' f:=TJSFunction(@DoIt).bind(nil,13);',
  16260. ' f:=TJSFunction(@Sub);',
  16261. ' f:=TJSFunction(@GetIt);',
  16262. 'end;',
  16263. 'begin']);
  16264. ConvertProgram;
  16265. CheckSource('TestExternalClass_TypeCastToJSFunction',
  16266. LinesToStr([ // statements
  16267. 'rtl.createClass($mod, "TObject", null, function () {',
  16268. ' this.$init = function () {',
  16269. ' };',
  16270. ' this.$final = function () {',
  16271. ' };',
  16272. ' this.DoIt = function (i) {',
  16273. ' var $Self = this;',
  16274. ' function Sub() {',
  16275. ' };',
  16276. ' var f = null;',
  16277. ' f = rtl.createCallback($Self, "DoIt");',
  16278. ' f = rtl.createCallback($Self, "DoIt").bind(null, 13);',
  16279. ' f = Sub;',
  16280. ' f = $mod.GetIt;',
  16281. ' };',
  16282. '});',
  16283. 'this.GetIt = function (o) {',
  16284. ' var Result = 0;',
  16285. ' function Sub() {',
  16286. ' };',
  16287. ' var f = null;',
  16288. ' var fi = null;',
  16289. ' fi = f;',
  16290. ' f = fi;',
  16291. ' f = $mod.GetIt;',
  16292. ' f = $mod.GetIt.bind(null, 3);',
  16293. ' f = Sub;',
  16294. ' f = rtl.createCallback(o, "DoIt");',
  16295. ' f = fi.bind(null, 4);',
  16296. ' return Result;',
  16297. '};',
  16298. '']),
  16299. LinesToStr([ // $mod.$main
  16300. '']));
  16301. end;
  16302. procedure TTestModule.TestExternalClass_TypeCastDelphiUnrelated;
  16303. begin
  16304. StartProgram(false);
  16305. Add([
  16306. '{$mode delphi}',
  16307. '{$modeswitch externalclass}',
  16308. 'type',
  16309. ' TJSObject = class external name ''Object'' end;',
  16310. ' TJSWindow = class external name ''Window''(TJSObject)',
  16311. ' procedure Open;',
  16312. ' end;',
  16313. ' TJSEventTarget = class external name ''Event''(TJSObject)',
  16314. ' procedure Execute;',
  16315. ' end;',
  16316. 'procedure Fly;',
  16317. 'var',
  16318. ' w: TJSWindow;',
  16319. ' e: TJSEventTarget;',
  16320. 'begin',
  16321. ' w:=TJSWindow(e);',
  16322. ' e:=TJSEventTarget(w);',
  16323. 'end;',
  16324. 'begin']);
  16325. ConvertProgram;
  16326. CheckSource('TestExternalClass_TypeCastDelphiUnrelated',
  16327. LinesToStr([ // statements
  16328. 'this.Fly = function () {',
  16329. ' var w = null;',
  16330. ' var e = null;',
  16331. ' w = e;',
  16332. ' e = w;',
  16333. '};',
  16334. '']),
  16335. LinesToStr([ // $mod.$main
  16336. '']));
  16337. end;
  16338. procedure TTestModule.TestExternalClass_CallClassFunctionOfInstanceFail;
  16339. begin
  16340. StartProgram(false);
  16341. Add('{$modeswitch externalclass}');
  16342. Add('type');
  16343. Add(' TJSString = class external name ''String''');
  16344. Add(' class function fromCharCode() : string; varargs;');
  16345. Add(' end;');
  16346. Add('var');
  16347. Add(' s: string;');
  16348. Add(' sObj: TJSString;');
  16349. Add('begin');
  16350. Add(' s:=sObj.fromCharCode(65,66);');
  16351. SetExpectedPasResolverError('External class instance cannot access static class function fromCharCode',
  16352. nExternalClassInstanceCannotAccessStaticX);
  16353. ConvertProgram;
  16354. end;
  16355. procedure TTestModule.TestExternalClass_BracketAccessor;
  16356. begin
  16357. StartProgram(false);
  16358. Add([
  16359. '{$modeswitch externalclass}',
  16360. 'type',
  16361. ' TJSArray = class external name ''Array2''',
  16362. ' function GetItems(Index: longint): jsvalue; external name ''[]'';',
  16363. ' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';',
  16364. ' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;',
  16365. ' end;',
  16366. 'procedure DoIt(vI: JSValue; const vJ: jsvalue; var vK: jsvalue; out vL: jsvalue);',
  16367. 'begin end;',
  16368. 'var',
  16369. ' Arr: tjsarray;',
  16370. ' s: string;',
  16371. ' i: longint;',
  16372. ' v: jsvalue;',
  16373. 'begin',
  16374. ' v:=arr[0];',
  16375. ' v:=arr.items[1];',
  16376. ' arr[2]:=s;',
  16377. ' arr.items[3]:=s;',
  16378. ' arr[4]:=i;',
  16379. ' arr[5]:=arr[6];',
  16380. ' arr.items[7]:=arr.items[8];',
  16381. ' with arr do items[9]:=items[10];',
  16382. ' doit(arr[7],arr[8],arr[9],arr[10]);',
  16383. ' with arr do begin',
  16384. ' v:=GetItems(14);',
  16385. ' setitems(15,16);',
  16386. ' end;',
  16387. ' v:=test1.arr.items[17];',
  16388. ' test1.arr.items[18]:=v;',
  16389. '']);
  16390. ConvertProgram;
  16391. CheckSource('TestExternalClass_BracketAccessor',
  16392. LinesToStr([ // statements
  16393. 'this.DoIt = function (vI, vJ, vK, vL) {',
  16394. '};',
  16395. 'this.Arr = null;',
  16396. 'this.s = "";',
  16397. 'this.i = 0;',
  16398. 'this.v = undefined;',
  16399. '']),
  16400. LinesToStr([ // $mod.$main
  16401. '$mod.v = $mod.Arr[0];',
  16402. '$mod.v = $mod.Arr[1];',
  16403. '$mod.Arr[2] = $mod.s;',
  16404. '$mod.Arr[3] = $mod.s;',
  16405. '$mod.Arr[4] = $mod.i;',
  16406. '$mod.Arr[5] = $mod.Arr[6];',
  16407. '$mod.Arr[7] = $mod.Arr[8];',
  16408. 'var $with1 = $mod.Arr;',
  16409. '$with1[9] = $with1[10];',
  16410. '$mod.DoIt($mod.Arr[7], $mod.Arr[8], {',
  16411. ' a: 9,',
  16412. ' p: $mod.Arr,',
  16413. ' get: function () {',
  16414. ' return this.p[this.a];',
  16415. ' },',
  16416. ' set: function (v) {',
  16417. ' this.p[this.a] = v;',
  16418. ' }',
  16419. '}, {',
  16420. ' a: 10,',
  16421. ' p: $mod.Arr,',
  16422. ' get: function () {',
  16423. ' return this.p[this.a];',
  16424. ' },',
  16425. ' set: function (v) {',
  16426. ' this.p[this.a] = v;',
  16427. ' }',
  16428. '});',
  16429. 'var $with2 = $mod.Arr;',
  16430. '$mod.v = $with2[14];',
  16431. '$with2[15] = 16;',
  16432. '$mod.v = $mod.Arr[17];',
  16433. '$mod.Arr[18] = $mod.v;',
  16434. '']));
  16435. end;
  16436. procedure TTestModule.TestExternalClass_BracketAccessor_Call;
  16437. begin
  16438. StartProgram(false);
  16439. Add([
  16440. '{$modeswitch externalclass}',
  16441. 'type',
  16442. ' TJSArray = class external name ''Array2''',
  16443. ' function GetItems(Index: longint): jsvalue; external name ''[]'';',
  16444. ' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';',
  16445. ' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;',
  16446. ' end;',
  16447. ' TMyArr = class(TJSArray)',
  16448. ' procedure DoIt;',
  16449. ' end;',
  16450. 'procedure tmyarr.DoIt;',
  16451. 'begin',
  16452. ' Items[1]:=Items[2];',
  16453. ' SetItems(3,getItems(4));',
  16454. 'end;',
  16455. 'var',
  16456. ' Arr: tmyarr;',
  16457. ' s: string;',
  16458. ' i: longint;',
  16459. ' v: jsvalue;',
  16460. 'begin',
  16461. ' v:=arr[0];',
  16462. ' v:=arr.items[1];',
  16463. ' arr[2]:=s;',
  16464. ' arr.items[3]:=s;',
  16465. ' arr[4]:=i;',
  16466. ' arr[5]:=arr[6];',
  16467. ' arr.items[7]:=arr.items[8];',
  16468. ' with arr do items[9]:=items[10];',
  16469. ' with arr do begin',
  16470. ' v:=GetItems(14);',
  16471. ' setitems(15,16);',
  16472. ' end;',
  16473. '']);
  16474. ConvertProgram;
  16475. CheckSource('TestExternalClass_BracketAccessor_Call',
  16476. LinesToStr([ // statements
  16477. 'rtl.createClassExt($mod, "TMyArr", Array2, "", function () {',
  16478. ' this.$init = function () {',
  16479. ' };',
  16480. ' this.$final = function () {',
  16481. ' };',
  16482. ' this.DoIt = function () {',
  16483. ' this[1] = this[2];',
  16484. ' this[3] = this[4];',
  16485. ' };',
  16486. '});',
  16487. 'this.Arr = null;',
  16488. 'this.s = "";',
  16489. 'this.i = 0;',
  16490. 'this.v = undefined;',
  16491. '']),
  16492. LinesToStr([ // $mod.$main
  16493. '$mod.v = $mod.Arr[0];',
  16494. '$mod.v = $mod.Arr[1];',
  16495. '$mod.Arr[2] = $mod.s;',
  16496. '$mod.Arr[3] = $mod.s;',
  16497. '$mod.Arr[4] = $mod.i;',
  16498. '$mod.Arr[5] = $mod.Arr[6];',
  16499. '$mod.Arr[7] = $mod.Arr[8];',
  16500. 'var $with1 = $mod.Arr;',
  16501. '$with1[9] = $with1[10];',
  16502. 'var $with2 = $mod.Arr;',
  16503. '$mod.v = $with2[14];',
  16504. '$with2[15] = 16;',
  16505. '']));
  16506. end;
  16507. procedure TTestModule.TestExternalClass_BracketAccessor_2ParamsFail;
  16508. begin
  16509. StartProgram(false);
  16510. Add('{$modeswitch externalclass}');
  16511. Add('type');
  16512. Add(' TJSArray = class external name ''Array2''');
  16513. Add(' function GetItems(Index1, Index2: longint): jsvalue; external name ''[]'';');
  16514. Add(' procedure SetItems(Index1, Index2: longint; Value: jsvalue); external name ''[]'';');
  16515. Add(' property Items[Index1, Index2: longint]: jsvalue read GetItems write SetItems; default;');
  16516. Add(' end;');
  16517. Add('begin');
  16518. SetExpectedPasResolverError(sBracketAccessorOfExternalClassMustHaveOneParameter,
  16519. nBracketAccessorOfExternalClassMustHaveOneParameter);
  16520. ConvertProgram;
  16521. end;
  16522. procedure TTestModule.TestExternalClass_BracketAccessor_ReadOnly;
  16523. begin
  16524. StartProgram(false);
  16525. Add('{$modeswitch externalclass}');
  16526. Add('type');
  16527. Add(' TJSArray = class external name ''Array2''');
  16528. Add(' function GetItems(Index: longint): jsvalue; external name ''[]'';');
  16529. Add(' property Items[Index: longint]: jsvalue read GetItems; default;');
  16530. Add(' end;');
  16531. Add('procedure DoIt(vI: JSValue; const vJ: jsvalue);');
  16532. Add('begin end;');
  16533. Add('var');
  16534. Add(' Arr: tjsarray;');
  16535. Add(' v: jsvalue;');
  16536. Add('begin');
  16537. Add(' v:=arr[0];');
  16538. Add(' v:=arr.items[1];');
  16539. Add(' with arr do v:=items[2];');
  16540. Add(' doit(arr[3],arr[4]);');
  16541. ConvertProgram;
  16542. CheckSource('TestExternalClass_BracketAccessor_ReadOnly',
  16543. LinesToStr([ // statements
  16544. 'this.DoIt = function (vI, vJ) {',
  16545. '};',
  16546. 'this.Arr = null;',
  16547. 'this.v = undefined;',
  16548. '']),
  16549. LinesToStr([ // $mod.$main
  16550. '$mod.v = $mod.Arr[0];',
  16551. '$mod.v = $mod.Arr[1];',
  16552. 'var $with1 = $mod.Arr;',
  16553. '$mod.v = $with1[2];',
  16554. '$mod.DoIt($mod.Arr[3], $mod.Arr[4]);',
  16555. '']));
  16556. end;
  16557. procedure TTestModule.TestExternalClass_BracketAccessor_WriteOnly;
  16558. begin
  16559. StartProgram(false);
  16560. Add('{$modeswitch externalclass}');
  16561. Add('type');
  16562. Add(' TJSArray = class external name ''Array2''');
  16563. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  16564. Add(' property Items[Index: longint]: jsvalue write SetItems; default;');
  16565. Add(' end;');
  16566. Add('var');
  16567. Add(' Arr: tjsarray;');
  16568. Add(' s: string;');
  16569. Add(' i: longint;');
  16570. Add(' v: jsvalue;');
  16571. Add('begin');
  16572. Add(' arr[2]:=s;');
  16573. Add(' arr.items[3]:=s;');
  16574. Add(' arr[4]:=i;');
  16575. Add(' with arr do items[5]:=i;');
  16576. ConvertProgram;
  16577. CheckSource('TestExternalClass_BracketAccessor_WriteOnly',
  16578. LinesToStr([ // statements
  16579. 'this.Arr = null;',
  16580. 'this.s = "";',
  16581. 'this.i = 0;',
  16582. 'this.v = undefined;',
  16583. '']),
  16584. LinesToStr([ // $mod.$main
  16585. '$mod.Arr[2] = $mod.s;',
  16586. '$mod.Arr[3] = $mod.s;',
  16587. '$mod.Arr[4] = $mod.i;',
  16588. 'var $with1 = $mod.Arr;',
  16589. '$with1[5] = $mod.i;',
  16590. '']));
  16591. end;
  16592. procedure TTestModule.TestExternalClass_BracketAccessor_MultiType;
  16593. begin
  16594. StartProgram(false);
  16595. Add('{$modeswitch externalclass}');
  16596. Add('type');
  16597. Add(' TJSArray = class external name ''Array2''');
  16598. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  16599. Add(' property Items[Index: longint]: jsvalue write SetItems; default;');
  16600. Add(' procedure SetNumbers(Index: longint; Value: longint); external name ''[]'';');
  16601. Add(' property Numbers[Index: longint]: longint write SetNumbers;');
  16602. Add(' end;');
  16603. Add('var');
  16604. Add(' Arr: tjsarray;');
  16605. Add(' s: string;');
  16606. Add(' i: longint;');
  16607. Add(' v: jsvalue;');
  16608. Add('begin');
  16609. Add(' arr[2]:=s;');
  16610. Add(' arr.items[3]:=s;');
  16611. Add(' arr.numbers[4]:=i;');
  16612. Add(' with arr do items[5]:=i;');
  16613. Add(' with arr do numbers[6]:=i;');
  16614. ConvertProgram;
  16615. CheckSource('TestExternalClass_BracketAccessor_MultiType',
  16616. LinesToStr([ // statements
  16617. 'this.Arr = null;',
  16618. 'this.s = "";',
  16619. 'this.i = 0;',
  16620. 'this.v = undefined;',
  16621. '']),
  16622. LinesToStr([ // $mod.$main
  16623. '$mod.Arr[2] = $mod.s;',
  16624. '$mod.Arr[3] = $mod.s;',
  16625. '$mod.Arr[4] = $mod.i;',
  16626. 'var $with1 = $mod.Arr;',
  16627. '$with1[5] = $mod.i;',
  16628. 'var $with2 = $mod.Arr;',
  16629. '$with2[6] = $mod.i;',
  16630. '']));
  16631. end;
  16632. procedure TTestModule.TestExternalClass_BracketAccessor_Index;
  16633. begin
  16634. StartProgram(false);
  16635. Add('{$modeswitch externalclass}');
  16636. Add('type');
  16637. Add(' TJSArray = class external name ''Array2''');
  16638. Add(' function GetItems(Index: longint): jsvalue; external name ''[]'';');
  16639. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  16640. Add(' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;');
  16641. Add(' end;');
  16642. Add('var');
  16643. Add(' Arr: tjsarray;');
  16644. Add(' i: longint;');
  16645. Add(' IntArr: array of longint;');
  16646. Add(' v: jsvalue;');
  16647. Add('begin');
  16648. Add(' v:=arr.items[i];');
  16649. Add(' arr[longint(v)]:=arr.items[intarr[0]];');
  16650. Add(' arr.items[intarr[1]]:=arr[IntArr[2]];');
  16651. ConvertProgram;
  16652. CheckSource('TestExternalClass_BracketAccessor_Index',
  16653. LinesToStr([ // statements
  16654. 'this.Arr = null;',
  16655. 'this.i = 0;',
  16656. 'this.IntArr = [];',
  16657. 'this.v = undefined;',
  16658. '']),
  16659. LinesToStr([ // $mod.$main
  16660. '$mod.v = $mod.Arr[$mod.i];',
  16661. '$mod.Arr[Math.floor($mod.v)] = $mod.Arr[$mod.IntArr[0]];',
  16662. '$mod.Arr[$mod.IntArr[1]] = $mod.Arr[$mod.IntArr[2]];',
  16663. '']));
  16664. end;
  16665. procedure TTestModule.TestExternalClass_ForInJSObject;
  16666. begin
  16667. StartProgram(false);
  16668. Add([
  16669. '{$modeswitch externalclass}',
  16670. 'type',
  16671. ' TJSObject = class external name ''Object''',
  16672. ' end;',
  16673. 'var',
  16674. ' o: TJSObject;',
  16675. ' key: string;',
  16676. 'begin',
  16677. ' for key in o do',
  16678. ' if key=''abc'' then ;',
  16679. '']);
  16680. ConvertProgram;
  16681. CheckSource('TestExternalClass_ForInJSObject',
  16682. LinesToStr([ // statements
  16683. 'this.o = null;',
  16684. 'this.key = "";',
  16685. '']),
  16686. LinesToStr([ // $mod.$main
  16687. 'for ($mod.key in $mod.o) if ($mod.key === "abc") ;',
  16688. '']));
  16689. end;
  16690. procedure TTestModule.TestExternalClass_ForInJSArray;
  16691. begin
  16692. StartProgram(false);
  16693. Add([
  16694. '{$modeswitch externalclass}',
  16695. 'type',
  16696. ' TJSInt8Array = class external name ''Int8Array''',
  16697. ' private',
  16698. ' flength: NativeInt external name ''length'';',
  16699. ' function getValue(Index: NativeInt): shortint; external name ''[]'';',
  16700. ' public',
  16701. ' property values[Index: NativeInt]: Shortint Read getValue; default;',
  16702. ' property Length: NativeInt read flength;',
  16703. ' end;',
  16704. 'var',
  16705. ' a: TJSInt8Array;',
  16706. ' value: shortint;',
  16707. 'begin',
  16708. ' for value in a do',
  16709. ' if value=3 then ;',
  16710. '']);
  16711. ConvertProgram;
  16712. CheckSource('TestExternalClass_ForInJSArray',
  16713. LinesToStr([ // statements
  16714. 'this.a = null;',
  16715. 'this.value = 0;',
  16716. '']),
  16717. LinesToStr([ // $mod.$main
  16718. 'for (var $in1 = $mod.a, $l2 = 0, $end3 = rtl.length($in1) - 1; $l2 <= $end3; $l2++) {',
  16719. ' $mod.value = $in1[$l2];',
  16720. ' if ($mod.value === 3) ;',
  16721. '};',
  16722. '']));
  16723. end;
  16724. procedure TTestModule.TestExternalClass_IncompatibleArgDuplicateIdentifier;
  16725. begin
  16726. AddModuleWithIntfImplSrc('unit2.pas',
  16727. LinesToStr([
  16728. '{$modeswitch externalclass}',
  16729. 'type',
  16730. ' TJSBufferSource = class external name ''BufferSource''',
  16731. ' end;',
  16732. 'procedure DoIt(s: TJSBufferSource); external name ''DoIt'';',
  16733. '']),
  16734. '');
  16735. AddModuleWithIntfImplSrc('unit3.pas',
  16736. LinesToStr([
  16737. '{$modeswitch externalclass}',
  16738. 'type',
  16739. ' TJSBufferSource = class external name ''BufferSource''',
  16740. ' end;',
  16741. '']),
  16742. '');
  16743. StartUnit(true);
  16744. Add([
  16745. 'interface',
  16746. 'uses unit2, unit3;',
  16747. 'procedure DoSome(s: TJSBufferSource);',
  16748. 'implementation',
  16749. 'procedure DoSome(s: TJSBufferSource);',
  16750. 'begin',
  16751. ' DoIt(s);',
  16752. 'end;',
  16753. '']);
  16754. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "unit3.TJSBufferSource", expected "unit2.TJSBufferSource"',
  16755. nIncompatibleTypeArgNo);
  16756. ConvertUnit;
  16757. end;
  16758. procedure TTestModule.TestClassInterface_Corba;
  16759. begin
  16760. StartProgram(false);
  16761. Add([
  16762. '{$interfaces corba}',
  16763. 'type',
  16764. ' IUnknown = interface;',
  16765. ' IUnknown = interface',
  16766. ' [''{00000000-0000-0000-C000-000000000046}'']',
  16767. ' end;',
  16768. ' IInterface = IUnknown;',
  16769. ' IBird = interface(IInterface)',
  16770. ' function GetSize: longint;',
  16771. ' procedure SetSize(i: longint);',
  16772. ' property Size: longint read GetSize write SetSize;',
  16773. ' procedure DoIt(i: longint);',
  16774. ' end;',
  16775. ' TObject = class',
  16776. ' end;',
  16777. ' TBird = class(TObject,IBird)',
  16778. ' function GetSize: longint; virtual; abstract;',
  16779. ' procedure SetSize(i: longint); virtual; abstract;',
  16780. ' procedure DoIt(i: longint); virtual; abstract;',
  16781. ' end;',
  16782. 'var',
  16783. ' BirdIntf: IBird;',
  16784. 'begin',
  16785. ' BirdIntf.Size:=BirdIntf.Size;',
  16786. '']);
  16787. ConvertProgram;
  16788. CheckSource('TestClassInterface_Corba',
  16789. LinesToStr([ // statements
  16790. 'rtl.createInterface($mod, "IUnknown", "{00000000-0000-0000-C000-000000000046}", [], null);',
  16791. 'rtl.createInterface($mod, "IBird", "{5BD1A53B-69BB-37EE-AF32-BEFB86D85B03}", ["GetSize", "SetSize", "DoIt"], $mod.IUnknown);',
  16792. 'rtl.createClass($mod, "TObject", null, function () {',
  16793. ' this.$init = function () {',
  16794. ' };',
  16795. ' this.$final = function () {',
  16796. ' };',
  16797. '});',
  16798. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16799. ' rtl.addIntf(this, $mod.IBird);',
  16800. '});',
  16801. 'this.BirdIntf = null;',
  16802. '']),
  16803. LinesToStr([ // $mod.$main
  16804. ' $mod.BirdIntf.SetSize($mod.BirdIntf.GetSize());',
  16805. '']));
  16806. end;
  16807. procedure TTestModule.TestClassInterface_ProcExternalFail;
  16808. begin
  16809. StartProgram(false);
  16810. Add([
  16811. '{$interfaces corba}',
  16812. 'type',
  16813. ' IUnknown = interface',
  16814. ' procedure DoIt; external name ''foo'';',
  16815. ' end;',
  16816. 'begin']);
  16817. SetExpectedParserError(
  16818. 'Fields are not allowed in interface at token "Identifier external" in file test1.pp at line 6 column 21',
  16819. nParserNoFieldsAllowed);
  16820. ConvertProgram;
  16821. end;
  16822. procedure TTestModule.TestClassInterface_Overloads;
  16823. begin
  16824. StartProgram(false);
  16825. Add([
  16826. '{$interfaces corba}',
  16827. 'type',
  16828. ' integer = longint;',
  16829. ' IUnknown = interface',
  16830. ' procedure DoIt(i: integer);',
  16831. ' procedure DoIt(s: string);',
  16832. ' end;',
  16833. ' IBird = interface(IUnknown)',
  16834. ' procedure DoIt(b: boolean); overload;',
  16835. ' end;',
  16836. ' TObject = class',
  16837. ' end;',
  16838. ' TBird = class(TObject,IBird)',
  16839. ' procedure DoIt(o: TObject);',
  16840. ' procedure DoIt(s: string);',
  16841. ' procedure DoIt(i: integer);',
  16842. ' procedure DoIt(b: boolean);',
  16843. ' end;',
  16844. 'procedure TBird.DoIt(o: TObject); begin end;',
  16845. 'procedure TBird.DoIt(s: string); begin end;',
  16846. 'procedure TBird.DoIt(i: integer); begin end;',
  16847. 'procedure TBird.DoIt(b: boolean); begin end;',
  16848. 'var',
  16849. ' BirdIntf: IBird;',
  16850. 'begin',
  16851. ' BirdIntf.DoIt(3);',
  16852. ' BirdIntf.DoIt(''abc'');',
  16853. ' BirdIntf.DoIt(true);',
  16854. '']);
  16855. ConvertProgram;
  16856. CheckSource('TestClassInterface_Overloads',
  16857. LinesToStr([ // statements
  16858. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-BDC4-8A2AE2C59400}", ["DoIt", "DoIt$1"], null);',
  16859. 'rtl.createInterface($mod, "IBird", "{8285DD5E-EA3E-396E-AE88-000B86AABF05}", ["DoIt$2"], $mod.IUnknown);',
  16860. 'rtl.createClass($mod, "TObject", null, function () {',
  16861. ' this.$init = function () {',
  16862. ' };',
  16863. ' this.$final = function () {',
  16864. ' };',
  16865. '});',
  16866. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16867. ' this.DoIt = function (o) {',
  16868. ' };',
  16869. ' this.DoIt$1 = function (s) {',
  16870. ' };',
  16871. ' this.DoIt$2 = function (i) {',
  16872. ' };',
  16873. ' this.DoIt$3 = function (b) {',
  16874. ' };',
  16875. ' rtl.addIntf(this, $mod.IBird, {',
  16876. ' DoIt$2: "DoIt$3",',
  16877. ' DoIt: "DoIt$2"',
  16878. ' });',
  16879. '});',
  16880. 'this.BirdIntf = null;',
  16881. '']),
  16882. LinesToStr([ // $mod.$main
  16883. '$mod.BirdIntf.DoIt(3);',
  16884. '$mod.BirdIntf.DoIt$1("abc");',
  16885. '$mod.BirdIntf.DoIt$2(true);',
  16886. '']));
  16887. end;
  16888. procedure TTestModule.TestClassInterface_DuplicateGUIInIntfListFail;
  16889. begin
  16890. StartProgram(false);
  16891. Add([
  16892. '{$interfaces corba}',
  16893. 'type',
  16894. ' IBird = interface',
  16895. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16896. ' end;',
  16897. ' IDog = interface',
  16898. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16899. ' end;',
  16900. ' TObject = class(IBird,IDog)',
  16901. ' end;',
  16902. 'begin']);
  16903. SetExpectedPasResolverError('Duplicate GUID {4B3BA825-E0EC-4799-A19C-55F714A07959} in IDog and IBird',
  16904. nDuplicateGUIDXInYZ);
  16905. ConvertProgram;
  16906. end;
  16907. procedure TTestModule.TestClassInterface_DuplicateGUIInAncestorFail;
  16908. begin
  16909. StartProgram(false);
  16910. Add([
  16911. '{$interfaces corba}',
  16912. 'type',
  16913. ' IAnimal = interface',
  16914. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16915. ' end;',
  16916. ' IBird = interface(IAnimal)',
  16917. ' end;',
  16918. ' IHawk = interface(IBird)',
  16919. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16920. ' end;',
  16921. 'begin']);
  16922. SetExpectedPasResolverError('Duplicate GUID {4B3BA825-E0EC-4799-A19C-55F714A07959} in IHawk and IAnimal',
  16923. nDuplicateGUIDXInYZ);
  16924. ConvertProgram;
  16925. end;
  16926. procedure TTestModule.TestClassInterface_AncestorImpl;
  16927. begin
  16928. StartProgram(false);
  16929. Add([
  16930. '{$interfaces corba}',
  16931. 'type',
  16932. ' integer = longint;',
  16933. ' IUnknown = interface',
  16934. ' procedure DoIt(i: integer);',
  16935. ' end;',
  16936. ' IBird = interface',
  16937. ' procedure Fly(i: integer);',
  16938. ' end;',
  16939. ' TObject = class(IUnknown)',
  16940. ' procedure DoIt(i: integer);',
  16941. ' end;',
  16942. ' TBird = class(IBird)',
  16943. ' procedure Fly(i: integer);',
  16944. ' end;',
  16945. 'procedure TObject.DoIt(i: integer); begin end;',
  16946. 'procedure TBird.Fly(i: integer); begin end;',
  16947. 'begin',
  16948. '']);
  16949. ConvertProgram;
  16950. CheckSource('TestClassInterface_AncestorIntf',
  16951. LinesToStr([ // statements
  16952. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-BDC4-8A2800000000}", ["DoIt"], null);',
  16953. 'rtl.createInterface($mod, "IBird", "{B92D5841-6264-3AE3-BF20-000000000000}", ["Fly"], null);',
  16954. 'rtl.createClass($mod, "TObject", null, function () {',
  16955. ' this.$init = function () {',
  16956. ' };',
  16957. ' this.$final = function () {',
  16958. ' };',
  16959. ' this.DoIt = function (i) {',
  16960. ' };',
  16961. ' rtl.addIntf(this, $mod.IUnknown);',
  16962. '});',
  16963. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16964. ' this.Fly = function (i) {',
  16965. ' };',
  16966. ' rtl.addIntf(this, $mod.IBird);',
  16967. ' rtl.addIntf(this, $mod.IUnknown);',
  16968. '});',
  16969. '']),
  16970. LinesToStr([ // $mod.$main
  16971. '']));
  16972. end;
  16973. procedure TTestModule.TestClassInterface_ImplReintroduce;
  16974. begin
  16975. StartProgram(false);
  16976. Add([
  16977. '{$interfaces corba}',
  16978. 'type',
  16979. ' integer = longint;',
  16980. ' IBird = interface',
  16981. ' procedure DoIt(i: integer);',
  16982. ' end;',
  16983. ' TObject = class',
  16984. ' procedure DoIt(i: integer);',
  16985. ' end;',
  16986. ' TBird = class(IBird)',
  16987. ' procedure DoIt(i: integer); virtual; reintroduce;',
  16988. ' end;',
  16989. 'procedure TObject.DoIt(i: integer); begin end;',
  16990. 'procedure TBird.DoIt(i: integer); begin end;',
  16991. 'begin',
  16992. '']);
  16993. ConvertProgram;
  16994. CheckSource('TestClassInterface_ImplReintroduce',
  16995. LinesToStr([ // statements
  16996. 'rtl.createInterface($mod, "IBird", "{B92D5841-6264-3AE2-8594-000000000000}", ["DoIt"], null);',
  16997. 'rtl.createClass($mod, "TObject", null, function () {',
  16998. ' this.$init = function () {',
  16999. ' };',
  17000. ' this.$final = function () {',
  17001. ' };',
  17002. ' this.DoIt = function (i) {',
  17003. ' };',
  17004. '});',
  17005. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17006. ' this.DoIt$1 = function (i) {',
  17007. ' };',
  17008. ' rtl.addIntf(this, $mod.IBird, {',
  17009. ' DoIt: "DoIt$1"',
  17010. ' });',
  17011. '});',
  17012. '']),
  17013. LinesToStr([ // $mod.$main
  17014. '']));
  17015. end;
  17016. procedure TTestModule.TestClassInterface_MethodResolution;
  17017. begin
  17018. StartProgram(false);
  17019. Add([
  17020. '{$interfaces corba}',
  17021. 'type',
  17022. ' IUnknown = interface',
  17023. ' procedure Walk(i: longint);',
  17024. ' end;',
  17025. ' IBird = interface(IUnknown)',
  17026. ' procedure Walk(b: boolean); overload;',
  17027. ' procedure Fly(s: string);',
  17028. ' end;',
  17029. ' TObject = class',
  17030. ' end;',
  17031. ' TBird = class(TObject,IBird)',
  17032. ' procedure IBird.Fly = Move;',
  17033. ' procedure IBird.Walk = Hop;',
  17034. ' procedure Hop(i: longint);',
  17035. ' procedure Move(s: string);',
  17036. ' procedure Hop(b: boolean);',
  17037. ' end;',
  17038. 'procedure TBird.Move(s: string); begin end;',
  17039. 'procedure TBird.Hop(i: longint); begin end;',
  17040. 'procedure TBird.Hop(b: boolean); begin end;',
  17041. 'var',
  17042. ' BirdIntf: IBird;',
  17043. 'begin',
  17044. ' BirdIntf.Walk(3);',
  17045. ' BirdIntf.Walk(true);',
  17046. ' BirdIntf.Fly(''abc'');',
  17047. '']);
  17048. ConvertProgram;
  17049. CheckSource('TestClassInterface_MethodResolution',
  17050. LinesToStr([ // statements
  17051. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-BDD7-23D600000000}", ["Walk"], null);',
  17052. 'rtl.createInterface($mod, "IBird", "{CF8A4986-80F6-396E-AE88-000B86AAE208}", ["Walk$1", "Fly"], $mod.IUnknown);',
  17053. 'rtl.createClass($mod, "TObject", null, function () {',
  17054. ' this.$init = function () {',
  17055. ' };',
  17056. ' this.$final = function () {',
  17057. ' };',
  17058. '});',
  17059. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17060. ' this.Hop = function (i) {',
  17061. ' };',
  17062. ' this.Move = function (s) {',
  17063. ' };',
  17064. ' this.Hop$1 = function (b) {',
  17065. ' };',
  17066. ' rtl.addIntf(this, $mod.IBird, {',
  17067. ' Walk$1: "Hop$1",',
  17068. ' Fly: "Move",',
  17069. ' Walk: "Hop"',
  17070. ' });',
  17071. '});',
  17072. 'this.BirdIntf = null;',
  17073. '']),
  17074. LinesToStr([ // $mod.$main
  17075. '$mod.BirdIntf.Walk(3);',
  17076. '$mod.BirdIntf.Walk$1(true);',
  17077. '$mod.BirdIntf.Fly("abc");',
  17078. '']));
  17079. end;
  17080. procedure TTestModule.TestClassInterface_AncestorMoreInterfaces;
  17081. begin
  17082. StartProgram(false);
  17083. Add([
  17084. '{$interfaces com}',
  17085. 'type',
  17086. ' IUnknown = interface',
  17087. ' function _AddRef: longint;',
  17088. ' procedure Walk;',
  17089. ' end;',
  17090. ' IBird = interface end;',
  17091. ' IDog = interface end;',
  17092. ' TObject = class(IBird,IDog)',
  17093. ' function _AddRef: longint; virtual; abstract;',
  17094. ' procedure Walk; virtual; abstract;',
  17095. ' end;',
  17096. ' TBird = class(IUnknown)',
  17097. ' end;',
  17098. 'begin',
  17099. '']);
  17100. ConvertProgram;
  17101. CheckSource('TestClassInterface_COM_AncestorLess',
  17102. LinesToStr([ // statements
  17103. 'rtl.createInterface($mod, "IUnknown", "{8F2D5841-758A-322B-BDDF-21CD521DD723}", ["_AddRef", "Walk"], null);',
  17104. 'rtl.createInterface($mod, "IBird", "{CCE11D4C-6504-3AEE-AE88-000B86AAE675}", [], $mod.IUnknown);',
  17105. 'rtl.createInterface($mod, "IDog", "{CCE11D4C-6504-3AEE-AE88-000B8E5FC675}", [], $mod.IUnknown);',
  17106. 'rtl.createClass($mod, "TObject", null, function () {',
  17107. ' this.$init = function () {',
  17108. ' };',
  17109. ' this.$final = function () {',
  17110. ' };',
  17111. ' rtl.addIntf(this, $mod.IBird);',
  17112. ' rtl.addIntf(this, $mod.IDog);',
  17113. '});',
  17114. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17115. ' rtl.addIntf(this, $mod.IUnknown);',
  17116. ' rtl.addIntf(this, $mod.IBird);',
  17117. ' rtl.addIntf(this, $mod.IDog);',
  17118. '});',
  17119. '']),
  17120. LinesToStr([ // $mod.$main
  17121. '']));
  17122. end;
  17123. procedure TTestModule.TestClassInterface_MethodOverride;
  17124. begin
  17125. StartProgram(false);
  17126. Add([
  17127. '{$interfaces corba}',
  17128. 'type',
  17129. ' IUnknown = interface',
  17130. ' [''{D6D98E5B-8A10-4FEC-856A-7BFC847FE74B}'']',
  17131. ' procedure Go;',
  17132. ' end;',
  17133. ' TObject = class(IUnknown)',
  17134. ' procedure Go; virtual; abstract;',
  17135. ' end;',
  17136. ' TBird = class',
  17137. ' procedure Go; override;',
  17138. ' end;',
  17139. ' TCat = class(TObject)',
  17140. ' procedure Go; override;',
  17141. ' end;',
  17142. ' TDog = class(TObject, IUnknown)',
  17143. ' procedure Go; override;',
  17144. ' end;',
  17145. 'procedure TBird.Go; begin end;',
  17146. 'procedure TCat.Go; begin end;',
  17147. 'procedure TDog.Go; begin end;',
  17148. 'begin',
  17149. '']);
  17150. ConvertProgram;
  17151. CheckSource('TestClassInterface_MethodOverride',
  17152. LinesToStr([ // statements
  17153. 'rtl.createInterface($mod, "IUnknown", "{D6D98E5B-8A10-4FEC-856A-7BFC847FE74B}", ["Go"], null);',
  17154. 'rtl.createClass($mod, "TObject", null, function () {',
  17155. ' this.$init = function () {',
  17156. ' };',
  17157. ' this.$final = function () {',
  17158. ' };',
  17159. ' rtl.addIntf(this, $mod.IUnknown);',
  17160. '});',
  17161. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17162. ' this.Go = function () {',
  17163. ' };',
  17164. ' rtl.addIntf(this, $mod.IUnknown);',
  17165. '});',
  17166. 'rtl.createClass($mod, "TCat", $mod.TObject, function () {',
  17167. ' this.Go = function () {',
  17168. ' };',
  17169. ' rtl.addIntf(this, $mod.IUnknown);',
  17170. '});',
  17171. 'rtl.createClass($mod, "TDog", $mod.TObject, function () {',
  17172. ' this.Go = function () {',
  17173. ' };',
  17174. ' rtl.addIntf(this, $mod.IUnknown);',
  17175. '});',
  17176. '']),
  17177. LinesToStr([ // $mod.$main
  17178. '']));
  17179. end;
  17180. procedure TTestModule.TestClassInterface_Corba_Delegation;
  17181. begin
  17182. StartProgram(false);
  17183. Add([
  17184. '{$interfaces corba}',
  17185. 'type',
  17186. ' IUnknown = interface',
  17187. ' end;',
  17188. ' IBird = interface(IUnknown)',
  17189. ' procedure Fly(s: string);',
  17190. ' end;',
  17191. ' IEagle = interface(IBird)',
  17192. ' end;',
  17193. ' IDove = interface(IBird)',
  17194. ' end;',
  17195. ' ISwallow = interface(IBird)',
  17196. ' end;',
  17197. ' TObject = class',
  17198. ' end;',
  17199. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  17200. ' procedure Fly(s: string); virtual; abstract;',
  17201. ' end;',
  17202. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  17203. ' FBirdIntf: IBird;',
  17204. ' property BirdIntf: IBird read FBirdIntf implements IBird;',
  17205. ' function GetEagleIntf: IEagle; virtual; abstract;',
  17206. ' property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  17207. ' FDoveObj: TBird;',
  17208. ' property DoveObj: TBird read FDoveObj implements IDove;',
  17209. ' function GetSwallowObj: TBird; virtual; abstract;',
  17210. ' property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  17211. ' end;',
  17212. 'begin',
  17213. '']);
  17214. ConvertProgram;
  17215. CheckSource('TestClassInterface_Delegation',
  17216. LinesToStr([ // statements
  17217. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17218. 'rtl.createInterface($mod, "IBird", "{478D080B-C0F6-396E-AE88-000B87785B07}", ["Fly"], $mod.IUnknown);',
  17219. 'rtl.createInterface($mod, "IEagle", "{489289DE-FDE2-34A6-8288-39119022B1B4}", [], $mod.IBird);',
  17220. 'rtl.createInterface($mod, "IDove", "{489289DE-FDE2-34A6-8288-39118EF16074}", [], $mod.IBird);',
  17221. 'rtl.createInterface($mod, "ISwallow", "{B89289DE-FDE2-34A6-8288-3911CBDCB359}", [], $mod.IBird);',
  17222. 'rtl.createClass($mod, "TObject", null, function () {',
  17223. ' this.$init = function () {',
  17224. ' };',
  17225. ' this.$final = function () {',
  17226. ' };',
  17227. '});',
  17228. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17229. ' rtl.addIntf(this, $mod.IBird);',
  17230. ' rtl.addIntf(this, $mod.IEagle);',
  17231. ' rtl.addIntf(this, $mod.IDove);',
  17232. ' rtl.addIntf(this, $mod.ISwallow);',
  17233. '});',
  17234. 'rtl.createClass($mod, "TBat", $mod.TObject, function () {',
  17235. ' this.$init = function () {',
  17236. ' $mod.TObject.$init.call(this);',
  17237. ' this.FBirdIntf = null;',
  17238. ' this.FDoveObj = null;',
  17239. ' };',
  17240. ' this.$final = function () {',
  17241. ' this.FBirdIntf = undefined;',
  17242. ' this.FDoveObj = undefined;',
  17243. ' $mod.TObject.$final.call(this);',
  17244. ' };',
  17245. ' this.$intfmaps = {',
  17246. ' "{478D080B-C0F6-396E-AE88-000B87785B07}": function () {',
  17247. ' return this.FBirdIntf;',
  17248. ' },',
  17249. ' "{489289DE-FDE2-34A6-8288-39119022B1B4}": function () {',
  17250. ' return this.GetEagleIntf();',
  17251. ' },',
  17252. ' "{489289DE-FDE2-34A6-8288-39118EF16074}": function () {',
  17253. ' return rtl.getIntfT(this.FDoveObj, $mod.IDove);',
  17254. ' },',
  17255. ' "{B89289DE-FDE2-34A6-8288-3911CBDCB359}": function () {',
  17256. ' return rtl.getIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  17257. ' }',
  17258. ' };',
  17259. '});',
  17260. '']),
  17261. LinesToStr([ // $mod.$main
  17262. '']));
  17263. end;
  17264. procedure TTestModule.TestClassInterface_Corba_DelegationStatic;
  17265. begin
  17266. StartProgram(false);
  17267. Add([
  17268. '{$interfaces corba}',
  17269. 'type',
  17270. ' IUnknown = interface',
  17271. ' end;',
  17272. ' IBird = interface(IUnknown)',
  17273. ' procedure Fly(s: string);',
  17274. ' end;',
  17275. ' IEagle = interface(IBird)',
  17276. ' end;',
  17277. ' IDove = interface(IBird)',
  17278. ' end;',
  17279. ' ISwallow = interface(IBird)',
  17280. ' end;',
  17281. ' TObject = class',
  17282. ' end;',
  17283. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  17284. ' procedure Fly(s: string); virtual; abstract;',
  17285. ' end;',
  17286. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  17287. ' private',
  17288. ' class var FBirdIntf: IBird;',
  17289. ' class var FDoveObj: TBird;',
  17290. ' class function GetEagleIntf: IEagle; virtual; abstract;',
  17291. ' class function GetSwallowObj: TBird; virtual; abstract;',
  17292. ' protected',
  17293. ' class property BirdIntf: IBird read FBirdIntf implements IBird;',
  17294. ' class property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  17295. ' class property DoveObj: TBird read FDoveObj implements IDove;',
  17296. ' class property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  17297. ' end;',
  17298. 'begin',
  17299. '']);
  17300. ConvertProgram;
  17301. CheckSource('TestClassInterface_DelegationStatic',
  17302. LinesToStr([ // statements
  17303. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17304. 'rtl.createInterface($mod, "IBird", "{478D080B-C0F6-396E-AE88-000B87785B07}", ["Fly"], $mod.IUnknown);',
  17305. 'rtl.createInterface($mod, "IEagle", "{489289DE-FDE2-34A6-8288-39119022B1B4}", [], $mod.IBird);',
  17306. 'rtl.createInterface($mod, "IDove", "{489289DE-FDE2-34A6-8288-39118EF16074}", [], $mod.IBird);',
  17307. 'rtl.createInterface($mod, "ISwallow", "{B89289DE-FDE2-34A6-8288-3911CBDCB359}", [], $mod.IBird);',
  17308. 'rtl.createClass($mod, "TObject", null, function () {',
  17309. ' this.$init = function () {',
  17310. ' };',
  17311. ' this.$final = function () {',
  17312. ' };',
  17313. '});',
  17314. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17315. ' rtl.addIntf(this, $mod.IBird);',
  17316. ' rtl.addIntf(this, $mod.IEagle);',
  17317. ' rtl.addIntf(this, $mod.IDove);',
  17318. ' rtl.addIntf(this, $mod.ISwallow);',
  17319. '});',
  17320. 'rtl.createClass($mod, "TBat", $mod.TObject, function () {',
  17321. ' this.FBirdIntf = null;',
  17322. ' this.FDoveObj = null;',
  17323. ' this.$intfmaps = {',
  17324. ' "{478D080B-C0F6-396E-AE88-000B87785B07}": function () {',
  17325. ' return this.FBirdIntf;',
  17326. ' },',
  17327. ' "{489289DE-FDE2-34A6-8288-39119022B1B4}": function () {',
  17328. ' return this.$class.GetEagleIntf();',
  17329. ' },',
  17330. ' "{489289DE-FDE2-34A6-8288-39118EF16074}": function () {',
  17331. ' return rtl.getIntfT(this.FDoveObj, $mod.IDove);',
  17332. ' },',
  17333. ' "{B89289DE-FDE2-34A6-8288-3911CBDCB359}": function () {',
  17334. ' return rtl.getIntfT(this.$class.GetSwallowObj(), $mod.ISwallow);',
  17335. ' }',
  17336. ' };',
  17337. '});',
  17338. '']),
  17339. LinesToStr([ // $mod.$main
  17340. '']));
  17341. end;
  17342. procedure TTestModule.TestClassInterface_Corba_Operators;
  17343. begin
  17344. StartProgram(false);
  17345. Add([
  17346. '{$interfaces corba}',
  17347. 'type',
  17348. ' IUnknown = interface',
  17349. ' end;',
  17350. ' IBird = interface(IUnknown)',
  17351. ' function GetItems(Index: longint): longint;',
  17352. ' procedure SetItems(Index: longint; Value: longint);',
  17353. ' property Items[Index: longint]: longint read GetItems write SetItems; default;',
  17354. ' end;',
  17355. ' TObject = class',
  17356. ' end;',
  17357. ' TBird = class(TObject,IBird)',
  17358. ' function GetItems(Index: longint): longint; virtual; abstract;',
  17359. ' procedure SetItems(Index: longint; Value: longint); virtual; abstract;',
  17360. ' end;',
  17361. 'var',
  17362. ' IntfVar: IBird = nil;',
  17363. ' IntfVar2: IBird;',
  17364. ' ObjVar: TBird;',
  17365. ' v: JSValue;',
  17366. 'begin',
  17367. ' IntfVar:=nil;',
  17368. ' IntfVar[3]:=IntfVar[4];',
  17369. ' if Assigned(IntfVar) then ;',
  17370. ' IntfVar:=IntfVar2;',
  17371. ' IntfVar:=ObjVar;',
  17372. ' if IntfVar=IntfVar2 then ;',
  17373. ' if IntfVar<>IntfVar2 then ;',
  17374. ' if IntfVar is IBird then ;',
  17375. ' if IntfVar is TBird then ;',
  17376. ' if ObjVar is IBird then ;',
  17377. ' IntfVar:=IntfVar2 as IBird;',
  17378. ' ObjVar:=IntfVar2 as TBird;',
  17379. ' IntfVar:=ObjVar as IBird;',
  17380. ' IntfVar:=IBird(IntfVar2);',
  17381. ' ObjVar:=TBird(IntfVar);',
  17382. ' IntfVar:=IBird(ObjVar);',
  17383. ' v:=IntfVar;',
  17384. ' IntfVar:=IBird(v);',
  17385. ' if v is IBird then ;',
  17386. ' v:=JSValue(IntfVar);',
  17387. ' v:=IBird;',
  17388. '']);
  17389. ConvertProgram;
  17390. CheckSource('TestClassInterface_Corba_Operators',
  17391. LinesToStr([ // statements
  17392. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17393. 'rtl.createInterface($mod, "IBird", "{D53FED90-DE59-3202-B1AE-000B87785B08}", ["GetItems", "SetItems"], $mod.IUnknown);',
  17394. 'rtl.createClass($mod, "TObject", null, function () {',
  17395. ' this.$init = function () {',
  17396. ' };',
  17397. ' this.$final = function () {',
  17398. ' };',
  17399. '});',
  17400. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17401. ' rtl.addIntf(this, $mod.IBird);',
  17402. '});',
  17403. 'this.IntfVar = null;',
  17404. 'this.IntfVar2 = null;',
  17405. 'this.ObjVar = null;',
  17406. 'this.v = undefined;',
  17407. '']),
  17408. LinesToStr([ // $mod.$main
  17409. '$mod.IntfVar = null;',
  17410. '$mod.IntfVar.SetItems(3, $mod.IntfVar.GetItems(4));',
  17411. 'if ($mod.IntfVar != null) ;',
  17412. '$mod.IntfVar = $mod.IntfVar2;',
  17413. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar,$mod.IBird);',
  17414. 'if ($mod.IntfVar === $mod.IntfVar2) ;',
  17415. 'if ($mod.IntfVar !== $mod.IntfVar2) ;',
  17416. 'if ($mod.IBird.isPrototypeOf($mod.IntfVar)) ;',
  17417. 'if (rtl.intfIsClass($mod.IntfVar, $mod.TBird)) ;',
  17418. 'if (rtl.getIntfT($mod.ObjVar, $mod.IBird) !== null) ;',
  17419. '$mod.IntfVar = rtl.as($mod.IntfVar2, $mod.IBird);',
  17420. '$mod.ObjVar = rtl.intfAsClass($mod.IntfVar2, $mod.TBird);',
  17421. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar, $mod.IBird);',
  17422. '$mod.IntfVar = $mod.IntfVar2;',
  17423. '$mod.ObjVar = rtl.intfToClass($mod.IntfVar, $mod.TBird);',
  17424. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar, $mod.IBird);',
  17425. '$mod.v = $mod.IntfVar;',
  17426. '$mod.IntfVar = rtl.getObject($mod.v);',
  17427. 'if (rtl.isExt($mod.v, $mod.IBird, 1)) ;',
  17428. '$mod.v = $mod.IntfVar;',
  17429. '$mod.v = $mod.IBird;',
  17430. '']));
  17431. end;
  17432. procedure TTestModule.TestClassInterface_Corba_Args;
  17433. begin
  17434. StartProgram(false);
  17435. Add([
  17436. '{$interfaces corba}',
  17437. 'type',
  17438. ' IUnknown = interface',
  17439. ' end;',
  17440. ' IBird = interface(IUnknown)',
  17441. ' end;',
  17442. ' TObject = class',
  17443. ' end;',
  17444. ' TBird = class(TObject,IBird)',
  17445. ' end;',
  17446. 'procedure DoIt(var u; i: IBird; const j: IBird);',
  17447. 'begin',
  17448. ' DoIt(i,i,i);',
  17449. 'end;',
  17450. 'procedure Change(var i: IBird; out j: IBird);',
  17451. 'begin',
  17452. ' DoIt(i,i,i);',
  17453. ' Change(i,i);',
  17454. 'end;',
  17455. 'var',
  17456. ' i: IBird;',
  17457. ' o: TBird;',
  17458. 'begin',
  17459. ' DoIt(i,i,i);',
  17460. ' Change(i,i);',
  17461. ' DoIt(o,o,o);',
  17462. '']);
  17463. ConvertProgram;
  17464. CheckSource('TestClassInterface_Corba_Args',
  17465. LinesToStr([ // statements
  17466. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17467. 'rtl.createInterface($mod, "IBird", "{4B0D080B-C0F6-396E-AE88-000B87785074}", [], $mod.IUnknown);',
  17468. 'rtl.createClass($mod, "TObject", null, function () {',
  17469. ' this.$init = function () {',
  17470. ' };',
  17471. ' this.$final = function () {',
  17472. ' };',
  17473. '});',
  17474. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17475. ' rtl.addIntf(this, $mod.IBird);',
  17476. '});',
  17477. 'this.DoIt = function (u, i, j) {',
  17478. ' $mod.DoIt({',
  17479. ' get: function () {',
  17480. ' return i;',
  17481. ' },',
  17482. ' set: function (v) {',
  17483. ' i = v;',
  17484. ' }',
  17485. ' }, i, i);',
  17486. '};',
  17487. 'this.Change = function (i, j) {',
  17488. ' $mod.DoIt(i, i.get(), i.get());',
  17489. ' $mod.Change(i, i);',
  17490. '};',
  17491. 'this.i = null;',
  17492. 'this.o = null;',
  17493. '']),
  17494. LinesToStr([ // $mod.$main
  17495. '$mod.DoIt({',
  17496. ' p: $mod,',
  17497. ' get: function () {',
  17498. ' return this.p.i;',
  17499. ' },',
  17500. ' set: function (v) {',
  17501. ' this.p.i = v;',
  17502. ' }',
  17503. '}, $mod.i, $mod.i);',
  17504. '$mod.Change({',
  17505. ' p: $mod,',
  17506. ' get: function () {',
  17507. ' return this.p.i;',
  17508. ' },',
  17509. ' set: function (v) {',
  17510. ' this.p.i = v;',
  17511. ' }',
  17512. '}, {',
  17513. ' p: $mod,',
  17514. ' get: function () {',
  17515. ' return this.p.i;',
  17516. ' },',
  17517. ' set: function (v) {',
  17518. ' this.p.i = v;',
  17519. ' }',
  17520. '});',
  17521. '$mod.DoIt({',
  17522. ' p: $mod,',
  17523. ' get: function () {',
  17524. ' return this.p.o;',
  17525. ' },',
  17526. ' set: function (v) {',
  17527. ' this.p.o = v;',
  17528. ' }',
  17529. '}, rtl.getIntfT($mod.o, $mod.IBird), rtl.getIntfT($mod.o, $mod.IBird));',
  17530. '']));
  17531. end;
  17532. procedure TTestModule.TestClassInterface_Corba_ForIn;
  17533. begin
  17534. StartProgram(false);
  17535. Add([
  17536. '{$interfaces corba}',
  17537. 'type',
  17538. ' IUnknown = interface end;',
  17539. ' TObject = class',
  17540. ' Id: longint;',
  17541. ' end;',
  17542. ' IEnumerator = interface(IUnknown)',
  17543. ' function GetCurrent: TObject;',
  17544. ' function MoveNext: Boolean;',
  17545. ' property Current: TObject read GetCurrent;',
  17546. ' end;',
  17547. ' IEnumerable = interface(IUnknown)',
  17548. ' function GetEnumerator: IEnumerator;',
  17549. ' end;',
  17550. 'var',
  17551. ' o: TObject;',
  17552. ' i: IEnumerable;',
  17553. 'begin',
  17554. ' for o in i do o.Id:=3;',
  17555. '']);
  17556. ConvertProgram;
  17557. CheckSource('TestClassInterface_Corba_ForIn',
  17558. LinesToStr([ // statements
  17559. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17560. 'rtl.createClass($mod, "TObject", null, function () {',
  17561. ' this.$init = function () {',
  17562. ' this.Id = 0;',
  17563. ' };',
  17564. ' this.$final = function () {',
  17565. ' };',
  17566. '});',
  17567. 'rtl.createInterface($mod, "IEnumerator", "{95D7745D-ED61-3F13-BBE4-07708161999E}", ["GetCurrent", "MoveNext"], $mod.IUnknown);',
  17568. 'rtl.createInterface($mod, "IEnumerable", "{8CC9D45D-ED7D-3B73-96B6-290B931BB19E}", ["GetEnumerator"], $mod.IUnknown);',
  17569. 'this.o = null;',
  17570. 'this.i = null;',
  17571. '']),
  17572. LinesToStr([ // $mod.$main
  17573. 'var $in1 = $mod.i.GetEnumerator();',
  17574. 'while ($in1.MoveNext()) {',
  17575. ' $mod.o = $in1.GetCurrent();',
  17576. ' $mod.o.Id = 3;',
  17577. '};',
  17578. '']));
  17579. end;
  17580. procedure TTestModule.TestClassInterface_COM_AssignVar;
  17581. begin
  17582. StartProgram(false);
  17583. Add([
  17584. '{$interfaces com}',
  17585. 'type',
  17586. ' IUnknown = interface',
  17587. ' function _AddRef: longint;',
  17588. ' function _Release: longint;',
  17589. ' end;',
  17590. ' TObject = class(IUnknown)',
  17591. ' function _AddRef: longint; virtual; abstract;',
  17592. ' function _Release: longint; virtual; abstract;',
  17593. ' end;',
  17594. 'var',
  17595. ' i: IUnknown;',
  17596. 'procedure DoGlobal(o: TObject);',
  17597. 'begin',
  17598. ' i:=nil;',
  17599. ' i:=o;',
  17600. ' i:=i;',
  17601. 'end;',
  17602. 'procedure DoLocal(o: TObject);',
  17603. 'const k: IUnknown = nil;',
  17604. 'var j: IUnknown;',
  17605. 'begin',
  17606. ' k:=o;',
  17607. ' k:=i;',
  17608. ' j:=o;',
  17609. ' j:=i;',
  17610. 'end;',
  17611. 'var o: TObject;',
  17612. 'begin',
  17613. ' i:=nil;',
  17614. ' i:=o;',
  17615. '']);
  17616. ConvertProgram;
  17617. CheckSource('TestClassInterface_COM_AssignVar',
  17618. LinesToStr([ // statements
  17619. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17620. 'rtl.createClass($mod, "TObject", null, function () {',
  17621. ' this.$init = function () {',
  17622. ' };',
  17623. ' this.$final = function () {',
  17624. ' };',
  17625. ' rtl.addIntf(this, $mod.IUnknown);',
  17626. '});',
  17627. 'this.i = null;',
  17628. 'this.DoGlobal = function (o) {',
  17629. ' rtl.setIntfP($mod, "i", null);',
  17630. ' rtl.setIntfP($mod, "i", rtl.queryIntfT(o, $mod.IUnknown), true);',
  17631. ' rtl.setIntfP($mod, "i", $mod.i);',
  17632. '};',
  17633. 'var k = null;',
  17634. 'this.DoLocal = function (o) {',
  17635. ' var j = null;',
  17636. ' try{',
  17637. ' k = rtl.setIntfL(k, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17638. ' k = rtl.setIntfL(k, $mod.i);',
  17639. ' j = rtl.setIntfL(j, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17640. ' j = rtl.setIntfL(j, $mod.i);',
  17641. ' }finally{',
  17642. ' rtl._Release(j);',
  17643. ' };',
  17644. '};',
  17645. 'this.o = null;',
  17646. '']),
  17647. LinesToStr([ // $mod.$main
  17648. 'rtl.setIntfP($mod, "i", null);',
  17649. 'rtl.setIntfP($mod, "i", rtl.queryIntfT($mod.o, $mod.IUnknown), true);',
  17650. '']));
  17651. end;
  17652. procedure TTestModule.TestClassInterface_COM_AssignArg;
  17653. begin
  17654. StartProgram(false);
  17655. Add([
  17656. '{$interfaces com}',
  17657. 'type',
  17658. ' IUnknown = interface',
  17659. ' function _AddRef: longint;',
  17660. ' function _Release: longint;',
  17661. ' end;',
  17662. ' TObject = class(IUnknown)',
  17663. ' function _AddRef: longint; virtual; abstract;',
  17664. ' function _Release: longint; virtual; abstract;',
  17665. ' end;',
  17666. 'procedure DoDefault(i, j: IUnknown);',
  17667. 'begin',
  17668. ' i:=nil;',
  17669. ' i:=j;',
  17670. 'end;',
  17671. 'begin',
  17672. '']);
  17673. ConvertProgram;
  17674. CheckSource('TestClassInterface_COM_AssignArg',
  17675. LinesToStr([ // statements
  17676. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17677. 'rtl.createClass($mod, "TObject", null, function () {',
  17678. ' this.$init = function () {',
  17679. ' };',
  17680. ' this.$final = function () {',
  17681. ' };',
  17682. ' rtl.addIntf(this, $mod.IUnknown);',
  17683. '});',
  17684. 'this.DoDefault = function (i, j) {',
  17685. ' rtl._AddRef(i);',
  17686. ' try {',
  17687. ' i = rtl.setIntfL(i, null);',
  17688. ' i = rtl.setIntfL(i, j);',
  17689. ' } finally {',
  17690. ' rtl._Release(i);',
  17691. ' };',
  17692. '};',
  17693. '']),
  17694. LinesToStr([ // $mod.$main
  17695. '']));
  17696. end;
  17697. procedure TTestModule.TestClassInterface_COM_FunctionResult;
  17698. begin
  17699. StartProgram(false);
  17700. Add([
  17701. '{$interfaces com}',
  17702. 'type',
  17703. ' IUnknown = interface',
  17704. ' function _AddRef: longint;',
  17705. ' function _Release: longint;',
  17706. ' end;',
  17707. ' TObject = class(IUnknown)',
  17708. ' function _AddRef: longint; virtual; abstract;',
  17709. ' function _Release: longint; virtual; abstract;',
  17710. ' end;',
  17711. 'function DoDefault(i: IUnknown): IUnknown;',
  17712. 'begin',
  17713. ' Result:=i;',
  17714. ' if Result<>nil then exit;',
  17715. 'end;',
  17716. 'begin',
  17717. '']);
  17718. ConvertProgram;
  17719. CheckSource('TestClassInterface_COM_FunctionResult',
  17720. LinesToStr([ // statements
  17721. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17722. 'rtl.createClass($mod, "TObject", null, function () {',
  17723. ' this.$init = function () {',
  17724. ' };',
  17725. ' this.$final = function () {',
  17726. ' };',
  17727. ' rtl.addIntf(this, $mod.IUnknown);',
  17728. '});',
  17729. 'this.DoDefault = function (i) {',
  17730. ' var Result = null;',
  17731. ' var $ok = false;',
  17732. ' try {',
  17733. ' Result = rtl.setIntfL(Result, i);',
  17734. ' if(Result !== null){',
  17735. ' $ok = true;',
  17736. ' return Result;',
  17737. ' };',
  17738. ' $ok = true;',
  17739. ' } finally {',
  17740. ' if(!$ok) rtl._Release(Result);',
  17741. ' };',
  17742. ' return Result;',
  17743. '};',
  17744. '']),
  17745. LinesToStr([ // $mod.$main
  17746. '']));
  17747. end;
  17748. procedure TTestModule.TestClassInterface_COM_InheritedFuncResult;
  17749. begin
  17750. StartProgram(false);
  17751. Add([
  17752. '{$interfaces com}',
  17753. 'type',
  17754. ' IUnknown = interface',
  17755. ' function _AddRef: longint;',
  17756. ' function _Release: longint;',
  17757. ' end;',
  17758. ' TObject = class(IUnknown)',
  17759. ' function _AddRef: longint; virtual; abstract;',
  17760. ' function _Release: longint; virtual; abstract;',
  17761. ' function GetIntf: IUnknown; virtual;',
  17762. ' end;',
  17763. ' TMouse = class',
  17764. ' function GetIntf: IUnknown; override;',
  17765. ' end;',
  17766. 'function TObject.GetIntf: IUnknown; begin end;',
  17767. 'function TMouse.GetIntf: IUnknown;',
  17768. 'var i: IUnknown;',
  17769. 'begin',
  17770. ' inherited;',
  17771. ' inherited GetIntf;',
  17772. ' inherited GetIntf();',
  17773. ' Result:=inherited GetIntf;',
  17774. ' Result:=inherited GetIntf();',
  17775. ' i:=inherited GetIntf;',
  17776. ' i:=inherited GetIntf();',
  17777. 'end;',
  17778. 'begin',
  17779. '']);
  17780. ConvertProgram;
  17781. CheckSource('TestClassInterface_COM_InheritedFuncResult',
  17782. LinesToStr([ // statements
  17783. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17784. 'rtl.createClass($mod, "TObject", null, function () {',
  17785. ' this.$init = function () {',
  17786. ' };',
  17787. ' this.$final = function () {',
  17788. ' };',
  17789. ' this.GetIntf = function () {',
  17790. ' var Result = null;',
  17791. ' return Result;',
  17792. ' };',
  17793. ' rtl.addIntf(this, $mod.IUnknown);',
  17794. '});',
  17795. 'rtl.createClass($mod, "TMouse", $mod.TObject, function () {',
  17796. ' this.GetIntf = function () {',
  17797. ' var Result = null;',
  17798. ' var i = null;',
  17799. ' var $ir = rtl.createIntfRefs();',
  17800. ' var $ok = false;',
  17801. ' try {',
  17802. ' $ir.ref(1, $mod.TObject.GetIntf.call(this));',
  17803. ' $ir.ref(2, $mod.TObject.GetIntf.call(this));',
  17804. ' $ir.ref(3, $mod.TObject.GetIntf.call(this));',
  17805. ' Result = rtl.setIntfL(Result, $mod.TObject.GetIntf.call(this), true);',
  17806. ' Result = rtl.setIntfL(Result, $mod.TObject.GetIntf.call(this), true);',
  17807. ' i = rtl.setIntfL(i, $mod.TObject.GetIntf.call(this), true);',
  17808. ' i = rtl.setIntfL(i, $mod.TObject.GetIntf.call(this), true);',
  17809. ' $ok = true;',
  17810. ' } finally {',
  17811. ' $ir.free();',
  17812. ' rtl._Release(i);',
  17813. ' if (!$ok) rtl._Release(Result);',
  17814. ' };',
  17815. ' return Result;',
  17816. ' };',
  17817. ' rtl.addIntf(this, $mod.IUnknown);',
  17818. '});',
  17819. '']),
  17820. LinesToStr([ // $mod.$main
  17821. '']));
  17822. end;
  17823. procedure TTestModule.TestClassInterface_COM_IsAsTypeCasts;
  17824. begin
  17825. StartProgram(false);
  17826. Add([
  17827. '{$interfaces com}',
  17828. 'type',
  17829. ' IUnknown = interface',
  17830. ' function _AddRef: longint;',
  17831. ' function _Release: longint;',
  17832. ' end;',
  17833. ' TObject = class(IUnknown)',
  17834. ' function _AddRef: longint; virtual; abstract;',
  17835. ' function _Release: longint; virtual; abstract;',
  17836. ' end;',
  17837. 'procedure DoDefault(i, j: IUnknown; o: TObject);',
  17838. 'begin',
  17839. ' if i is IUnknown then ;',
  17840. ' if o is IUnknown then ;',
  17841. ' if i is TObject then ;',
  17842. ' i:=j as IUnknown;',
  17843. ' i:=o as IUnknown;',
  17844. ' o:=j as TObject;',
  17845. ' i:=IUnknown(j);',
  17846. ' i:=IUnknown(o);',
  17847. ' o:=TObject(i);',
  17848. 'end;',
  17849. 'begin',
  17850. '']);
  17851. ConvertProgram;
  17852. CheckSource('TestClassInterface_COM_IsAsTypeCasts',
  17853. LinesToStr([ // statements
  17854. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17855. 'rtl.createClass($mod, "TObject", null, function () {',
  17856. ' this.$init = function () {',
  17857. ' };',
  17858. ' this.$final = function () {',
  17859. ' };',
  17860. ' rtl.addIntf(this, $mod.IUnknown);',
  17861. '});',
  17862. 'this.DoDefault = function (i, j, o) {',
  17863. ' rtl._AddRef(i);',
  17864. ' try {',
  17865. ' if ($mod.IUnknown.isPrototypeOf(i)) ;',
  17866. ' if (rtl.queryIntfIsT(o, $mod.IUnknown)) ;',
  17867. ' if (rtl.intfIsClass(i, $mod.TObject)) ;',
  17868. ' i = rtl.setIntfL(i, rtl.as(j, $mod.IUnknown));',
  17869. ' i = rtl.setIntfL(i, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17870. ' o = rtl.intfAsClass(j, $mod.TObject);',
  17871. ' i = rtl.setIntfL(i, j);',
  17872. ' i = rtl.setIntfL(i, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17873. ' o = rtl.intfToClass(i, $mod.TObject);',
  17874. ' } finally {',
  17875. ' rtl._Release(i);',
  17876. ' };',
  17877. '};',
  17878. '']),
  17879. LinesToStr([ // $mod.$main
  17880. '']));
  17881. end;
  17882. procedure TTestModule.TestClassInterface_COM_PassAsArg;
  17883. begin
  17884. StartProgram(false);
  17885. Add([
  17886. '{$interfaces com}',
  17887. 'type',
  17888. ' IUnknown = interface',
  17889. ' function _AddRef: longint;',
  17890. ' function _Release: longint;',
  17891. ' end;',
  17892. ' TObject = class(IUnknown)',
  17893. ' function _AddRef: longint; virtual; abstract;',
  17894. ' function _Release: longint; virtual; abstract;',
  17895. ' end;',
  17896. 'procedure DoIt(v: IUnknown; const j: IUnknown; var k: IUnknown; out l: IUnknown);',
  17897. 'var o: TObject;',
  17898. 'begin',
  17899. ' DoIt(v,v,v,v);',
  17900. ' DoIt(o,o,k,k);',
  17901. 'end;',
  17902. 'procedure DoSome;',
  17903. 'var v: IUnknown;',
  17904. 'begin',
  17905. ' DoIt(v,v,v,v);',
  17906. 'end;',
  17907. 'var i: IUnknown;',
  17908. 'begin',
  17909. ' DoIt(i,i,i,i);',
  17910. '']);
  17911. ConvertProgram;
  17912. CheckSource('TestClassInterface_COM_PassAsArg',
  17913. LinesToStr([ // statements
  17914. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17915. 'rtl.createClass($mod, "TObject", null, function () {',
  17916. ' this.$init = function () {',
  17917. ' };',
  17918. ' this.$final = function () {',
  17919. ' };',
  17920. ' rtl.addIntf(this, $mod.IUnknown);',
  17921. '});',
  17922. 'this.DoIt = function (v, j, k, l) {',
  17923. ' var o = null;',
  17924. ' var $ir = rtl.createIntfRefs();',
  17925. ' rtl._AddRef(v);',
  17926. ' try {',
  17927. ' $mod.DoIt(v, v, {',
  17928. ' get: function () {',
  17929. ' return v;',
  17930. ' },',
  17931. ' set: function (w) {',
  17932. ' v = rtl.setIntfL(v, w);',
  17933. ' }',
  17934. ' }, {',
  17935. ' get: function () {',
  17936. ' return v;',
  17937. ' },',
  17938. ' set: function (w) {',
  17939. ' v = rtl.setIntfL(v, w);',
  17940. ' }',
  17941. ' });',
  17942. ' $mod.DoIt($ir.ref(1, rtl.queryIntfT(o, $mod.IUnknown)), $ir.ref(2, rtl.queryIntfT(o, $mod.IUnknown)), k, k);',
  17943. ' } finally {',
  17944. ' $ir.free();',
  17945. ' rtl._Release(v);',
  17946. ' };',
  17947. '};',
  17948. 'this.DoSome = function () {',
  17949. ' var v = null;',
  17950. ' try {',
  17951. ' $mod.DoIt(v, v, {',
  17952. ' get: function () {',
  17953. ' return v;',
  17954. ' },',
  17955. ' set: function (w) {',
  17956. ' v = rtl.setIntfL(v, w);',
  17957. ' }',
  17958. ' }, {',
  17959. ' get: function () {',
  17960. ' return v;',
  17961. ' },',
  17962. ' set: function (w) {',
  17963. ' v = rtl.setIntfL(v, w);',
  17964. ' }',
  17965. ' });',
  17966. ' } finally {',
  17967. ' rtl._Release(v);',
  17968. ' };',
  17969. '};',
  17970. 'this.i = null;',
  17971. '']),
  17972. LinesToStr([ // $mod.$main
  17973. '$mod.DoIt($mod.i, $mod.i, {',
  17974. ' p: $mod,',
  17975. ' get: function () {',
  17976. ' return this.p.i;',
  17977. ' },',
  17978. ' set: function (v) {',
  17979. ' rtl.setIntfP(this.p, "i", v);',
  17980. ' }',
  17981. '}, {',
  17982. ' p: $mod,',
  17983. ' get: function () {',
  17984. ' return this.p.i;',
  17985. ' },',
  17986. ' set: function (v) {',
  17987. ' rtl.setIntfP(this.p, "i", v);',
  17988. ' }',
  17989. '});',
  17990. '']));
  17991. end;
  17992. procedure TTestModule.TestClassInterface_COM_PassToUntypedParam;
  17993. begin
  17994. StartProgram(false);
  17995. Add([
  17996. '{$interfaces com}',
  17997. 'type',
  17998. ' IUnknown = interface',
  17999. ' function _AddRef: longint;',
  18000. ' function _Release: longint;',
  18001. ' end;',
  18002. ' TObject = class(IUnknown)',
  18003. ' function _AddRef: longint; virtual; abstract;',
  18004. ' function _Release: longint; virtual; abstract;',
  18005. ' end;',
  18006. 'procedure DoIt(out i);',
  18007. 'begin end;',
  18008. 'procedure DoSome;',
  18009. 'var v: IUnknown;',
  18010. 'begin',
  18011. ' DoIt(v);',
  18012. 'end;',
  18013. 'function GetIt: IUnknown;',
  18014. 'begin',
  18015. ' DoIt(Result);',
  18016. 'end;',
  18017. 'var i: IUnknown;',
  18018. 'begin',
  18019. ' DoIt(i);',
  18020. '']);
  18021. ConvertProgram;
  18022. CheckSource('TestClassInterface_COM_PassToUntypedParam',
  18023. LinesToStr([ // statements
  18024. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18025. 'rtl.createClass($mod, "TObject", null, function () {',
  18026. ' this.$init = function () {',
  18027. ' };',
  18028. ' this.$final = function () {',
  18029. ' };',
  18030. ' rtl.addIntf(this, $mod.IUnknown);',
  18031. '});',
  18032. 'this.DoIt = function (i) {',
  18033. '};',
  18034. 'this.DoSome = function () {',
  18035. ' var v = null;',
  18036. ' try {',
  18037. ' $mod.DoIt({',
  18038. ' get: function () {',
  18039. ' return v;',
  18040. ' },',
  18041. ' set: function (w) {',
  18042. ' v = w;',
  18043. ' }',
  18044. ' });',
  18045. ' } finally {',
  18046. ' rtl._Release(v);',
  18047. ' };',
  18048. '};',
  18049. 'this.GetIt = function () {',
  18050. ' var Result = null;',
  18051. ' var $ok = false;',
  18052. ' try {',
  18053. ' $mod.DoIt({',
  18054. ' get: function () {',
  18055. ' return Result;',
  18056. ' },',
  18057. ' set: function (v) {',
  18058. ' Result = v;',
  18059. ' }',
  18060. ' });',
  18061. ' $ok = true;',
  18062. ' } finally {',
  18063. ' if (!$ok) rtl._Release(Result);',
  18064. ' };',
  18065. ' return Result;',
  18066. '};',
  18067. 'this.i = null;',
  18068. '']),
  18069. LinesToStr([ // $mod.$main
  18070. 'try {',
  18071. ' $mod.DoIt({',
  18072. ' p: $mod,',
  18073. ' get: function () {',
  18074. ' return this.p.i;',
  18075. ' },',
  18076. ' set: function (v) {',
  18077. ' this.p.i = v;',
  18078. ' }',
  18079. ' });',
  18080. '} finally {',
  18081. ' rtl._Release($mod.i);',
  18082. '};',
  18083. '']));
  18084. end;
  18085. procedure TTestModule.TestClassInterface_COM_FunctionInExpr;
  18086. begin
  18087. StartProgram(false);
  18088. Add([
  18089. '{$interfaces com}',
  18090. 'type',
  18091. ' IUnknown = interface',
  18092. ' function _AddRef: longint;',
  18093. ' function _Release: longint;',
  18094. ' end;',
  18095. ' TObject = class(IUnknown)',
  18096. ' function _AddRef: longint; virtual; abstract;',
  18097. ' function _Release: longint; virtual; abstract;',
  18098. ' end;',
  18099. 'function GetIt: IUnknown;',
  18100. 'begin',
  18101. 'end;',
  18102. 'procedure DoSome;',
  18103. 'var v: IUnknown;',
  18104. ' i: longint;',
  18105. 'begin',
  18106. ' v:=GetIt;',
  18107. ' v:=GetIt();',
  18108. ' GetIt()._AddRef;',
  18109. ' i:=GetIt()._AddRef;',
  18110. 'end;',
  18111. 'var v: IUnknown;',
  18112. ' i: longint;',
  18113. 'begin',
  18114. ' v:=GetIt;',
  18115. ' v:=GetIt();',
  18116. ' GetIt()._AddRef;',
  18117. ' i:=GetIt()._AddRef;',
  18118. '']);
  18119. ConvertProgram;
  18120. CheckSource('TestClassInterface_COM_FunctionInExpr',
  18121. LinesToStr([ // statements
  18122. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18123. 'rtl.createClass($mod, "TObject", null, function () {',
  18124. ' this.$init = function () {',
  18125. ' };',
  18126. ' this.$final = function () {',
  18127. ' };',
  18128. ' rtl.addIntf(this, $mod.IUnknown);',
  18129. '});',
  18130. 'this.GetIt = function () {',
  18131. ' var Result = null;',
  18132. ' return Result;',
  18133. '};',
  18134. 'this.DoSome = function () {',
  18135. ' var v = null;',
  18136. ' var i = 0;',
  18137. ' var $ir = rtl.createIntfRefs();',
  18138. ' try {',
  18139. ' v = rtl.setIntfL(v, $mod.GetIt(), true);',
  18140. ' v = rtl.setIntfL(v, $mod.GetIt(), true);',
  18141. ' $ir.ref(1, $mod.GetIt())._AddRef();',
  18142. ' i = $ir.ref(2, $mod.GetIt())._AddRef();',
  18143. ' } finally {',
  18144. ' $ir.free();',
  18145. ' rtl._Release(v);',
  18146. ' };',
  18147. '};',
  18148. 'this.v = null;',
  18149. 'this.i = 0;',
  18150. '']),
  18151. LinesToStr([ // $mod.$main
  18152. 'var $ir = rtl.createIntfRefs();',
  18153. 'try {',
  18154. ' rtl.setIntfP($mod, "v", $mod.GetIt(), true);',
  18155. ' rtl.setIntfP($mod, "v", $mod.GetIt(), true);',
  18156. ' $ir.ref(1, $mod.GetIt())._AddRef();',
  18157. ' $mod.i = $ir.ref(2, $mod.GetIt())._AddRef();',
  18158. '} finally {',
  18159. ' $ir.free();',
  18160. '};',
  18161. '']));
  18162. end;
  18163. procedure TTestModule.TestClassInterface_COM_Property;
  18164. begin
  18165. StartProgram(false);
  18166. Add([
  18167. '{$interfaces com}',
  18168. 'type',
  18169. ' IUnknown = interface',
  18170. ' function _AddRef: longint;',
  18171. ' function _Release: longint;',
  18172. ' end;',
  18173. ' TObject = class(IUnknown)',
  18174. ' FAnt: IUnknown;',
  18175. ' function _AddRef: longint; virtual; abstract;',
  18176. ' function _Release: longint; virtual; abstract;',
  18177. ' function GetBird: IUnknown; virtual; abstract;',
  18178. ' procedure SetBird(Value: IUnknown); virtual; abstract;',
  18179. ' function GetItems(Index: longint): IUnknown; virtual; abstract;',
  18180. ' procedure SetItems(Index: longint; Value: IUnknown); virtual; abstract;',
  18181. ' property Ant: IUnknown read FAnt write FAnt;',
  18182. ' property Bird: IUnknown read GetBird write SetBird;',
  18183. ' property Items[Index: longint]: IUnknown read GetItems write SetItems; default;',
  18184. ' end;',
  18185. 'procedure DoIt;',
  18186. 'var',
  18187. ' o: TObject;',
  18188. ' v: IUnknown;',
  18189. 'begin',
  18190. ' v:=o.Ant;',
  18191. ' o.Ant:=v;',
  18192. ' o.Ant:=o.Ant;',
  18193. ' v:=o.Bird;',
  18194. ' o.Bird:=v;',
  18195. ' o.Bird:=o.Bird;',
  18196. ' v:=o.Items[1];',
  18197. ' o.Items[2]:=v;',
  18198. ' o.Items[3]:=o.Items[4];',
  18199. ' v:=o[5];',
  18200. ' o[6]:=v;',
  18201. ' o[7]:=o[8];',
  18202. 'end;',
  18203. 'begin',
  18204. '']);
  18205. ConvertProgram;
  18206. CheckSource('TestClassInterface_COM_Property',
  18207. LinesToStr([ // statements
  18208. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18209. 'rtl.createClass($mod, "TObject", null, function () {',
  18210. ' this.$init = function () {',
  18211. ' this.FAnt = null;',
  18212. ' };',
  18213. ' this.$final = function () {',
  18214. ' this.FAnt = undefined;',
  18215. ' };',
  18216. ' rtl.addIntf(this, $mod.IUnknown);',
  18217. '});',
  18218. 'this.DoIt = function () {',
  18219. ' var o = null;',
  18220. ' var v = null;',
  18221. ' var $ir = rtl.createIntfRefs();',
  18222. ' try {',
  18223. ' v = rtl.setIntfL(v, o.FAnt);',
  18224. ' rtl.setIntfP(o, "FAnt", v);',
  18225. ' rtl.setIntfP(o, "FAnt", o.FAnt);',
  18226. ' v = rtl.setIntfL(v, o.GetBird(), true);',
  18227. ' o.SetBird(v);',
  18228. ' o.SetBird($ir.ref(1, o.GetBird()));',
  18229. ' v = rtl.setIntfL(v, o.GetItems(1), true);',
  18230. ' o.SetItems(2, v);',
  18231. ' o.SetItems(3, $ir.ref(2, o.GetItems(4)));',
  18232. ' v = rtl.setIntfL(v, o.GetItems(5), true);',
  18233. ' o.SetItems(6, v);',
  18234. ' o.SetItems(7, $ir.ref(3, o.GetItems(8)));',
  18235. ' } finally {',
  18236. ' $ir.free();',
  18237. ' rtl._Release(v);',
  18238. ' };',
  18239. '};',
  18240. '']),
  18241. LinesToStr([ // $mod.$main
  18242. '']));
  18243. end;
  18244. procedure TTestModule.TestClassInterface_COM_IntfProperty;
  18245. begin
  18246. StartProgram(false);
  18247. Add([
  18248. '{$interfaces com}',
  18249. 'type',
  18250. ' IUnknown = interface',
  18251. ' function _AddRef: longint;',
  18252. ' function _Release: longint;',
  18253. ' function GetBird: IUnknown;',
  18254. ' procedure SetBird(Value: IUnknown);',
  18255. ' function GetItems(Index: longint): IUnknown;',
  18256. ' procedure SetItems(Index: longint; Value: IUnknown);',
  18257. ' property Bird: IUnknown read GetBird write SetBird;',
  18258. ' property Items[Index: longint]: IUnknown read GetItems write SetItems; default;',
  18259. ' end;',
  18260. ' TObject = class(IUnknown)',
  18261. ' function _AddRef: longint; virtual; abstract;',
  18262. ' function _Release: longint; virtual; abstract;',
  18263. ' function GetBird: IUnknown; virtual; abstract;',
  18264. ' procedure SetBird(Value: IUnknown); virtual; abstract;',
  18265. ' function GetItems(Index: longint): IUnknown; virtual; abstract;',
  18266. ' procedure SetItems(Index: longint; Value: IUnknown); virtual; abstract;',
  18267. ' end;',
  18268. 'procedure DoIt;',
  18269. 'var',
  18270. ' o: TObject;',
  18271. ' v: IUnknown;',
  18272. 'begin',
  18273. ' v:=v.Items[1];',
  18274. ' v.Items[2]:=v;',
  18275. ' v.Items[3]:=v.Items[4];',
  18276. ' v:=v[5];',
  18277. ' v[6]:=v;',
  18278. ' v[7]:=v[8];',
  18279. ' v[9].Bird.Bird:=v;',
  18280. ' v:=v.Bird[10].Bird',
  18281. 'end;',
  18282. 'begin',
  18283. '']);
  18284. ConvertProgram;
  18285. CheckSource('TestClassInterface_COM_IntfProperty',
  18286. LinesToStr([ // statements
  18287. 'rtl.createInterface($mod, "IUnknown", "{385F5482-571B-338C-8130-4E97F330543B}", [',
  18288. ' "_AddRef",',
  18289. ' "_Release",',
  18290. ' "GetBird",',
  18291. ' "SetBird",',
  18292. ' "GetItems",',
  18293. ' "SetItems"',
  18294. '], null);',
  18295. 'rtl.createClass($mod, "TObject", null, function () {',
  18296. ' this.$init = function () {',
  18297. ' };',
  18298. ' this.$final = function () {',
  18299. ' };',
  18300. ' rtl.addIntf(this, $mod.IUnknown);',
  18301. '});',
  18302. 'this.DoIt = function () {',
  18303. ' var o = null;',
  18304. ' var v = null;',
  18305. ' var $ir = rtl.createIntfRefs();',
  18306. ' try {',
  18307. ' v = rtl.setIntfL(v, v.GetItems(1), true);',
  18308. ' v.SetItems(2, v);',
  18309. ' v.SetItems(3, $ir.ref(1, v.GetItems(4)));',
  18310. ' v = rtl.setIntfL(v, v.GetItems(5), true);',
  18311. ' v.SetItems(6, v);',
  18312. ' v.SetItems(7, $ir.ref(2, v.GetItems(8)));',
  18313. ' $ir.ref(4, $ir.ref(3, v.GetItems(9)).GetBird()).SetBird(v);',
  18314. ' v = rtl.setIntfL(v, $ir.ref(6, $ir.ref(5, v.GetBird()).GetItems(10)).GetBird(), true);',
  18315. ' } finally {',
  18316. ' $ir.free();',
  18317. ' rtl._Release(v);',
  18318. ' };',
  18319. '};',
  18320. '']),
  18321. LinesToStr([ // $mod.$main
  18322. '']));
  18323. end;
  18324. procedure TTestModule.TestClassInterface_COM_Delegation;
  18325. begin
  18326. StartProgram(false);
  18327. Add([
  18328. '{$interfaces com}',
  18329. 'type',
  18330. ' IUnknown = interface',
  18331. ' function _AddRef: longint;',
  18332. ' function _Release: longint;',
  18333. ' end;',
  18334. ' IBird = interface(IUnknown)',
  18335. ' procedure Fly(s: string);',
  18336. ' end;',
  18337. ' IEagle = interface(IBird) end;',
  18338. ' IDove = interface(IBird) end;',
  18339. ' ISwallow = interface(IBird) end;',
  18340. ' TObject = class',
  18341. ' end;',
  18342. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  18343. ' function _AddRef: longint; virtual; abstract;',
  18344. ' function _Release: longint; virtual; abstract;',
  18345. ' procedure Fly(s: string); virtual; abstract;',
  18346. ' end;',
  18347. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  18348. ' function _AddRef: longint; virtual; abstract;',
  18349. ' function _Release: longint; virtual; abstract;',
  18350. ' FBirdIntf: IBird;',
  18351. ' property BirdIntf: IBird read FBirdIntf implements IBird;',
  18352. ' function GetEagleIntf: IEagle; virtual; abstract;',
  18353. ' property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  18354. ' FDoveObj: TBird;',
  18355. ' property DoveObj: TBird read FDoveObj implements IDove;',
  18356. ' function GetSwallowObj: TBird; virtual; abstract;',
  18357. ' property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  18358. ' end;',
  18359. 'begin',
  18360. '']);
  18361. ConvertProgram;
  18362. CheckSource('TestClassInterface_COM_Delegation',
  18363. LinesToStr([ // statements
  18364. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18365. 'rtl.createInterface($mod, "IBird", "{CC440C7F-7623-3DEE-AE88-000B86AAF108}", ["Fly"], $mod.IUnknown);',
  18366. 'rtl.createInterface($mod, "IEagle", "{4B6A41C9-B020-3D7C-B688-96D19022B1B4}", [], $mod.IBird);',
  18367. 'rtl.createInterface($mod, "IDove", "{4B6A41C9-B020-3D7C-B688-96D18EF16074}", [], $mod.IBird);',
  18368. 'rtl.createInterface($mod, "ISwallow", "{BB6A41C9-B020-3D7C-B688-96D1CBDCB359}", [], $mod.IBird);',
  18369. 'rtl.createClass($mod, "TObject", null, function () {',
  18370. ' this.$init = function () {',
  18371. ' };',
  18372. ' this.$final = function () {',
  18373. ' };',
  18374. '});',
  18375. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  18376. ' rtl.addIntf(this, $mod.IBird);',
  18377. ' rtl.addIntf(this, $mod.IEagle);',
  18378. ' rtl.addIntf(this, $mod.IDove);',
  18379. ' rtl.addIntf(this, $mod.ISwallow);',
  18380. '});',
  18381. 'rtl.createClass($mod, "TBat", $mod.TObject, function () {',
  18382. ' this.$init = function () {',
  18383. ' $mod.TObject.$init.call(this);',
  18384. ' this.FBirdIntf = null;',
  18385. ' this.FDoveObj = null;',
  18386. ' };',
  18387. ' this.$final = function () {',
  18388. ' this.FBirdIntf = undefined;',
  18389. ' this.FDoveObj = undefined;',
  18390. ' $mod.TObject.$final.call(this);',
  18391. ' };',
  18392. ' this.$intfmaps = {',
  18393. ' "{CC440C7F-7623-3DEE-AE88-000B86AAF108}": function () {',
  18394. ' return rtl._AddRef(this.FBirdIntf);',
  18395. ' },',
  18396. ' "{4B6A41C9-B020-3D7C-B688-96D19022B1B4}": function () {',
  18397. ' return this.GetEagleIntf();',
  18398. ' },',
  18399. ' "{4B6A41C9-B020-3D7C-B688-96D18EF16074}": function () {',
  18400. ' return rtl.queryIntfT(this.FDoveObj, $mod.IDove);',
  18401. ' },',
  18402. ' "{BB6A41C9-B020-3D7C-B688-96D1CBDCB359}": function () {',
  18403. ' return rtl.queryIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  18404. ' }',
  18405. ' };',
  18406. '});',
  18407. '']),
  18408. LinesToStr([ // $mod.$main
  18409. '']));
  18410. end;
  18411. procedure TTestModule.TestClassInterface_COM_With;
  18412. begin
  18413. StartProgram(false);
  18414. Add([
  18415. '{$interfaces com}',
  18416. 'type',
  18417. ' IUnknown = interface',
  18418. ' function _AddRef: longint;',
  18419. ' function _Release: longint;',
  18420. ' function GetAnt: IUnknown;',
  18421. ' property Ant: IUnknown read GetAnt;',
  18422. ' end;',
  18423. ' TObject = class(IUnknown)',
  18424. ' function _AddRef: longint; virtual; abstract;',
  18425. ' function _Release: longint; virtual; abstract;',
  18426. ' function GetAnt: IUnknown; virtual; abstract;',
  18427. ' property Ant: IUnknown read GetAnt;',
  18428. ' end;',
  18429. 'procedure DoIt;',
  18430. 'var',
  18431. ' i: IUnknown;',
  18432. 'begin',
  18433. ' with i do ',
  18434. ' GetAnt;',
  18435. ' with i.Ant, Ant do ',
  18436. ' GetAnt;',
  18437. 'end;',
  18438. 'begin',
  18439. '']);
  18440. ConvertProgram;
  18441. CheckSource('TestClassInterface_COM_With',
  18442. LinesToStr([ // statements
  18443. 'rtl.createInterface($mod, "IUnknown", "{D7ADB00D-C6B6-39FB-BDDF-21CD521DDFA9}", ["_AddRef", "_Release", "GetAnt"], null);',
  18444. 'rtl.createClass($mod, "TObject", null, function () {',
  18445. ' this.$init = function () {',
  18446. ' };',
  18447. ' this.$final = function () {',
  18448. ' };',
  18449. ' rtl.addIntf(this, $mod.IUnknown);',
  18450. '});',
  18451. 'this.DoIt = function () {',
  18452. ' var i = null;',
  18453. ' var $ir = rtl.createIntfRefs();',
  18454. ' try {',
  18455. ' $ir.ref(1, i.GetAnt());',
  18456. ' var $with1 = $ir.ref(2, i.GetAnt());',
  18457. ' var $with2 = $ir.ref(3, $with1.GetAnt());',
  18458. ' $ir.ref(4, $with2.GetAnt());',
  18459. ' } finally {',
  18460. ' $ir.free();',
  18461. ' };',
  18462. '};',
  18463. '']),
  18464. LinesToStr([ // $mod.$main
  18465. '']));
  18466. end;
  18467. procedure TTestModule.TestClassInterface_COM_ForIn;
  18468. begin
  18469. StartProgram(false);
  18470. Add([
  18471. '{$interfaces com}',
  18472. 'type',
  18473. ' IUnknown = interface end;',
  18474. ' TObject = class',
  18475. ' Id: longint;',
  18476. ' end;',
  18477. ' IEnumerator = interface(IUnknown)',
  18478. ' function GetCurrent: TObject;',
  18479. ' function MoveNext: Boolean;',
  18480. ' property Current: TObject read GetCurrent;',
  18481. ' end;',
  18482. ' IEnumerable = interface(IUnknown)',
  18483. ' function GetEnumerator: IEnumerator;',
  18484. ' end;',
  18485. 'var',
  18486. ' o: TObject;',
  18487. ' i: IEnumerable;',
  18488. 'begin',
  18489. ' for o in i do o.Id:=3;',
  18490. '']);
  18491. ConvertProgram;
  18492. CheckSource('TestClassInterface_COM_ForIn',
  18493. LinesToStr([ // statements
  18494. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  18495. 'rtl.createClass($mod, "TObject", null, function () {',
  18496. ' this.$init = function () {',
  18497. ' this.Id = 0;',
  18498. ' };',
  18499. ' this.$final = function () {',
  18500. ' };',
  18501. '});',
  18502. 'rtl.createInterface($mod, "IEnumerator", "{95D7745D-ED61-3F13-BBE4-07708161999E}", ["GetCurrent", "MoveNext"], $mod.IUnknown);',
  18503. 'rtl.createInterface($mod, "IEnumerable", "{8CC9D45D-ED7D-3B73-96B6-290B931BB19E}", ["GetEnumerator"], $mod.IUnknown);',
  18504. 'this.o = null;',
  18505. 'this.i = null;',
  18506. '']),
  18507. LinesToStr([ // $mod.$main
  18508. 'var $in1 = $mod.i.GetEnumerator();',
  18509. 'try {',
  18510. ' while ($in1.MoveNext()) {',
  18511. ' $mod.o = $in1.GetCurrent();',
  18512. ' $mod.o.Id = 3;',
  18513. ' }',
  18514. '} finally {',
  18515. ' rtl._Release($in1)',
  18516. '};',
  18517. '']));
  18518. end;
  18519. procedure TTestModule.TestClassInterface_COM_ArrayOfIntfFail;
  18520. begin
  18521. StartProgram(false);
  18522. Add([
  18523. '{$interfaces com}',
  18524. 'type',
  18525. ' IUnknown = interface',
  18526. ' function _AddRef: longint;',
  18527. ' function _Release: longint;',
  18528. ' end;',
  18529. ' TObject = class',
  18530. ' end;',
  18531. ' TArrOfIntf = array of IUnknown;',
  18532. 'begin',
  18533. '']);
  18534. SetExpectedPasResolverError('Not supported: array of COM-interface',nNotSupportedX);
  18535. ConvertProgram;
  18536. end;
  18537. procedure TTestModule.TestClassInterface_COM_RecordIntfFail;
  18538. begin
  18539. StartProgram(false);
  18540. Add([
  18541. '{$interfaces com}',
  18542. 'type',
  18543. ' IUnknown = interface',
  18544. ' function _AddRef: longint;',
  18545. ' function _Release: longint;',
  18546. ' end;',
  18547. ' TRec = record',
  18548. ' i: IUnknown;',
  18549. ' end;',
  18550. 'begin',
  18551. '']);
  18552. SetExpectedPasResolverError('Not supported: COM-interface as record member',nNotSupportedX);
  18553. ConvertProgram;
  18554. end;
  18555. procedure TTestModule.TestClassInterface_COM_UnitInitialization;
  18556. begin
  18557. StartUnit(false);
  18558. Add([
  18559. '{$interfaces com}',
  18560. 'interface',
  18561. 'implementation',
  18562. 'type',
  18563. ' IUnknown = interface',
  18564. ' function _AddRef: longint;',
  18565. ' end;',
  18566. ' TObject = class(IUnknown)',
  18567. ' function _AddRef: longint;',
  18568. ' end;',
  18569. 'function TObject._AddRef: longint; begin end;',
  18570. 'var i: IUnknown;',
  18571. ' o: TObject;',
  18572. 'initialization',
  18573. ' i:=nil;',
  18574. ' i:=i;',
  18575. ' i:=o;',
  18576. ' if (o as IUnknown)=nil then ;',
  18577. '']);
  18578. ConvertUnit;
  18579. CheckSource('TestClassInterface_COM_UnitInitialization',
  18580. LinesToStr([ // statements
  18581. 'var $impl = $mod.$impl;',
  18582. '']),
  18583. LinesToStr([ // this.$init
  18584. 'var $ir = rtl.createIntfRefs();',
  18585. 'try {',
  18586. ' rtl.setIntfP($impl, "i", null);',
  18587. ' rtl.setIntfP($impl, "i", $impl.i);',
  18588. ' rtl.setIntfP($impl, "i", rtl.queryIntfT($impl.o, $impl.IUnknown), true);',
  18589. ' if ($ir.ref(1, rtl.queryIntfT($impl.o, $impl.IUnknown)) === null) ;',
  18590. '} finally {',
  18591. ' $ir.free();',
  18592. '};',
  18593. '']),
  18594. LinesToStr([ // implementation
  18595. 'rtl.createInterface($impl, "IUnknown", "{B92D5841-758A-322B-BDDF-21CD52180000}", ["_AddRef"], null);',
  18596. 'rtl.createClass($impl, "TObject", null, function () {',
  18597. ' this.$init = function () {',
  18598. ' };',
  18599. ' this.$final = function () {',
  18600. ' };',
  18601. ' this._AddRef = function () {',
  18602. ' var Result = 0;',
  18603. ' return Result;',
  18604. ' };',
  18605. ' rtl.addIntf(this, $impl.IUnknown);',
  18606. '});',
  18607. '$impl.i = null;',
  18608. '$impl.o = null;',
  18609. ''])
  18610. );
  18611. end;
  18612. procedure TTestModule.TestClassInterface_GUID;
  18613. begin
  18614. StartProgram(false);
  18615. Add([
  18616. '{$interfaces corba}',
  18617. 'type',
  18618. ' IUnknown = interface',
  18619. ' [''{f31db68f-3010-D355-4EBA-CDD4EF4A737C}'']',
  18620. ' end;',
  18621. ' TObject = class end;',
  18622. ' TGUID = record D1, D2, D3, D4: word; end;',
  18623. ' TAliasGUID = TGUID;',
  18624. ' TGUIDString = type string;',
  18625. ' TAliasGUIDString = TGUIDString;',
  18626. 'procedure DoConstGUIDIt(const g: TAliasGUID); overload;',
  18627. 'begin end;',
  18628. 'procedure DoDefGUID(g: TAliasGUID); overload;',
  18629. 'begin end;',
  18630. 'procedure DoStr(const s: TAliasGUIDString); overload;',
  18631. 'begin end;',
  18632. 'var',
  18633. ' i: IUnknown;',
  18634. ' g: TAliasGUID = ''{d91c9af4-3C93-420F-A303-BF5BA82BFD23}'';',
  18635. ' s: TAliasGUIDString;',
  18636. 'begin',
  18637. ' DoConstGUIDIt(IUnknown);',
  18638. ' DoDefGUID(IUnknown);',
  18639. ' DoStr(IUnknown);',
  18640. ' DoConstGUIDIt(i);',
  18641. ' DoDefGUID(i);',
  18642. ' DoStr(i);',
  18643. ' DoConstGUIDIt(''{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}'');',
  18644. ' DoDefGUID(''{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}'');',
  18645. ' DoStr(g);',
  18646. ' g:=i;',
  18647. ' g:=IUnknown;',
  18648. ' g:=''{D91C9AF4-3C93-420F-A303-bf5ba82bfd23}'';',
  18649. ' s:=i;',
  18650. ' s:=IUnknown;',
  18651. ' s:=g;',
  18652. ' if g=i then ;',
  18653. ' if i=g then ;',
  18654. ' if g=IUnknown then ;',
  18655. ' if IUnknown=g then ;',
  18656. ' if s=i then ;',
  18657. ' if i=s then ;',
  18658. ' if s=IUnknown then ;',
  18659. ' if IUnknown=s then ;',
  18660. ' if s=g then ;',
  18661. ' if g=s then ;',
  18662. '']);
  18663. ConvertProgram;
  18664. CheckSource('TestClassInterface_GUID',
  18665. LinesToStr([ // statements
  18666. 'rtl.createInterface($mod, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
  18667. 'rtl.createClass($mod, "TObject", null, function () {',
  18668. ' this.$init = function () {',
  18669. ' };',
  18670. ' this.$final = function () {',
  18671. ' };',
  18672. '});',
  18673. 'rtl.recNewT($mod, "TGUID", function () {',
  18674. ' this.D1 = 0;',
  18675. ' this.D2 = 0;',
  18676. ' this.D3 = 0;',
  18677. ' this.D4 = 0;',
  18678. ' this.$eq = function (b) {',
  18679. ' return (this.D1 === b.D1) && (this.D2 === b.D2) && (this.D3 === b.D3) && (this.D4 === b.D4);',
  18680. ' };',
  18681. ' this.$assign = function (s) {',
  18682. ' this.D1 = s.D1;',
  18683. ' this.D2 = s.D2;',
  18684. ' this.D3 = s.D3;',
  18685. ' this.D4 = s.D4;',
  18686. ' return this;',
  18687. ' };',
  18688. '});',
  18689. 'this.DoConstGUIDIt = function (g) {',
  18690. '};',
  18691. 'this.DoDefGUID = function (g) {',
  18692. '};',
  18693. 'this.DoStr = function (s) {',
  18694. '};',
  18695. 'this.i = null;',
  18696. 'this.g = $mod.TGUID.$clone({',
  18697. ' D1: 0xD91C9AF4,',
  18698. ' D2: 0x3C93,',
  18699. ' D3: 0x420F,',
  18700. ' D4: [',
  18701. ' 0xA3,',
  18702. ' 0x03,',
  18703. ' 0xBF,',
  18704. ' 0x5B,',
  18705. ' 0xA8,',
  18706. ' 0x2B,',
  18707. ' 0xFD,',
  18708. ' 0x23',
  18709. ' ]',
  18710. '});',
  18711. 'this.s = "";',
  18712. '']),
  18713. LinesToStr([ // $mod.$main
  18714. '$mod.DoConstGUIDIt(rtl.getIntfGUIDR($mod.IUnknown));',
  18715. '$mod.DoDefGUID($mod.TGUID.$clone(rtl.getIntfGUIDR($mod.IUnknown)));',
  18716. '$mod.DoStr($mod.IUnknown.$guid);',
  18717. '$mod.DoConstGUIDIt(rtl.getIntfGUIDR($mod.i));',
  18718. '$mod.DoDefGUID($mod.TGUID.$clone(rtl.getIntfGUIDR($mod.i)));',
  18719. '$mod.DoStr($mod.i.$guid);',
  18720. '$mod.DoConstGUIDIt(rtl.strToGUIDR("{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}"));',
  18721. '$mod.DoDefGUID(rtl.strToGUIDR("{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}"));',
  18722. '$mod.DoStr(rtl.guidrToStr($mod.g));',
  18723. '$mod.g.$assign(rtl.getIntfGUIDR($mod.i));',
  18724. '$mod.g.$assign(rtl.getIntfGUIDR($mod.IUnknown));',
  18725. '$mod.g.$assign({',
  18726. ' D1: 0xD91C9AF4,',
  18727. ' D2: 0x3C93,',
  18728. ' D3: 0x420F,',
  18729. ' D4: [',
  18730. ' 0xA3,',
  18731. ' 0x03,',
  18732. ' 0xBF,',
  18733. ' 0x5B,',
  18734. ' 0xA8,',
  18735. ' 0x2B,',
  18736. ' 0xFD,',
  18737. ' 0x23',
  18738. ' ]',
  18739. '});',
  18740. '$mod.s = $mod.i.$guid;',
  18741. '$mod.s = $mod.IUnknown.$guid;',
  18742. '$mod.s = rtl.guidrToStr($mod.g);',
  18743. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.i))) ;',
  18744. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.i))) ;',
  18745. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.IUnknown))) ;',
  18746. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.IUnknown))) ;',
  18747. 'if ($mod.s === $mod.i.$guid) ;',
  18748. 'if ($mod.i.$guid === $mod.s) ;',
  18749. 'if ($mod.s === $mod.IUnknown.$guid) ;',
  18750. 'if ($mod.IUnknown.$guid === $mod.s) ;',
  18751. 'if ($mod.g.$eq(rtl.createTGUID($mod.s))) ;',
  18752. 'if ($mod.g.$eq(rtl.createTGUID($mod.s))) ;',
  18753. '']));
  18754. end;
  18755. procedure TTestModule.TestClassInterface_GUIDProperty;
  18756. begin
  18757. StartProgram(false);
  18758. Add([
  18759. '{$interfaces corba}',
  18760. 'type',
  18761. ' IUnknown = interface',
  18762. ' [''{f31db68f-3010-D355-4EBA-CDD4EF4A737C}'']',
  18763. ' end;',
  18764. ' TGUID = record D1, D2, D3, D4: word; end;',
  18765. ' TAliasGUID = TGUID;',
  18766. ' TGUIDString = type string;',
  18767. ' TAliasGUIDString = TGUIDString;',
  18768. ' TObject = class',
  18769. ' function GetG: TAliasGUID; virtual; abstract;',
  18770. ' procedure SetG(const Value: TAliasGUID); virtual; abstract;',
  18771. ' function GetS: TAliasGUIDString; virtual; abstract;',
  18772. ' procedure SetS(const Value: TAliasGUIDString); virtual; abstract;',
  18773. ' property g: TAliasGUID read GetG write SetG;',
  18774. ' property s: TAliasGUIDString read GetS write SetS;',
  18775. ' end;',
  18776. 'var o: TObject;',
  18777. 'begin',
  18778. ' o.g:=IUnknown;',
  18779. ' o.g:=''{D91C9AF4-3C93-420F-A303-bf5ba82bfd23}'';',
  18780. ' o.s:=IUnknown;',
  18781. ' o.s:=o.g;',
  18782. '']);
  18783. ConvertProgram;
  18784. CheckSource('TestClassInterface_GUIDProperty',
  18785. LinesToStr([ // statements
  18786. 'rtl.createInterface($mod, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
  18787. 'rtl.recNewT($mod, "TGUID", function () {',
  18788. ' this.D1 = 0;',
  18789. ' this.D2 = 0;',
  18790. ' this.D3 = 0;',
  18791. ' this.D4 = 0;',
  18792. ' this.$eq = function (b) {',
  18793. ' return (this.D1 === b.D1) && (this.D2 === b.D2) && (this.D3 === b.D3) && (this.D4 === b.D4);',
  18794. ' };',
  18795. ' this.$assign = function (s) {',
  18796. ' this.D1 = s.D1;',
  18797. ' this.D2 = s.D2;',
  18798. ' this.D3 = s.D3;',
  18799. ' this.D4 = s.D4;',
  18800. ' return this;',
  18801. ' };',
  18802. '});',
  18803. 'rtl.createClass($mod, "TObject", null, function () {',
  18804. ' this.$init = function () {',
  18805. ' };',
  18806. ' this.$final = function () {',
  18807. ' };',
  18808. '});',
  18809. 'this.o = null;',
  18810. '']),
  18811. LinesToStr([ // $mod.$main
  18812. '$mod.o.SetG(rtl.getIntfGUIDR($mod.IUnknown));',
  18813. '$mod.o.SetG({',
  18814. ' D1: 0xD91C9AF4,',
  18815. ' D2: 0x3C93,',
  18816. ' D3: 0x420F,',
  18817. ' D4: [',
  18818. ' 0xA3,',
  18819. ' 0x03,',
  18820. ' 0xBF,',
  18821. ' 0x5B,',
  18822. ' 0xA8,',
  18823. ' 0x2B,',
  18824. ' 0xFD,',
  18825. ' 0x23',
  18826. ' ]',
  18827. '});',
  18828. '$mod.o.SetS($mod.IUnknown.$guid);',
  18829. '$mod.o.SetS(rtl.guidrToStr($mod.o.GetG()));',
  18830. '']));
  18831. end;
  18832. procedure TTestModule.TestClassHelper_ClassVar;
  18833. begin
  18834. StartProgram(false);
  18835. Add([
  18836. 'type',
  18837. ' TObject = class',
  18838. ' end;',
  18839. ' THelper = class helper for TObject',
  18840. ' const',
  18841. ' One = 1;',
  18842. ' Two: word = 2;',
  18843. ' class var',
  18844. ' Glob: word;',
  18845. ' function Foo(w: word): word;',
  18846. ' class function Bar(w: word): word;',
  18847. ' end;',
  18848. 'function THelper.foo(w: word): word;',
  18849. 'begin',
  18850. ' Result:=w;',
  18851. ' Two:=One+w;',
  18852. ' Glob:=Glob;',
  18853. ' Result:=Self.Glob;',
  18854. ' Self.Glob:=Self.Glob;',
  18855. ' with Self do Glob:=Glob;',
  18856. 'end;',
  18857. 'class function THelper.bar(w: word): word;',
  18858. 'begin',
  18859. ' Result:=w;',
  18860. ' Two:=One;',
  18861. ' Glob:=Glob;',
  18862. ' Self.Glob:=Self.Glob;',
  18863. ' with Self do Glob:=Glob;',
  18864. 'end;',
  18865. 'var o: TObject;',
  18866. 'begin',
  18867. ' tobject.two:=tobject.one;',
  18868. ' tobject.Glob:=tobject.Glob;',
  18869. ' with tobject do begin',
  18870. ' two:=one;',
  18871. ' Glob:=Glob;',
  18872. ' end;',
  18873. ' o.two:=o.one;',
  18874. ' o.Glob:=o.Glob;',
  18875. ' with o do begin',
  18876. ' two:=one;',
  18877. ' Glob:=Glob;',
  18878. ' end;',
  18879. '']);
  18880. ConvertProgram;
  18881. CheckSource('TestClassHelper_ClassVar',
  18882. LinesToStr([ // statements
  18883. 'rtl.createClass($mod, "TObject", null, function () {',
  18884. ' this.$init = function () {',
  18885. ' };',
  18886. ' this.$final = function () {',
  18887. ' };',
  18888. '});',
  18889. 'rtl.createHelper($mod, "THelper", null, function () {',
  18890. ' this.One = 1;',
  18891. ' this.Two = 2;',
  18892. ' this.Glob = 0;',
  18893. ' this.Foo = function (w) {',
  18894. ' var Result = 0;',
  18895. ' Result = w;',
  18896. ' $mod.THelper.Two = 1 + w;',
  18897. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18898. ' Result = $mod.THelper.Glob;',
  18899. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18900. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18901. ' return Result;',
  18902. ' };',
  18903. ' this.Bar = function (w) {',
  18904. ' var Result = 0;',
  18905. ' Result = w;',
  18906. ' $mod.THelper.Two = 1;',
  18907. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18908. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18909. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18910. ' return Result;',
  18911. ' };',
  18912. '});',
  18913. 'this.o = null;',
  18914. '']),
  18915. LinesToStr([ // $mod.$main
  18916. '$mod.THelper.Two = 1;',
  18917. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18918. 'var $with1 = $mod.TObject;',
  18919. '$mod.THelper.Two = 1;',
  18920. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18921. '$mod.THelper.Two = 1;',
  18922. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18923. 'var $with2 = $mod.o;',
  18924. '$mod.THelper.Two = 1;',
  18925. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18926. '']));
  18927. end;
  18928. procedure TTestModule.TestClassHelper_Method_AccessInstanceFields;
  18929. begin
  18930. StartProgram(false);
  18931. Add([
  18932. 'type',
  18933. ' TObject = class',
  18934. ' FSize: word;',
  18935. ' property Size: word read FSize write FSize;',
  18936. ' end;',
  18937. ' THelper = class helper for TObject',
  18938. ' function Foo(w: word = 1): word;',
  18939. ' end;',
  18940. 'function THelper.foo(w: word): word;',
  18941. 'begin',
  18942. ' Result:=Size;',
  18943. ' Size:=Size+2;',
  18944. ' Self.Size:=Self.Size+3;',
  18945. ' FSize:=FSize+4;',
  18946. ' Self.FSize:=Self.FSize+5;',
  18947. ' with Self do begin',
  18948. ' Size:=Size+6;',
  18949. ' FSize:=FSize+7;',
  18950. ' FSize:=FSize+8;',
  18951. ' end;',
  18952. 'end;',
  18953. 'begin',
  18954. '']);
  18955. ConvertProgram;
  18956. CheckSource('TestClassHelper_Method_AccessInstanceFields',
  18957. LinesToStr([ // statements
  18958. 'rtl.createClass($mod, "TObject", null, function () {',
  18959. ' this.$init = function () {',
  18960. ' this.FSize = 0;',
  18961. ' };',
  18962. ' this.$final = function () {',
  18963. ' };',
  18964. '});',
  18965. 'rtl.createHelper($mod, "THelper", null, function () {',
  18966. ' this.Foo = function (w) {',
  18967. ' var Result = 0;',
  18968. ' Result = this.FSize;',
  18969. ' this.FSize = this.FSize + 2;',
  18970. ' this.FSize = this.FSize + 3;',
  18971. ' this.FSize = this.FSize + 4;',
  18972. ' this.FSize = this.FSize + 5;',
  18973. ' this.FSize = this.FSize + 6;',
  18974. ' this.FSize = this.FSize + 7;',
  18975. ' this.FSize = this.FSize + 8;',
  18976. ' return Result;',
  18977. ' };',
  18978. '});',
  18979. '']),
  18980. LinesToStr([ // $mod.$main
  18981. '']));
  18982. end;
  18983. procedure TTestModule.TestClassHelper_Method_Call;
  18984. begin
  18985. StartProgram(false);
  18986. Add([
  18987. 'type',
  18988. ' TObject = class',
  18989. ' procedure Run(w: word = 10);',
  18990. ' end;',
  18991. ' THelper = class helper for TObject',
  18992. ' function Foo(w: word = 1): word;',
  18993. ' end;',
  18994. 'procedure TObject.Run(w: word);',
  18995. 'begin',
  18996. ' Foo;',
  18997. ' Foo();',
  18998. ' Foo(2);',
  18999. ' Self.Foo;',
  19000. ' Self.Foo();',
  19001. ' Self.Foo(3);',
  19002. ' with Self do begin',
  19003. ' Foo;',
  19004. ' Foo();',
  19005. ' Foo(4);',
  19006. ' end;',
  19007. 'end;',
  19008. 'function THelper.foo(w: word): word;',
  19009. 'begin',
  19010. ' Run;',
  19011. ' Run();',
  19012. ' Run(11);',
  19013. ' Foo;',
  19014. ' Foo();',
  19015. ' Foo(12);',
  19016. ' Self.Foo;',
  19017. ' Self.Foo();',
  19018. ' Self.Foo(13);',
  19019. ' with Self do begin',
  19020. ' Foo;',
  19021. ' Foo();',
  19022. ' Foo(14);',
  19023. ' end;',
  19024. 'end;',
  19025. 'var Obj: TObject;',
  19026. 'begin',
  19027. ' obj.Foo;',
  19028. ' obj.Foo();',
  19029. ' obj.Foo(21);',
  19030. ' with obj do begin',
  19031. ' Foo;',
  19032. ' Foo();',
  19033. ' Foo(22);',
  19034. ' end;',
  19035. '']);
  19036. ConvertProgram;
  19037. CheckSource('TestClassHelper_Method_Call',
  19038. LinesToStr([ // statements
  19039. 'rtl.createClass($mod, "TObject", null, function () {',
  19040. ' this.$init = function () {',
  19041. ' };',
  19042. ' this.$final = function () {',
  19043. ' };',
  19044. ' this.Run = function (w) {',
  19045. ' $mod.THelper.Foo.call(this, 1);',
  19046. ' $mod.THelper.Foo.call(this, 1);',
  19047. ' $mod.THelper.Foo.call(this, 2);',
  19048. ' $mod.THelper.Foo.call(this, 1);',
  19049. ' $mod.THelper.Foo.call(this, 1);',
  19050. ' $mod.THelper.Foo.call(this, 3);',
  19051. ' $mod.THelper.Foo.call(this, 1);',
  19052. ' $mod.THelper.Foo.call(this, 1);',
  19053. ' $mod.THelper.Foo.call(this, 4);',
  19054. ' };',
  19055. '});',
  19056. 'rtl.createHelper($mod, "THelper", null, function () {',
  19057. ' this.Foo = function (w) {',
  19058. ' var Result = 0;',
  19059. ' this.Run(10);',
  19060. ' this.Run(10);',
  19061. ' this.Run(11);',
  19062. ' $mod.THelper.Foo.call(this, 1);',
  19063. ' $mod.THelper.Foo.call(this, 1);',
  19064. ' $mod.THelper.Foo.call(this, 12);',
  19065. ' $mod.THelper.Foo.call(this, 1);',
  19066. ' $mod.THelper.Foo.call(this, 1);',
  19067. ' $mod.THelper.Foo.call(this, 13);',
  19068. ' $mod.THelper.Foo.call(this, 1);',
  19069. ' $mod.THelper.Foo.call(this, 1);',
  19070. ' $mod.THelper.Foo.call(this, 14);',
  19071. ' return Result;',
  19072. ' };',
  19073. '});',
  19074. 'this.Obj = null;',
  19075. '']),
  19076. LinesToStr([ // $mod.$main
  19077. '$mod.THelper.Foo.call($mod.Obj, 1);',
  19078. '$mod.THelper.Foo.call($mod.Obj, 1);',
  19079. '$mod.THelper.Foo.call($mod.Obj, 21);',
  19080. 'var $with1 = $mod.Obj;',
  19081. '$mod.THelper.Foo.call($with1, 1);',
  19082. '$mod.THelper.Foo.call($with1, 1);',
  19083. '$mod.THelper.Foo.call($with1, 22);',
  19084. '']));
  19085. end;
  19086. procedure TTestModule.TestClassHelper_Method_Nested_Call;
  19087. begin
  19088. StartProgram(false);
  19089. Add([
  19090. 'type',
  19091. ' TObject = class',
  19092. ' procedure Run(w: word = 10);',
  19093. ' end;',
  19094. ' THelper = class helper for TObject',
  19095. ' function Foo(w: word = 1): word;',
  19096. ' end;',
  19097. 'procedure TObject.Run(w: word);',
  19098. ' procedure Sub(Self: TObject);',
  19099. ' begin',
  19100. ' Foo;',
  19101. ' Foo();',
  19102. ' Self.Foo;',
  19103. ' Self.Foo();',
  19104. ' with Self do begin',
  19105. ' Foo;',
  19106. ' Foo();',
  19107. ' end;',
  19108. ' end;',
  19109. 'begin',
  19110. 'end;',
  19111. 'function THelper.foo(w: word): word;',
  19112. ' procedure Sub(Self: TObject);',
  19113. ' begin',
  19114. ' Run;',
  19115. ' Run();',
  19116. ' Foo;',
  19117. ' Foo();',
  19118. ' Self.Foo;',
  19119. ' Self.Foo();',
  19120. ' with Self do begin',
  19121. ' Foo;',
  19122. ' Foo();',
  19123. ' end;',
  19124. ' end;',
  19125. 'begin',
  19126. 'end;',
  19127. 'begin',
  19128. '']);
  19129. ConvertProgram;
  19130. CheckSource('TestClassHelper_Method_Nested_Call',
  19131. LinesToStr([ // statements
  19132. 'rtl.createClass($mod, "TObject", null, function () {',
  19133. ' this.$init = function () {',
  19134. ' };',
  19135. ' this.$final = function () {',
  19136. ' };',
  19137. ' this.Run = function (w) {',
  19138. ' var $Self = this;',
  19139. ' function Sub(Self) {',
  19140. ' $mod.THelper.Foo.call($Self, 1);',
  19141. ' $mod.THelper.Foo.call($Self, 1);',
  19142. ' $mod.THelper.Foo.call(Self, 1);',
  19143. ' $mod.THelper.Foo.call(Self, 1);',
  19144. ' $mod.THelper.Foo.call(Self, 1);',
  19145. ' $mod.THelper.Foo.call($Self, 1);',
  19146. ' };',
  19147. ' };',
  19148. '});',
  19149. 'rtl.createHelper($mod, "THelper", null, function () {',
  19150. ' this.Foo = function (w) {',
  19151. ' var $Self = this;',
  19152. ' var Result = 0;',
  19153. ' function Sub(Self) {',
  19154. ' $Self.Run(10);',
  19155. ' $Self.Run(10);',
  19156. ' $mod.THelper.Foo.call($Self, 1);',
  19157. ' $mod.THelper.Foo.call($Self, 1);',
  19158. ' $mod.THelper.Foo.call(Self, 1);',
  19159. ' $mod.THelper.Foo.call(Self, 1);',
  19160. ' $mod.THelper.Foo.call(Self, 1);',
  19161. ' $mod.THelper.Foo.call($Self, 1);',
  19162. ' };',
  19163. ' return Result;',
  19164. ' };',
  19165. '});',
  19166. '']),
  19167. LinesToStr([ // $mod.$main
  19168. '']));
  19169. end;
  19170. procedure TTestModule.TestClassHelper_ClassMethod_Call;
  19171. begin
  19172. StartProgram(false);
  19173. Add([
  19174. 'type',
  19175. ' TObject = class',
  19176. ' class procedure Run(w: word = 10);',
  19177. ' end;',
  19178. ' THelper = class helper for TObject',
  19179. ' class function Foo(w: word = 1): word;',
  19180. ' end;',
  19181. 'class procedure TObject.Run(w: word);',
  19182. 'begin',
  19183. ' Foo;',
  19184. ' Foo();',
  19185. ' Self.Foo;',
  19186. ' Self.Foo();',
  19187. ' with Self do begin',
  19188. ' Foo;',
  19189. ' Foo();',
  19190. ' end;',
  19191. 'end;',
  19192. 'class function THelper.foo(w: word): word;',
  19193. 'begin',
  19194. ' Run;',
  19195. ' Run();',
  19196. ' Foo;',
  19197. ' Foo();',
  19198. ' Self.Foo;',
  19199. ' Self.Foo();',
  19200. ' with Self do begin',
  19201. ' Foo;',
  19202. ' Foo();',
  19203. ' end;',
  19204. 'end;',
  19205. 'var',
  19206. ' Obj: TObject;',
  19207. 'begin',
  19208. ' obj.Foo;',
  19209. ' obj.Foo();',
  19210. ' with obj do begin',
  19211. ' Foo;',
  19212. ' Foo();',
  19213. ' end;',
  19214. ' tobject.Foo;',
  19215. ' tobject.Foo();',
  19216. ' with tobject do begin',
  19217. ' Foo;',
  19218. ' Foo();',
  19219. ' end;',
  19220. '']);
  19221. ConvertProgram;
  19222. CheckSource('TestClassHelper_ClassMethod_Call',
  19223. LinesToStr([ // statements
  19224. 'rtl.createClass($mod, "TObject", null, function () {',
  19225. ' this.$init = function () {',
  19226. ' };',
  19227. ' this.$final = function () {',
  19228. ' };',
  19229. ' this.Run = function (w) {',
  19230. ' $mod.THelper.Foo.call(this, 1);',
  19231. ' $mod.THelper.Foo.call(this, 1);',
  19232. ' $mod.THelper.Foo.call(this, 1);',
  19233. ' $mod.THelper.Foo.call(this, 1);',
  19234. ' $mod.THelper.Foo.call(this, 1);',
  19235. ' $mod.THelper.Foo.call(this, 1);',
  19236. ' };',
  19237. '});',
  19238. 'rtl.createHelper($mod, "THelper", null, function () {',
  19239. ' this.Foo = function (w) {',
  19240. ' var Result = 0;',
  19241. ' this.Run(10);',
  19242. ' this.Run(10);',
  19243. ' $mod.THelper.Foo.call(this, 1);',
  19244. ' $mod.THelper.Foo.call(this, 1);',
  19245. ' $mod.THelper.Foo.call(this, 1);',
  19246. ' $mod.THelper.Foo.call(this, 1);',
  19247. ' $mod.THelper.Foo.call(this, 1);',
  19248. ' $mod.THelper.Foo.call(this, 1);',
  19249. ' return Result;',
  19250. ' };',
  19251. '});',
  19252. 'this.Obj = null;',
  19253. '']),
  19254. LinesToStr([ // $mod.$main
  19255. '$mod.THelper.Foo.call($mod.Obj.$class, 1);',
  19256. '$mod.THelper.Foo.call($mod.Obj.$class, 1);',
  19257. 'var $with1 = $mod.Obj;',
  19258. '$mod.THelper.Foo.call($with1.$class, 1);',
  19259. '$mod.THelper.Foo.call($with1.$class, 1);',
  19260. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19261. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19262. 'var $with2 = $mod.TObject;',
  19263. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19264. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19265. '']));
  19266. end;
  19267. procedure TTestModule.TestClassHelper_ClassOf;
  19268. begin
  19269. StartProgram(false);
  19270. Add([
  19271. 'type',
  19272. ' TObject = class',
  19273. ' end;',
  19274. ' TClass = class of TObject;',
  19275. ' THelper = class helper for TObject',
  19276. ' class function Foo(w: word = 1): word;',
  19277. ' end;',
  19278. 'class function THelper.foo(w: word): word;',
  19279. 'begin',
  19280. 'end;',
  19281. 'var',
  19282. ' c: TClass;',
  19283. 'begin',
  19284. ' c.Foo;',
  19285. ' c.Foo();',
  19286. ' with c do begin',
  19287. ' Foo;',
  19288. ' Foo();',
  19289. ' end;',
  19290. '']);
  19291. ConvertProgram;
  19292. CheckSource('TestClassHelper_ClassOf',
  19293. LinesToStr([ // statements
  19294. 'rtl.createClass($mod, "TObject", null, function () {',
  19295. ' this.$init = function () {',
  19296. ' };',
  19297. ' this.$final = function () {',
  19298. ' };',
  19299. '});',
  19300. 'rtl.createHelper($mod, "THelper", null, function () {',
  19301. ' this.Foo = function (w) {',
  19302. ' var Result = 0;',
  19303. ' return Result;',
  19304. ' };',
  19305. '});',
  19306. 'this.c = null;',
  19307. '']),
  19308. LinesToStr([ // $mod.$main
  19309. '$mod.THelper.Foo.call($mod.c, 1);',
  19310. '$mod.THelper.Foo.call($mod.c, 1);',
  19311. 'var $with1 = $mod.c;',
  19312. '$mod.THelper.Foo.call($with1, 1);',
  19313. '$mod.THelper.Foo.call($with1, 1);',
  19314. '']));
  19315. end;
  19316. procedure TTestModule.TestClassHelper_MethodRefObjFPC;
  19317. begin
  19318. StartProgram(false);
  19319. Add([
  19320. '{$mode objfpc}',
  19321. 'type',
  19322. ' TObject = class',
  19323. ' procedure DoIt;',
  19324. ' end;',
  19325. ' THelper = class helper for TObject',
  19326. ' procedure Fly(w: word = 1);',
  19327. ' class procedure Glide(w: word = 1);',
  19328. ' class procedure Run(w: word = 1); static;',
  19329. ' end;',
  19330. ' TFly = procedure(w: word) of object;',
  19331. ' TGlide = TFly;',
  19332. ' TRun = procedure(w: word);',
  19333. 'var',
  19334. ' f: TFly;',
  19335. ' g: TGlide;',
  19336. ' r: TRun;',
  19337. 'procedure TObject.DoIt;',
  19338. 'begin',
  19339. ' f:=@fly;',
  19340. ' g:=@glide;',
  19341. ' r:=@run;',
  19342. ' f:[email protected];',
  19343. ' g:[email protected];',
  19344. ' r:[email protected];',
  19345. ' with self do begin',
  19346. ' f:=@fly;',
  19347. ' g:=@glide;',
  19348. ' r:=@run;',
  19349. ' end;',
  19350. 'end;',
  19351. 'procedure THelper.fly(w: word);',
  19352. 'begin',
  19353. ' f:=@fly;',
  19354. ' g:=@glide;',
  19355. ' r:=@run;',
  19356. 'end;',
  19357. 'class procedure THelper.glide(w: word);',
  19358. 'begin',
  19359. ' g:=@glide;',
  19360. ' r:=@run;',
  19361. 'end;',
  19362. 'class procedure THelper.run(w: word);',
  19363. 'begin',
  19364. ' g:=@glide;',
  19365. ' r:=@run;',
  19366. 'end;',
  19367. 'var',
  19368. ' Obj: TObject;',
  19369. 'begin',
  19370. ' f:[email protected];',
  19371. ' g:[email protected];',
  19372. ' r:[email protected];',
  19373. ' with obj do begin',
  19374. ' f:=@fly;',
  19375. ' g:=@glide;',
  19376. ' r:=@run;',
  19377. ' end;',
  19378. ' g:[email protected];',
  19379. ' r:[email protected];',
  19380. ' with tobject do begin',
  19381. ' g:=@glide;',
  19382. ' r:=@run;',
  19383. ' end;',
  19384. '']);
  19385. ConvertProgram;
  19386. CheckSource('TestClassHelper_MethodRefObjFPC',
  19387. LinesToStr([ // statements
  19388. 'rtl.createClass($mod, "TObject", null, function () {',
  19389. ' this.$init = function () {',
  19390. ' };',
  19391. ' this.$final = function () {',
  19392. ' };',
  19393. ' this.DoIt = function () {',
  19394. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19395. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19396. ' $mod.r = $mod.THelper.Run;',
  19397. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19398. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19399. ' $mod.r = $mod.THelper.Run;',
  19400. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19401. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19402. ' $mod.r = $mod.THelper.Run;',
  19403. ' };',
  19404. '});',
  19405. 'rtl.createHelper($mod, "THelper", null, function () {',
  19406. ' this.Fly = function (w) {',
  19407. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19408. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19409. ' $mod.r = $mod.THelper.Run;',
  19410. ' };',
  19411. ' this.Glide = function (w) {',
  19412. ' $mod.g = rtl.createCallback(this, $mod.THelper.Glide);',
  19413. ' $mod.r = $mod.THelper.Run;',
  19414. ' };',
  19415. ' this.Run = function (w) {',
  19416. ' $mod.g = rtl.createCallback($mod.THelper, $mod.THelper.Glide);',
  19417. ' $mod.r = $mod.THelper.Run;',
  19418. ' };',
  19419. '});',
  19420. 'this.f = null;',
  19421. 'this.g = null;',
  19422. 'this.r = null;',
  19423. 'this.Obj = null;',
  19424. '']),
  19425. LinesToStr([ // $mod.$main
  19426. '$mod.f = rtl.createCallback($mod.Obj, $mod.THelper.Fly);',
  19427. '$mod.g = rtl.createCallback($mod.Obj.$class, $mod.THelper.Glide);',
  19428. '$mod.r = $mod.THelper.Run;',
  19429. 'var $with1 = $mod.Obj;',
  19430. '$mod.f = rtl.createCallback($with1, $mod.THelper.Fly);',
  19431. '$mod.g = rtl.createCallback($with1.$class, $mod.THelper.Glide);',
  19432. '$mod.r = $mod.THelper.Run;',
  19433. '$mod.g = rtl.createCallback($mod.TObject, $mod.THelper.Glide);',
  19434. '$mod.r = $mod.THelper.Run;',
  19435. 'var $with2 = $mod.TObject;',
  19436. '$mod.g = rtl.createCallback($with2, $mod.THelper.Glide);',
  19437. '$mod.r = $mod.THelper.Run;',
  19438. '']));
  19439. end;
  19440. procedure TTestModule.TestClassHelper_Constructor;
  19441. begin
  19442. StartProgram(false);
  19443. Add([
  19444. 'type',
  19445. ' TObject = class',
  19446. ' constructor Create;',
  19447. ' end;',
  19448. ' TClass = class of TObject;',
  19449. ' THelper = class helper for TObject',
  19450. ' constructor NewHlp(w: word);',
  19451. ' end;',
  19452. 'var',
  19453. ' obj: TObject;',
  19454. ' c: TClass;',
  19455. 'constructor TObject.Create;',
  19456. 'begin',
  19457. ' NewHlp(2);', // normal call
  19458. ' tobject.NewHlp(3);', // new instance
  19459. ' c.newhlp(4);', // new instance
  19460. 'end;',
  19461. 'constructor THelper.NewHlp(w: word);',
  19462. 'begin',
  19463. ' create;', // normal call
  19464. ' tobject.create;', // new instance
  19465. ' NewHlp(2);', // normal call
  19466. ' tobject.NewHlp(3);', // new instance
  19467. ' c.newhlp(4);', // new instance
  19468. 'end;',
  19469. 'begin',
  19470. ' obj.newhlp(2);', // normal call
  19471. ' with Obj do newhlp(12);', // normal call
  19472. ' tobject.newhlp(3);', // new instance
  19473. ' with tobject do newhlp(13);', // new instance
  19474. ' c.newhlp(4);', // new instance
  19475. ' with c do newhlp(14);', // new instance
  19476. '']);
  19477. ConvertProgram;
  19478. CheckSource('TestClassHelper_Constructor',
  19479. LinesToStr([ // statements
  19480. 'rtl.createClass($mod, "TObject", null, function () {',
  19481. ' this.$init = function () {',
  19482. ' };',
  19483. ' this.$final = function () {',
  19484. ' };',
  19485. ' this.Create = function () {',
  19486. ' $mod.THelper.NewHlp.call(this, 2);',
  19487. ' $mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  19488. ' $mod.c.$create($mod.THelper.NewHlp, [4]);',
  19489. ' return this;',
  19490. ' };',
  19491. '});',
  19492. 'rtl.createHelper($mod, "THelper", null, function () {',
  19493. ' this.NewHlp = function (w) {',
  19494. ' this.Create();',
  19495. ' $mod.TObject.$create("Create");',
  19496. ' $mod.THelper.NewHlp.call(this, 2);',
  19497. ' $mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  19498. ' $mod.c.$create($mod.THelper.NewHlp, [4]);',
  19499. ' return this;',
  19500. ' };',
  19501. '});',
  19502. 'this.obj = null;',
  19503. 'this.c = null;',
  19504. '']),
  19505. LinesToStr([ // $mod.$main
  19506. '$mod.THelper.NewHlp.call($mod.obj, 2);',
  19507. 'var $with1 = $mod.obj;',
  19508. '$mod.THelper.NewHlp.call($with1, 12);',
  19509. '$mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  19510. 'var $with2 = $mod.TObject;',
  19511. '$with2.$create($mod.THelper.NewHlp, [13]);',
  19512. '$mod.c.$create($mod.THelper.NewHlp, [4]);',
  19513. 'var $with3 = $mod.c;',
  19514. '$with3.$create($mod.THelper.NewHlp, [14]);',
  19515. '']));
  19516. end;
  19517. procedure TTestModule.TestClassHelper_InheritedObjFPC;
  19518. begin
  19519. StartProgram(false);
  19520. Add([
  19521. 'type',
  19522. ' TObject = class',
  19523. ' procedure Fly;',
  19524. ' end;',
  19525. ' TObjHelper = class helper for TObject',
  19526. ' procedure Fly;',
  19527. ' end;',
  19528. ' TBird = class',
  19529. ' procedure Fly;',
  19530. ' end;',
  19531. ' TBirdHelper = class helper for TBird',
  19532. ' procedure Fly;',
  19533. ' procedure Walk(w: word);',
  19534. ' end;',
  19535. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  19536. ' procedure Fly;',
  19537. ' procedure Walk(w: word);',
  19538. ' end;',
  19539. 'procedure Tobject.fly;',
  19540. 'begin',
  19541. ' inherited;', // ignore
  19542. 'end;',
  19543. 'procedure Tobjhelper.fly;',
  19544. 'begin',
  19545. ' {@TObject_Fly}inherited;',
  19546. ' inherited {@TObject_Fly}Fly;',
  19547. 'end;',
  19548. 'procedure Tbird.fly;',
  19549. 'begin',
  19550. ' {@TObjHelper_Fly}inherited;',
  19551. ' inherited {@TObjHelper_Fly}Fly;',
  19552. 'end;',
  19553. 'procedure Tbirdhelper.fly;',
  19554. 'begin',
  19555. ' {@TBird_Fly}inherited;',
  19556. ' inherited {@TBird_Fly}Fly;',
  19557. 'end;',
  19558. 'procedure Tbirdhelper.walk(w: word);',
  19559. 'begin',
  19560. 'end;',
  19561. 'procedure teagleHelper.fly;',
  19562. 'begin',
  19563. ' {@TBird_Fly}inherited;',
  19564. ' inherited {@TBird_Fly}Fly;',
  19565. 'end;',
  19566. 'procedure teagleHelper.walk(w: word);',
  19567. 'begin',
  19568. ' {@TBirdHelper_Walk}inherited;',
  19569. ' inherited {@TBirdHelper_Walk}Walk(3);',
  19570. 'end;',
  19571. 'begin',
  19572. '']);
  19573. ConvertProgram;
  19574. CheckSource('TestClassHelper_InheritedObjFPC',
  19575. LinesToStr([ // statements
  19576. 'rtl.createClass($mod, "TObject", null, function () {',
  19577. ' this.$init = function () {',
  19578. ' };',
  19579. ' this.$final = function () {',
  19580. ' };',
  19581. ' this.Fly = function () {',
  19582. ' };',
  19583. '});',
  19584. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19585. ' this.Fly = function () {',
  19586. ' $mod.TObject.Fly.call(this);',
  19587. ' $mod.TObject.Fly.call(this);',
  19588. ' };',
  19589. '});',
  19590. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19591. ' this.Fly$1 = function () {',
  19592. ' $mod.TObjHelper.Fly.call(this);',
  19593. ' $mod.TObjHelper.Fly.call(this);',
  19594. ' };',
  19595. '});',
  19596. 'rtl.createHelper($mod, "TBirdHelper", null, function () {',
  19597. ' this.Fly = function () {',
  19598. ' $mod.TBird.Fly$1.call(this);',
  19599. ' $mod.TBird.Fly$1.call(this);',
  19600. ' };',
  19601. ' this.Walk = function (w) {',
  19602. ' };',
  19603. '});',
  19604. 'rtl.createHelper($mod, "TEagleHelper", $mod.TBirdHelper, function () {',
  19605. ' this.Fly$1 = function () {',
  19606. ' $mod.TBird.Fly$1.call(this);',
  19607. ' $mod.TBird.Fly$1.call(this);',
  19608. ' };',
  19609. ' this.Walk$1 = function (w) {',
  19610. ' $mod.TBirdHelper.Walk.apply(this, arguments);',
  19611. ' $mod.TBirdHelper.Walk.call(this, 3);',
  19612. ' };',
  19613. '});',
  19614. '']),
  19615. LinesToStr([ // $mod.$main
  19616. '']));
  19617. end;
  19618. procedure TTestModule.TestClassHelper_Property;
  19619. begin
  19620. StartProgram(false);
  19621. Add([
  19622. 'type',
  19623. ' TObject = class',
  19624. ' FSize: word;',
  19625. ' function GetSpeed: word;',
  19626. ' procedure SetSpeed(Value: word);',
  19627. ' end;',
  19628. ' TObjHelper = class helper for TObject',
  19629. ' function GetLeft: word;',
  19630. ' procedure SetLeft(Value: word);',
  19631. ' property Size: word read FSize write FSize;',
  19632. ' property Speed: word read GetSpeed write SetSpeed;',
  19633. ' property Left: word read GetLeft write SetLeft;',
  19634. ' end;',
  19635. ' TBird = class',
  19636. ' property NotRight: word read GetLeft write SetLeft;',
  19637. ' procedure DoIt;',
  19638. ' end;',
  19639. 'var',
  19640. ' b: TBird;',
  19641. 'function Tobject.GetSpeed: word;',
  19642. 'begin',
  19643. ' Size:=Size+11;',
  19644. ' Speed:=Speed+12;',
  19645. ' Result:=Left+13;',
  19646. ' Left:=13;',
  19647. ' Left:=Left+13;',
  19648. ' Self.Size:=Self.Size+21;',
  19649. ' Self.Speed:=Self.Speed+22;',
  19650. ' Self.Left:=Self.Left+23;',
  19651. ' with Self do begin',
  19652. ' Size:=Size+31;',
  19653. ' Speed:=Speed+32;',
  19654. ' Left:=Left+33;',
  19655. ' end;',
  19656. 'end;',
  19657. 'procedure Tobject.SetSpeed(Value: word);',
  19658. 'begin',
  19659. 'end;',
  19660. 'function TObjHelper.GetLeft: word;',
  19661. 'begin',
  19662. ' Size:=Size+11;',
  19663. ' Speed:=Speed+12;',
  19664. ' Left:=Left+13;',
  19665. ' Self.Size:=Self.Size+21;',
  19666. ' Self.Speed:=Self.Speed+22;',
  19667. ' Self.Left:=Self.Left+23;',
  19668. ' with Self do begin',
  19669. ' Size:=Size+31;',
  19670. ' Speed:=Speed+32;',
  19671. ' Left:=Left+33;',
  19672. ' end;',
  19673. 'end;',
  19674. 'procedure TObjHelper.SetLeft(Value: word);',
  19675. 'begin',
  19676. 'end;',
  19677. 'procedure TBird.DoIt;',
  19678. 'begin',
  19679. ' NotRight:=NotRight+11;',
  19680. ' Self.NotRight:=Self.NotRight+21;',
  19681. ' with Self do begin',
  19682. ' NotRight:=NotRight+31;',
  19683. ' end;',
  19684. 'end;',
  19685. 'begin',
  19686. ' b.Size:=b.Size+11;',
  19687. ' b.Speed:=b.Speed+12;',
  19688. ' b.Left:=b.Left+13;',
  19689. ' b.NotRight:=b.NotRight+14;',
  19690. ' with b do begin',
  19691. ' Size:=Size+31;',
  19692. ' Speed:=Speed+32;',
  19693. ' Left:=Left+33;',
  19694. ' NotRight:=NotRight+34;',
  19695. ' end;',
  19696. '']);
  19697. ConvertProgram;
  19698. CheckSource('TestClassHelper_Property',
  19699. LinesToStr([ // statements
  19700. 'rtl.createClass($mod, "TObject", null, function () {',
  19701. ' this.$init = function () {',
  19702. ' this.FSize = 0;',
  19703. ' };',
  19704. ' this.$final = function () {',
  19705. ' };',
  19706. ' this.GetSpeed = function () {',
  19707. ' var Result = 0;',
  19708. ' this.FSize = this.FSize + 11;',
  19709. ' this.SetSpeed(this.GetSpeed() + 12);',
  19710. ' Result = $mod.TObjHelper.GetLeft.call(this) + 13;',
  19711. ' $mod.TObjHelper.SetLeft.call(this, 13);',
  19712. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  19713. ' this.FSize = this.FSize + 21;',
  19714. ' this.SetSpeed(this.GetSpeed() + 22);',
  19715. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  19716. ' this.FSize = this.FSize + 31;',
  19717. ' this.SetSpeed(this.GetSpeed() + 32);',
  19718. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  19719. ' return Result;',
  19720. ' };',
  19721. ' this.SetSpeed = function (Value) {',
  19722. ' };',
  19723. '});',
  19724. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19725. ' this.GetLeft = function () {',
  19726. ' var Result = 0;',
  19727. ' this.FSize = this.FSize + 11;',
  19728. ' this.SetSpeed(this.GetSpeed() + 12);',
  19729. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  19730. ' this.FSize = this.FSize + 21;',
  19731. ' this.SetSpeed(this.GetSpeed() + 22);',
  19732. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  19733. ' this.FSize = this.FSize + 31;',
  19734. ' this.SetSpeed(this.GetSpeed() + 32);',
  19735. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  19736. ' return Result;',
  19737. ' };',
  19738. ' this.SetLeft = function (Value) {',
  19739. ' };',
  19740. '});',
  19741. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19742. ' this.DoIt = function () {',
  19743. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 11);',
  19744. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 21);',
  19745. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 31);',
  19746. ' };',
  19747. '});',
  19748. 'this.b = null;',
  19749. '']),
  19750. LinesToStr([ // $mod.$main
  19751. '$mod.b.FSize = $mod.b.FSize + 11;',
  19752. '$mod.b.SetSpeed($mod.b.GetSpeed() + 12);',
  19753. '$mod.TObjHelper.SetLeft.call($mod.b, $mod.TObjHelper.GetLeft.call($mod.b) + 13);',
  19754. '$mod.TObjHelper.SetLeft.call($mod.b, $mod.TObjHelper.GetLeft.call($mod.b) + 14);',
  19755. 'var $with1 = $mod.b;',
  19756. '$with1.FSize = $with1.FSize + 31;',
  19757. '$with1.SetSpeed($with1.GetSpeed() + 32);',
  19758. '$mod.TObjHelper.SetLeft.call($with1, $mod.TObjHelper.GetLeft.call($with1) + 33);',
  19759. '$mod.TObjHelper.SetLeft.call($with1, $mod.TObjHelper.GetLeft.call($with1) + 34);',
  19760. '']));
  19761. end;
  19762. procedure TTestModule.TestClassHelper_Property_Array;
  19763. begin
  19764. StartProgram(false);
  19765. Add([
  19766. 'type',
  19767. ' TObject = class',
  19768. ' function GetSpeed(Index: boolean): word;',
  19769. ' procedure SetSpeed(Index: boolean; Value: word);',
  19770. ' end;',
  19771. ' TObjHelper = class helper for TObject',
  19772. ' function GetSize(Index: boolean): word;',
  19773. ' procedure SetSize(Index: boolean; Value: word);',
  19774. ' property Size[Index: boolean]: word read GetSize write SetSize;',
  19775. ' property Speed[Index: boolean]: word read GetSpeed write SetSpeed;',
  19776. ' end;',
  19777. ' TBird = class',
  19778. ' property Items[Index: boolean]: word read GetSize write SetSize;',
  19779. ' procedure DoIt;',
  19780. ' end;',
  19781. 'var',
  19782. ' b: TBird;',
  19783. 'function Tobject.GetSpeed(Index: boolean): word;',
  19784. 'begin',
  19785. ' Result:=Size[false];',
  19786. ' Size[true]:=Size[false]+11;',
  19787. ' Speed[true]:=Speed[false]+12;',
  19788. ' Self.Size[true]:=Self.Size[false]+21;',
  19789. ' Self.Speed[true]:=Self.Speed[false]+22;',
  19790. ' with Self do begin',
  19791. ' Size[true]:=Size[false]+31;',
  19792. ' Speed[true]:=Speed[false]+32;',
  19793. ' end;',
  19794. 'end;',
  19795. 'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
  19796. 'begin',
  19797. 'end;',
  19798. 'function TObjHelper.GetSize(Index: boolean): word;',
  19799. 'begin',
  19800. ' Size[true]:=Size[false]+11;',
  19801. ' Speed[true]:=Speed[false]+12;',
  19802. ' Self.Size[true]:=Self.Size[false]+21;',
  19803. ' Self.Speed[true]:=Self.Speed[false]+22;',
  19804. ' with Self do begin',
  19805. ' Size[true]:=Size[false]+31;',
  19806. ' Speed[true]:=Speed[false]+32;',
  19807. ' end;',
  19808. 'end;',
  19809. 'procedure TObjHelper.SetSize(Index: boolean; Value: word);',
  19810. 'begin',
  19811. 'end;',
  19812. 'procedure TBird.DoIt;',
  19813. 'begin',
  19814. ' Items[true]:=Items[false]+11;',
  19815. ' Self.Items[true]:=Self.Items[false]+21;',
  19816. ' with Self do Items[true]:=Items[false]+31;',
  19817. 'end;',
  19818. 'begin',
  19819. ' b.Size[true]:=b.Size[false]+11;',
  19820. ' b.Speed[true]:=b.Speed[false]+12;',
  19821. ' b.Items[true]:=b.Items[false]+13;',
  19822. ' with b do begin',
  19823. ' Size[true]:=Size[false]+21;',
  19824. ' Speed[true]:=Speed[false]+22;',
  19825. ' Items[true]:=Items[false]+23;',
  19826. ' end;',
  19827. '']);
  19828. ConvertProgram;
  19829. CheckSource('TestClassHelper_Property_Array',
  19830. LinesToStr([ // statements
  19831. 'rtl.createClass($mod, "TObject", null, function () {',
  19832. ' this.$init = function () {',
  19833. ' };',
  19834. ' this.$final = function () {',
  19835. ' };',
  19836. ' this.GetSpeed = function (Index) {',
  19837. ' var Result = 0;',
  19838. ' Result = $mod.TObjHelper.GetSize.call(this, false);',
  19839. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  19840. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  19841. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  19842. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  19843. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  19844. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  19845. ' return Result;',
  19846. ' };',
  19847. ' this.SetSpeed = function (Index, Value) {',
  19848. ' };',
  19849. '});',
  19850. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19851. ' this.GetSize = function (Index) {',
  19852. ' var Result = 0;',
  19853. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  19854. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  19855. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  19856. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  19857. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  19858. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  19859. ' return Result;',
  19860. ' };',
  19861. ' this.SetSize = function (Index, Value) {',
  19862. ' };',
  19863. '});',
  19864. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19865. ' this.DoIt = function () {',
  19866. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  19867. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  19868. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  19869. ' };',
  19870. '});',
  19871. 'this.b = null;',
  19872. '']),
  19873. LinesToStr([ // $mod.$main
  19874. '$mod.TObjHelper.SetSize.call($mod.b, true, $mod.TObjHelper.GetSize.call($mod.b, false) + 11);',
  19875. '$mod.b.SetSpeed(true, $mod.b.GetSpeed(false) + 12);',
  19876. '$mod.TObjHelper.SetSize.call($mod.b, true, $mod.TObjHelper.GetSize.call($mod.b, false) + 13);',
  19877. 'var $with1 = $mod.b;',
  19878. '$mod.TObjHelper.SetSize.call($with1, true, $mod.TObjHelper.GetSize.call($with1, false) + 21);',
  19879. '$with1.SetSpeed(true, $with1.GetSpeed(false) + 22);',
  19880. '$mod.TObjHelper.SetSize.call($with1, true, $mod.TObjHelper.GetSize.call($with1, false) + 23);',
  19881. '']));
  19882. end;
  19883. procedure TTestModule.TestClassHelper_Property_Array_Default;
  19884. begin
  19885. StartProgram(false);
  19886. Add([
  19887. 'type',
  19888. ' TObject = class',
  19889. ' function GetSpeed(Index: boolean): word;',
  19890. ' procedure SetSpeed(Index: boolean; Value: word);',
  19891. ' end;',
  19892. ' TObjHelper = class helper for TObject',
  19893. ' property Speed[Index: boolean]: word read GetSpeed write SetSpeed; default;',
  19894. ' end;',
  19895. ' TBird = class',
  19896. ' end;',
  19897. ' TBirdHelper = class helper for TBird',
  19898. ' function GetSize(Index: word): boolean;',
  19899. ' procedure SetSize(Index: word; Value: boolean);',
  19900. ' property Size[Index: word]: boolean read GetSize write SetSize; default;',
  19901. ' end;',
  19902. 'function Tobject.GetSpeed(Index: boolean): word;',
  19903. 'begin',
  19904. ' Self[true]:=Self[false]+1;',
  19905. 'end;',
  19906. 'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
  19907. 'begin',
  19908. 'end;',
  19909. 'function TBirdHelper.GetSize(Index: word): boolean;',
  19910. 'begin',
  19911. ' Self[1]:=not Self[2];',
  19912. 'end;',
  19913. 'procedure TBirdHelper.SetSize(Index: word; Value: boolean);',
  19914. 'begin',
  19915. 'end;',
  19916. 'var',
  19917. ' o: TObject;',
  19918. ' b: TBird;',
  19919. 'begin',
  19920. ' o[true]:=o[false]+1;',
  19921. ' b[3]:=not b[4];',
  19922. '']);
  19923. ConvertProgram;
  19924. CheckSource('TestClassHelper_Property_Array_Default',
  19925. LinesToStr([ // statements
  19926. 'rtl.createClass($mod, "TObject", null, function () {',
  19927. ' this.$init = function () {',
  19928. ' };',
  19929. ' this.$final = function () {',
  19930. ' };',
  19931. ' this.GetSpeed = function (Index) {',
  19932. ' var Result = 0;',
  19933. ' this.SetSpeed(true, this.GetSpeed(false) + 1);',
  19934. ' return Result;',
  19935. ' };',
  19936. ' this.SetSpeed = function (Index, Value) {',
  19937. ' };',
  19938. '});',
  19939. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19940. '});',
  19941. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19942. '});',
  19943. 'rtl.createHelper($mod, "TBirdHelper", null, function () {',
  19944. ' this.GetSize = function (Index) {',
  19945. ' var Result = false;',
  19946. ' $mod.TBirdHelper.SetSize.call(this, 1, !$mod.TBirdHelper.GetSize.call(this, 2));',
  19947. ' return Result;',
  19948. ' };',
  19949. ' this.SetSize = function (Index, Value) {',
  19950. ' };',
  19951. '});',
  19952. 'this.o = null;',
  19953. 'this.b = null;',
  19954. '']),
  19955. LinesToStr([ // $mod.$main
  19956. '$mod.o.SetSpeed(true, $mod.o.GetSpeed(false) + 1);',
  19957. '$mod.TBirdHelper.SetSize.call($mod.b, 3, !$mod.TBirdHelper.GetSize.call($mod.b, 4));',
  19958. '']));
  19959. end;
  19960. procedure TTestModule.TestClassHelper_Property_Array_DefaultDefault;
  19961. begin
  19962. StartProgram(false);
  19963. Add([
  19964. 'type',
  19965. ' TObject = class',
  19966. ' end;',
  19967. ' TObjHelper = class helper for TObject',
  19968. ' function GetItems(Index: word): TObject;',
  19969. ' procedure SetItems(Index: word; Value: TObject);',
  19970. ' property Items[Index: word]: TObject read GetItems write SetItems; default;',
  19971. ' end;',
  19972. 'function Tobjhelper.GetItems(Index: word): TObject;',
  19973. 'begin',
  19974. ' Self[1][2]:=Self[3][4];',
  19975. 'end;',
  19976. 'procedure Tobjhelper.SetItems(Index: word; Value: TObject);',
  19977. 'begin',
  19978. 'end;',
  19979. 'var',
  19980. ' o: TObject;',
  19981. 'begin',
  19982. ' o[1][2]:=o[3][4];',
  19983. '']);
  19984. ConvertProgram;
  19985. CheckSource('TestClassHelper_Property_Array_DefaultDefault',
  19986. LinesToStr([ // statements
  19987. 'rtl.createClass($mod, "TObject", null, function () {',
  19988. ' this.$init = function () {',
  19989. ' };',
  19990. ' this.$final = function () {',
  19991. ' };',
  19992. '});',
  19993. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19994. ' this.GetItems = function (Index) {',
  19995. ' var Result = null;',
  19996. ' $mod.TObjHelper.SetItems.call($mod.TObjHelper.GetItems.call(this, 1), 2, $mod.TObjHelper.GetItems.call($mod.TObjHelper.GetItems.call(this, 3), 4));',
  19997. ' return Result;',
  19998. ' };',
  19999. ' this.SetItems = function (Index, Value) {',
  20000. ' };',
  20001. '});',
  20002. 'this.o = null;',
  20003. '']),
  20004. LinesToStr([ // $mod.$main
  20005. '$mod.TObjHelper.SetItems.call($mod.TObjHelper.GetItems.call($mod.o, 1), 2, $mod.TObjHelper.GetItems.call($mod.TObjHelper.GetItems.call($mod.o, 3), 4));',
  20006. '']));
  20007. end;
  20008. procedure TTestModule.TestClassHelper_ClassProperty;
  20009. begin
  20010. StartProgram(false);
  20011. Add([
  20012. 'type',
  20013. ' TObject = class',
  20014. ' class var FSize: word;',
  20015. ' class function GetSpeed: word;',
  20016. ' class procedure SetSpeed(Value: word); virtual; abstract;',
  20017. ' end;',
  20018. ' TObjHelper = class helper for TObject',
  20019. ' class function GetLeft: word;',
  20020. ' class procedure SetLeft(Value: word);',
  20021. ' class property Size: word read FSize write FSize;',
  20022. ' class property Speed: word read GetSpeed write SetSpeed;',
  20023. ' class property Left: word read GetLeft write SetLeft;',
  20024. ' end;',
  20025. ' TBird = class',
  20026. ' class property NotRight: word read GetLeft write SetLeft;',
  20027. ' class procedure DoIt;',
  20028. ' end;',
  20029. ' TBirdClass = class of TBird;',
  20030. 'class function Tobject.GetSpeed: word;',
  20031. 'begin',
  20032. ' Size:=Size+11;',
  20033. ' Speed:=Speed+12;',
  20034. ' Left:=Left+13;',
  20035. ' Self.Size:=Self.Size+21;',
  20036. ' Self.Speed:=Self.Speed+22;',
  20037. ' Self.Left:=Self.Left+23;',
  20038. ' with Self do begin',
  20039. ' Size:=Size+31;',
  20040. ' Speed:=Speed+32;',
  20041. ' Left:=Left+33;',
  20042. ' end;',
  20043. 'end;',
  20044. 'class function TObjHelper.GetLeft: word;',
  20045. 'begin',
  20046. ' Size:=Size+11;',
  20047. ' Speed:=Speed+12;',
  20048. ' Left:=Left+13;',
  20049. ' Self.Size:=Self.Size+21;',
  20050. ' Self.Speed:=Self.Speed+22;',
  20051. ' Self.Left:=Self.Left+23;',
  20052. ' with Self do begin',
  20053. ' Size:=Size+31;',
  20054. ' Speed:=Speed+32;',
  20055. ' Left:=Left+33;',
  20056. ' end;',
  20057. 'end;',
  20058. 'class procedure TObjHelper.SetLeft(Value: word);',
  20059. 'begin',
  20060. 'end;',
  20061. 'class procedure TBird.DoIt;',
  20062. 'begin',
  20063. ' NotRight:=NotRight+11;',
  20064. ' Self.NotRight:=Self.NotRight+21;',
  20065. ' with Self do NotRight:=NotRight+31;',
  20066. 'end;',
  20067. 'var',
  20068. ' b: TBird;',
  20069. ' c: TBirdClass;',
  20070. 'begin',
  20071. ' b.Size:=b.Size+11;',
  20072. ' b.Speed:=b.Speed+12;',
  20073. ' b.Left:=b.Left+13;',
  20074. ' b.NotRight:=b.NotRight+14;',
  20075. ' with b do begin',
  20076. ' Size:=Size+31;',
  20077. ' Speed:=Speed+32;',
  20078. ' Left:=Left+33;',
  20079. ' NotRight:=NotRight+34;',
  20080. ' end;',
  20081. ' c.Size:=c.Size+11;',
  20082. ' c.Speed:=c.Speed+12;',
  20083. ' c.Left:=c.Left+13;',
  20084. ' c.NotRight:=c.NotRight+14;',
  20085. ' with c do begin',
  20086. ' Size:=Size+31;',
  20087. ' Speed:=Speed+32;',
  20088. ' Left:=Left+33;',
  20089. ' NotRight:=NotRight+34;',
  20090. ' end;',
  20091. ' tbird.Size:=tbird.Size+11;',
  20092. ' tbird.Speed:=tbird.Speed+12;',
  20093. ' tbird.Left:=tbird.Left+13;',
  20094. ' tbird.NotRight:=tbird.NotRight+14;',
  20095. ' with tbird do begin',
  20096. ' Size:=Size+31;',
  20097. ' Speed:=Speed+32;',
  20098. ' Left:=Left+33;',
  20099. ' NotRight:=NotRight+34;',
  20100. ' end;',
  20101. '']);
  20102. ConvertProgram;
  20103. CheckSource('TestClassHelper_ClassProperty',
  20104. LinesToStr([ // statements
  20105. 'rtl.createClass($mod, "TObject", null, function () {',
  20106. ' this.FSize = 0;',
  20107. ' this.$init = function () {',
  20108. ' };',
  20109. ' this.$final = function () {',
  20110. ' };',
  20111. ' this.GetSpeed = function () {',
  20112. ' var Result = 0;',
  20113. ' $mod.TObject.FSize = this.FSize + 11;',
  20114. ' this.SetSpeed(this.GetSpeed() + 12);',
  20115. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  20116. ' $mod.TObject.FSize = this.FSize + 21;',
  20117. ' this.SetSpeed(this.GetSpeed() + 22);',
  20118. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  20119. ' $mod.TObject.FSize = this.FSize + 31;',
  20120. ' this.SetSpeed(this.GetSpeed() + 32);',
  20121. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  20122. ' return Result;',
  20123. ' };',
  20124. '});',
  20125. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  20126. ' this.GetLeft = function () {',
  20127. ' var Result = 0;',
  20128. ' $mod.TObject.FSize = this.FSize + 11;',
  20129. ' this.SetSpeed(this.GetSpeed() + 12);',
  20130. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  20131. ' $mod.TObject.FSize = this.FSize + 21;',
  20132. ' this.SetSpeed(this.GetSpeed() + 22);',
  20133. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  20134. ' $mod.TObject.FSize = this.FSize + 31;',
  20135. ' this.SetSpeed(this.GetSpeed() + 32);',
  20136. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  20137. ' return Result;',
  20138. ' };',
  20139. ' this.SetLeft = function (Value) {',
  20140. ' };',
  20141. '});',
  20142. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20143. ' this.DoIt = function () {',
  20144. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 11);',
  20145. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 21);',
  20146. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 31);',
  20147. ' };',
  20148. '});',
  20149. 'this.b = null;',
  20150. 'this.c = null;',
  20151. '']),
  20152. LinesToStr([ // $mod.$main
  20153. '$mod.TObject.FSize = $mod.b.FSize + 11;',
  20154. '$mod.b.$class.SetSpeed($mod.b.$class.GetSpeed() + 12);',
  20155. '$mod.TObjHelper.SetLeft.call($mod.b.$class, $mod.TObjHelper.GetLeft.call($mod.b.$class) + 13);',
  20156. '$mod.TObjHelper.SetLeft.call($mod.b.$class, $mod.TObjHelper.GetLeft.call($mod.b.$class) + 14);',
  20157. 'var $with1 = $mod.b;',
  20158. '$mod.TObject.FSize = $with1.FSize + 31;',
  20159. '$with1.$class.SetSpeed($with1.$class.GetSpeed() + 32);',
  20160. '$mod.TObjHelper.SetLeft.call($with1.$class, $mod.TObjHelper.GetLeft.call($with1.$class) + 33);',
  20161. '$mod.TObjHelper.SetLeft.call($with1.$class, $mod.TObjHelper.GetLeft.call($with1.$class) + 34);',
  20162. '$mod.TObject.FSize = $mod.c.FSize + 11;',
  20163. '$mod.c.SetSpeed($mod.c.GetSpeed() + 12);',
  20164. '$mod.TObjHelper.SetLeft.call($mod.c, $mod.TObjHelper.GetLeft.call($mod.c) + 13);',
  20165. '$mod.TObjHelper.SetLeft.call($mod.c, $mod.TObjHelper.GetLeft.call($mod.c) + 14);',
  20166. 'var $with2 = $mod.c;',
  20167. '$mod.TObject.FSize = $with2.FSize + 31;',
  20168. '$with2.SetSpeed($with2.GetSpeed() + 32);',
  20169. '$mod.TObjHelper.SetLeft.call($with2, $mod.TObjHelper.GetLeft.call($with2) + 33);',
  20170. '$mod.TObjHelper.SetLeft.call($with2, $mod.TObjHelper.GetLeft.call($with2) + 34);',
  20171. '$mod.TObject.FSize = $mod.TBird.FSize + 11;',
  20172. '$mod.TBird.SetSpeed($mod.TBird.GetSpeed() + 12);',
  20173. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 13);',
  20174. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 14);',
  20175. 'var $with3 = $mod.TBird;',
  20176. '$mod.TObject.FSize = $with3.FSize + 31;',
  20177. '$with3.SetSpeed($with3.GetSpeed() + 32);',
  20178. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 33);',
  20179. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 34);',
  20180. '']));
  20181. end;
  20182. procedure TTestModule.TestClassHelper_ClassPropertyStatic;
  20183. begin
  20184. StartProgram(false);
  20185. Add([
  20186. 'type',
  20187. ' TObject = class',
  20188. ' class function GetSpeed: word; static;',
  20189. ' class procedure SetSpeed(Value: word); static;',
  20190. ' end;',
  20191. ' TObjHelper = class helper for TObject',
  20192. ' class function GetLeft: word; static;',
  20193. ' class procedure SetLeft(Value: word); static;',
  20194. ' class property Speed: word read GetSpeed write SetSpeed;',
  20195. ' class property Left: word read GetLeft write SetLeft;',
  20196. ' end;',
  20197. ' TBird = class',
  20198. ' class property NotRight: word read GetLeft write SetLeft;',
  20199. ' class procedure DoIt; static;',
  20200. ' class procedure DoSome;',
  20201. ' end;',
  20202. ' TBirdClass = class of TBird;',
  20203. 'class function Tobject.GetSpeed: word;',
  20204. 'begin',
  20205. ' Speed:=Speed+12;',
  20206. ' Left:=Left+13;',
  20207. 'end;',
  20208. 'class procedure TObject.SetSpeed(Value: word);',
  20209. 'begin',
  20210. 'end;',
  20211. 'class function TObjHelper.GetLeft: word;',
  20212. 'begin',
  20213. ' Speed:=Speed+12;',
  20214. ' Left:=Left+13;',
  20215. 'end;',
  20216. 'class procedure TObjHelper.SetLeft(Value: word);',
  20217. 'begin',
  20218. 'end;',
  20219. 'class procedure TBird.DoIt;',
  20220. 'begin',
  20221. ' NotRight:=NotRight+11;',
  20222. 'end;',
  20223. 'class procedure TBird.DoSome;',
  20224. 'begin',
  20225. ' Speed:=Speed+12;',
  20226. ' Left:=Left+13;',
  20227. ' Self.Speed:=Self.Speed+22;',
  20228. ' Self.Left:=Self.Left+23;',
  20229. ' with Self do begin',
  20230. ' Speed:=Speed+32;',
  20231. ' Left:=Left+33;',
  20232. ' end;',
  20233. ' NotRight:=NotRight+11;',
  20234. ' Self.NotRight:=Self.NotRight+21;',
  20235. ' with Self do NotRight:=NotRight+31;',
  20236. 'end;',
  20237. 'var',
  20238. ' b: TBird;',
  20239. ' c: TBirdClass;',
  20240. 'begin',
  20241. ' b.Speed:=b.Speed+12;',
  20242. ' b.Left:=b.Left+13;',
  20243. ' b.NotRight:=b.NotRight+14;',
  20244. ' with b do begin',
  20245. ' Speed:=Speed+32;',
  20246. ' Left:=Left+33;',
  20247. ' NotRight:=NotRight+34;',
  20248. ' end;',
  20249. ' c.Speed:=c.Speed+12;',
  20250. ' c.Left:=c.Left+13;',
  20251. ' c.NotRight:=c.NotRight+14;',
  20252. ' with c do begin',
  20253. ' Speed:=Speed+32;',
  20254. ' Left:=Left+33;',
  20255. ' NotRight:=NotRight+34;',
  20256. ' end;',
  20257. ' tbird.Speed:=tbird.Speed+12;',
  20258. ' tbird.Left:=tbird.Left+13;',
  20259. ' tbird.NotRight:=tbird.NotRight+14;',
  20260. ' with tbird do begin',
  20261. ' Speed:=Speed+32;',
  20262. ' Left:=Left+33;',
  20263. ' NotRight:=NotRight+34;',
  20264. ' end;',
  20265. '']);
  20266. ConvertProgram;
  20267. CheckSource('TestClassHelper_ClassPropertyStatic',
  20268. LinesToStr([ // statements
  20269. 'rtl.createClass($mod, "TObject", null, function () {',
  20270. ' this.$init = function () {',
  20271. ' };',
  20272. ' this.$final = function () {',
  20273. ' };',
  20274. ' this.GetSpeed = function () {',
  20275. ' var Result = 0;',
  20276. ' this.SetSpeed(this.GetSpeed() + 12);',
  20277. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20278. ' return Result;',
  20279. ' };',
  20280. ' this.SetSpeed = function (Value) {',
  20281. ' };',
  20282. '});',
  20283. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  20284. ' this.GetLeft = function () {',
  20285. ' var Result = 0;',
  20286. ' this.SetSpeed(this.GetSpeed() + 12);',
  20287. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20288. ' return Result;',
  20289. ' };',
  20290. ' this.SetLeft = function (Value) {',
  20291. ' };',
  20292. '});',
  20293. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20294. ' this.DoIt = function () {',
  20295. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 11);',
  20296. ' };',
  20297. ' this.DoSome = function () {',
  20298. ' this.SetSpeed(this.GetSpeed() + 12);',
  20299. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20300. ' this.SetSpeed(this.GetSpeed() + 22);',
  20301. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 23);',
  20302. ' this.SetSpeed(this.GetSpeed() + 32);',
  20303. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20304. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 11);',
  20305. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 21);',
  20306. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 31);',
  20307. ' };',
  20308. '});',
  20309. 'this.b = null;',
  20310. 'this.c = null;',
  20311. '']),
  20312. LinesToStr([ // $mod.$main
  20313. '$mod.b.SetSpeed($mod.b.GetSpeed() + 12);',
  20314. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20315. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  20316. 'var $with1 = $mod.b;',
  20317. '$with1.SetSpeed($with1.GetSpeed() + 32);',
  20318. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20319. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  20320. '$mod.c.SetSpeed($mod.c.GetSpeed() + 12);',
  20321. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20322. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  20323. 'var $with2 = $mod.c;',
  20324. '$with2.SetSpeed($with2.GetSpeed() + 32);',
  20325. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20326. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  20327. '$mod.TBird.SetSpeed($mod.TBird.GetSpeed() + 12);',
  20328. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20329. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  20330. 'var $with3 = $mod.TBird;',
  20331. '$with3.SetSpeed($with3.GetSpeed() + 32);',
  20332. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20333. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  20334. '']));
  20335. end;
  20336. procedure TTestModule.TestClassHelper_ClassProperty_Array;
  20337. begin
  20338. StartProgram(false);
  20339. Add([
  20340. 'type',
  20341. ' TObject = class',
  20342. ' class function GetSpeed(Index: boolean): word;',
  20343. ' class procedure SetSpeed(Index: boolean; Value: word); virtual; abstract;',
  20344. ' end;',
  20345. ' TObjHelper = class helper for TObject',
  20346. ' class function GetSize(Index: boolean): word;',
  20347. ' class procedure SetSize(Index: boolean; Value: word);',
  20348. ' class property Size[Index: boolean]: word read GetSize write SetSize;',
  20349. ' class property Speed[Index: boolean]: word read GetSpeed write SetSpeed;',
  20350. ' end;',
  20351. ' TBird = class',
  20352. ' class property Items[Index: boolean]: word read GetSize write SetSize;',
  20353. ' class procedure DoIt;',
  20354. ' end;',
  20355. ' TBirdClass = class of TBird;',
  20356. 'class function Tobject.GetSpeed(Index: boolean): word;',
  20357. 'begin',
  20358. ' Size[true]:=Size[false]+11;',
  20359. ' Speed[true]:=Speed[false]+12;',
  20360. ' Self.Size[true]:=Self.Size[false]+21;',
  20361. ' Self.Speed[true]:=Self.Speed[false]+22;',
  20362. ' with Self do begin',
  20363. ' Size[true]:=Size[false]+31;',
  20364. ' Speed[true]:=Speed[false]+32;',
  20365. ' end;',
  20366. 'end;',
  20367. 'class function TObjHelper.GetSize(Index: boolean): word;',
  20368. 'begin',
  20369. ' Size[true]:=Size[false]+11;',
  20370. ' Speed[true]:=Speed[false]+12;',
  20371. ' Self.Size[true]:=Self.Size[false]+21;',
  20372. ' Self.Speed[true]:=Self.Speed[false]+22;',
  20373. ' with Self do begin',
  20374. ' Size[true]:=Size[false]+31;',
  20375. ' Speed[true]:=Speed[false]+32;',
  20376. ' end;',
  20377. 'end;',
  20378. 'class procedure TObjHelper.SetSize(Index: boolean; Value: word);',
  20379. 'begin',
  20380. 'end;',
  20381. 'class procedure TBird.DoIt;',
  20382. 'begin',
  20383. ' Items[true]:=Items[false]+11;',
  20384. ' Self.Items[true]:=Self.Items[false]+21;',
  20385. ' with Self do Items[true]:=Items[false]+31;',
  20386. 'end;',
  20387. 'var',
  20388. ' b: TBird;',
  20389. ' c: TBirdClass;',
  20390. 'begin',
  20391. ' b.Size[true]:=b.Size[false]+11;',
  20392. ' b.Speed[true]:=b.Speed[false]+12;',
  20393. ' b.Items[true]:=b.Items[false]+13;',
  20394. ' with b do begin',
  20395. ' Size[true]:=Size[false]+21;',
  20396. ' Speed[true]:=Speed[false]+22;',
  20397. ' Items[true]:=Items[false]+23;',
  20398. ' end;',
  20399. ' c.Size[true]:=c.Size[false]+11;',
  20400. ' c.Speed[true]:=c.Speed[false]+12;',
  20401. ' c.Items[true]:=c.Items[false]+13;',
  20402. ' with c do begin',
  20403. ' Size[true]:=Size[false]+21;',
  20404. ' Speed[true]:=Speed[false]+22;',
  20405. ' Items[true]:=Items[false]+23;',
  20406. ' end;',
  20407. ' TBird.Size[true]:=TBird.Size[false]+11;',
  20408. ' TBird.Speed[true]:=TBird.Speed[false]+12;',
  20409. ' TBird.Items[true]:=TBird.Items[false]+13;',
  20410. ' with TBird do begin',
  20411. ' Size[true]:=Size[false]+21;',
  20412. ' Speed[true]:=Speed[false]+22;',
  20413. ' Items[true]:=Items[false]+23;',
  20414. ' end;',
  20415. '']);
  20416. ConvertProgram;
  20417. CheckSource('TestClassHelper_ClassProperty_Array',
  20418. LinesToStr([ // statements
  20419. 'rtl.createClass($mod, "TObject", null, function () {',
  20420. ' this.$init = function () {',
  20421. ' };',
  20422. ' this.$final = function () {',
  20423. ' };',
  20424. ' this.GetSpeed = function (Index) {',
  20425. ' var Result = 0;',
  20426. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  20427. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  20428. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  20429. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  20430. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  20431. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  20432. ' return Result;',
  20433. ' };',
  20434. '});',
  20435. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  20436. ' this.GetSize = function (Index) {',
  20437. ' var Result = 0;',
  20438. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  20439. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  20440. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  20441. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  20442. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  20443. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  20444. ' return Result;',
  20445. ' };',
  20446. ' this.SetSize = function (Index, Value) {',
  20447. ' };',
  20448. '});',
  20449. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20450. ' this.DoIt = function () {',
  20451. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  20452. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  20453. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  20454. ' };',
  20455. '});',
  20456. 'this.b = null;',
  20457. 'this.c = null;',
  20458. '']),
  20459. LinesToStr([ // $mod.$main
  20460. '$mod.TObjHelper.SetSize.call($mod.b.$class, true, $mod.TObjHelper.GetSize.call($mod.b.$class, false) + 11);',
  20461. '$mod.b.$class.SetSpeed(true, $mod.b.$class.GetSpeed(false) + 12);',
  20462. '$mod.TObjHelper.SetSize.call($mod.b.$class, true, $mod.TObjHelper.GetSize.call($mod.b.$class, false) + 13);',
  20463. 'var $with1 = $mod.b;',
  20464. '$mod.TObjHelper.SetSize.call($with1.$class, true, $mod.TObjHelper.GetSize.call($with1.$class, false) + 21);',
  20465. '$with1.$class.SetSpeed(true, $with1.$class.GetSpeed(false) + 22);',
  20466. '$mod.TObjHelper.SetSize.call($with1.$class, true, $mod.TObjHelper.GetSize.call($with1.$class, false) + 23);',
  20467. '$mod.TObjHelper.SetSize.call($mod.c, true, $mod.TObjHelper.GetSize.call($mod.c, false) + 11);',
  20468. '$mod.c.SetSpeed(true, $mod.c.GetSpeed(false) + 12);',
  20469. '$mod.TObjHelper.SetSize.call($mod.c, true, $mod.TObjHelper.GetSize.call($mod.c, false) + 13);',
  20470. 'var $with2 = $mod.c;',
  20471. '$mod.TObjHelper.SetSize.call($with2, true, $mod.TObjHelper.GetSize.call($with2, false) + 21);',
  20472. '$with2.SetSpeed(true, $with2.GetSpeed(false) + 22);',
  20473. '$mod.TObjHelper.SetSize.call($with2, true, $mod.TObjHelper.GetSize.call($with2, false) + 23);',
  20474. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 11);',
  20475. '$mod.TBird.SetSpeed(true, $mod.TBird.GetSpeed(false) + 12);',
  20476. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 13);',
  20477. 'var $with3 = $mod.TBird;',
  20478. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 21);',
  20479. '$with3.SetSpeed(true, $with3.GetSpeed(false) + 22);',
  20480. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 23);',
  20481. '']));
  20482. end;
  20483. procedure TTestModule.TestClassHelper_ForIn;
  20484. begin
  20485. StartProgram(false);
  20486. Add([
  20487. 'type',
  20488. ' TObject = class end;',
  20489. ' TItem = TObject;',
  20490. ' TEnumerator = class',
  20491. ' FCurrent: TItem;',
  20492. ' property Current: TItem read FCurrent;',
  20493. ' function MoveNext: boolean;',
  20494. ' end;',
  20495. ' TBird = class',
  20496. ' end;',
  20497. ' TBirdHelper = class helper for TBird',
  20498. ' function GetEnumerator: TEnumerator;',
  20499. ' end;',
  20500. 'function TEnumerator.MoveNext: boolean;',
  20501. 'begin',
  20502. 'end;',
  20503. 'function TBirdHelper.GetEnumerator: TEnumerator;',
  20504. 'begin',
  20505. 'end;',
  20506. 'var',
  20507. ' b: TBird;',
  20508. ' i, i2: TItem;',
  20509. 'begin',
  20510. ' for i in b do i2:=i;']);
  20511. ConvertProgram;
  20512. CheckSource('TestClassHelper_ForIn',
  20513. LinesToStr([ // statements
  20514. 'rtl.createClass($mod, "TObject", null, function () {',
  20515. ' this.$init = function () {',
  20516. ' };',
  20517. ' this.$final = function () {',
  20518. ' };',
  20519. '});',
  20520. 'rtl.createClass($mod, "TEnumerator", $mod.TObject, function () {',
  20521. ' this.$init = function () {',
  20522. ' $mod.TObject.$init.call(this);',
  20523. ' this.FCurrent = null;',
  20524. ' };',
  20525. ' this.$final = function () {',
  20526. ' this.FCurrent = undefined;',
  20527. ' $mod.TObject.$final.call(this);',
  20528. ' };',
  20529. ' this.MoveNext = function () {',
  20530. ' var Result = false;',
  20531. ' return Result;',
  20532. ' };',
  20533. '});',
  20534. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20535. '});',
  20536. 'rtl.createHelper($mod, "TBirdHelper", null, function () {',
  20537. ' this.GetEnumerator = function () {',
  20538. ' var Result = null;',
  20539. ' return Result;',
  20540. ' };',
  20541. '});',
  20542. 'this.b = null;',
  20543. 'this.i = null;',
  20544. 'this.i2 = null;'
  20545. ]),
  20546. LinesToStr([ // $mod.$main
  20547. 'var $in1 = $mod.TBirdHelper.GetEnumerator.call($mod.b);',
  20548. 'try {',
  20549. ' while ($in1.MoveNext()){',
  20550. ' $mod.i = $in1.FCurrent;',
  20551. ' $mod.i2 = $mod.i;',
  20552. ' }',
  20553. '} finally {',
  20554. ' $in1 = rtl.freeLoc($in1)',
  20555. '};',
  20556. '']));
  20557. end;
  20558. procedure TTestModule.TestClassHelper_PassProperty;
  20559. begin
  20560. StartProgram(false);
  20561. Add([
  20562. 'type',
  20563. ' TObject = class',
  20564. ' FField: TObject;',
  20565. ' property Field: TObject read FField write FField;',
  20566. ' end;',
  20567. ' THelper = class helper for TObject',
  20568. ' procedure Fly;',
  20569. ' class procedure Run;',
  20570. ' class procedure Jump; static;',
  20571. ' end;',
  20572. 'procedure THelper.Fly;',
  20573. 'begin',
  20574. ' Field.Fly;',
  20575. ' Field.Run;',
  20576. ' Field.Jump;',
  20577. ' with Field do begin',
  20578. ' Fly;',
  20579. ' Run;',
  20580. ' Jump;',
  20581. ' end;',
  20582. 'end;',
  20583. 'class procedure THelper.Run;',
  20584. 'begin',
  20585. 'end;',
  20586. 'class procedure THelper.Jump;',
  20587. 'begin',
  20588. 'end;',
  20589. 'var',
  20590. ' b: TObject;',
  20591. 'begin',
  20592. ' b.Field.Fly;',
  20593. ' b.Field.Run;',
  20594. ' b.Field.Jump;',
  20595. ' with b do begin',
  20596. ' Field.Run;',
  20597. ' Field.Fly;',
  20598. ' Field.Jump;',
  20599. ' end;',
  20600. ' with b.Field do begin',
  20601. ' Run;',
  20602. ' Fly;',
  20603. ' Jump;',
  20604. ' end;',
  20605. '']);
  20606. ConvertProgram;
  20607. CheckSource('TestClassHelper_PassProperty',
  20608. LinesToStr([ // statements
  20609. 'rtl.createClass($mod, "TObject", null, function () {',
  20610. ' this.$init = function () {',
  20611. ' this.FField = null;',
  20612. ' };',
  20613. ' this.$final = function () {',
  20614. ' this.FField = undefined;',
  20615. ' };',
  20616. '});',
  20617. 'rtl.createHelper($mod, "THelper", null, function () {',
  20618. ' this.Fly = function () {',
  20619. ' $mod.THelper.Fly.call(this.FField);',
  20620. ' $mod.THelper.Run.call(this.FField.$class);',
  20621. ' $mod.THelper.Jump();',
  20622. ' var $with1 = this.FField;',
  20623. ' $mod.THelper.Fly.call($with1);',
  20624. ' $mod.THelper.Run.call($with1.$class);',
  20625. ' $mod.THelper.Jump();',
  20626. ' };',
  20627. ' this.Run = function () {',
  20628. ' };',
  20629. ' this.Jump = function () {',
  20630. ' };',
  20631. '});',
  20632. 'this.b = null;',
  20633. '']),
  20634. LinesToStr([ // $mod.$main
  20635. '$mod.THelper.Fly.call($mod.b.FField);',
  20636. '$mod.THelper.Run.call($mod.b.FField.$class);',
  20637. '$mod.THelper.Jump();',
  20638. 'var $with1 = $mod.b;',
  20639. '$mod.THelper.Run.call($with1.FField.$class);',
  20640. '$mod.THelper.Fly.call($with1.FField);',
  20641. '$mod.THelper.Jump();',
  20642. 'var $with2 = $mod.b.FField;',
  20643. '$mod.THelper.Run.call($with2.$class);',
  20644. '$mod.THelper.Fly.call($with2);',
  20645. '$mod.THelper.Jump();',
  20646. '']));
  20647. end;
  20648. procedure TTestModule.TestExtClassHelper_ClassVar;
  20649. begin
  20650. StartProgram(false);
  20651. Add([
  20652. '{$modeswitch externalclass}',
  20653. 'type',
  20654. ' TExtA = class external name ''ExtObj''',
  20655. ' end;',
  20656. ' THelper = class helper for TExtA',
  20657. ' const',
  20658. ' One = 1;',
  20659. ' Two: word = 2;',
  20660. ' class var',
  20661. ' Glob: word;',
  20662. ' function Foo(w: word): word;',
  20663. ' class function Bar(w: word): word; static;',
  20664. ' end;',
  20665. 'function THelper.foo(w: word): word;',
  20666. 'begin',
  20667. ' Result:=w;',
  20668. ' Two:=One+w;',
  20669. ' Glob:=Glob;',
  20670. ' Result:=Self.Glob;',
  20671. ' Self.Glob:=Self.Glob;',
  20672. ' with Self do Glob:=Glob;',
  20673. 'end;',
  20674. 'class function THelper.bar(w: word): word;',
  20675. 'begin',
  20676. ' Result:=w;',
  20677. ' Two:=One;',
  20678. ' Glob:=Glob;',
  20679. 'end;',
  20680. 'var o: TExtA;',
  20681. 'begin',
  20682. ' texta.two:=texta.one;',
  20683. ' texta.Glob:=texta.Glob;',
  20684. ' with texta do begin',
  20685. ' two:=one;',
  20686. ' Glob:=Glob;',
  20687. ' end;',
  20688. ' o.two:=o.one;',
  20689. ' o.Glob:=o.Glob;',
  20690. ' with o do begin',
  20691. ' two:=one;',
  20692. ' Glob:=Glob;',
  20693. ' end;',
  20694. '']);
  20695. ConvertProgram;
  20696. CheckSource('TestExtClassHelper_ClassVar',
  20697. LinesToStr([ // statements
  20698. 'rtl.createHelper($mod, "THelper", null, function () {',
  20699. ' this.One = 1;',
  20700. ' this.Two = 2;',
  20701. ' this.Glob = 0;',
  20702. ' this.Foo = function (w) {',
  20703. ' var Result = 0;',
  20704. ' Result = w;',
  20705. ' $mod.THelper.Two = 1 + w;',
  20706. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20707. ' Result = $mod.THelper.Glob;',
  20708. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20709. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20710. ' return Result;',
  20711. ' };',
  20712. ' this.Bar = function (w) {',
  20713. ' var Result = 0;',
  20714. ' Result = w;',
  20715. ' $mod.THelper.Two = 1;',
  20716. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20717. ' return Result;',
  20718. ' };',
  20719. '});',
  20720. 'this.o = null;',
  20721. '']),
  20722. LinesToStr([ // $mod.$main
  20723. '$mod.THelper.Two = 1;',
  20724. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20725. '$mod.THelper.Two = 1;',
  20726. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20727. '$mod.THelper.Two = 1;',
  20728. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20729. 'var $with1 = $mod.o;',
  20730. '$mod.THelper.Two = 1;',
  20731. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20732. '']));
  20733. end;
  20734. procedure TTestModule.TestExtClassHelper_Method_Call;
  20735. begin
  20736. StartProgram(false);
  20737. Add([
  20738. '{$modeswitch externalclass}',
  20739. 'type',
  20740. ' TFly = function(w: word): word of object;',
  20741. ' TExtA = class external name ''ExtObj''',
  20742. ' procedure Run(w: word = 10);',
  20743. ' end;',
  20744. ' THelper = class helper for TExtA',
  20745. ' function Foo(w: word = 1): word;',
  20746. ' function Fly(w: word = 2): word; external name ''Fly'';',
  20747. ' end;',
  20748. 'var p: TFly;',
  20749. 'function THelper.foo(w: word): word;',
  20750. 'begin',
  20751. ' Run;',
  20752. ' Run();',
  20753. ' Run(11);',
  20754. ' Foo;',
  20755. ' Foo();',
  20756. ' Foo(12);',
  20757. ' Self.Foo;',
  20758. ' Self.Foo();',
  20759. ' Self.Foo(13);',
  20760. ' Fly;',
  20761. ' Fly();',
  20762. ' with Self do begin',
  20763. ' Foo;',
  20764. ' Foo();',
  20765. ' Foo(14);',
  20766. ' Fly;',
  20767. ' Fly();',
  20768. ' end;',
  20769. ' p:=@Fly;',
  20770. 'end;',
  20771. 'var Obj: TExtA;',
  20772. 'begin',
  20773. ' obj.Foo;',
  20774. ' obj.Foo();',
  20775. ' obj.Foo(21);',
  20776. ' obj.Fly;',
  20777. ' obj.Fly();',
  20778. ' with obj do begin',
  20779. ' Foo;',
  20780. ' Foo();',
  20781. ' Foo(22);',
  20782. ' Fly;',
  20783. ' Fly();',
  20784. ' end;',
  20785. ' p:[email protected];',
  20786. '']);
  20787. ConvertProgram;
  20788. CheckSource('TestExtClassHelper_Method_Call',
  20789. LinesToStr([ // statements
  20790. 'rtl.createHelper($mod, "THelper", null, function () {',
  20791. ' this.Foo = function (w) {',
  20792. ' var Result = 0;',
  20793. ' this.Run(10);',
  20794. ' this.Run(10);',
  20795. ' this.Run(11);',
  20796. ' $mod.THelper.Foo.call(this, 1);',
  20797. ' $mod.THelper.Foo.call(this, 1);',
  20798. ' $mod.THelper.Foo.call(this, 12);',
  20799. ' $mod.THelper.Foo.call(this, 1);',
  20800. ' $mod.THelper.Foo.call(this, 1);',
  20801. ' $mod.THelper.Foo.call(this, 13);',
  20802. ' this.Fly(2);',
  20803. ' this.Fly(2);',
  20804. ' $mod.THelper.Foo.call(this, 1);',
  20805. ' $mod.THelper.Foo.call(this, 1);',
  20806. ' $mod.THelper.Foo.call(this, 14);',
  20807. ' this.Fly(2);',
  20808. ' this.Fly(2);',
  20809. ' $mod.p = rtl.createCallback(this, "Fly");',
  20810. ' return Result;',
  20811. ' };',
  20812. '});',
  20813. 'this.p = null;',
  20814. 'this.Obj = null;',
  20815. '']),
  20816. LinesToStr([ // $mod.$main
  20817. '$mod.THelper.Foo.call($mod.Obj, 1);',
  20818. '$mod.THelper.Foo.call($mod.Obj, 1);',
  20819. '$mod.THelper.Foo.call($mod.Obj, 21);',
  20820. '$mod.Obj.Fly(2);',
  20821. '$mod.Obj.Fly(2);',
  20822. 'var $with1 = $mod.Obj;',
  20823. '$mod.THelper.Foo.call($with1, 1);',
  20824. '$mod.THelper.Foo.call($with1, 1);',
  20825. '$mod.THelper.Foo.call($with1, 22);',
  20826. '$with1.Fly(2);',
  20827. '$with1.Fly(2);',
  20828. '$mod.p = rtl.createCallback($mod.Obj, "Fly");',
  20829. '']));
  20830. end;
  20831. procedure TTestModule.TestRecordHelper_ClassVar;
  20832. begin
  20833. StartProgram(false);
  20834. Add([
  20835. 'type',
  20836. ' TRec = record',
  20837. ' end;',
  20838. ' THelper = record helper for TRec',
  20839. ' const',
  20840. ' One = 1;',
  20841. ' Two: word = 2;',
  20842. ' class var',
  20843. ' Glob: word;',
  20844. ' function Foo(w: word): word;',
  20845. ' class function Bar(w: word): word; static;',
  20846. ' end;',
  20847. 'function THelper.foo(w: word): word;',
  20848. 'begin',
  20849. ' Result:=w;',
  20850. ' Two:=One+w;',
  20851. ' Glob:=Glob;',
  20852. ' Result:=Self.Glob;',
  20853. ' Self.Glob:=Self.Glob;',
  20854. ' with Self do Glob:=Glob;',
  20855. ' Self:=Self;',
  20856. 'end;',
  20857. 'class function THelper.bar(w: word): word;',
  20858. 'begin',
  20859. ' Result:=w;',
  20860. ' Two:=One;',
  20861. ' Glob:=Glob;',
  20862. 'end;',
  20863. 'var r: TRec;',
  20864. 'begin',
  20865. ' trec.two:=trec.one;',
  20866. ' trec.Glob:=trec.Glob;',
  20867. ' with trec do begin',
  20868. ' two:=one;',
  20869. ' Glob:=Glob;',
  20870. ' end;',
  20871. ' r.two:=r.one;',
  20872. ' r.Glob:=r.Glob;',
  20873. ' with r do begin',
  20874. ' two:=one;',
  20875. ' Glob:=Glob;',
  20876. ' end;',
  20877. '']);
  20878. ConvertProgram;
  20879. CheckSource('TestRecordHelper_ClassVar',
  20880. LinesToStr([ // statements
  20881. 'rtl.recNewT($mod, "TRec", function () {',
  20882. ' this.$eq = function (b) {',
  20883. ' return true;',
  20884. ' };',
  20885. ' this.$assign = function (s) {',
  20886. ' return this;',
  20887. ' };',
  20888. '});',
  20889. 'rtl.createHelper($mod, "THelper", null, function () {',
  20890. ' this.One = 1;',
  20891. ' this.Two = 2;',
  20892. ' this.Glob = 0;',
  20893. ' this.Foo = function (w) {',
  20894. ' var Result = 0;',
  20895. ' Result = w;',
  20896. ' $mod.THelper.Two = 1 + w;',
  20897. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20898. ' Result = $mod.THelper.Glob;',
  20899. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20900. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20901. ' this.$assign(this);',
  20902. ' return Result;',
  20903. ' };',
  20904. ' this.Bar = function (w) {',
  20905. ' var Result = 0;',
  20906. ' Result = w;',
  20907. ' $mod.THelper.Two = 1;',
  20908. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20909. ' return Result;',
  20910. ' };',
  20911. '});',
  20912. 'this.r = $mod.TRec.$new();',
  20913. '']),
  20914. LinesToStr([ // $mod.$main
  20915. '$mod.THelper.Two = 1;',
  20916. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20917. 'var $with1 = $mod.TRec;',
  20918. '$mod.THelper.Two = 1;',
  20919. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20920. '$mod.THelper.Two = 1;',
  20921. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20922. 'var $with2 = $mod.r;',
  20923. '$mod.THelper.Two = 1;',
  20924. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20925. '']));
  20926. end;
  20927. procedure TTestModule.TestRecordHelper_Method_Call;
  20928. begin
  20929. StartProgram(false);
  20930. Add([
  20931. '{$modeswitch AdvancedRecords}',
  20932. 'type',
  20933. ' TRec = record',
  20934. ' procedure Run(w: word = 10);',
  20935. ' end;',
  20936. ' THelper = record helper for TRec',
  20937. ' function Foo(w: word = 1): word;',
  20938. ' end;',
  20939. 'procedure TRec.Run(w: word);',
  20940. 'begin',
  20941. ' Foo;',
  20942. ' Foo();',
  20943. ' Foo(2);',
  20944. ' Self.Foo;',
  20945. ' Self.Foo();',
  20946. ' Self.Foo(3);',
  20947. ' with Self do begin',
  20948. ' Foo;',
  20949. ' Foo();',
  20950. ' Foo(4);',
  20951. ' end;',
  20952. 'end;',
  20953. 'function THelper.foo(w: word): word;',
  20954. 'begin',
  20955. ' Run;',
  20956. ' Run();',
  20957. ' Run(11);',
  20958. ' Foo;',
  20959. ' Foo();',
  20960. ' Foo(12);',
  20961. ' Self.Foo;',
  20962. ' Self.Foo();',
  20963. ' Self.Foo(13);',
  20964. ' with Self do begin',
  20965. ' Foo;',
  20966. ' Foo();',
  20967. ' Foo(14);',
  20968. ' end;',
  20969. 'end;',
  20970. 'var Rec: TRec;',
  20971. 'begin',
  20972. ' Rec.Foo;',
  20973. ' Rec.Foo();',
  20974. ' Rec.Foo(21);',
  20975. ' with Rec do begin',
  20976. ' Foo;',
  20977. ' Foo();',
  20978. ' Foo(22);',
  20979. ' end;',
  20980. '']);
  20981. ConvertProgram;
  20982. CheckSource('TestRecordHelper_Method_Call',
  20983. LinesToStr([ // statements
  20984. 'rtl.recNewT($mod, "TRec", function () {',
  20985. ' this.$eq = function (b) {',
  20986. ' return true;',
  20987. ' };',
  20988. ' this.$assign = function (s) {',
  20989. ' return this;',
  20990. ' };',
  20991. ' this.Run = function (w) {',
  20992. ' $mod.THelper.Foo.call(this, 1);',
  20993. ' $mod.THelper.Foo.call(this, 1);',
  20994. ' $mod.THelper.Foo.call(this, 2);',
  20995. ' $mod.THelper.Foo.call(this, 1);',
  20996. ' $mod.THelper.Foo.call(this, 1);',
  20997. ' $mod.THelper.Foo.call(this, 3);',
  20998. ' $mod.THelper.Foo.call(this, 1);',
  20999. ' $mod.THelper.Foo.call(this, 1);',
  21000. ' $mod.THelper.Foo.call(this, 4);',
  21001. ' };',
  21002. '});',
  21003. 'rtl.createHelper($mod, "THelper", null, function () {',
  21004. ' this.Foo = function (w) {',
  21005. ' var Result = 0;',
  21006. ' this.Run(10);',
  21007. ' this.Run(10);',
  21008. ' this.Run(11);',
  21009. ' $mod.THelper.Foo.call(this, 1);',
  21010. ' $mod.THelper.Foo.call(this, 1);',
  21011. ' $mod.THelper.Foo.call(this, 12);',
  21012. ' $mod.THelper.Foo.call(this, 1);',
  21013. ' $mod.THelper.Foo.call(this, 1);',
  21014. ' $mod.THelper.Foo.call(this, 13);',
  21015. ' $mod.THelper.Foo.call(this, 1);',
  21016. ' $mod.THelper.Foo.call(this, 1);',
  21017. ' $mod.THelper.Foo.call(this, 14);',
  21018. ' return Result;',
  21019. ' };',
  21020. '});',
  21021. 'this.Rec = $mod.TRec.$new();',
  21022. '']),
  21023. LinesToStr([ // $mod.$main
  21024. '$mod.THelper.Foo.call($mod.Rec, 1);',
  21025. '$mod.THelper.Foo.call($mod.Rec, 1);',
  21026. '$mod.THelper.Foo.call($mod.Rec, 21);',
  21027. 'var $with1 = $mod.Rec;',
  21028. '$mod.THelper.Foo.call($with1, 1);',
  21029. '$mod.THelper.Foo.call($with1, 1);',
  21030. '$mod.THelper.Foo.call($with1, 22);',
  21031. '']));
  21032. end;
  21033. procedure TTestModule.TestRecordHelper_Constructor;
  21034. begin
  21035. StartProgram(false);
  21036. Add([
  21037. '{$modeswitch AdvancedRecords}',
  21038. 'type',
  21039. ' TRec = record',
  21040. ' constructor Create(w: word);',
  21041. ' end;',
  21042. ' THelper = record helper for TRec',
  21043. ' constructor NewHlp(w: word);',
  21044. ' end;',
  21045. 'var',
  21046. ' Rec: TRec;',
  21047. 'constructor TRec.Create(w: word);',
  21048. 'begin',
  21049. ' NewHlp(2);', // normal call
  21050. ' trec.NewHlp(3);', // new instance
  21051. 'end;',
  21052. 'constructor THelper.NewHlp(w: word);',
  21053. 'begin',
  21054. ' create(2);', // normal call
  21055. ' trec.create(3);', // new instance
  21056. ' NewHlp(4);', // normal call
  21057. ' trec.NewHlp(5);', // new instance
  21058. 'end;',
  21059. 'begin',
  21060. ' rec.newhlp(2);', // normal call
  21061. ' with rec do newhlp(12);', // normal call
  21062. ' trec.newhlp(3);', // new instance
  21063. ' with trec do newhlp(13);', // new instance
  21064. '']);
  21065. ConvertProgram;
  21066. CheckSource('TestRecordHelper_Constructor',
  21067. LinesToStr([ // statements
  21068. 'rtl.recNewT($mod, "TRec", function () {',
  21069. ' this.$eq = function (b) {',
  21070. ' return true;',
  21071. ' };',
  21072. ' this.$assign = function (s) {',
  21073. ' return this;',
  21074. ' };',
  21075. ' this.Create = function (w) {',
  21076. ' $mod.THelper.NewHlp.call(this, 2);',
  21077. ' $mod.THelper.$new("NewHlp", [3]);',
  21078. ' return this;',
  21079. ' };',
  21080. '}, true);',
  21081. 'rtl.createHelper($mod, "THelper", null, function () {',
  21082. ' this.NewHlp = function (w) {',
  21083. ' this.Create(2);',
  21084. ' $mod.TRec.$new().Create(3);',
  21085. ' $mod.THelper.NewHlp.call(this, 4);',
  21086. ' $mod.THelper.$new("NewHlp", [5]);',
  21087. ' return this;',
  21088. ' };',
  21089. ' this.$new = function (fn, args) {',
  21090. ' return this[fn].apply($mod.TRec.$new(), args);',
  21091. ' };',
  21092. '});',
  21093. 'this.Rec = $mod.TRec.$new();',
  21094. '']),
  21095. LinesToStr([ // $mod.$main
  21096. '$mod.THelper.NewHlp.call($mod.Rec, 2);',
  21097. 'var $with1 = $mod.Rec;',
  21098. '$mod.THelper.NewHlp.call($with1, 12);',
  21099. '$mod.THelper.$new("NewHlp", [3]);',
  21100. 'var $with2 = $mod.TRec;',
  21101. '$mod.THelper.$new("NewHlp", [13]);',
  21102. '']));
  21103. end;
  21104. procedure TTestModule.TestTypeHelper_ClassVar;
  21105. begin
  21106. StartProgram(false);
  21107. Add([
  21108. '{$modeswitch typehelpers}',
  21109. 'type',
  21110. ' THelper = type helper for byte',
  21111. ' const',
  21112. ' One = 1;',
  21113. ' Two: word = 2;',
  21114. ' class var',
  21115. ' Glob: word;',
  21116. ' function Foo(w: word): word;',
  21117. ' class function Bar(w: word): word; static;',
  21118. ' end;',
  21119. 'function THelper.foo(w: word): word;',
  21120. 'begin',
  21121. ' Result:=w;',
  21122. ' Two:=One+w;',
  21123. ' Glob:=Glob;',
  21124. ' Result:=Self.Glob;',
  21125. ' Self.Glob:=Self.Glob;',
  21126. ' with Self do Glob:=Glob;',
  21127. 'end;',
  21128. 'class function THelper.bar(w: word): word;',
  21129. 'begin',
  21130. ' Result:=w;',
  21131. ' Two:=One;',
  21132. ' Glob:=Glob;',
  21133. 'end;',
  21134. 'var b: byte;',
  21135. 'begin',
  21136. ' byte.two:=byte.one;',
  21137. ' byte.Glob:=byte.Glob;',
  21138. ' with byte do begin',
  21139. ' two:=one;',
  21140. ' Glob:=Glob;',
  21141. ' end;',
  21142. ' b.two:=b.one;',
  21143. ' b.Glob:=b.Glob;',
  21144. ' with b do begin',
  21145. ' two:=one;',
  21146. ' Glob:=Glob;',
  21147. ' end;',
  21148. '']);
  21149. ConvertProgram;
  21150. CheckSource('TestTypeHelper_ClassVar',
  21151. LinesToStr([ // statements
  21152. 'rtl.createHelper($mod, "THelper", null, function () {',
  21153. ' this.One = 1;',
  21154. ' this.Two = 2;',
  21155. ' this.Glob = 0;',
  21156. ' this.Foo = function (w) {',
  21157. ' var Result = 0;',
  21158. ' Result = w;',
  21159. ' $mod.THelper.Two = 1 + w;',
  21160. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21161. ' Result = $mod.THelper.Glob;',
  21162. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21163. ' var $with1 = this.get();',
  21164. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21165. ' return Result;',
  21166. ' };',
  21167. ' this.Bar = function (w) {',
  21168. ' var Result = 0;',
  21169. ' Result = w;',
  21170. ' $mod.THelper.Two = 1;',
  21171. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21172. ' return Result;',
  21173. ' };',
  21174. '});',
  21175. 'this.b = 0;',
  21176. '']),
  21177. LinesToStr([ // $mod.$main
  21178. '$mod.THelper.Two = 1;',
  21179. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21180. '$mod.THelper.Two = 1;',
  21181. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21182. '$mod.THelper.Two = 1;',
  21183. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21184. 'var $with1 = $mod.b;',
  21185. '$mod.THelper.Two = 1;',
  21186. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21187. '']));
  21188. end;
  21189. procedure TTestModule.TestTypeHelper_PassResultElement;
  21190. begin
  21191. StartProgram(false);
  21192. Add([
  21193. '{$modeswitch typehelpers}',
  21194. 'type',
  21195. ' THelper = type helper for word',
  21196. ' procedure DoIt(e: byte = 123);',
  21197. ' class procedure DoSome(e: byte = 456); static;',
  21198. ' end;',
  21199. 'procedure THelper.DoIt(e: byte);',
  21200. 'begin',
  21201. 'end;',
  21202. 'class procedure THelper.DoSome(e: byte);',
  21203. 'begin',
  21204. 'end;',
  21205. 'function Foo(w: word): word;',
  21206. 'begin',
  21207. ' Result.DoIt;',
  21208. ' Result.DoIt();',
  21209. ' Result.DoSome;',
  21210. ' Result.DoSome();',
  21211. ' with Result do begin',
  21212. ' DoIt;',
  21213. ' DoIt();',
  21214. ' DoSome;',
  21215. ' DoSome();',
  21216. ' end;',
  21217. 'end;',
  21218. 'begin',
  21219. '']);
  21220. ConvertProgram;
  21221. CheckSource('TestTypeHelper_PassResultElement',
  21222. LinesToStr([ // statements
  21223. 'rtl.createHelper($mod, "THelper", null, function () {',
  21224. ' this.DoIt = function (e) {',
  21225. ' };',
  21226. ' this.DoSome = function (e) {',
  21227. ' };',
  21228. '});',
  21229. 'this.Foo = function (w) {',
  21230. ' var Result = 0;',
  21231. ' $mod.THelper.DoIt.call({',
  21232. ' get: function () {',
  21233. ' return Result;',
  21234. ' },',
  21235. ' set: function (v) {',
  21236. ' Result = v;',
  21237. ' }',
  21238. ' }, 123);',
  21239. ' $mod.THelper.DoIt.call({',
  21240. ' get: function () {',
  21241. ' return Result;',
  21242. ' },',
  21243. ' set: function (v) {',
  21244. ' Result = v;',
  21245. ' }',
  21246. ' }, 123);',
  21247. ' $mod.THelper.DoSome(456);',
  21248. ' $mod.THelper.DoSome(456);',
  21249. ' $mod.THelper.DoIt.call({',
  21250. ' get: function () {',
  21251. ' return Result;',
  21252. ' },',
  21253. ' set: function (v) {',
  21254. ' Result = v;',
  21255. ' }',
  21256. ' }, 123);',
  21257. ' $mod.THelper.DoIt.call({',
  21258. ' get: function () {',
  21259. ' return Result;',
  21260. ' },',
  21261. ' set: function (v) {',
  21262. ' Result = v;',
  21263. ' }',
  21264. ' }, 123);',
  21265. ' $mod.THelper.DoSome(456);',
  21266. ' $mod.THelper.DoSome(456);',
  21267. ' return Result;',
  21268. '};',
  21269. '']),
  21270. LinesToStr([ // $mod.$main
  21271. '']));
  21272. end;
  21273. procedure TTestModule.TestTypeHelper_PassArgs;
  21274. begin
  21275. StartProgram(false);
  21276. Add([
  21277. '{$modeswitch typehelpers}',
  21278. 'type',
  21279. ' THelper = type helper for word',
  21280. ' procedure DoIt(e: byte = 123);',
  21281. ' end;',
  21282. 'procedure THelper.DoIt(e: byte);',
  21283. 'begin',
  21284. 'end;',
  21285. 'procedure FooDefault(a: word);',
  21286. 'begin',
  21287. ' a.DoIt;',
  21288. ' with a do DoIt;',
  21289. 'end;',
  21290. 'procedure FooConst(const a: word);',
  21291. 'begin',
  21292. ' a.DoIt;',
  21293. ' with a do DoIt;',
  21294. 'end;',
  21295. 'procedure FooVar(var a: word);',
  21296. 'begin',
  21297. ' a.DoIt;',
  21298. ' with a do DoIt;',
  21299. 'end;',
  21300. 'begin',
  21301. '']);
  21302. ConvertProgram;
  21303. CheckSource('TestTypeHelper_PassArgs',
  21304. LinesToStr([ // statements
  21305. 'rtl.createHelper($mod, "THelper", null, function () {',
  21306. ' this.DoIt = function (e) {',
  21307. ' };',
  21308. '});',
  21309. 'this.FooDefault = function (a) {',
  21310. ' $mod.THelper.DoIt.call({',
  21311. ' get: function () {',
  21312. ' return a;',
  21313. ' },',
  21314. ' set: function (v) {',
  21315. ' a = v;',
  21316. ' }',
  21317. ' }, 123);',
  21318. ' $mod.THelper.DoIt.call({',
  21319. ' get: function () {',
  21320. ' return a;',
  21321. ' },',
  21322. ' set: function (v) {',
  21323. ' a = v;',
  21324. ' }',
  21325. ' }, 123);',
  21326. '};',
  21327. 'this.FooConst = function (a) {',
  21328. ' $mod.THelper.DoIt.call({',
  21329. ' get: function () {',
  21330. ' return a;',
  21331. ' },',
  21332. ' set: function (v) {',
  21333. ' rtl.raiseE("EPropReadOnly");',
  21334. ' }',
  21335. ' }, 123);',
  21336. ' $mod.THelper.DoIt.call({',
  21337. ' get: function () {',
  21338. ' return a;',
  21339. ' },',
  21340. ' set: function () {',
  21341. ' rtl.raiseE("EPropReadOnly");',
  21342. ' }',
  21343. ' }, 123);',
  21344. '};',
  21345. 'this.FooVar = function (a) {',
  21346. ' $mod.THelper.DoIt.call(a, 123);',
  21347. ' var $with1 = a.get();',
  21348. ' $mod.THelper.DoIt.call(a, 123);',
  21349. '};',
  21350. '']),
  21351. LinesToStr([ // $mod.$main
  21352. '']));
  21353. end;
  21354. procedure TTestModule.TestTypeHelper_PassVarConst;
  21355. begin
  21356. StartProgram(false);
  21357. Add([
  21358. '{$modeswitch typehelpers}',
  21359. 'type',
  21360. ' THelper = type helper for word',
  21361. ' procedure DoIt(e: byte = 123);',
  21362. ' end;',
  21363. 'procedure THelper.DoIt(e: byte);',
  21364. 'begin',
  21365. 'end;',
  21366. 'var a: word;',
  21367. 'const c: word = 2;',
  21368. '{$writeableconst off}',
  21369. 'const r: word = 3;',
  21370. 'begin',
  21371. ' a.DoIt;',
  21372. ' with a do DoIt;',
  21373. ' c.DoIt;',
  21374. ' with c do DoIt;',
  21375. ' r.DoIt;',
  21376. ' with r do DoIt;',
  21377. '']);
  21378. ConvertProgram;
  21379. CheckSource('TestTypeHelper_PassVarConst',
  21380. LinesToStr([ // statements
  21381. 'rtl.createHelper($mod, "THelper", null, function () {',
  21382. ' this.DoIt = function (e) {',
  21383. ' };',
  21384. '});',
  21385. 'this.a = 0;',
  21386. 'this.c = 2;',
  21387. 'this.r = 3;',
  21388. '']),
  21389. LinesToStr([ // $mod.$main
  21390. '$mod.THelper.DoIt.call({',
  21391. ' p: $mod,',
  21392. ' get: function () {',
  21393. ' return this.p.a;',
  21394. ' },',
  21395. ' set: function (v) {',
  21396. ' this.p.a = v;',
  21397. ' }',
  21398. '}, 123);',
  21399. 'var $with1 = $mod.a;',
  21400. '$mod.THelper.DoIt.call({',
  21401. ' get: function () {',
  21402. ' return $with1;',
  21403. ' },',
  21404. ' set: function (v) {',
  21405. ' $with1 = v;',
  21406. ' }',
  21407. '}, 123);',
  21408. '$mod.THelper.DoIt.call({',
  21409. ' p: $mod,',
  21410. ' get: function () {',
  21411. ' return this.p.c;',
  21412. ' },',
  21413. ' set: function (v) {',
  21414. ' this.p.c = v;',
  21415. ' }',
  21416. '}, 123);',
  21417. 'var $with2 = $mod.c;',
  21418. '$mod.THelper.DoIt.call({',
  21419. ' get: function () {',
  21420. ' return $with2;',
  21421. ' },',
  21422. ' set: function (v) {',
  21423. ' $with2 = v;',
  21424. ' }',
  21425. '}, 123);',
  21426. '$mod.THelper.DoIt.call({',
  21427. ' get: function () {',
  21428. ' return 3;',
  21429. ' },',
  21430. ' set: function (v) {',
  21431. ' rtl.raiseE("EPropReadOnly");',
  21432. ' }',
  21433. '}, 123);',
  21434. 'var $with3 = 3;',
  21435. ' $mod.THelper.DoIt.call({',
  21436. ' get: function () {',
  21437. ' return $with3;',
  21438. ' },',
  21439. ' set: function () {',
  21440. ' rtl.raiseE("EPropReadOnly");',
  21441. ' }',
  21442. ' }, 123);',
  21443. '']));
  21444. end;
  21445. procedure TTestModule.TestTypeHelper_PassFuncResult;
  21446. begin
  21447. StartProgram(false);
  21448. Add([
  21449. '{$modeswitch typehelpers}',
  21450. 'type',
  21451. ' THelper = type helper for word',
  21452. ' procedure DoIt(e: byte = 123);',
  21453. ' end;',
  21454. 'procedure THelper.DoIt(e: byte);',
  21455. 'begin',
  21456. 'end;',
  21457. 'function Foo(b: byte = 1): word;',
  21458. 'begin',
  21459. 'end;',
  21460. 'begin',
  21461. ' Foo.DoIt;',
  21462. ' Foo().DoIt;',
  21463. ' with Foo do DoIt;',
  21464. ' with Foo() do DoIt;',
  21465. '']);
  21466. ConvertProgram;
  21467. CheckSource('TestTypeHelper_PassFuncResult',
  21468. LinesToStr([ // statements
  21469. 'rtl.createHelper($mod, "THelper", null, function () {',
  21470. ' this.DoIt = function (e) {',
  21471. ' };',
  21472. '});',
  21473. 'this.Foo = function (b) {',
  21474. ' var Result = 0;',
  21475. ' return Result;',
  21476. '};',
  21477. '']),
  21478. LinesToStr([ // $mod.$main
  21479. '$mod.THelper.DoIt.call({',
  21480. ' a: $mod.Foo(1),',
  21481. ' get: function () {',
  21482. ' return this.a;',
  21483. ' },',
  21484. ' set: function (v) {',
  21485. ' this.a = v;',
  21486. ' }',
  21487. '}, 123);',
  21488. '$mod.THelper.DoIt.call({',
  21489. ' a: $mod.Foo(1),',
  21490. ' get: function () {',
  21491. ' return this.a;',
  21492. ' },',
  21493. ' set: function (v) {',
  21494. ' this.a = v;',
  21495. ' }',
  21496. '}, 123);',
  21497. 'var $with1 = $mod.Foo(1);',
  21498. '$mod.THelper.DoIt.call({',
  21499. ' get: function () {',
  21500. ' return $with1;',
  21501. ' },',
  21502. ' set: function (v) {',
  21503. ' $with1 = v;',
  21504. ' }',
  21505. '}, 123);',
  21506. 'var $with2 = $mod.Foo(1);',
  21507. '$mod.THelper.DoIt.call({',
  21508. ' get: function () {',
  21509. ' return $with2;',
  21510. ' },',
  21511. ' set: function (v) {',
  21512. ' $with2 = v;',
  21513. ' }',
  21514. '}, 123);',
  21515. '']));
  21516. end;
  21517. procedure TTestModule.TestTypeHelper_PassPropertyField;
  21518. begin
  21519. StartProgram(false);
  21520. Add([
  21521. '{$modeswitch typehelpers}',
  21522. 'type',
  21523. ' TObject = class',
  21524. ' FField: word;',
  21525. ' procedure SetField(Value: word);',
  21526. ' property Field: word read FField write SetField;',
  21527. ' end;',
  21528. ' THelper = type helper for word',
  21529. ' procedure Fly;',
  21530. ' class procedure Run; static;',
  21531. ' end;',
  21532. 'procedure TObject.SetField(Value: word);',
  21533. 'begin',
  21534. ' Field.Fly;',
  21535. ' Field.Run;',
  21536. ' Self.Field.Fly;',
  21537. ' Self.Field.Run;',
  21538. ' with Self do begin',
  21539. ' Field.Fly;',
  21540. ' Field.Run;',
  21541. ' end;',
  21542. ' with Self.Field do begin',
  21543. ' Fly;',
  21544. ' Run;',
  21545. ' end;',
  21546. 'end;',
  21547. 'procedure THelper.Fly;',
  21548. 'begin',
  21549. 'end;',
  21550. 'class procedure THelper.Run;',
  21551. 'begin',
  21552. 'end;',
  21553. 'var',
  21554. ' o: TObject;',
  21555. 'begin',
  21556. ' o.Field.Fly;',
  21557. ' o.Field.Run;',
  21558. ' with o do begin',
  21559. ' Field.Fly;',
  21560. ' Field.Run;',
  21561. ' end;',
  21562. ' with o.Field do begin',
  21563. ' Fly;',
  21564. ' Run;',
  21565. ' end;',
  21566. '']);
  21567. ConvertProgram;
  21568. CheckSource('TestTypeHelper_PassPropertyField',
  21569. LinesToStr([ // statements
  21570. 'rtl.createClass($mod, "TObject", null, function () {',
  21571. ' this.$init = function () {',
  21572. ' this.FField = 0;',
  21573. ' };',
  21574. ' this.$final = function () {',
  21575. ' };',
  21576. ' this.SetField = function (Value) {',
  21577. ' $mod.THelper.Fly.call({',
  21578. ' p: this,',
  21579. ' get: function () {',
  21580. ' return this.p.FField;',
  21581. ' },',
  21582. ' set: function (v) {',
  21583. ' this.p.FField = v;',
  21584. ' }',
  21585. ' });',
  21586. ' $mod.THelper.Run();',
  21587. ' $mod.THelper.Fly.call({',
  21588. ' p: this,',
  21589. ' get: function () {',
  21590. ' return this.p.FField;',
  21591. ' },',
  21592. ' set: function (v) {',
  21593. ' this.p.FField = v;',
  21594. ' }',
  21595. ' });',
  21596. ' $mod.THelper.Run();',
  21597. ' $mod.THelper.Fly.call({',
  21598. ' p: this,',
  21599. ' get: function () {',
  21600. ' return this.p.FField;',
  21601. ' },',
  21602. ' set: function (v) {',
  21603. ' this.p.FField = v;',
  21604. ' }',
  21605. ' });',
  21606. ' $mod.THelper.Run();',
  21607. ' var $with1 = this.FField;',
  21608. ' $mod.THelper.Fly.call({',
  21609. ' get: function () {',
  21610. ' return $with1;',
  21611. ' },',
  21612. ' set: function (v) {',
  21613. ' $with1 = v;',
  21614. ' }',
  21615. ' });',
  21616. ' $mod.THelper.Run();',
  21617. ' };',
  21618. '});',
  21619. 'rtl.createHelper($mod, "THelper", null, function () {',
  21620. ' this.Fly = function () {',
  21621. ' };',
  21622. ' this.Run = function () {',
  21623. ' };',
  21624. '});',
  21625. 'this.o = null;',
  21626. '']),
  21627. LinesToStr([ // $mod.$main
  21628. '$mod.THelper.Fly.call({',
  21629. ' p: $mod.o,',
  21630. ' get: function () {',
  21631. ' return this.p.FField;',
  21632. ' },',
  21633. ' set: function (v) {',
  21634. ' this.p.FField = v;',
  21635. ' }',
  21636. '});',
  21637. '$mod.THelper.Run();',
  21638. 'var $with1 = $mod.o;',
  21639. '$mod.THelper.Fly.call({',
  21640. ' p: $with1,',
  21641. ' get: function () {',
  21642. ' return this.p.FField;',
  21643. ' },',
  21644. ' set: function (v) {',
  21645. ' this.p.FField = v;',
  21646. ' }',
  21647. '});',
  21648. '$mod.THelper.Run();',
  21649. 'var $with2 = $mod.o.FField;',
  21650. '$mod.THelper.Fly.call({',
  21651. ' get: function () {',
  21652. ' return $with2;',
  21653. ' },',
  21654. ' set: function (v) {',
  21655. ' $with2 = v;',
  21656. ' }',
  21657. '});',
  21658. '$mod.THelper.Run();',
  21659. '']));
  21660. end;
  21661. procedure TTestModule.TestTypeHelper_PassPropertyGetter;
  21662. begin
  21663. StartProgram(false);
  21664. Add([
  21665. '{$modeswitch typehelpers}',
  21666. 'type',
  21667. ' TObject = class',
  21668. ' FField: word;',
  21669. ' function GetField: word;',
  21670. ' property Field: word read GetField write FField;',
  21671. ' end;',
  21672. ' THelper = type helper for word',
  21673. ' procedure Fly;',
  21674. ' class procedure Run; static;',
  21675. ' end;',
  21676. 'function TObject.GetField: word;',
  21677. 'begin',
  21678. ' Field.Fly;',
  21679. ' Field.Run;',
  21680. ' Self.Field.Fly;',
  21681. ' Self.Field.Run;',
  21682. ' with Self do begin',
  21683. ' Field.Fly;',
  21684. ' Field.Run;',
  21685. ' end;',
  21686. ' with Self.Field do begin',
  21687. ' Fly;',
  21688. ' Run;',
  21689. ' end;',
  21690. 'end;',
  21691. 'procedure THelper.Fly;',
  21692. 'begin',
  21693. 'end;',
  21694. 'class procedure THelper.Run;',
  21695. 'begin',
  21696. 'end;',
  21697. 'var',
  21698. ' o: TObject;',
  21699. 'begin',
  21700. ' o.Field.Fly;',
  21701. ' o.Field.Run;',
  21702. ' with o do begin',
  21703. ' Field.Fly;',
  21704. ' Field.Run;',
  21705. ' end;',
  21706. ' with o.Field do begin',
  21707. ' Fly;',
  21708. ' Run;',
  21709. ' end;',
  21710. '']);
  21711. ConvertProgram;
  21712. CheckSource('TestTypeHelper_PassPropertyGetter',
  21713. LinesToStr([ // statements
  21714. 'rtl.createClass($mod, "TObject", null, function () {',
  21715. ' this.$init = function () {',
  21716. ' this.FField = 0;',
  21717. ' };',
  21718. ' this.$final = function () {',
  21719. ' };',
  21720. ' this.GetField = function () {',
  21721. ' var Result = 0;',
  21722. ' $mod.THelper.Fly.call({',
  21723. ' p: this.GetField(),',
  21724. ' get: function () {',
  21725. ' return this.p;',
  21726. ' },',
  21727. ' set: function (v) {',
  21728. ' this.p = v;',
  21729. ' }',
  21730. ' });',
  21731. ' $mod.THelper.Run();',
  21732. ' $mod.THelper.Fly.call({',
  21733. ' p: this.GetField(),',
  21734. ' get: function () {',
  21735. ' return this.p;',
  21736. ' },',
  21737. ' set: function (v) {',
  21738. ' this.p = v;',
  21739. ' }',
  21740. ' });',
  21741. ' $mod.THelper.Run();',
  21742. ' $mod.THelper.Fly.call({',
  21743. ' p: this.GetField(),',
  21744. ' get: function () {',
  21745. ' return this.p;',
  21746. ' },',
  21747. ' set: function (v) {',
  21748. ' this.p = v;',
  21749. ' }',
  21750. ' });',
  21751. ' $mod.THelper.Run();',
  21752. ' var $with1 = this.GetField();',
  21753. ' $mod.THelper.Fly.call({',
  21754. ' get: function () {',
  21755. ' return $with1;',
  21756. ' },',
  21757. ' set: function (v) {',
  21758. ' $with1 = v;',
  21759. ' }',
  21760. ' });',
  21761. ' $mod.THelper.Run();',
  21762. ' return Result;',
  21763. ' };',
  21764. '});',
  21765. 'rtl.createHelper($mod, "THelper", null, function () {',
  21766. ' this.Fly = function () {',
  21767. ' };',
  21768. ' this.Run = function () {',
  21769. ' };',
  21770. '});',
  21771. 'this.o = null;',
  21772. '']),
  21773. LinesToStr([ // $mod.$main
  21774. '$mod.THelper.Fly.call({',
  21775. ' p: $mod.o.GetField(),',
  21776. ' get: function () {',
  21777. ' return this.p;',
  21778. ' },',
  21779. ' set: function (v) {',
  21780. ' this.p = v;',
  21781. ' }',
  21782. '});',
  21783. '$mod.THelper.Run();',
  21784. 'var $with1 = $mod.o;',
  21785. '$mod.THelper.Fly.call({',
  21786. ' p: $with1.GetField(),',
  21787. ' get: function () {',
  21788. ' return this.p;',
  21789. ' },',
  21790. ' set: function (v) {',
  21791. ' this.p = v;',
  21792. ' }',
  21793. '});',
  21794. '$mod.THelper.Run();',
  21795. 'var $with2 = $mod.o.GetField();',
  21796. '$mod.THelper.Fly.call({',
  21797. ' get: function () {',
  21798. ' return $with2;',
  21799. ' },',
  21800. ' set: function (v) {',
  21801. ' $with2 = v;',
  21802. ' }',
  21803. '});',
  21804. '$mod.THelper.Run();',
  21805. '']));
  21806. end;
  21807. procedure TTestModule.TestTypeHelper_PassClassPropertyField;
  21808. begin
  21809. StartProgram(false);
  21810. Add([
  21811. '{$modeswitch typehelpers}',
  21812. 'type',
  21813. ' TObject = class',
  21814. ' class var FField: word;',
  21815. ' class procedure SetField(Value: word);',
  21816. ' class property Field: word read FField write SetField;',
  21817. ' end;',
  21818. ' THelper = type helper for word',
  21819. ' procedure Fly(n: byte);',
  21820. ' end;',
  21821. 'class procedure TObject.SetField(Value: word);',
  21822. 'begin',
  21823. ' Field.Fly(1);',
  21824. ' Self.Field.Fly(2);',
  21825. ' with Self do Field.Fly(3);',
  21826. ' with Self.Field do Fly(4);',
  21827. ' TObject.Field.Fly(5);',
  21828. ' with TObject do Field.Fly(6);',
  21829. ' with TObject.Field do Fly(7);',
  21830. 'end;',
  21831. 'procedure THelper.Fly(n: byte);',
  21832. 'begin',
  21833. 'end;',
  21834. 'var',
  21835. ' o: TObject;',
  21836. 'begin',
  21837. ' o.Field.Fly(11);',
  21838. ' with o do Field.Fly(12);',
  21839. ' with o.Field do Fly(13);',
  21840. ' TObject.Field.Fly(14);',
  21841. ' with TObject do Field.Fly(15);',
  21842. ' with TObject.Field do Fly(16);',
  21843. '']);
  21844. ConvertProgram;
  21845. CheckSource('TestTypeHelper_PassClassPropertyField',
  21846. LinesToStr([ // statements
  21847. 'rtl.createClass($mod, "TObject", null, function () {',
  21848. ' this.FField = 0;',
  21849. ' this.$init = function () {',
  21850. ' };',
  21851. ' this.$final = function () {',
  21852. ' };',
  21853. ' this.SetField = function (Value) {',
  21854. ' $mod.THelper.Fly.call({',
  21855. ' p: this,',
  21856. ' get: function () {',
  21857. ' return this.p.FField;',
  21858. ' },',
  21859. ' set: function (v) {',
  21860. ' $mod.TObject.FField = v;',
  21861. ' }',
  21862. ' }, 1);',
  21863. ' $mod.THelper.Fly.call({',
  21864. ' p: this,',
  21865. ' get: function () {',
  21866. ' return this.p.FField;',
  21867. ' },',
  21868. ' set: function (v) {',
  21869. ' $mod.TObject.FField = v;',
  21870. ' }',
  21871. ' }, 2);',
  21872. ' $mod.THelper.Fly.call({',
  21873. ' p: this,',
  21874. ' get: function () {',
  21875. ' return this.p.FField;',
  21876. ' },',
  21877. ' set: function (v) {',
  21878. ' $mod.TObject.FField = v;',
  21879. ' }',
  21880. ' }, 3);',
  21881. ' var $with1 = this.FField;',
  21882. ' $mod.THelper.Fly.call({',
  21883. ' get: function () {',
  21884. ' return $with1;',
  21885. ' },',
  21886. ' set: function (v) {',
  21887. ' $with1 = v;',
  21888. ' }',
  21889. ' }, 4);',
  21890. ' $mod.THelper.Fly.call({',
  21891. ' p: $mod.TObject,',
  21892. ' get: function () {',
  21893. ' return this.p.FField;',
  21894. ' },',
  21895. ' set: function (v) {',
  21896. ' $mod.TObject.FField = v;',
  21897. ' }',
  21898. ' }, 5);',
  21899. ' var $with2 = $mod.TObject;',
  21900. ' $mod.THelper.Fly.call({',
  21901. ' p: $with2,',
  21902. ' get: function () {',
  21903. ' return this.p.FField;',
  21904. ' },',
  21905. ' set: function (v) {',
  21906. ' $mod.TObject.FField = v;',
  21907. ' }',
  21908. ' }, 6);',
  21909. ' var $with3 = $mod.TObject.FField;',
  21910. ' $mod.THelper.Fly.call({',
  21911. ' get: function () {',
  21912. ' return $with3;',
  21913. ' },',
  21914. ' set: function (v) {',
  21915. ' $with3 = v;',
  21916. ' }',
  21917. ' }, 7);',
  21918. ' };',
  21919. '});',
  21920. 'rtl.createHelper($mod, "THelper", null, function () {',
  21921. ' this.Fly = function (n) {',
  21922. ' };',
  21923. '});',
  21924. 'this.o = null;',
  21925. '']),
  21926. LinesToStr([ // $mod.$main
  21927. '$mod.THelper.Fly.call({',
  21928. ' p: $mod.o,',
  21929. ' get: function () {',
  21930. ' return this.p.FField;',
  21931. ' },',
  21932. ' set: function (v) {',
  21933. ' $mod.TObject.FField = v;',
  21934. ' }',
  21935. '}, 11);',
  21936. 'var $with1 = $mod.o;',
  21937. '$mod.THelper.Fly.call({',
  21938. ' p: $with1,',
  21939. ' get: function () {',
  21940. ' return this.p.FField;',
  21941. ' },',
  21942. ' set: function (v) {',
  21943. ' $mod.TObject.FField = v;',
  21944. ' }',
  21945. '}, 12);',
  21946. 'var $with2 = $mod.o.FField;',
  21947. '$mod.THelper.Fly.call({',
  21948. ' get: function () {',
  21949. ' return $with2;',
  21950. ' },',
  21951. ' set: function (v) {',
  21952. ' $with2 = v;',
  21953. ' }',
  21954. '}, 13);',
  21955. '$mod.THelper.Fly.call({',
  21956. ' p: $mod.TObject,',
  21957. ' get: function () {',
  21958. ' return this.p.FField;',
  21959. ' },',
  21960. ' set: function (v) {',
  21961. ' $mod.TObject.FField = v;',
  21962. ' }',
  21963. '}, 14);',
  21964. 'var $with3 = $mod.TObject;',
  21965. '$mod.THelper.Fly.call({',
  21966. ' p: $with3,',
  21967. ' get: function () {',
  21968. ' return this.p.FField;',
  21969. ' },',
  21970. ' set: function (v) {',
  21971. ' $mod.TObject.FField = v;',
  21972. ' }',
  21973. '}, 15);',
  21974. 'var $with4 = $mod.TObject.FField;',
  21975. '$mod.THelper.Fly.call({',
  21976. ' get: function () {',
  21977. ' return $with4;',
  21978. ' },',
  21979. ' set: function (v) {',
  21980. ' $with4 = v;',
  21981. ' }',
  21982. '}, 16);',
  21983. '']));
  21984. end;
  21985. procedure TTestModule.TestTypeHelper_PassClassPropertyGetterStatic;
  21986. begin
  21987. StartProgram(false);
  21988. Add([
  21989. '{$modeswitch typehelpers}',
  21990. 'type',
  21991. ' TObject = class',
  21992. ' class var FField: word;',
  21993. ' class function GetField: word; static;',
  21994. ' class property Field: word read GetField write FField;',
  21995. ' end;',
  21996. ' THelper = type helper for word',
  21997. ' procedure Fly(n: byte);',
  21998. ' end;',
  21999. 'class function TObject.GetField: word;',
  22000. 'begin',
  22001. ' Field.Fly(1);',
  22002. ' TObject.Field.Fly(5);',
  22003. ' with TObject do Field.Fly(6);',
  22004. ' with TObject.Field do Fly(7);',
  22005. 'end;',
  22006. 'procedure THelper.Fly(n: byte);',
  22007. 'begin',
  22008. 'end;',
  22009. 'var',
  22010. ' o: TObject;',
  22011. 'begin',
  22012. ' o.Field.Fly(11);',
  22013. ' with o do Field.Fly(12);',
  22014. ' with o.Field do Fly(13);',
  22015. '']);
  22016. ConvertProgram;
  22017. CheckSource('TestTypeHelper_PassClassPropertyGetterStatic',
  22018. LinesToStr([ // statements
  22019. 'rtl.createClass($mod, "TObject", null, function () {',
  22020. ' this.FField = 0;',
  22021. ' this.$init = function () {',
  22022. ' };',
  22023. ' this.$final = function () {',
  22024. ' };',
  22025. ' this.GetField = function () {',
  22026. ' var Result = 0;',
  22027. ' $mod.THelper.Fly.call({',
  22028. ' p: this.GetField(),',
  22029. ' get: function () {',
  22030. ' return this.p;',
  22031. ' },',
  22032. ' set: function (v) {',
  22033. ' this.p = v;',
  22034. ' }',
  22035. ' }, 1);',
  22036. ' $mod.THelper.Fly.call({',
  22037. ' p: $mod.TObject.GetField(),',
  22038. ' get: function () {',
  22039. ' return this.p;',
  22040. ' },',
  22041. ' set: function (v) {',
  22042. ' this.p = v;',
  22043. ' }',
  22044. ' }, 5);',
  22045. ' var $with1 = $mod.TObject;',
  22046. ' $mod.THelper.Fly.call({',
  22047. ' p: $with1.GetField(),',
  22048. ' get: function () {',
  22049. ' return this.p;',
  22050. ' },',
  22051. ' set: function (v) {',
  22052. ' this.p = v;',
  22053. ' }',
  22054. ' }, 6);',
  22055. ' var $with2 = $mod.TObject.GetField();',
  22056. ' $mod.THelper.Fly.call({',
  22057. ' get: function () {',
  22058. ' return $with2;',
  22059. ' },',
  22060. ' set: function (v) {',
  22061. ' $with2 = v;',
  22062. ' }',
  22063. ' }, 7);',
  22064. ' return Result;',
  22065. ' };',
  22066. '});',
  22067. 'rtl.createHelper($mod, "THelper", null, function () {',
  22068. ' this.Fly = function (n) {',
  22069. ' };',
  22070. '});',
  22071. 'this.o = null;',
  22072. '']),
  22073. LinesToStr([ // $mod.$main
  22074. '$mod.THelper.Fly.call({',
  22075. ' p: $mod.o.GetField(),',
  22076. ' get: function () {',
  22077. ' return this.p;',
  22078. ' },',
  22079. ' set: function (v) {',
  22080. ' this.p = v;',
  22081. ' }',
  22082. '}, 11);',
  22083. 'var $with1 = $mod.o;',
  22084. '$mod.THelper.Fly.call({',
  22085. ' p: $with1.GetField(),',
  22086. ' get: function () {',
  22087. ' return this.p;',
  22088. ' },',
  22089. ' set: function (v) {',
  22090. ' this.p = v;',
  22091. ' }',
  22092. '}, 12);',
  22093. 'var $with2 = $mod.o.GetField();',
  22094. '$mod.THelper.Fly.call({',
  22095. ' get: function () {',
  22096. ' return $with2;',
  22097. ' },',
  22098. ' set: function (v) {',
  22099. ' $with2 = v;',
  22100. ' }',
  22101. '}, 13);',
  22102. '']));
  22103. end;
  22104. procedure TTestModule.TestTypeHelper_PassClassPropertyGetterNonStatic;
  22105. begin
  22106. StartProgram(false);
  22107. Add([
  22108. '{$modeswitch typehelpers}',
  22109. 'type',
  22110. ' TObject = class',
  22111. ' class var FField: word;',
  22112. ' class function GetField: word;',
  22113. ' class property Field: word read GetField write FField;',
  22114. ' end;',
  22115. ' TClass = class of TObject;',
  22116. ' THelper = type helper for word',
  22117. ' procedure Fly(n: byte);',
  22118. ' end;',
  22119. 'class function TObject.GetField: word;',
  22120. 'begin',
  22121. ' Field.Fly(1);',
  22122. ' Self.Field.Fly(5);',
  22123. ' with Self do Field.Fly(6);',
  22124. ' with Self.Field do Fly(7);',
  22125. 'end;',
  22126. 'procedure THelper.Fly(n: byte);',
  22127. 'begin',
  22128. 'end;',
  22129. 'var',
  22130. ' o: TObject;',
  22131. ' c: TClass;',
  22132. 'begin',
  22133. ' o.Field.Fly(11);',
  22134. ' with o do Field.Fly(12);',
  22135. ' with o.Field do Fly(13);',
  22136. ' c.Field.Fly(14);',
  22137. ' with c do Field.Fly(15);',
  22138. ' with c.Field do Fly(16);',
  22139. '']);
  22140. ConvertProgram;
  22141. CheckSource('TestTypeHelper_PassClassPropertyGetterNonStatic',
  22142. LinesToStr([ // statements
  22143. 'rtl.createClass($mod, "TObject", null, function () {',
  22144. ' this.FField = 0;',
  22145. ' this.$init = function () {',
  22146. ' };',
  22147. ' this.$final = function () {',
  22148. ' };',
  22149. ' this.GetField = function () {',
  22150. ' var Result = 0;',
  22151. ' $mod.THelper.Fly.call({',
  22152. ' p: this.GetField(),',
  22153. ' get: function () {',
  22154. ' return this.p;',
  22155. ' },',
  22156. ' set: function (v) {',
  22157. ' this.p = v;',
  22158. ' }',
  22159. ' }, 1);',
  22160. ' $mod.THelper.Fly.call({',
  22161. ' p: this.GetField(),',
  22162. ' get: function () {',
  22163. ' return this.p;',
  22164. ' },',
  22165. ' set: function (v) {',
  22166. ' this.p = v;',
  22167. ' }',
  22168. ' }, 5);',
  22169. ' $mod.THelper.Fly.call({',
  22170. ' p: this.GetField(),',
  22171. ' get: function () {',
  22172. ' return this.p;',
  22173. ' },',
  22174. ' set: function (v) {',
  22175. ' this.p = v;',
  22176. ' }',
  22177. ' }, 6);',
  22178. ' var $with1 = this.GetField();',
  22179. ' $mod.THelper.Fly.call({',
  22180. ' get: function () {',
  22181. ' return $with1;',
  22182. ' },',
  22183. ' set: function (v) {',
  22184. ' $with1 = v;',
  22185. ' }',
  22186. ' }, 7);',
  22187. ' return Result;',
  22188. ' };',
  22189. '});',
  22190. 'rtl.createHelper($mod, "THelper", null, function () {',
  22191. ' this.Fly = function (n) {',
  22192. ' };',
  22193. '});',
  22194. 'this.o = null;',
  22195. 'this.c = null;',
  22196. '']),
  22197. LinesToStr([ // $mod.$main
  22198. '$mod.THelper.Fly.call({',
  22199. ' p: $mod.o.$class.GetField(),',
  22200. ' get: function () {',
  22201. ' return this.p;',
  22202. ' },',
  22203. ' set: function (v) {',
  22204. ' this.p = v;',
  22205. ' }',
  22206. '}, 11);',
  22207. 'var $with1 = $mod.o;',
  22208. '$mod.THelper.Fly.call({',
  22209. ' p: $with1.$class.GetField(),',
  22210. ' get: function () {',
  22211. ' return this.p;',
  22212. ' },',
  22213. ' set: function (v) {',
  22214. ' this.p = v;',
  22215. ' }',
  22216. '}, 12);',
  22217. 'var $with2 = $mod.o.$class.GetField();',
  22218. '$mod.THelper.Fly.call({',
  22219. ' get: function () {',
  22220. ' return $with2;',
  22221. ' },',
  22222. ' set: function (v) {',
  22223. ' $with2 = v;',
  22224. ' }',
  22225. '}, 13);',
  22226. '$mod.THelper.Fly.call({',
  22227. ' p: $mod.c.GetField(),',
  22228. ' get: function () {',
  22229. ' return this.p;',
  22230. ' },',
  22231. ' set: function (v) {',
  22232. ' this.p = v;',
  22233. ' }',
  22234. '}, 14);',
  22235. 'var $with3 = $mod.c;',
  22236. '$mod.THelper.Fly.call({',
  22237. ' p: $with3.GetField(),',
  22238. ' get: function () {',
  22239. ' return this.p;',
  22240. ' },',
  22241. ' set: function (v) {',
  22242. ' this.p = v;',
  22243. ' }',
  22244. '}, 15);',
  22245. 'var $with4 = $mod.c.GetField();',
  22246. '$mod.THelper.Fly.call({',
  22247. ' get: function () {',
  22248. ' return $with4;',
  22249. ' },',
  22250. ' set: function (v) {',
  22251. ' $with4 = v;',
  22252. ' }',
  22253. '}, 16);',
  22254. '']));
  22255. end;
  22256. procedure TTestModule.TestTypeHelper_Property;
  22257. begin
  22258. StartProgram(false);
  22259. Add([
  22260. '{$modeswitch typehelpers}',
  22261. 'type',
  22262. ' THelper = type helper for word',
  22263. ' function GetSize: longint;',
  22264. ' procedure SetSize(Value: longint);',
  22265. ' property Size: longint read GetSize write SetSize;',
  22266. ' end;',
  22267. 'function THelper.GetSize: longint;',
  22268. 'begin',
  22269. ' Result:=Size+1;',
  22270. ' Size:=2;',
  22271. ' Result:=Self.Size+3;',
  22272. ' Self.Size:=4;',
  22273. ' with Self do begin',
  22274. ' Result:=Size+5;',
  22275. ' Size:=6;',
  22276. ' end;',
  22277. 'end;',
  22278. 'procedure THelper.SetSize(Value: longint);',
  22279. 'begin',
  22280. 'end;',
  22281. 'var w: word;',
  22282. 'begin',
  22283. ' w:=w.Size+7;',
  22284. ' w.Size:=w+8;',
  22285. ' with w do begin',
  22286. ' w:=Size+9;',
  22287. ' Size:=w+10;',
  22288. ' end;',
  22289. '']);
  22290. ConvertProgram;
  22291. CheckSource('TestTypeHelper_Property',
  22292. LinesToStr([ // statements
  22293. 'rtl.createHelper($mod, "THelper", null, function () {',
  22294. ' this.GetSize = function () {',
  22295. ' var Result = 0;',
  22296. ' Result = $mod.THelper.GetSize.call(this) + 1;',
  22297. ' $mod.THelper.SetSize.call(this, 2);',
  22298. ' Result = $mod.THelper.GetSize.call(this) + 3;',
  22299. ' $mod.THelper.SetSize.call(this, 4);',
  22300. ' var $with1 = this.get();',
  22301. ' Result = $mod.THelper.GetSize.call(this) + 5;',
  22302. ' $mod.THelper.SetSize.call(this, 6);',
  22303. ' return Result;',
  22304. ' };',
  22305. ' this.SetSize = function (Value) {',
  22306. ' };',
  22307. '});',
  22308. 'this.w = 0;',
  22309. '']),
  22310. LinesToStr([ // $mod.$main
  22311. '$mod.w = $mod.THelper.GetSize.call({',
  22312. ' p: $mod,',
  22313. ' get: function () {',
  22314. ' return this.p.w;',
  22315. ' },',
  22316. ' set: function (v) {',
  22317. ' this.p.w = v;',
  22318. ' }',
  22319. '}) + 7;',
  22320. '$mod.THelper.SetSize.call({',
  22321. ' p: $mod,',
  22322. ' get: function () {',
  22323. ' return this.p.w;',
  22324. ' },',
  22325. ' set: function (v) {',
  22326. ' this.p.w = v;',
  22327. ' }',
  22328. '}, $mod.w + 8);',
  22329. 'var $with1 = $mod.w;',
  22330. '$mod.w = $mod.THelper.GetSize.call({',
  22331. ' get: function () {',
  22332. ' return $with1;',
  22333. ' },',
  22334. ' set: function (v) {',
  22335. ' $with1 = v;',
  22336. ' }',
  22337. '}) + 9;',
  22338. '$mod.THelper.SetSize.call({',
  22339. ' get: function () {',
  22340. ' return $with1;',
  22341. ' },',
  22342. ' set: function (v) {',
  22343. ' $with1 = v;',
  22344. ' }',
  22345. '}, $mod.w + 10);',
  22346. '']));
  22347. end;
  22348. procedure TTestModule.TestTypeHelper_Property_Array;
  22349. begin
  22350. StartProgram(false);
  22351. Add([
  22352. '{$modeswitch typehelpers}',
  22353. 'type',
  22354. ' THelper = type helper for word',
  22355. ' function GetItems(Index: byte): boolean;',
  22356. ' procedure SetItems(Index: byte; Value: boolean);',
  22357. ' property Items[Index: byte]: boolean read GetItems write SetItems;',
  22358. ' end;',
  22359. 'function THelper.GetItems(Index: byte): boolean;',
  22360. 'begin',
  22361. ' Result:=Items[1];',
  22362. ' Items[2]:=false;',
  22363. ' Result:=Self.Items[3];',
  22364. ' Self.Items[4]:=true;',
  22365. ' with Self do begin',
  22366. ' Result:=Items[5];',
  22367. ' Items[6]:=false;',
  22368. ' end;',
  22369. 'end;',
  22370. 'procedure THelper.SetItems(Index: byte; Value: boolean);',
  22371. 'begin',
  22372. 'end;',
  22373. 'var',
  22374. ' w: word;',
  22375. ' b: boolean;',
  22376. 'begin',
  22377. ' b:=w.Items[1];',
  22378. ' w.Items[2]:=b;',
  22379. ' with w do begin',
  22380. ' b:=Items[3];',
  22381. ' Items[4]:=b;',
  22382. ' end;',
  22383. '']);
  22384. ConvertProgram;
  22385. CheckSource('TestTypeHelper_Property_Array',
  22386. LinesToStr([ // statements
  22387. 'rtl.createHelper($mod, "THelper", null, function () {',
  22388. ' this.GetItems = function (Index) {',
  22389. ' var Result = false;',
  22390. ' Result = $mod.THelper.GetItems.call(this, 1);',
  22391. ' $mod.THelper.SetItems.call(this, 2, false);',
  22392. ' Result = $mod.THelper.GetItems.call(this, 3);',
  22393. ' $mod.THelper.SetItems.call(this, 4, true);',
  22394. ' var $with1 = this.get();',
  22395. ' Result = $mod.THelper.GetItems.call(this, 5);',
  22396. ' $mod.THelper.SetItems.call(this, 6, false);',
  22397. ' return Result;',
  22398. ' };',
  22399. ' this.SetItems = function (Index, Value) {',
  22400. ' };',
  22401. '});',
  22402. 'this.w = 0;',
  22403. 'this.b = false;',
  22404. '']),
  22405. LinesToStr([ // $mod.$main
  22406. '$mod.b = $mod.THelper.GetItems.call({',
  22407. ' p: $mod,',
  22408. ' get: function () {',
  22409. ' return this.p.w;',
  22410. ' },',
  22411. ' set: function (v) {',
  22412. ' this.p.w = v;',
  22413. ' }',
  22414. '}, 1);',
  22415. '$mod.THelper.SetItems.call({',
  22416. ' p: $mod,',
  22417. ' get: function () {',
  22418. ' return this.p.w;',
  22419. ' },',
  22420. ' set: function (v) {',
  22421. ' this.p.w = v;',
  22422. ' }',
  22423. '}, 2, $mod.b);',
  22424. 'var $with1 = $mod.w;',
  22425. '$mod.b = $mod.THelper.GetItems.call({',
  22426. ' get: function () {',
  22427. ' return $with1;',
  22428. ' },',
  22429. ' set: function (v) {',
  22430. ' $with1 = v;',
  22431. ' }',
  22432. '}, 3);',
  22433. '$mod.THelper.SetItems.call({',
  22434. ' get: function () {',
  22435. ' return $with1;',
  22436. ' },',
  22437. ' set: function (v) {',
  22438. ' $with1 = v;',
  22439. ' }',
  22440. '}, 4, $mod.b);',
  22441. '']));
  22442. end;
  22443. procedure TTestModule.TestTypeHelper_ClassProperty;
  22444. begin
  22445. StartProgram(false);
  22446. Add([
  22447. '{$modeswitch typehelpers}',
  22448. 'type',
  22449. ' THelper = type helper for word',
  22450. ' class function GetSize: longint; static;',
  22451. ' class procedure SetSize(Value: longint); static;',
  22452. ' class property Size: longint read GetSize write SetSize;',
  22453. ' end;',
  22454. 'class function THelper.GetSize: longint;',
  22455. 'begin',
  22456. ' Result:=Size+1;',
  22457. ' Size:=2;',
  22458. 'end;',
  22459. 'class procedure THelper.SetSize(Value: longint);',
  22460. 'begin',
  22461. 'end;',
  22462. 'begin',
  22463. '']);
  22464. ConvertProgram;
  22465. CheckSource('TestTypeHelper_ClassProperty',
  22466. LinesToStr([ // statements
  22467. 'rtl.createHelper($mod, "THelper", null, function () {',
  22468. ' this.GetSize = function () {',
  22469. ' var Result = 0;',
  22470. ' Result = $mod.THelper.GetSize() + 1;',
  22471. ' $mod.THelper.SetSize(2);',
  22472. ' return Result;',
  22473. ' };',
  22474. ' this.SetSize = function (Value) {',
  22475. ' };',
  22476. '});',
  22477. '']),
  22478. LinesToStr([ // $mod.$main
  22479. '']));
  22480. end;
  22481. procedure TTestModule.TestTypeHelper_ClassProperty_Array;
  22482. begin
  22483. StartProgram(false);
  22484. Add([
  22485. '{$modeswitch typehelpers}',
  22486. 'type',
  22487. ' THelper = type helper for word',
  22488. ' class function GetItems(Index: byte): boolean; static;',
  22489. ' class procedure SetItems(Index: byte; Value: boolean); static;',
  22490. ' class property Items[Index: byte]: boolean read GetItems write SetItems;',
  22491. ' end;',
  22492. 'class function THelper.GetItems(Index: byte): boolean;',
  22493. 'begin',
  22494. ' Result:=Items[1];',
  22495. ' Items[2]:=false;',
  22496. 'end;',
  22497. 'class procedure THelper.SetItems(Index: byte; Value: boolean);',
  22498. 'begin',
  22499. 'end;',
  22500. 'var',
  22501. ' w: word;',
  22502. ' b: boolean;',
  22503. 'begin',
  22504. ' b:=w.Items[1];',
  22505. ' w.Items[2]:=b;',
  22506. ' with w do begin',
  22507. ' b:=Items[3];',
  22508. ' Items[4]:=b;',
  22509. ' end;',
  22510. '']);
  22511. ConvertProgram;
  22512. CheckSource('TestTypeHelper_ClassProperty_Array',
  22513. LinesToStr([ // statements
  22514. 'rtl.createHelper($mod, "THelper", null, function () {',
  22515. ' this.GetItems = function (Index) {',
  22516. ' var Result = false;',
  22517. ' Result = $mod.THelper.GetItems(1);',
  22518. ' $mod.THelper.SetItems(2, false);',
  22519. ' return Result;',
  22520. ' };',
  22521. ' this.SetItems = function (Index, Value) {',
  22522. ' };',
  22523. '});',
  22524. 'this.w = 0;',
  22525. 'this.b = false;',
  22526. '']),
  22527. LinesToStr([ // $mod.$main
  22528. '$mod.b = $mod.THelper.GetItems(1);',
  22529. '$mod.THelper.SetItems(2, $mod.b);',
  22530. 'var $with1 = $mod.w;',
  22531. '$mod.b = $mod.THelper.GetItems(3);',
  22532. '$mod.THelper.SetItems(4, $mod.b);',
  22533. '']));
  22534. end;
  22535. procedure TTestModule.TestTypeHelper_ClassMethod;
  22536. begin
  22537. StartProgram(false);
  22538. Add([
  22539. '{$modeswitch typehelpers}',
  22540. 'type',
  22541. ' THelper = type helper for word',
  22542. ' class procedure DoStatic; static;',
  22543. ' end;',
  22544. 'class procedure THelper.DoStatic;',
  22545. 'begin',
  22546. ' DoStatic;',
  22547. ' DoStatic();',
  22548. 'end;',
  22549. 'var w: word;',
  22550. 'begin',
  22551. ' w.DoStatic;',
  22552. ' w.DoStatic();',
  22553. '']);
  22554. ConvertProgram;
  22555. CheckSource('TestTypeHelper_ClassMethod',
  22556. LinesToStr([ // statements
  22557. 'rtl.createHelper($mod, "THelper", null, function () {',
  22558. ' this.DoStatic = function () {',
  22559. ' $mod.THelper.DoStatic();',
  22560. ' $mod.THelper.DoStatic();',
  22561. ' };',
  22562. '});',
  22563. 'this.w = 0;',
  22564. '']),
  22565. LinesToStr([ // $mod.$main
  22566. '$mod.THelper.DoStatic();',
  22567. '$mod.THelper.DoStatic();',
  22568. '']));
  22569. end;
  22570. procedure TTestModule.TestTypeHelper_ExtClassMethodFail;
  22571. begin
  22572. StartProgram(false);
  22573. Add([
  22574. '{$modeswitch typehelpers}',
  22575. 'type',
  22576. ' THelper = type helper for word',
  22577. ' procedure Run; external name ''Run'';',
  22578. ' end;',
  22579. 'var w: word;',
  22580. 'begin',
  22581. ' w.Run;',
  22582. '']);
  22583. SetExpectedPasResolverError('Not supported: external method in type helper',nNotSupportedX);
  22584. ConvertProgram;
  22585. end;
  22586. procedure TTestModule.TestTypeHelper_Constructor;
  22587. begin
  22588. StartProgram(false);
  22589. Add([
  22590. '{$modeswitch typehelpers}',
  22591. 'type',
  22592. ' THelper = type helper for word',
  22593. ' constructor Init(e: longint);',
  22594. ' end;',
  22595. 'constructor THelper.Init(e: longint);',
  22596. 'begin',
  22597. ' Self:=e;',
  22598. ' Init(e+1);',
  22599. 'end;',
  22600. 'var w: word;',
  22601. 'begin',
  22602. ' w:=word.Init(2);',
  22603. ' w:=w.Init(3);',
  22604. ' with word do w:=Init(4);',
  22605. ' with w do w:=Init(5);',
  22606. '']);
  22607. ConvertProgram;
  22608. CheckSource('TestTypeHelper_Constructor',
  22609. LinesToStr([ // statements
  22610. 'rtl.createHelper($mod, "THelper", null, function () {',
  22611. ' this.Init = function (e) {',
  22612. ' this.set(e);',
  22613. ' $mod.THelper.Init.call(this, e + 1);',
  22614. ' return this.get();',
  22615. ' };',
  22616. ' this.$new = function (fn, args) {',
  22617. ' return this[fn].apply({',
  22618. ' p: 0,',
  22619. ' get: function () {',
  22620. ' return this.p;',
  22621. ' },',
  22622. ' set: function (v) {',
  22623. ' this.p = v;',
  22624. ' }',
  22625. ' }, args);',
  22626. ' };',
  22627. '});',
  22628. 'this.w = 0;',
  22629. '']),
  22630. LinesToStr([ // $mod.$main
  22631. '$mod.w = $mod.THelper.$new("Init", [2]);',
  22632. '$mod.w = $mod.THelper.Init.call({',
  22633. ' p: $mod,',
  22634. ' get: function () {',
  22635. ' return this.p.w;',
  22636. ' },',
  22637. ' set: function (v) {',
  22638. ' this.p.w = v;',
  22639. ' }',
  22640. '}, 3);',
  22641. '$mod.w = $mod.THelper.$new("Init", [4]);',
  22642. 'var $with1 = $mod.w;',
  22643. '$mod.w = $mod.THelper.Init.call({',
  22644. ' get: function () {',
  22645. ' return $with1;',
  22646. ' },',
  22647. ' set: function (v) {',
  22648. ' $with1 = v;',
  22649. ' }',
  22650. '}, 5);',
  22651. '']));
  22652. end;
  22653. procedure TTestModule.TestTypeHelper_Word;
  22654. begin
  22655. StartProgram(false);
  22656. Add([
  22657. '{$modeswitch typehelpers}',
  22658. 'type',
  22659. ' THelper = type helper for word',
  22660. ' procedure DoIt(e: byte = 123);',
  22661. ' end;',
  22662. 'procedure THelper.DoIt(e: byte);',
  22663. 'begin',
  22664. ' Self:=e;',
  22665. ' Self:=Self+1;',
  22666. ' with Self do Doit;',
  22667. 'end;',
  22668. 'begin',
  22669. ' word(3).DoIt;',
  22670. '']);
  22671. ConvertProgram;
  22672. CheckSource('TestTypeHelper_Word',
  22673. LinesToStr([ // statements
  22674. 'rtl.createHelper($mod, "THelper", null, function () {',
  22675. ' this.DoIt = function (e) {',
  22676. ' this.set(e);',
  22677. ' this.set(this.get() + 1);',
  22678. ' var $with1 = this.get();',
  22679. ' $mod.THelper.DoIt.call(this, 123);',
  22680. ' };',
  22681. '});',
  22682. '']),
  22683. LinesToStr([ // $mod.$main
  22684. '$mod.THelper.DoIt.call({',
  22685. ' get: function () {',
  22686. ' return 3;',
  22687. ' },',
  22688. ' set: function (v) {',
  22689. ' rtl.raiseE("EPropReadOnly");',
  22690. ' }',
  22691. '}, 123);',
  22692. '']));
  22693. end;
  22694. procedure TTestModule.TestTypeHelper_Double;
  22695. begin
  22696. StartProgram(false);
  22697. Add([
  22698. '{$modeswitch typehelpers}',
  22699. 'type',
  22700. ' Float = type double;',
  22701. ' THelper = type helper for double',
  22702. ' const NPI = 3.141592;',
  22703. ' function ToStr: String;',
  22704. ' end;',
  22705. 'function THelper.ToStr: String;',
  22706. 'begin',
  22707. 'end;',
  22708. 'procedure DoIt(s: string);',
  22709. 'begin',
  22710. 'end;',
  22711. 'var f: Float;',
  22712. 'begin',
  22713. ' DoIt(f.toStr);',
  22714. ' DoIt(f.toStr());',
  22715. ' (f*f).toStr;',
  22716. ' DoIt((f*f).toStr);',
  22717. '']);
  22718. ConvertProgram;
  22719. CheckSource('TestTypeHelper_Double',
  22720. LinesToStr([ // statements
  22721. 'rtl.createHelper($mod, "THelper", null, function () {',
  22722. ' this.NPI = 3.141592;',
  22723. ' this.ToStr = function () {',
  22724. ' var Result = "";',
  22725. ' return Result;',
  22726. ' };',
  22727. '});',
  22728. 'this.DoIt = function (s) {',
  22729. '};',
  22730. 'this.f = 0.0;',
  22731. '']),
  22732. LinesToStr([ // $mod.$main
  22733. '$mod.DoIt($mod.THelper.ToStr.call({',
  22734. ' p: $mod,',
  22735. ' get: function () {',
  22736. ' return this.p.f;',
  22737. ' },',
  22738. ' set: function (v) {',
  22739. ' this.p.f = v;',
  22740. ' }',
  22741. '}));',
  22742. '$mod.DoIt($mod.THelper.ToStr.call({',
  22743. ' p: $mod,',
  22744. ' get: function () {',
  22745. ' return this.p.f;',
  22746. ' },',
  22747. ' set: function (v) {',
  22748. ' this.p.f = v;',
  22749. ' }',
  22750. '}));',
  22751. '$mod.THelper.ToStr.call({',
  22752. ' a: $mod.f * $mod.f,',
  22753. ' get: function () {',
  22754. ' return this.a;',
  22755. ' },',
  22756. ' set: function (v) {',
  22757. ' rtl.raiseE("EPropReadOnly");',
  22758. ' }',
  22759. '});',
  22760. '$mod.DoIt($mod.THelper.ToStr.call({',
  22761. ' a: $mod.f * $mod.f,',
  22762. ' get: function () {',
  22763. ' return this.a;',
  22764. ' },',
  22765. ' set: function (v) {',
  22766. ' rtl.raiseE("EPropReadOnly");',
  22767. ' }',
  22768. '}));',
  22769. '']));
  22770. end;
  22771. procedure TTestModule.TestTypeHelper_StringChar;
  22772. begin
  22773. StartProgram(false);
  22774. Add([
  22775. '{$modeswitch typehelpers}',
  22776. 'type',
  22777. ' TStringHelper = type helper for string',
  22778. ' procedure DoIt(e: byte = 123);',
  22779. ' end;',
  22780. ' TCharHelper = type helper for char',
  22781. ' procedure Fly;',
  22782. ' end;',
  22783. 'procedure TStringHelper.DoIt(e: byte);',
  22784. 'begin',
  22785. ' Self[1]:=''c'';',
  22786. ' Self[2]:=Self[3];',
  22787. 'end;',
  22788. 'procedure TCharHelper.Fly;',
  22789. 'begin',
  22790. ' Self:=''c'';',
  22791. 'end;',
  22792. 'begin',
  22793. ' ''abc''.DoIt;',
  22794. ' ''xyz''.DoIt();',
  22795. ' ''c''.Fly();',
  22796. '']);
  22797. ConvertProgram;
  22798. CheckSource('TestTypeHelper_StringChar',
  22799. LinesToStr([ // statements
  22800. 'rtl.createHelper($mod, "TStringHelper", null, function () {',
  22801. ' this.DoIt = function (e) {',
  22802. ' this.set(rtl.setCharAt(this.get(), 0, "c"));',
  22803. ' this.set(rtl.setCharAt(this.get(), 1, this.get().charAt(2)));',
  22804. ' };',
  22805. '});',
  22806. 'rtl.createHelper($mod, "TCharHelper", null, function () {',
  22807. ' this.Fly = function () {',
  22808. ' this.set("c");',
  22809. ' };',
  22810. '});',
  22811. '']),
  22812. LinesToStr([ // $mod.$main
  22813. '$mod.TStringHelper.DoIt.call({',
  22814. ' get: function () {',
  22815. ' return "abc";',
  22816. ' },',
  22817. ' set: function (v) {',
  22818. ' rtl.raiseE("EPropReadOnly");',
  22819. ' }',
  22820. '}, 123);',
  22821. '$mod.TStringHelper.DoIt.call({',
  22822. ' get: function () {',
  22823. ' return "xyz";',
  22824. ' },',
  22825. ' set: function (v) {',
  22826. ' rtl.raiseE("EPropReadOnly");',
  22827. ' }',
  22828. '}, 123);',
  22829. '$mod.TCharHelper.Fly.call({',
  22830. ' get: function () {',
  22831. ' return "c";',
  22832. ' },',
  22833. ' set: function (v) {',
  22834. ' rtl.raiseE("EPropReadOnly");',
  22835. ' }',
  22836. '});',
  22837. '']));
  22838. end;
  22839. procedure TTestModule.TestTypeHelper_Array;
  22840. begin
  22841. StartProgram(false);
  22842. Add([
  22843. '{$modeswitch typehelpers}',
  22844. 'type',
  22845. ' TArrOfBool = array of boolean;',
  22846. ' TArrOfJS = array of jsvalue;',
  22847. ' THelper = type helper for TArrOfBool',
  22848. ' procedure DoIt(e: byte = 123);',
  22849. ' end;',
  22850. 'procedure THelper.DoIt(e: byte);',
  22851. 'begin',
  22852. ' Self[1]:=true;',
  22853. ' Self[2]:=not Self[3];',
  22854. ' SetLength(Self,4);',
  22855. 'end;',
  22856. 'var',
  22857. ' b: TArrOfBool;',
  22858. ' j: TArrOfJS;',
  22859. 'begin',
  22860. ' b.DoIt;',
  22861. ' TArrOfBool(j).DoIt();',
  22862. '']);
  22863. ConvertProgram;
  22864. CheckSource('TestTypeHelper_Array',
  22865. LinesToStr([ // statements
  22866. 'rtl.createHelper($mod, "THelper", null, function () {',
  22867. ' this.DoIt = function (e) {',
  22868. ' this.get()[1] = true;',
  22869. ' this.get()[2] = !this.get()[3];',
  22870. ' this.set(rtl.arraySetLength(this.get(), false, 4));',
  22871. ' };',
  22872. '});',
  22873. 'this.b = [];',
  22874. 'this.j = [];',
  22875. '']),
  22876. LinesToStr([ // $mod.$main
  22877. '$mod.THelper.DoIt.call({',
  22878. ' p: $mod,',
  22879. ' get: function () {',
  22880. ' return this.p.b;',
  22881. ' },',
  22882. ' set: function (v) {',
  22883. ' this.p.b = v;',
  22884. ' }',
  22885. '}, 123);',
  22886. '$mod.THelper.DoIt.call({',
  22887. ' p: $mod,',
  22888. ' get: function () {',
  22889. ' return this.p.j;',
  22890. ' },',
  22891. ' set: function (v) {',
  22892. ' this.p.j = v;',
  22893. ' }',
  22894. '}, 123);',
  22895. '']));
  22896. end;
  22897. procedure TTestModule.TestTypeHelper_EnumType;
  22898. begin
  22899. StartProgram(false);
  22900. Add([
  22901. '{$modeswitch typehelpers}',
  22902. 'type',
  22903. ' TEnum = (red,blue);',
  22904. ' THelper = type helper for TEnum',
  22905. ' procedure DoIt(e: byte = 123);',
  22906. ' class procedure Swing(w: word); static;',
  22907. ' end;',
  22908. 'procedure THelper.DoIt(e: byte);',
  22909. 'begin',
  22910. ' Self:=red;',
  22911. ' Self:=succ(Self);',
  22912. ' with Self do Doit;',
  22913. 'end;',
  22914. 'class procedure THelper.Swing(w: word);',
  22915. 'begin',
  22916. 'end;',
  22917. 'var e: TEnum;',
  22918. 'begin',
  22919. ' e.DoIt;',
  22920. ' red.DoIt;',
  22921. ' TEnum.blue.DoIt;',
  22922. ' TEnum(1).DoIt;',
  22923. ' TEnum.Swing(3);',
  22924. '']);
  22925. ConvertProgram;
  22926. CheckSource('TestTypeHelper_EnumType',
  22927. LinesToStr([ // statements
  22928. 'this.TEnum = {',
  22929. ' "0": "red",',
  22930. ' red: 0,',
  22931. ' "1": "blue",',
  22932. ' blue: 1',
  22933. '};',
  22934. 'rtl.createHelper($mod, "THelper", null, function () {',
  22935. ' this.DoIt = function (e) {',
  22936. ' this.set($mod.TEnum.red);',
  22937. ' this.set(this.get() + 1);',
  22938. ' var $with1 = this.get();',
  22939. ' $mod.THelper.DoIt.call(this, 123);',
  22940. ' };',
  22941. ' this.Swing = function (w) {',
  22942. ' };',
  22943. '});',
  22944. 'this.e = 0;',
  22945. '']),
  22946. LinesToStr([ // $mod.$main
  22947. '$mod.THelper.DoIt.call({',
  22948. ' p: $mod,',
  22949. ' get: function () {',
  22950. ' return this.p.e;',
  22951. ' },',
  22952. ' set: function (v) {',
  22953. ' this.p.e = v;',
  22954. ' }',
  22955. '}, 123);',
  22956. '$mod.THelper.DoIt.call({',
  22957. ' p: $mod.TEnum,',
  22958. ' get: function () {',
  22959. ' return this.p.red;',
  22960. ' },',
  22961. ' set: function (v) {',
  22962. ' rtl.raiseE("EPropReadOnly");',
  22963. ' }',
  22964. '}, 123);',
  22965. '$mod.THelper.DoIt.call({',
  22966. ' p: $mod.TEnum,',
  22967. ' get: function () {',
  22968. ' return this.p.blue;',
  22969. ' },',
  22970. ' set: function (v) {',
  22971. ' rtl.raiseE("EPropReadOnly");',
  22972. ' }',
  22973. '}, 123);',
  22974. '$mod.THelper.DoIt.call({',
  22975. ' get: function () {',
  22976. ' return 1;',
  22977. ' },',
  22978. ' set: function (v) {',
  22979. ' rtl.raiseE("EPropReadOnly");',
  22980. ' }',
  22981. '}, 123);',
  22982. '$mod.THelper.Swing(3);',
  22983. '']));
  22984. end;
  22985. procedure TTestModule.TestTypeHelper_SetType;
  22986. begin
  22987. StartProgram(false);
  22988. Add([
  22989. '{$modeswitch typehelpers}',
  22990. 'type',
  22991. ' TEnum = (red,blue);',
  22992. ' TSetOfEnum = set of TEnum;',
  22993. ' THelper = type helper for TSetOfEnum',
  22994. ' procedure DoIt(e: byte = 123);',
  22995. ' constructor Init(e: TEnum);',
  22996. ' constructor InitEmpty;',
  22997. ' end;',
  22998. 'procedure THelper.DoIt(e: byte);',
  22999. 'begin',
  23000. ' Self:=[];',
  23001. ' Self:=[red];',
  23002. ' Include(Self,blue);',
  23003. 'end;',
  23004. 'constructor THelper.Init(e: TEnum);',
  23005. 'begin',
  23006. ' Self:=[];',
  23007. ' Self:=[e];',
  23008. ' Include(Self,blue);',
  23009. 'end;',
  23010. 'constructor THelper.InitEmpty;',
  23011. 'begin',
  23012. 'end;',
  23013. 'var s: TSetOfEnum;',
  23014. 'begin',
  23015. ' s.DoIt;',
  23016. //' [red].DoIt;',
  23017. //' with s do DoIt;',
  23018. //' with [red,blue] do DoIt;',
  23019. ' s:=TSetOfEnum.Init(blue);',
  23020. ' s:=s.Init(blue);',
  23021. '']);
  23022. ConvertProgram;
  23023. CheckSource('TestTypeHelper_SetType',
  23024. LinesToStr([ // statements
  23025. 'this.TEnum = {',
  23026. ' "0": "red",',
  23027. ' red: 0,',
  23028. ' "1": "blue",',
  23029. ' blue: 1',
  23030. '};',
  23031. 'rtl.createHelper($mod, "THelper", null, function () {',
  23032. ' this.DoIt = function (e) {',
  23033. ' this.set({});',
  23034. ' this.set(rtl.createSet($mod.TEnum.red));',
  23035. ' this.set(rtl.includeSet(this.get(), $mod.TEnum.blue));',
  23036. ' };',
  23037. ' this.Init = function (e) {',
  23038. ' this.set({});',
  23039. ' this.set(rtl.createSet(e));',
  23040. ' this.set(rtl.includeSet(this.get(), $mod.TEnum.blue));',
  23041. ' return this.get();',
  23042. ' };',
  23043. ' this.InitEmpty = function () {',
  23044. ' return this.get();',
  23045. ' };',
  23046. ' this.$new = function (fn, args) {',
  23047. ' return this[fn].apply({',
  23048. ' p: {},',
  23049. ' get: function () {',
  23050. ' return this.p;',
  23051. ' },',
  23052. ' set: function (v) {',
  23053. ' this.p = v;',
  23054. ' }',
  23055. ' }, args);',
  23056. ' };',
  23057. '});',
  23058. 'this.s = {};',
  23059. '']),
  23060. LinesToStr([ // $mod.$main
  23061. '$mod.THelper.DoIt.call({',
  23062. ' p: $mod,',
  23063. ' get: function () {',
  23064. ' return this.p.s;',
  23065. ' },',
  23066. ' set: function (v) {',
  23067. ' this.p.s = v;',
  23068. ' }',
  23069. '}, 123);',
  23070. '$mod.s = rtl.refSet($mod.THelper.$new("Init", [$mod.TEnum.blue]));',
  23071. '$mod.s = rtl.refSet($mod.THelper.Init.call({',
  23072. ' p: $mod,',
  23073. ' get: function () {',
  23074. ' return this.p.s;',
  23075. ' },',
  23076. ' set: function (v) {',
  23077. ' this.p.s = v;',
  23078. ' }',
  23079. '}, $mod.TEnum.blue));',
  23080. '']));
  23081. end;
  23082. procedure TTestModule.TestTypeHelper_InterfaceType;
  23083. begin
  23084. StartProgram(false);
  23085. Add([
  23086. '{$interfaces com}',
  23087. '{$modeswitch typehelpers}',
  23088. 'type',
  23089. ' IUnknown = interface',
  23090. ' function _AddRef: longint;',
  23091. ' function _Release: longint;',
  23092. ' end;',
  23093. ' TObject = class(IUnknown)',
  23094. ' function _AddRef: longint; virtual; abstract;',
  23095. ' function _Release: longint; virtual; abstract;',
  23096. ' end;',
  23097. ' THelper = type helper for IUnknown',
  23098. ' procedure Fly(e: byte = 123);',
  23099. ' class procedure Run; static;',
  23100. ' end;',
  23101. 'var',
  23102. ' i: IUnknown;',
  23103. ' o: TObject;',
  23104. 'procedure THelper.Fly(e: byte);',
  23105. 'begin',
  23106. ' i:=Self;',
  23107. ' o:=Self as TObject;',
  23108. ' Self:=nil;',
  23109. ' Self:=i;',
  23110. ' Self:=o;',
  23111. ' with Self do begin',
  23112. ' Fly;',
  23113. ' Fly();',
  23114. ' end;',
  23115. 'end;',
  23116. 'class procedure THelper.Run;',
  23117. 'var l: IUnknown;',
  23118. 'begin',
  23119. ' l.Fly;',
  23120. ' l.Fly();',
  23121. 'end;',
  23122. 'begin',
  23123. ' i.Fly;',
  23124. ' i.Fly();',
  23125. ' i.Run;',
  23126. ' i.Run();',
  23127. ' IUnknown.Run;',
  23128. ' IUnknown.Run();',
  23129. '']);
  23130. ConvertProgram;
  23131. CheckSource('TestTypeHelper_InterfaceType',
  23132. LinesToStr([ // statements
  23133. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  23134. 'rtl.createClass($mod, "TObject", null, function () {',
  23135. ' this.$init = function () {',
  23136. ' };',
  23137. ' this.$final = function () {',
  23138. ' };',
  23139. ' rtl.addIntf(this, $mod.IUnknown);',
  23140. '});',
  23141. 'rtl.createHelper($mod, "THelper", null, function () {',
  23142. ' this.Fly = function (e) {',
  23143. ' var $ir = rtl.createIntfRefs();',
  23144. ' try {',
  23145. ' rtl.setIntfP($mod, "i", this.get());',
  23146. ' $mod.o = rtl.intfAsClass(this.get(), $mod.TObject);',
  23147. ' this.set(null);',
  23148. ' this.set($mod.i);',
  23149. ' this.set($ir.ref(1, rtl.queryIntfT($mod.o, $mod.IUnknown)));',
  23150. ' var $with1 = this.get();',
  23151. ' $mod.THelper.Fly.call(this, 123);',
  23152. ' $mod.THelper.Fly.call(this, 123);',
  23153. ' } finally {',
  23154. ' $ir.free();',
  23155. ' };',
  23156. ' };',
  23157. ' this.Run = function () {',
  23158. ' var l = null;',
  23159. ' try {',
  23160. ' $mod.THelper.Fly.call({',
  23161. ' get: function () {',
  23162. ' return l;',
  23163. ' },',
  23164. ' set: function (v) {',
  23165. ' l = rtl.setIntfL(l, v);',
  23166. ' }',
  23167. ' }, 123);',
  23168. ' $mod.THelper.Fly.call({',
  23169. ' get: function () {',
  23170. ' return l;',
  23171. ' },',
  23172. ' set: function (v) {',
  23173. ' l = rtl.setIntfL(l, v);',
  23174. ' }',
  23175. ' }, 123);',
  23176. ' } finally {',
  23177. ' rtl._Release(l);',
  23178. ' };',
  23179. ' };',
  23180. '});',
  23181. 'this.i = null;',
  23182. 'this.o = null;',
  23183. '']),
  23184. LinesToStr([ // $mod.$main
  23185. '$mod.THelper.Fly.call({',
  23186. ' p: $mod,',
  23187. ' get: function () {',
  23188. ' return this.p.i;',
  23189. ' },',
  23190. ' set: function (v) {',
  23191. ' rtl.setIntfP(this.p, "i", v);',
  23192. ' }',
  23193. '}, 123);',
  23194. '$mod.THelper.Fly.call({',
  23195. ' p: $mod,',
  23196. ' get: function () {',
  23197. ' return this.p.i;',
  23198. ' },',
  23199. ' set: function (v) {',
  23200. ' rtl.setIntfP(this.p, "i", v);',
  23201. ' }',
  23202. '}, 123);',
  23203. '$mod.THelper.Run();',
  23204. '$mod.THelper.Run();',
  23205. '$mod.THelper.Run();',
  23206. '$mod.THelper.Run();',
  23207. '']));
  23208. end;
  23209. procedure TTestModule.TestProcType;
  23210. begin
  23211. StartProgram(false);
  23212. Add([
  23213. 'type',
  23214. ' TProcInt = procedure(vI: longint = 1);',
  23215. 'procedure DoIt(vJ: longint);',
  23216. 'begin end;',
  23217. 'var',
  23218. ' b: boolean;',
  23219. ' vP, vQ: tprocint;',
  23220. 'begin',
  23221. ' vp:=nil;',
  23222. ' vp:=vp;',
  23223. ' vp:=@doit;',
  23224. ' vp;',
  23225. ' vp();',
  23226. ' vp(2);',
  23227. ' b:=vp=nil;',
  23228. ' b:=nil=vp;',
  23229. ' b:=vp=vq;',
  23230. ' b:=vp=@doit;',
  23231. ' b:=@doit=vp;',
  23232. ' b:=vp<>nil;',
  23233. ' b:=nil<>vp;',
  23234. ' b:=vp<>vq;',
  23235. ' b:=vp<>@doit;',
  23236. ' b:=@doit<>vp;',
  23237. ' b:=Assigned(vp);',
  23238. ' if Assigned(vp) then ;']);
  23239. ConvertProgram;
  23240. CheckSource('TestProcType',
  23241. LinesToStr([ // statements
  23242. 'this.DoIt = function(vJ) {',
  23243. '};',
  23244. 'this.b = false;',
  23245. 'this.vP = null;',
  23246. 'this.vQ = null;'
  23247. ]),
  23248. LinesToStr([ // $mod.$main
  23249. '$mod.vP = null;',
  23250. '$mod.vP = $mod.vP;',
  23251. '$mod.vP = $mod.DoIt;',
  23252. '$mod.vP(1);',
  23253. '$mod.vP(1);',
  23254. '$mod.vP(2);',
  23255. '$mod.b = $mod.vP === null;',
  23256. '$mod.b = null === $mod.vP;',
  23257. '$mod.b = rtl.eqCallback($mod.vP,$mod.vQ);',
  23258. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  23259. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  23260. '$mod.b = $mod.vP !== null;',
  23261. '$mod.b = null !== $mod.vP;',
  23262. '$mod.b = !rtl.eqCallback($mod.vP,$mod.vQ);',
  23263. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  23264. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  23265. '$mod.b = $mod.vP != null;',
  23266. 'if ($mod.vP != null) ;',
  23267. '']));
  23268. end;
  23269. procedure TTestModule.TestProcType_Arg;
  23270. begin
  23271. StartProgram(false);
  23272. Add([
  23273. 'type',
  23274. ' TProcInt = procedure(vI: longint = 1);',
  23275. 'procedure DoIt(vJ: longint); begin end;',
  23276. 'procedure DoSome(vP, vQ: TProcInt);',
  23277. 'var',
  23278. ' b: boolean;',
  23279. 'begin',
  23280. ' vp:=nil;',
  23281. ' vp:=vp;',
  23282. ' vp:=@doit;',
  23283. ' vp;',
  23284. ' vp();',
  23285. ' vp(2);',
  23286. ' b:=vp=nil;',
  23287. ' b:=nil=vp;',
  23288. ' b:=vp=vq;',
  23289. ' b:=vp=@doit;',
  23290. ' b:=@doit=vp;',
  23291. ' b:=vp<>nil;',
  23292. ' b:=nil<>vp;',
  23293. ' b:=vp<>vq;',
  23294. ' b:=vp<>@doit;',
  23295. ' b:=@doit<>vp;',
  23296. ' b:=Assigned(vp);',
  23297. ' if Assigned(vp) then ;',
  23298. 'end;',
  23299. 'begin',
  23300. ' DoSome(@DoIt,nil);']);
  23301. ConvertProgram;
  23302. CheckSource('TestProcType_Arg',
  23303. LinesToStr([ // statements
  23304. 'this.DoIt = function(vJ) {',
  23305. '};',
  23306. 'this.DoSome = function(vP, vQ) {',
  23307. ' var b = false;',
  23308. ' vP = null;',
  23309. ' vP = vP;',
  23310. ' vP = $mod.DoIt;',
  23311. ' vP(1);',
  23312. ' vP(1);',
  23313. ' vP(2);',
  23314. ' b = vP === null;',
  23315. ' b = null === vP;',
  23316. ' b = rtl.eqCallback(vP,vQ);',
  23317. ' b = rtl.eqCallback(vP, $mod.DoIt);',
  23318. ' b = rtl.eqCallback($mod.DoIt, vP);',
  23319. ' b = vP !== null;',
  23320. ' b = null !== vP;',
  23321. ' b = !rtl.eqCallback(vP, vQ);',
  23322. ' b = !rtl.eqCallback(vP, $mod.DoIt);',
  23323. ' b = !rtl.eqCallback($mod.DoIt, vP);',
  23324. ' b = vP != null;',
  23325. ' if (vP != null) ;',
  23326. '};',
  23327. '']),
  23328. LinesToStr([ // $mod.$main
  23329. '$mod.DoSome($mod.DoIt,null);',
  23330. '']));
  23331. end;
  23332. procedure TTestModule.TestProcType_FunctionFPC;
  23333. begin
  23334. StartProgram(false);
  23335. Add('type');
  23336. Add(' TFuncInt = function(vA: longint = 1): longint;');
  23337. Add('function DoIt(vI: longint): longint;');
  23338. Add('begin end;');
  23339. Add('var');
  23340. Add(' b: boolean;');
  23341. Add(' vP, vQ: tfuncint;');
  23342. Add('begin');
  23343. Add(' vp:=nil;');
  23344. Add(' vp:=vp;');
  23345. Add(' vp:=@doit;'); // ok in fpc and delphi
  23346. //Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  23347. Add(' vp;'); // ok in fpc and delphi
  23348. Add(' vp();');
  23349. Add(' vp(2);');
  23350. Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  23351. Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  23352. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  23353. Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  23354. Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  23355. //Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  23356. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  23357. Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  23358. Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  23359. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  23360. Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  23361. Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  23362. //Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  23363. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  23364. Add(' b:=Assigned(vp);');
  23365. //Add(' doit(vp);'); // illegal in fpc, ok in delphi
  23366. Add(' doit(vp());'); // ok in fpc and delphi
  23367. Add(' doit(vp(2));'); // ok in fpc and delphi
  23368. ConvertProgram;
  23369. CheckSource('TestProcType_FunctionFPC',
  23370. LinesToStr([ // statements
  23371. 'this.DoIt = function(vI) {',
  23372. ' var Result = 0;',
  23373. ' return Result;',
  23374. '};',
  23375. 'this.b = false;',
  23376. 'this.vP = null;',
  23377. 'this.vQ = null;'
  23378. ]),
  23379. LinesToStr([ // $mod.$main
  23380. '$mod.vP = null;',
  23381. '$mod.vP = $mod.vP;',
  23382. '$mod.vP = $mod.DoIt;',
  23383. '$mod.vP(1);',
  23384. '$mod.vP(1);',
  23385. '$mod.vP(2);',
  23386. '$mod.b = $mod.vP === null;',
  23387. '$mod.b = null === $mod.vP;',
  23388. '$mod.b = rtl.eqCallback($mod.vP,$mod.vQ);',
  23389. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  23390. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  23391. '$mod.b = 4 === $mod.vP(1);',
  23392. '$mod.b = $mod.vP !== null;',
  23393. '$mod.b = null !== $mod.vP;',
  23394. '$mod.b = !rtl.eqCallback($mod.vP,$mod.vQ);',
  23395. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  23396. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  23397. '$mod.b = 6 !== $mod.vP(1);',
  23398. '$mod.b = $mod.vP != null;',
  23399. '$mod.DoIt($mod.vP(1));',
  23400. '$mod.DoIt($mod.vP(2));',
  23401. '']));
  23402. end;
  23403. procedure TTestModule.TestProcType_FunctionDelphi;
  23404. begin
  23405. StartProgram(false);
  23406. Add('{$mode Delphi}');
  23407. Add('type');
  23408. Add(' TFuncInt = function(vA: longint = 1): longint;');
  23409. Add('function DoIt(vI: longint): longint;');
  23410. Add('begin end;');
  23411. Add('var');
  23412. Add(' b: boolean;');
  23413. Add(' vP, vQ: tfuncint;');
  23414. Add('begin');
  23415. Add(' vp:=nil;');
  23416. Add(' vp:=vp;');
  23417. Add(' vp:=@doit;'); // ok in fpc and delphi
  23418. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  23419. Add(' vp;'); // ok in fpc and delphi
  23420. Add(' vp();');
  23421. Add(' vp(2);');
  23422. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  23423. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  23424. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  23425. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  23426. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  23427. Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  23428. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  23429. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  23430. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  23431. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  23432. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  23433. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  23434. Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  23435. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  23436. Add(' b:=Assigned(vp);');
  23437. Add(' doit(vp);'); // illegal in fpc, ok in delphi
  23438. Add(' doit(vp());'); // ok in fpc and delphi
  23439. Add(' doit(vp(2));'); // ok in fpc and delphi *)
  23440. ConvertProgram;
  23441. CheckSource('TestProcType_FunctionDelphi',
  23442. LinesToStr([ // statements
  23443. 'this.DoIt = function(vI) {',
  23444. ' var Result = 0;',
  23445. ' return Result;',
  23446. '};',
  23447. 'this.b = false;',
  23448. 'this.vP = null;',
  23449. 'this.vQ = null;'
  23450. ]),
  23451. LinesToStr([ // $mod.$main
  23452. '$mod.vP = null;',
  23453. '$mod.vP = $mod.vP;',
  23454. '$mod.vP = $mod.DoIt;',
  23455. '$mod.vP = $mod.DoIt;',
  23456. '$mod.vP(1);',
  23457. '$mod.vP(1);',
  23458. '$mod.vP(2);',
  23459. '$mod.b = $mod.vP(1) === $mod.vQ(1);',
  23460. '$mod.b = $mod.vP(1) === 3;',
  23461. '$mod.b = 4 === $mod.vP(1);',
  23462. '$mod.b = $mod.vP(1) !== $mod.vQ(1);',
  23463. '$mod.b = $mod.vP(1) !== 5;',
  23464. '$mod.b = 6 !== $mod.vP(1);',
  23465. '$mod.b = $mod.vP != null;',
  23466. '$mod.DoIt($mod.vP(1));',
  23467. '$mod.DoIt($mod.vP(1));',
  23468. '$mod.DoIt($mod.vP(2));',
  23469. '']));
  23470. end;
  23471. procedure TTestModule.TestProcType_ProcedureDelphi;
  23472. begin
  23473. StartProgram(false);
  23474. Add('{$mode Delphi}');
  23475. Add('type');
  23476. Add(' TProc = procedure;');
  23477. Add('procedure DoIt;');
  23478. Add('begin end;');
  23479. Add('var');
  23480. Add(' b: boolean;');
  23481. Add(' vP, vQ: tproc;');
  23482. Add('begin');
  23483. Add(' vp:=nil;');
  23484. Add(' vp:=vp;');
  23485. Add(' vp:=vq;');
  23486. 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
  23487. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  23488. //Add(' vp:=@doit;'); // illegal in fpc, ok in delphi (because Delphi treats @F as Pointer), not supported by resolver
  23489. Add(' vp;'); // ok in fpc and delphi
  23490. Add(' vp();');
  23491. // equal
  23492. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  23493. Add(' b:=@@vp=nil;'); // ok in fpc delphi mode, ok in delphi
  23494. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  23495. Add(' b:=nil=@@vp;'); // ok in fpc delphi mode, ok in delphi
  23496. Add(' b:=@@vp=@@vq;'); // ok in fpc delphi mode, ok in Delphi
  23497. //Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  23498. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  23499. Add(' b:=@@vp=@doit;'); // ok in fpc delphi mode, ok in delphi
  23500. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  23501. Add(' b:=@doit=@@vp;'); // ok in fpc delphi mode, ok in delphi
  23502. // unequal
  23503. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  23504. Add(' b:=@@vp<>nil;'); // ok in fpc mode delphi, ok in delphi
  23505. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  23506. Add(' b:=nil<>@@vp;'); // ok in fpc mode delphi, ok in delphi
  23507. //Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  23508. Add(' b:=@@vp<>@@vq;'); // ok in fpc mode delphi, ok in delphi
  23509. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  23510. Add(' b:=@@vp<>@doit;'); // ok in fpc mode delphi, illegal in delphi
  23511. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  23512. Add(' b:=@doit<>@@vp;'); // ok in fpc mode delphi, illegal in delphi
  23513. Add(' b:=Assigned(vp);');
  23514. ConvertProgram;
  23515. CheckSource('TestProcType_ProcedureDelphi',
  23516. LinesToStr([ // statements
  23517. 'this.DoIt = function() {',
  23518. '};',
  23519. 'this.b = false;',
  23520. 'this.vP = null;',
  23521. 'this.vQ = null;'
  23522. ]),
  23523. LinesToStr([ // $mod.$main
  23524. '$mod.vP = null;',
  23525. '$mod.vP = $mod.vP;',
  23526. '$mod.vP = $mod.vQ;',
  23527. '$mod.vP = $mod.DoIt;',
  23528. '$mod.vP = $mod.DoIt;',
  23529. '$mod.vP();',
  23530. '$mod.vP();',
  23531. '$mod.b = $mod.vP === null;',
  23532. '$mod.b = null === $mod.vP;',
  23533. '$mod.b = rtl.eqCallback($mod.vP, $mod.vQ);',
  23534. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  23535. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  23536. '$mod.b = $mod.vP !== null;',
  23537. '$mod.b = null !== $mod.vP;',
  23538. '$mod.b = !rtl.eqCallback($mod.vP, $mod.vQ);',
  23539. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  23540. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  23541. '$mod.b = $mod.vP != null;',
  23542. '']));
  23543. end;
  23544. procedure TTestModule.TestProcType_AsParam;
  23545. begin
  23546. StartProgram(false);
  23547. Add('type');
  23548. Add(' TFuncInt = function(vA: longint = 1): longint;');
  23549. Add('procedure DoIt(vG: tfuncint; const vH: tfuncint; var vI: tfuncint);');
  23550. Add('var vJ: tfuncint;');
  23551. Add('begin');
  23552. Add(' vg:=vg;');
  23553. Add(' vj:=vh;');
  23554. Add(' vi:=vi;');
  23555. Add(' doit(vg,vg,vg);');
  23556. Add(' doit(vh,vh,vj);');
  23557. Add(' doit(vi,vi,vi);');
  23558. Add(' doit(vj,vj,vj);');
  23559. Add('end;');
  23560. Add('var i: tfuncint;');
  23561. Add('begin');
  23562. Add(' doit(i,i,i);');
  23563. ConvertProgram;
  23564. CheckSource('TestProcType_AsParam',
  23565. LinesToStr([ // statements
  23566. 'this.DoIt = function (vG,vH,vI) {',
  23567. ' var vJ = null;',
  23568. ' vG = vG;',
  23569. ' vJ = vH;',
  23570. ' vI.set(vI.get());',
  23571. ' $mod.DoIt(vG, vG, {',
  23572. ' get: function () {',
  23573. ' return vG;',
  23574. ' },',
  23575. ' set: function (v) {',
  23576. ' vG = v;',
  23577. ' }',
  23578. ' });',
  23579. ' $mod.DoIt(vH, vH, {',
  23580. ' get: function () {',
  23581. ' return vJ;',
  23582. ' },',
  23583. ' set: function (v) {',
  23584. ' vJ = v;',
  23585. ' }',
  23586. ' });',
  23587. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  23588. ' $mod.DoIt(vJ, vJ, {',
  23589. ' get: function () {',
  23590. ' return vJ;',
  23591. ' },',
  23592. ' set: function (v) {',
  23593. ' vJ = v;',
  23594. ' }',
  23595. ' });',
  23596. '};',
  23597. 'this.i = null;'
  23598. ]),
  23599. LinesToStr([
  23600. '$mod.DoIt($mod.i,$mod.i,{',
  23601. ' p: $mod,',
  23602. ' get: function () {',
  23603. ' return this.p.i;',
  23604. ' },',
  23605. ' set: function (v) {',
  23606. ' this.p.i = v;',
  23607. ' }',
  23608. '});'
  23609. ]));
  23610. end;
  23611. procedure TTestModule.TestProcType_MethodFPC;
  23612. begin
  23613. StartProgram(false);
  23614. Add('type');
  23615. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23616. Add(' TObject = class');
  23617. Add(' function DoIt(vA: longint = 1): longint;');
  23618. Add(' end;');
  23619. Add('function TObject.DoIt(vA: longint = 1): longint;');
  23620. Add('begin');
  23621. Add('end;');
  23622. Add('var');
  23623. Add(' Obj: TObject;');
  23624. Add(' vP: tfuncint;');
  23625. Add(' b: boolean;');
  23626. Add('begin');
  23627. Add(' vp:[email protected];'); // ok in fpc and delphi
  23628. //Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  23629. Add(' vp;'); // ok in fpc and delphi
  23630. Add(' vp();');
  23631. Add(' vp(2);');
  23632. Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  23633. Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  23634. Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  23635. Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  23636. ConvertProgram;
  23637. CheckSource('TestProcType_MethodFPC',
  23638. LinesToStr([ // statements
  23639. 'rtl.createClass($mod, "TObject", null, function () {',
  23640. ' this.$init = function () {',
  23641. ' };',
  23642. ' this.$final = function () {',
  23643. ' };',
  23644. ' this.DoIt = function (vA) {',
  23645. ' var Result = 0;',
  23646. ' return Result;',
  23647. ' };',
  23648. '});',
  23649. 'this.Obj = null;',
  23650. 'this.vP = null;',
  23651. 'this.b = false;'
  23652. ]),
  23653. LinesToStr([
  23654. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  23655. '$mod.vP(1);',
  23656. '$mod.vP(1);',
  23657. '$mod.vP(2);',
  23658. '$mod.b = rtl.eqCallback($mod.vP, rtl.createCallback($mod.Obj, "DoIt"));',
  23659. '$mod.b = rtl.eqCallback(rtl.createCallback($mod.Obj, "DoIt"), $mod.vP);',
  23660. '$mod.b = !rtl.eqCallback($mod.vP, rtl.createCallback($mod.Obj, "DoIt"));',
  23661. '$mod.b = !rtl.eqCallback(rtl.createCallback($mod.Obj, "DoIt"), $mod.vP);',
  23662. '']));
  23663. end;
  23664. procedure TTestModule.TestProcType_MethodDelphi;
  23665. begin
  23666. StartProgram(false);
  23667. Add('{$mode delphi}');
  23668. Add('type');
  23669. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23670. Add(' TObject = class');
  23671. Add(' function DoIt(vA: longint = 1): longint;');
  23672. Add(' end;');
  23673. Add('function TObject.DoIt(vA: longint = 1): longint;');
  23674. Add('begin');
  23675. Add('end;');
  23676. Add('var');
  23677. Add(' Obj: TObject;');
  23678. Add(' vP: tfuncint;');
  23679. Add(' b: boolean;');
  23680. Add('begin');
  23681. Add(' vp:[email protected];'); // ok in fpc and delphi
  23682. Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  23683. Add(' vp;'); // ok in fpc and delphi
  23684. Add(' vp();');
  23685. Add(' vp(2);');
  23686. //Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  23687. //Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  23688. //Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  23689. //Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  23690. ConvertProgram;
  23691. CheckSource('TestProcType_MethodDelphi',
  23692. LinesToStr([ // statements
  23693. 'rtl.createClass($mod, "TObject", null, function () {',
  23694. ' this.$init = function () {',
  23695. ' };',
  23696. ' this.$final = function () {',
  23697. ' };',
  23698. ' this.DoIt = function (vA) {',
  23699. ' var Result = 0;',
  23700. ' return Result;',
  23701. ' };',
  23702. '});',
  23703. 'this.Obj = null;',
  23704. 'this.vP = null;',
  23705. 'this.b = false;'
  23706. ]),
  23707. LinesToStr([
  23708. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  23709. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  23710. '$mod.vP(1);',
  23711. '$mod.vP(1);',
  23712. '$mod.vP(2);',
  23713. '']));
  23714. end;
  23715. procedure TTestModule.TestProcType_PropertyFPC;
  23716. begin
  23717. StartProgram(false);
  23718. Add('type');
  23719. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23720. Add(' TObject = class');
  23721. Add(' FOnFoo: TFuncInt;');
  23722. Add(' function DoIt(vA: longint = 1): longint;');
  23723. Add(' function GetFoo: TFuncInt;');
  23724. Add(' procedure SetFoo(const Value: TFuncInt);');
  23725. Add(' function GetEvents(Index: longint): TFuncInt;');
  23726. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  23727. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  23728. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  23729. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  23730. Add(' end;');
  23731. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  23732. Add('function tobject.getfoo: tfuncint; begin end;');
  23733. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  23734. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  23735. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  23736. Add('var');
  23737. Add(' Obj: TObject;');
  23738. Add(' vP: tfuncint;');
  23739. Add(' b: boolean;');
  23740. Add('begin');
  23741. Add(' obj.onfoo:=nil;');
  23742. Add(' obj.onbar:=nil;');
  23743. Add(' obj.events[1]:=nil;');
  23744. Add(' obj.onfoo:=obj.onfoo;');
  23745. Add(' obj.onbar:=obj.onbar;');
  23746. Add(' obj.events[2]:=obj.events[3];');
  23747. Add(' obj.onfoo:[email protected];');
  23748. Add(' obj.onbar:[email protected];');
  23749. Add(' obj.events[4]:[email protected];');
  23750. //Add(' obj.onfoo:=obj.doit;'); // delphi
  23751. //Add(' obj.onbar:=obj.doit;'); // delphi
  23752. //Add(' obj.events[4]:=obj.doit;'); // delphi
  23753. Add(' obj.onfoo;');
  23754. Add(' obj.onbar;');
  23755. //Add(' obj.events[5];'); ToDo in pasresolver
  23756. Add(' obj.onfoo();');
  23757. Add(' obj.onbar();');
  23758. Add(' obj.events[6]();');
  23759. Add(' b:=obj.onfoo=nil;');
  23760. Add(' b:=obj.onbar=nil;');
  23761. Add(' b:=obj.events[7]=nil;');
  23762. Add(' b:=obj.onfoo<>nil;');
  23763. Add(' b:=obj.onbar<>nil;');
  23764. Add(' b:=obj.events[8]<>nil;');
  23765. Add(' b:=obj.onfoo=vp;');
  23766. Add(' b:=obj.onbar=vp;');
  23767. Add(' b:=obj.events[9]=vp;');
  23768. Add(' b:=obj.onfoo=obj.onfoo;');
  23769. Add(' b:=obj.onbar=obj.onfoo;');
  23770. Add(' b:=obj.events[10]=obj.onfoo;');
  23771. Add(' b:=obj.onfoo<>obj.onfoo;');
  23772. Add(' b:=obj.onbar<>obj.onfoo;');
  23773. Add(' b:=obj.events[11]<>obj.onfoo;');
  23774. Add(' b:[email protected];');
  23775. Add(' b:[email protected];');
  23776. Add(' b:=obj.events[12][email protected];');
  23777. Add(' b:=obj.onfoo<>@obj.doit;');
  23778. Add(' b:=obj.onbar<>@obj.doit;');
  23779. Add(' b:=obj.events[12]<>@obj.doit;');
  23780. Add(' b:=Assigned(obj.onfoo);');
  23781. Add(' b:=Assigned(obj.onbar);');
  23782. Add(' b:=Assigned(obj.events[13]);');
  23783. ConvertProgram;
  23784. CheckSource('TestProcType_PropertyFPC',
  23785. LinesToStr([ // statements
  23786. 'rtl.createClass($mod, "TObject", null, function () {',
  23787. ' this.$init = function () {',
  23788. ' this.FOnFoo = null;',
  23789. ' };',
  23790. ' this.$final = function () {',
  23791. ' this.FOnFoo = undefined;',
  23792. ' };',
  23793. ' this.DoIt = function (vA) {',
  23794. ' var Result = 0;',
  23795. ' return Result;',
  23796. ' };',
  23797. 'this.GetFoo = function () {',
  23798. ' var Result = null;',
  23799. ' return Result;',
  23800. '};',
  23801. 'this.SetFoo = function (Value) {',
  23802. '};',
  23803. 'this.GetEvents = function (Index) {',
  23804. ' var Result = null;',
  23805. ' return Result;',
  23806. '};',
  23807. 'this.SetEvents = function (Index, Value) {',
  23808. '};',
  23809. '});',
  23810. 'this.Obj = null;',
  23811. 'this.vP = null;',
  23812. 'this.b = false;'
  23813. ]),
  23814. LinesToStr([
  23815. '$mod.Obj.FOnFoo = null;',
  23816. '$mod.Obj.SetFoo(null);',
  23817. '$mod.Obj.SetEvents(1, null);',
  23818. '$mod.Obj.FOnFoo = $mod.Obj.FOnFoo;',
  23819. '$mod.Obj.SetFoo($mod.Obj.GetFoo());',
  23820. '$mod.Obj.SetEvents(2, $mod.Obj.GetEvents(3));',
  23821. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  23822. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  23823. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  23824. '$mod.Obj.FOnFoo(1);',
  23825. '$mod.Obj.GetFoo();',
  23826. '$mod.Obj.FOnFoo(1);',
  23827. '$mod.Obj.GetFoo()(1);',
  23828. '$mod.Obj.GetEvents(6)(1);',
  23829. '$mod.b = $mod.Obj.FOnFoo === null;',
  23830. '$mod.b = $mod.Obj.GetFoo() === null;',
  23831. '$mod.b = $mod.Obj.GetEvents(7) === null;',
  23832. '$mod.b = $mod.Obj.FOnFoo !== null;',
  23833. '$mod.b = $mod.Obj.GetFoo() !== null;',
  23834. '$mod.b = $mod.Obj.GetEvents(8) !== null;',
  23835. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, $mod.vP);',
  23836. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), $mod.vP);',
  23837. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(9), $mod.vP);',
  23838. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, $mod.Obj.FOnFoo);',
  23839. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), $mod.Obj.FOnFoo);',
  23840. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(10), $mod.Obj.FOnFoo);',
  23841. '$mod.b = !rtl.eqCallback($mod.Obj.FOnFoo, $mod.Obj.FOnFoo);',
  23842. '$mod.b = !rtl.eqCallback($mod.Obj.GetFoo(), $mod.Obj.FOnFoo);',
  23843. '$mod.b = !rtl.eqCallback($mod.Obj.GetEvents(11), $mod.Obj.FOnFoo);',
  23844. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, rtl.createCallback($mod.Obj, "DoIt"));',
  23845. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), rtl.createCallback($mod.Obj, "DoIt"));',
  23846. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(12), rtl.createCallback($mod.Obj, "DoIt"));',
  23847. '$mod.b = !rtl.eqCallback($mod.Obj.FOnFoo, rtl.createCallback($mod.Obj, "DoIt"));',
  23848. '$mod.b = !rtl.eqCallback($mod.Obj.GetFoo(), rtl.createCallback($mod.Obj, "DoIt"));',
  23849. '$mod.b = !rtl.eqCallback($mod.Obj.GetEvents(12), rtl.createCallback($mod.Obj, "DoIt"));',
  23850. '$mod.b = $mod.Obj.FOnFoo != null;',
  23851. '$mod.b = $mod.Obj.GetFoo() != null;',
  23852. '$mod.b = $mod.Obj.GetEvents(13) != null;',
  23853. '']));
  23854. end;
  23855. procedure TTestModule.TestProcType_PropertyDelphi;
  23856. begin
  23857. StartProgram(false);
  23858. Add('{$mode delphi}');
  23859. Add('type');
  23860. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23861. Add(' TObject = class');
  23862. Add(' FOnFoo: TFuncInt;');
  23863. Add(' function DoIt(vA: longint = 1): longint;');
  23864. Add(' function GetFoo: TFuncInt;');
  23865. Add(' procedure SetFoo(const Value: TFuncInt);');
  23866. Add(' function GetEvents(Index: longint): TFuncInt;');
  23867. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  23868. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  23869. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  23870. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  23871. Add(' end;');
  23872. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  23873. Add('function tobject.getfoo: tfuncint; begin end;');
  23874. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  23875. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  23876. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  23877. Add('var');
  23878. Add(' Obj: TObject;');
  23879. Add(' vP: tfuncint;');
  23880. Add(' b: boolean;');
  23881. Add('begin');
  23882. Add(' obj.onfoo:=nil;');
  23883. Add(' obj.onbar:=nil;');
  23884. Add(' obj.events[1]:=nil;');
  23885. Add(' obj.onfoo:=obj.onfoo;');
  23886. Add(' obj.onbar:=obj.onbar;');
  23887. Add(' obj.events[2]:=obj.events[3];');
  23888. Add(' obj.onfoo:[email protected];');
  23889. Add(' obj.onbar:[email protected];');
  23890. Add(' obj.events[4]:[email protected];');
  23891. Add(' obj.onfoo:=obj.doit;'); // delphi
  23892. Add(' obj.onbar:=obj.doit;'); // delphi
  23893. Add(' obj.events[4]:=obj.doit;'); // delphi
  23894. Add(' obj.onfoo;');
  23895. Add(' obj.onbar;');
  23896. //Add(' obj.events[5];'); ToDo in pasresolver
  23897. Add(' obj.onfoo();');
  23898. Add(' obj.onbar();');
  23899. Add(' obj.events[6]();');
  23900. //Add(' b:=obj.onfoo=nil;'); // fpc
  23901. //Add(' b:=obj.onbar=nil;'); // fpc
  23902. //Add(' b:=obj.events[7]=nil;'); // fpc
  23903. //Add(' b:=obj.onfoo<>nil;'); // fpc
  23904. //Add(' b:=obj.onbar<>nil;'); // fpc
  23905. //Add(' b:=obj.events[8]<>nil;'); // fpc
  23906. Add(' b:=obj.onfoo=vp;');
  23907. Add(' b:=obj.onbar=vp;');
  23908. //Add(' b:=obj.events[9]=vp;'); ToDo in pasresolver
  23909. Add(' b:=obj.onfoo=obj.onfoo;');
  23910. Add(' b:=obj.onbar=obj.onfoo;');
  23911. //Add(' b:=obj.events[10]=obj.onfoo;'); // ToDo in pasresolver
  23912. Add(' b:=obj.onfoo<>obj.onfoo;');
  23913. Add(' b:=obj.onbar<>obj.onfoo;');
  23914. //Add(' b:=obj.events[11]<>obj.onfoo;'); // ToDo in pasresolver
  23915. //Add(' b:[email protected];'); // fpc
  23916. //Add(' b:[email protected];'); // fpc
  23917. //Add(' b:=obj.events[12][email protected];'); // fpc
  23918. //Add(' b:=obj.onfoo<>@obj.doit;'); // fpc
  23919. //Add(' b:=obj.onbar<>@obj.doit;'); // fpc
  23920. //Add(' b:=obj.events[12]<>@obj.doit;'); // fpc
  23921. Add(' b:=Assigned(obj.onfoo);');
  23922. Add(' b:=Assigned(obj.onbar);');
  23923. Add(' b:=Assigned(obj.events[13]);');
  23924. ConvertProgram;
  23925. CheckSource('TestProcType_PropertyDelphi',
  23926. LinesToStr([ // statements
  23927. 'rtl.createClass($mod, "TObject", null, function () {',
  23928. ' this.$init = function () {',
  23929. ' this.FOnFoo = null;',
  23930. ' };',
  23931. ' this.$final = function () {',
  23932. ' this.FOnFoo = undefined;',
  23933. ' };',
  23934. ' this.DoIt = function (vA) {',
  23935. ' var Result = 0;',
  23936. ' return Result;',
  23937. ' };',
  23938. 'this.GetFoo = function () {',
  23939. ' var Result = null;',
  23940. ' return Result;',
  23941. '};',
  23942. 'this.SetFoo = function (Value) {',
  23943. '};',
  23944. 'this.GetEvents = function (Index) {',
  23945. ' var Result = null;',
  23946. ' return Result;',
  23947. '};',
  23948. 'this.SetEvents = function (Index, Value) {',
  23949. '};',
  23950. '});',
  23951. 'this.Obj = null;',
  23952. 'this.vP = null;',
  23953. 'this.b = false;'
  23954. ]),
  23955. LinesToStr([
  23956. '$mod.Obj.FOnFoo = null;',
  23957. '$mod.Obj.SetFoo(null);',
  23958. '$mod.Obj.SetEvents(1, null);',
  23959. '$mod.Obj.FOnFoo = $mod.Obj.FOnFoo;',
  23960. '$mod.Obj.SetFoo($mod.Obj.GetFoo());',
  23961. '$mod.Obj.SetEvents(2, $mod.Obj.GetEvents(3));',
  23962. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  23963. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  23964. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  23965. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  23966. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  23967. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  23968. '$mod.Obj.FOnFoo(1);',
  23969. '$mod.Obj.GetFoo();',
  23970. '$mod.Obj.FOnFoo(1);',
  23971. '$mod.Obj.GetFoo()(1);',
  23972. '$mod.Obj.GetEvents(6)(1);',
  23973. '$mod.b = $mod.Obj.FOnFoo(1) === $mod.vP(1);',
  23974. '$mod.b = $mod.Obj.GetFoo() === $mod.vP(1);',
  23975. '$mod.b = $mod.Obj.FOnFoo(1) === $mod.Obj.FOnFoo(1);',
  23976. '$mod.b = $mod.Obj.GetFoo() === $mod.Obj.FOnFoo(1);',
  23977. '$mod.b = $mod.Obj.FOnFoo(1) !== $mod.Obj.FOnFoo(1);',
  23978. '$mod.b = $mod.Obj.GetFoo() !== $mod.Obj.FOnFoo(1);',
  23979. '$mod.b = $mod.Obj.FOnFoo != null;',
  23980. '$mod.b = $mod.Obj.GetFoo() != null;',
  23981. '$mod.b = $mod.Obj.GetEvents(13) != null;',
  23982. '']));
  23983. end;
  23984. procedure TTestModule.TestProcType_WithClassInstDoPropertyFPC;
  23985. begin
  23986. StartProgram(false);
  23987. Add('type');
  23988. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23989. Add(' TObject = class');
  23990. Add(' FOnFoo: TFuncInt;');
  23991. Add(' function DoIt(vA: longint = 1): longint;');
  23992. Add(' function GetFoo: TFuncInt;');
  23993. Add(' procedure SetFoo(const Value: TFuncInt);');
  23994. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  23995. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  23996. Add(' end;');
  23997. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  23998. Add('function tobject.getfoo: tfuncint; begin end;');
  23999. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  24000. Add('var');
  24001. Add(' Obj: TObject;');
  24002. Add(' vP: tfuncint;');
  24003. Add(' b: boolean;');
  24004. Add('begin');
  24005. Add('with obj do begin');
  24006. Add(' fonfoo:=nil;');
  24007. Add(' onfoo:=nil;');
  24008. Add(' onbar:=nil;');
  24009. Add(' fonfoo:=fonfoo;');
  24010. Add(' onfoo:=onfoo;');
  24011. Add(' onbar:=onbar;');
  24012. Add(' fonfoo:=@doit;');
  24013. Add(' onfoo:=@doit;');
  24014. Add(' onbar:=@doit;');
  24015. //Add(' fonfoo:=doit;'); // delphi
  24016. //Add(' onfoo:=doit;'); // delphi
  24017. //Add(' onbar:=doit;'); // delphi
  24018. Add(' fonfoo;');
  24019. Add(' onfoo;');
  24020. Add(' onbar;');
  24021. Add(' fonfoo();');
  24022. Add(' onfoo();');
  24023. Add(' onbar();');
  24024. Add(' b:=fonfoo=nil;');
  24025. Add(' b:=onfoo=nil;');
  24026. Add(' b:=onbar=nil;');
  24027. Add(' b:=fonfoo<>nil;');
  24028. Add(' b:=onfoo<>nil;');
  24029. Add(' b:=onbar<>nil;');
  24030. Add(' b:=fonfoo=vp;');
  24031. Add(' b:=onfoo=vp;');
  24032. Add(' b:=onbar=vp;');
  24033. Add(' b:=fonfoo=fonfoo;');
  24034. Add(' b:=onfoo=onfoo;');
  24035. Add(' b:=onbar=onfoo;');
  24036. Add(' b:=fonfoo<>fonfoo;');
  24037. Add(' b:=onfoo<>onfoo;');
  24038. Add(' b:=onbar<>onfoo;');
  24039. Add(' b:=fonfoo=@doit;');
  24040. Add(' b:=onfoo=@doit;');
  24041. Add(' b:=onbar=@doit;');
  24042. Add(' b:=fonfoo<>@doit;');
  24043. Add(' b:=onfoo<>@doit;');
  24044. Add(' b:=onbar<>@doit;');
  24045. Add(' b:=Assigned(fonfoo);');
  24046. Add(' b:=Assigned(onfoo);');
  24047. Add(' b:=Assigned(onbar);');
  24048. Add('end;');
  24049. ConvertProgram;
  24050. CheckSource('TestProcType_WithClassInstDoPropertyFPC',
  24051. LinesToStr([ // statements
  24052. 'rtl.createClass($mod, "TObject", null, function () {',
  24053. ' this.$init = function () {',
  24054. ' this.FOnFoo = null;',
  24055. ' };',
  24056. ' this.$final = function () {',
  24057. ' this.FOnFoo = undefined;',
  24058. ' };',
  24059. ' this.DoIt = function (vA) {',
  24060. ' var Result = 0;',
  24061. ' return Result;',
  24062. ' };',
  24063. ' this.GetFoo = function () {',
  24064. ' var Result = null;',
  24065. ' return Result;',
  24066. ' };',
  24067. ' this.SetFoo = function (Value) {',
  24068. ' };',
  24069. '});',
  24070. 'this.Obj = null;',
  24071. 'this.vP = null;',
  24072. 'this.b = false;'
  24073. ]),
  24074. LinesToStr([
  24075. 'var $with1 = $mod.Obj;',
  24076. '$with1.FOnFoo = null;',
  24077. '$with1.FOnFoo = null;',
  24078. '$with1.SetFoo(null);',
  24079. '$with1.FOnFoo = $with1.FOnFoo;',
  24080. '$with1.FOnFoo = $with1.FOnFoo;',
  24081. '$with1.SetFoo($with1.GetFoo());',
  24082. '$with1.FOnFoo = rtl.createCallback($with1, "DoIt");',
  24083. '$with1.FOnFoo = rtl.createCallback($with1, "DoIt");',
  24084. '$with1.SetFoo(rtl.createCallback($with1, "DoIt"));',
  24085. '$with1.FOnFoo(1);',
  24086. '$with1.FOnFoo(1);',
  24087. '$with1.GetFoo();',
  24088. '$with1.FOnFoo(1);',
  24089. '$with1.FOnFoo(1);',
  24090. '$with1.GetFoo()(1);',
  24091. '$mod.b = $with1.FOnFoo === null;',
  24092. '$mod.b = $with1.FOnFoo === null;',
  24093. '$mod.b = $with1.GetFoo() === null;',
  24094. '$mod.b = $with1.FOnFoo !== null;',
  24095. '$mod.b = $with1.FOnFoo !== null;',
  24096. '$mod.b = $with1.GetFoo() !== null;',
  24097. '$mod.b = rtl.eqCallback($with1.FOnFoo, $mod.vP);',
  24098. '$mod.b = rtl.eqCallback($with1.FOnFoo, $mod.vP);',
  24099. '$mod.b = rtl.eqCallback($with1.GetFoo(), $mod.vP);',
  24100. '$mod.b = rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24101. '$mod.b = rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24102. '$mod.b = rtl.eqCallback($with1.GetFoo(), $with1.FOnFoo);',
  24103. '$mod.b = !rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24104. '$mod.b = !rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24105. '$mod.b = !rtl.eqCallback($with1.GetFoo(), $with1.FOnFoo);',
  24106. '$mod.b = rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24107. '$mod.b = rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24108. '$mod.b = rtl.eqCallback($with1.GetFoo(), rtl.createCallback($with1, "DoIt"));',
  24109. '$mod.b = !rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24110. '$mod.b = !rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24111. '$mod.b = !rtl.eqCallback($with1.GetFoo(), rtl.createCallback($with1, "DoIt"));',
  24112. '$mod.b = $with1.FOnFoo != null;',
  24113. '$mod.b = $with1.FOnFoo != null;',
  24114. '$mod.b = $with1.GetFoo() != null;',
  24115. '']));
  24116. end;
  24117. procedure TTestModule.TestProcType_Nested;
  24118. begin
  24119. StartProgram(false);
  24120. Add([
  24121. 'type',
  24122. ' TProcInt = procedure(vI: longint = 1);',
  24123. 'procedure DoIt(vJ: longint);',
  24124. 'var aProc: TProcInt;',
  24125. ' b: boolean;',
  24126. ' procedure Sub(vK: longint);',
  24127. ' var aSub: TProcInt;',
  24128. ' procedure SubSub(vK: longint);',
  24129. ' var aSubSub: TProcInt;',
  24130. ' begin;',
  24131. ' aProc:=@DoIt;',
  24132. ' aSub:=@DoIt;',
  24133. ' aSubSub:=@DoIt;',
  24134. ' aProc:=@Sub;',
  24135. ' aSub:=@Sub;',
  24136. ' aSubSub:=@Sub;',
  24137. ' aProc:=@SubSub;',
  24138. ' aSub:=@SubSub;',
  24139. ' aSubSub:=@SubSub;',
  24140. ' end;',
  24141. ' begin;',
  24142. ' end;',
  24143. 'begin;',
  24144. ' aProc:=@Sub;',
  24145. ' b:=aProc=@Sub;',
  24146. ' b:=@Sub=aProc;',
  24147. 'end;',
  24148. 'begin',
  24149. '']);
  24150. ConvertProgram;
  24151. CheckSource('TestProcType_Nested',
  24152. LinesToStr([ // statements
  24153. 'this.DoIt = function (vJ) {',
  24154. ' var aProc = null;',
  24155. ' var b = false;',
  24156. ' function Sub(vK) {',
  24157. ' var aSub = null;',
  24158. ' function SubSub(vK) {',
  24159. ' var aSubSub = null;',
  24160. ' aProc = $mod.DoIt;',
  24161. ' aSub = $mod.DoIt;',
  24162. ' aSubSub = $mod.DoIt;',
  24163. ' aProc = Sub;',
  24164. ' aSub = Sub;',
  24165. ' aSubSub = Sub;',
  24166. ' aProc = SubSub;',
  24167. ' aSub = SubSub;',
  24168. ' aSubSub = SubSub;',
  24169. ' };',
  24170. ' };',
  24171. ' aProc = Sub;',
  24172. ' b = rtl.eqCallback(aProc, Sub);',
  24173. ' b = rtl.eqCallback(Sub, aProc);',
  24174. '};',
  24175. '']),
  24176. LinesToStr([ // $mod.$main
  24177. '']));
  24178. end;
  24179. procedure TTestModule.TestProcType_NestedOfObject;
  24180. begin
  24181. StartProgram(false);
  24182. Add([
  24183. 'type',
  24184. ' TProcInt = procedure(vI: longint = 1) of object;',
  24185. ' TObject = class',
  24186. ' procedure DoIt(vJ: longint);',
  24187. ' end;',
  24188. 'procedure TObject.DoIt(vJ: longint);',
  24189. 'var aProc: TProcInt;',
  24190. ' b: boolean;',
  24191. ' procedure Sub(vK: longint);',
  24192. ' var aSub: TProcInt;',
  24193. ' procedure SubSub(vK: longint);',
  24194. ' var aSubSub: TProcInt;',
  24195. ' begin;',
  24196. ' aProc:=@DoIt;',
  24197. ' aSub:=@DoIt;',
  24198. ' aSubSub:=@DoIt;',
  24199. ' aProc:=@Sub;',
  24200. ' aSub:=@Sub;',
  24201. ' aSubSub:=@Sub;',
  24202. ' aProc:=@SubSub;',
  24203. ' aSub:=@SubSub;',
  24204. ' aSubSub:=@SubSub;',
  24205. ' end;',
  24206. ' begin;',
  24207. ' end;',
  24208. 'begin;',
  24209. ' aProc:=@Sub;',
  24210. ' b:=aProc=@Sub;',
  24211. ' b:=@Sub=aProc;',
  24212. 'end;',
  24213. 'begin',
  24214. '']);
  24215. ConvertProgram;
  24216. CheckSource('TestProcType_Nested',
  24217. LinesToStr([ // statements
  24218. 'rtl.createClass($mod, "TObject", null, function () {',
  24219. ' this.$init = function () {',
  24220. ' };',
  24221. ' this.$final = function () {',
  24222. ' };',
  24223. ' this.DoIt = function (vJ) {',
  24224. ' var $Self = this;',
  24225. ' var aProc = null;',
  24226. ' var b = false;',
  24227. ' function Sub(vK) {',
  24228. ' var aSub = null;',
  24229. ' function SubSub(vK) {',
  24230. ' var aSubSub = null;',
  24231. ' aProc = rtl.createCallback($Self, "DoIt");',
  24232. ' aSub = rtl.createCallback($Self, "DoIt");',
  24233. ' aSubSub = rtl.createCallback($Self, "DoIt");',
  24234. ' aProc = Sub;',
  24235. ' aSub = Sub;',
  24236. ' aSubSub = Sub;',
  24237. ' aProc = SubSub;',
  24238. ' aSub = SubSub;',
  24239. ' aSubSub = SubSub;',
  24240. ' };',
  24241. ' };',
  24242. ' aProc = Sub;',
  24243. ' b = rtl.eqCallback(aProc, Sub);',
  24244. ' b = rtl.eqCallback(Sub, aProc);',
  24245. ' };',
  24246. '});',
  24247. '']),
  24248. LinesToStr([ // $mod.$main
  24249. '']));
  24250. end;
  24251. procedure TTestModule.TestProcType_ReferenceToProc;
  24252. begin
  24253. StartProgram(false);
  24254. Add([
  24255. 'type',
  24256. ' TProcRef = reference to procedure(i: longint = 0);',
  24257. ' TFuncRef = reference to function(i: longint = 0): longint;',
  24258. 'var',
  24259. ' p: TProcRef;',
  24260. ' f: TFuncRef;',
  24261. 'procedure DoIt(i: longint);',
  24262. 'begin',
  24263. 'end;',
  24264. 'function GetIt(i: longint): longint;',
  24265. 'begin',
  24266. ' p:=@DoIt;',
  24267. ' f:=@GetIt;',
  24268. ' f;',
  24269. ' f();',
  24270. ' f(1);',
  24271. 'end;',
  24272. 'begin',
  24273. ' p:=@DoIt;',
  24274. ' f:=@GetIt;',
  24275. ' f;',
  24276. ' f();',
  24277. ' f(1);',
  24278. ' p:=TProcRef(f);',
  24279. '']);
  24280. ConvertProgram;
  24281. CheckSource('TestProcType_ReferenceToProc',
  24282. LinesToStr([ // statements
  24283. 'this.p = null;',
  24284. 'this.f = null;',
  24285. 'this.DoIt = function (i) {',
  24286. '};',
  24287. 'this.GetIt = function (i) {',
  24288. ' var Result = 0;',
  24289. ' $mod.p = $mod.DoIt;',
  24290. ' $mod.f = $mod.GetIt;',
  24291. ' $mod.f(0);',
  24292. ' $mod.f(0);',
  24293. ' $mod.f(1);',
  24294. ' return Result;',
  24295. '};',
  24296. '']),
  24297. LinesToStr([ // $mod.$main
  24298. '$mod.p = $mod.DoIt;',
  24299. '$mod.f = $mod.GetIt;',
  24300. '$mod.f(0);',
  24301. '$mod.f(0);',
  24302. '$mod.f(1);',
  24303. '$mod.p = $mod.f;',
  24304. '']));
  24305. end;
  24306. procedure TTestModule.TestProcType_ReferenceToMethod;
  24307. begin
  24308. StartProgram(false);
  24309. Add([
  24310. 'type',
  24311. ' TFuncRef = reference to function(i: longint = 5): longint;',
  24312. ' TObject = class',
  24313. ' function Grow(s: longint): longint;',
  24314. ' end;',
  24315. 'var',
  24316. ' f: tfuncref;',
  24317. 'function tobject.grow(s: longint): longint;',
  24318. ' function GrowSub(i: longint): longint;',
  24319. ' begin',
  24320. ' f:=@grow;',
  24321. ' f:=@growsub;',
  24322. ' end;',
  24323. 'begin',
  24324. ' f:=@grow;',
  24325. ' f:=@growsub;',
  24326. 'end;',
  24327. 'begin',
  24328. '']);
  24329. ConvertProgram;
  24330. CheckSource('TestProcType_ReferenceToMethod',
  24331. LinesToStr([ // statements
  24332. 'rtl.createClass($mod, "TObject", null, function () {',
  24333. ' this.$init = function () {',
  24334. ' };',
  24335. ' this.$final = function () {',
  24336. ' };',
  24337. ' this.Grow = function (s) {',
  24338. ' var $Self = this;',
  24339. ' var Result = 0;',
  24340. ' function GrowSub(i) {',
  24341. ' var Result = 0;',
  24342. ' $mod.f = rtl.createCallback($Self, "Grow");',
  24343. ' $mod.f = GrowSub;',
  24344. ' return Result;',
  24345. ' };',
  24346. ' $mod.f = rtl.createCallback($Self, "Grow");',
  24347. ' $mod.f = GrowSub;',
  24348. ' return Result;',
  24349. ' };',
  24350. '});',
  24351. 'this.f = null;',
  24352. '']),
  24353. LinesToStr([ // $mod.$main
  24354. '']));
  24355. end;
  24356. procedure TTestModule.TestProcType_Typecast;
  24357. begin
  24358. StartProgram(false);
  24359. Add([
  24360. 'type',
  24361. ' TNotifyEvent = procedure(Sender: Pointer) of object;',
  24362. ' TEvent = procedure of object;',
  24363. ' TGetter = function:longint of object;',
  24364. ' TProcA = procedure(i: longint);',
  24365. ' TFuncB = function(i, j: longint): longint;',
  24366. 'procedure DoIt(); varargs; begin end;',
  24367. 'var',
  24368. ' Notify: tnotifyevent;',
  24369. ' Event: tevent;',
  24370. ' Getter: tgetter;',
  24371. ' ProcA: tproca;',
  24372. ' FuncB: tfuncb;',
  24373. ' p: pointer;',
  24374. 'begin',
  24375. ' notify:=tnotifyevent(event);',
  24376. ' event:=tevent(event);',
  24377. ' event:=tevent(notify);',
  24378. ' event:=tevent(getter);',
  24379. ' event:=tevent(proca);',
  24380. ' proca:=tproca(funcb);',
  24381. ' funcb:=tfuncb(funcb);',
  24382. ' funcb:=tfuncb(proca);',
  24383. ' funcb:=tfuncb(getter);',
  24384. ' proca:=tproca(p);',
  24385. ' funcb:=tfuncb(p);',
  24386. ' getter:=tgetter(p);',
  24387. ' p:=pointer(notify);',
  24388. ' p:=notify;',
  24389. ' p:=pointer(proca);',
  24390. ' p:=proca;',
  24391. ' p:=pointer(funcb);',
  24392. ' p:=funcb;',
  24393. ' doit(Pointer(notify),pointer(event),pointer(proca));',
  24394. '']);
  24395. ConvertProgram;
  24396. CheckSource('TestProcType_Typecast',
  24397. LinesToStr([ // statements
  24398. 'this.DoIt = function () {',
  24399. '};',
  24400. 'this.Notify = null;',
  24401. 'this.Event = null;',
  24402. 'this.Getter = null;',
  24403. 'this.ProcA = null;',
  24404. 'this.FuncB = null;',
  24405. 'this.p = null;',
  24406. '']),
  24407. LinesToStr([ // $mod.$main
  24408. '$mod.Notify = $mod.Event;',
  24409. '$mod.Event = $mod.Event;',
  24410. '$mod.Event = $mod.Notify;',
  24411. '$mod.Event = $mod.Getter;',
  24412. '$mod.Event = $mod.ProcA;',
  24413. '$mod.ProcA = $mod.FuncB;',
  24414. '$mod.FuncB = $mod.FuncB;',
  24415. '$mod.FuncB = $mod.ProcA;',
  24416. '$mod.FuncB = $mod.Getter;',
  24417. '$mod.ProcA = $mod.p;',
  24418. '$mod.FuncB = $mod.p;',
  24419. '$mod.Getter = $mod.p;',
  24420. '$mod.p = $mod.Notify;',
  24421. '$mod.p = $mod.Notify;',
  24422. '$mod.p = $mod.ProcA;',
  24423. '$mod.p = $mod.ProcA;',
  24424. '$mod.p = $mod.FuncB;',
  24425. '$mod.p = $mod.FuncB;',
  24426. '$mod.DoIt($mod.Notify, $mod.Event, $mod.ProcA);',
  24427. '']));
  24428. end;
  24429. procedure TTestModule.TestProcType_PassProcToUntyped;
  24430. begin
  24431. StartProgram(false);
  24432. Add([
  24433. 'type',
  24434. ' TEvent = procedure of object;',
  24435. ' TFunc = function: longint;',
  24436. 'procedure DoIt(); varargs; begin end;',
  24437. 'procedure DoSome(const a; var b; p: pointer); begin end;',
  24438. 'var',
  24439. ' Event: tevent;',
  24440. ' Func: TFunc;',
  24441. 'begin',
  24442. ' doit(event,func);',
  24443. ' dosome(event,event,event);',
  24444. ' dosome(func,func,func);',
  24445. '']);
  24446. ConvertProgram;
  24447. CheckSource('TestProcType_PassProcToUntyped',
  24448. LinesToStr([ // statements
  24449. 'this.DoIt = function () {',
  24450. '};',
  24451. 'this.DoSome = function (a, b, p) {',
  24452. '};',
  24453. 'this.Event = null;',
  24454. 'this.Func = null;',
  24455. '']),
  24456. LinesToStr([ // $mod.$main
  24457. '$mod.DoIt($mod.Event, $mod.Func);',
  24458. '$mod.DoSome($mod.Event, {',
  24459. ' p: $mod,',
  24460. ' get: function () {',
  24461. ' return this.p.Event;',
  24462. ' },',
  24463. ' set: function (v) {',
  24464. ' this.p.Event = v;',
  24465. ' }',
  24466. '}, $mod.Event);',
  24467. '$mod.DoSome($mod.Func, {',
  24468. ' p: $mod,',
  24469. ' get: function () {',
  24470. ' return this.p.Func;',
  24471. ' },',
  24472. ' set: function (v) {',
  24473. ' this.p.Func = v;',
  24474. ' }',
  24475. '}, $mod.Func);',
  24476. '']));
  24477. end;
  24478. procedure TTestModule.TestProcType_PassProcToArray;
  24479. begin
  24480. StartProgram(false);
  24481. Add([
  24482. 'type',
  24483. ' TFunc = function: longint;',
  24484. ' TArrFunc = array of TFunc;',
  24485. 'procedure DoIt(Arr: TArrFunc); begin end;',
  24486. 'function GetIt: longint; begin end;',
  24487. 'var',
  24488. ' Func: tfunc;',
  24489. 'begin',
  24490. ' doit([]);',
  24491. ' doit([@GetIt]);',
  24492. ' doit([Func]);',
  24493. '']);
  24494. ConvertProgram;
  24495. CheckSource('TestProcType_PassProcToArray',
  24496. LinesToStr([ // statements
  24497. 'this.DoIt = function (Arr) {',
  24498. '};',
  24499. 'this.GetIt = function () {',
  24500. ' var Result = 0;',
  24501. ' return Result;',
  24502. '};',
  24503. 'this.Func = null;',
  24504. '']),
  24505. LinesToStr([ // $mod.$main
  24506. '$mod.DoIt([]);',
  24507. '$mod.DoIt([$mod.GetIt]);',
  24508. '$mod.DoIt([$mod.Func]);',
  24509. '']));
  24510. end;
  24511. procedure TTestModule.TestPointer;
  24512. begin
  24513. StartProgram(false);
  24514. Add(['type',
  24515. ' TObject = class end;',
  24516. ' TClass = class of TObject;',
  24517. ' TArrInt = array of longint;',
  24518. 'const',
  24519. ' n = nil;',
  24520. 'var',
  24521. ' v: jsvalue;',
  24522. ' Obj: tobject;',
  24523. ' C: tclass;',
  24524. ' a: tarrint;',
  24525. ' p: Pointer = nil;',
  24526. ' s: string;',
  24527. 'begin',
  24528. ' p:=p;',
  24529. ' p:=nil;',
  24530. ' if p=nil then;',
  24531. ' if nil=p then;',
  24532. ' if Assigned(p) then;',
  24533. ' p:=Pointer(v);',
  24534. ' p:=obj;',
  24535. ' p:=c;',
  24536. ' p:=a;',
  24537. ' p:=tobject;',
  24538. ' obj:=TObject(p);',
  24539. ' c:=TClass(p);',
  24540. ' a:=TArrInt(p);',
  24541. ' p:=n;',
  24542. ' p:=Pointer(a);',
  24543. ' p:=pointer(s);',
  24544. ' s:=string(p);',
  24545. '']);
  24546. ConvertProgram;
  24547. CheckSource('TestPointer',
  24548. LinesToStr([ // statements
  24549. 'rtl.createClass($mod, "TObject", null, function () {',
  24550. ' this.$init = function () {',
  24551. ' };',
  24552. ' this.$final = function () {',
  24553. ' };',
  24554. '});',
  24555. 'this.n = null;',
  24556. 'this.v = undefined;',
  24557. 'this.Obj = null;',
  24558. 'this.C = null;',
  24559. 'this.a = [];',
  24560. 'this.p = null;',
  24561. 'this.s = "";',
  24562. '']),
  24563. LinesToStr([ // $mod.$main
  24564. '$mod.p = $mod.p;',
  24565. '$mod.p = null;',
  24566. 'if ($mod.p === null) ;',
  24567. 'if (null === $mod.p) ;',
  24568. 'if ($mod.p != null) ;',
  24569. '$mod.p = $mod.v;',
  24570. '$mod.p = $mod.Obj;',
  24571. '$mod.p = $mod.C;',
  24572. '$mod.p = $mod.a;',
  24573. '$mod.p = $mod.TObject;',
  24574. '$mod.Obj = $mod.p;',
  24575. '$mod.C = $mod.p;',
  24576. '$mod.a = $mod.p;',
  24577. '$mod.p = null;',
  24578. '$mod.p = $mod.a;',
  24579. '$mod.p = $mod.s;',
  24580. '$mod.s = $mod.p;',
  24581. '']));
  24582. end;
  24583. procedure TTestModule.TestPointer_Proc;
  24584. begin
  24585. StartProgram(false);
  24586. Add('type');
  24587. Add(' TObject = class');
  24588. Add(' procedure DoIt; virtual; abstract;');
  24589. Add(' end;');
  24590. Add('procedure DoSome; begin end;');
  24591. Add('var');
  24592. Add(' o: TObject;');
  24593. Add(' p: Pointer;');
  24594. Add('begin');
  24595. Add(' p:=@DoSome;');
  24596. Add(' p:[email protected];');
  24597. ConvertProgram;
  24598. CheckSource('TestPointer_Proc',
  24599. LinesToStr([ // statements
  24600. 'rtl.createClass($mod, "TObject", null, function () {',
  24601. ' this.$init = function () {',
  24602. ' };',
  24603. ' this.$final = function () {',
  24604. ' };',
  24605. '});',
  24606. 'this.DoSome = function () {',
  24607. '};',
  24608. 'this.o = null;',
  24609. 'this.p = null;',
  24610. '']),
  24611. LinesToStr([ // $mod.$main
  24612. '$mod.p = $mod.DoSome;',
  24613. '$mod.p = rtl.createCallback($mod.o, "DoIt");',
  24614. '']));
  24615. end;
  24616. procedure TTestModule.TestPointer_AssignRecordFail;
  24617. begin
  24618. StartProgram(false);
  24619. Add('type');
  24620. Add(' TRec = record end;');
  24621. Add('var');
  24622. Add(' p: Pointer;');
  24623. Add(' r: TRec;');
  24624. Add('begin');
  24625. Add(' p:=r;');
  24626. SetExpectedPasResolverError('Incompatible types: got "TRec" expected "Pointer"',
  24627. nIncompatibleTypesGotExpected);
  24628. ConvertProgram;
  24629. end;
  24630. procedure TTestModule.TestPointer_AssignStaticArrayFail;
  24631. begin
  24632. StartProgram(false);
  24633. Add('type');
  24634. Add(' TArr = array[boolean] of longint;');
  24635. Add('var');
  24636. Add(' p: Pointer;');
  24637. Add(' a: TArr;');
  24638. Add('begin');
  24639. Add(' p:=a;');
  24640. SetExpectedPasResolverError('Incompatible types: got "TArr" expected "Pointer"',
  24641. nIncompatibleTypesGotExpected);
  24642. ConvertProgram;
  24643. end;
  24644. procedure TTestModule.TestPointer_TypeCastJSValueToPointer;
  24645. begin
  24646. StartProgram(false);
  24647. Add([
  24648. 'procedure DoIt(args: array of jsvalue); begin end;',
  24649. 'procedure DoAll; varargs; begin end;',
  24650. 'var',
  24651. ' v: jsvalue;',
  24652. 'begin',
  24653. ' DoIt([pointer(v)]);',
  24654. ' DoAll(pointer(v));',
  24655. '']);
  24656. ConvertProgram;
  24657. CheckSource('TestPointer_TypeCastJSValueToPointer',
  24658. LinesToStr([ // statements
  24659. 'this.DoIt = function (args) {',
  24660. '};',
  24661. 'this.DoAll = function () {',
  24662. '};',
  24663. 'this.v = undefined;',
  24664. '']),
  24665. LinesToStr([ // $mod.$main
  24666. '$mod.DoIt([$mod.v]);',
  24667. '$mod.DoAll($mod.v);',
  24668. '']));
  24669. end;
  24670. procedure TTestModule.TestPointer_NonRecordFail;
  24671. begin
  24672. StartProgram(false);
  24673. Add([
  24674. 'type',
  24675. ' p = ^longint;',
  24676. 'begin',
  24677. '']);
  24678. SetExpectedPasResolverError('Not supported: pointer of Longint',nNotSupportedX);
  24679. ConvertProgram;
  24680. end;
  24681. procedure TTestModule.TestPointer_AnonymousArgTypeFail;
  24682. begin
  24683. StartProgram(false);
  24684. Add([
  24685. 'procedure DoIt(p: ^longint); begin end;',
  24686. 'begin',
  24687. '']);
  24688. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  24689. ConvertProgram;
  24690. end;
  24691. procedure TTestModule.TestPointer_AnonymousVarTypeFail;
  24692. begin
  24693. StartProgram(false);
  24694. Add([
  24695. 'var p: ^longint;',
  24696. 'begin',
  24697. '']);
  24698. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  24699. ConvertProgram;
  24700. end;
  24701. procedure TTestModule.TestPointer_AnonymousResultTypeFail;
  24702. begin
  24703. StartProgram(false);
  24704. Add([
  24705. 'function DoIt: ^longint; begin end;',
  24706. 'begin',
  24707. '']);
  24708. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  24709. ConvertProgram;
  24710. end;
  24711. procedure TTestModule.TestPointer_AddrOperatorFail;
  24712. begin
  24713. StartProgram(false);
  24714. Add([
  24715. 'var i: longint;',
  24716. 'begin',
  24717. ' if @i=nil then ;',
  24718. '']);
  24719. SetExpectedConverterError('illegal qualifier "@" in front of "i:Longint"',nIllegalQualifierInFrontOf);
  24720. ConvertProgram;
  24721. end;
  24722. procedure TTestModule.TestPointer_ArrayParamsFail;
  24723. begin
  24724. StartProgram(false);
  24725. Add([
  24726. 'var',
  24727. ' p: Pointer;',
  24728. 'begin',
  24729. ' p:=p[1];',
  24730. '']);
  24731. SetExpectedPasResolverError('illegal qualifier "[" after "Pointer"',nIllegalQualifierAfter);
  24732. ConvertProgram;
  24733. end;
  24734. procedure TTestModule.TestPointer_PointerAddFail;
  24735. begin
  24736. StartProgram(false);
  24737. Add([
  24738. 'var',
  24739. ' p: Pointer;',
  24740. 'begin',
  24741. ' p:=p+1;',
  24742. '']);
  24743. SetExpectedPasResolverError('Operator is not overloaded: "Pointer" + "Longint"',nOperatorIsNotOverloadedAOpB);
  24744. ConvertProgram;
  24745. end;
  24746. procedure TTestModule.TestPointer_IncPointerFail;
  24747. begin
  24748. StartProgram(false);
  24749. Add([
  24750. 'var',
  24751. ' p: Pointer;',
  24752. 'begin',
  24753. ' inc(p,1);',
  24754. '']);
  24755. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Pointer", expected "integer"',
  24756. nIncompatibleTypeArgNo);
  24757. ConvertProgram;
  24758. end;
  24759. procedure TTestModule.TestPointer_Record;
  24760. begin
  24761. StartProgram(false);
  24762. Add([
  24763. 'type',
  24764. ' TRec = record x: longint; end;',
  24765. ' PRec = ^TRec;',
  24766. 'var',
  24767. ' r: TRec;',
  24768. ' p: PRec;',
  24769. ' q: ^TRec;',
  24770. ' Ptr: pointer;',
  24771. 'begin',
  24772. ' new(p);',
  24773. ' p:=@r;',
  24774. ' r:=p^;',
  24775. ' r.x:=p^.x;',
  24776. ' p^.x:=r.x;',
  24777. ' if p^.x=3 then ;',
  24778. ' if 4=p^.x then ;',
  24779. ' dispose(p);',
  24780. ' new(q);',
  24781. ' dispose(q);',
  24782. ' Ptr:=p;',
  24783. ' p:=PRec(ptr);',
  24784. '']);
  24785. ConvertProgram;
  24786. CheckSource('TestPointer_Record',
  24787. LinesToStr([ // statements
  24788. 'rtl.recNewT($mod, "TRec", function () {',
  24789. ' this.x = 0;',
  24790. ' this.$eq = function (b) {',
  24791. ' return this.x === b.x;',
  24792. ' };',
  24793. ' this.$assign = function (s) {',
  24794. ' this.x = s.x;',
  24795. ' return this;',
  24796. ' };',
  24797. '});',
  24798. 'this.r = $mod.TRec.$new();',
  24799. 'this.p = null;',
  24800. 'this.q = null;',
  24801. 'this.Ptr = null;',
  24802. '']),
  24803. LinesToStr([ // $mod.$main
  24804. '$mod.p = $mod.TRec.$new();',
  24805. '$mod.p = $mod.r;',
  24806. '$mod.r.$assign($mod.p);',
  24807. '$mod.r.x = $mod.p.x;',
  24808. '$mod.p.x = $mod.r.x;',
  24809. 'if ($mod.p.x === 3) ;',
  24810. 'if (4 === $mod.p.x) ;',
  24811. '$mod.p = null;',
  24812. '$mod.q = $mod.TRec.$new();',
  24813. '$mod.q = null;',
  24814. '$mod.Ptr = $mod.p;',
  24815. '$mod.p = $mod.Ptr;',
  24816. '']));
  24817. end;
  24818. procedure TTestModule.TestPointer_RecordArg;
  24819. begin
  24820. StartProgram(false);
  24821. Add([
  24822. '{$modeswitch autoderef}',
  24823. 'type',
  24824. ' TRec = record x: longint; end;',
  24825. ' PRec = ^TRec;',
  24826. 'function DoIt(const a: PRec; var b: PRec; out c: PRec): TRec;',
  24827. 'begin',
  24828. ' a.x:=a.x;',
  24829. ' a^.x:=a^.x;',
  24830. ' with a^ do',
  24831. ' x:=x;',
  24832. 'end;',
  24833. 'function GetIt(p: PRec): PRec;',
  24834. 'begin',
  24835. ' p.x:=p.x;',
  24836. ' p^.x:=p^.x;',
  24837. ' with p^ do',
  24838. ' x:=x;',
  24839. 'end;',
  24840. 'var',
  24841. ' r: TRec;',
  24842. ' p: PRec;',
  24843. 'begin',
  24844. ' p:=GetIt(p);',
  24845. ' p^:=GetIt(@r)^;',
  24846. ' DoIt(p,p,p);',
  24847. ' DoIt(@r,p,p);',
  24848. '']);
  24849. ConvertProgram;
  24850. CheckSource('TestPointer_Record',
  24851. LinesToStr([ // statements
  24852. 'rtl.recNewT($mod, "TRec", function () {',
  24853. ' this.x = 0;',
  24854. ' this.$eq = function (b) {',
  24855. ' return this.x === b.x;',
  24856. ' };',
  24857. ' this.$assign = function (s) {',
  24858. ' this.x = s.x;',
  24859. ' return this;',
  24860. ' };',
  24861. '});',
  24862. 'this.DoIt = function (a, b, c) {',
  24863. ' var Result = $mod.TRec.$new();',
  24864. ' a.x = a.x;',
  24865. ' a.x = a.x;',
  24866. ' a.x = a.x;',
  24867. ' return Result;',
  24868. '};',
  24869. 'this.GetIt = function (p) {',
  24870. ' var Result = null;',
  24871. ' p.x = p.x;',
  24872. ' p.x = p.x;',
  24873. ' p.x = p.x;',
  24874. ' return Result;',
  24875. '};',
  24876. 'this.r = $mod.TRec.$new();',
  24877. 'this.p = null;',
  24878. '']),
  24879. LinesToStr([ // $mod.$main
  24880. '$mod.p = $mod.GetIt($mod.p);',
  24881. '$mod.p.$assign($mod.GetIt($mod.r));',
  24882. '$mod.DoIt($mod.p, {',
  24883. ' p: $mod,',
  24884. ' get: function () {',
  24885. ' return this.p.p;',
  24886. ' },',
  24887. ' set: function (v) {',
  24888. ' this.p.p = v;',
  24889. ' }',
  24890. '}, {',
  24891. ' p: $mod,',
  24892. ' get: function () {',
  24893. ' return this.p.p;',
  24894. ' },',
  24895. ' set: function (v) {',
  24896. ' this.p.p = v;',
  24897. ' }',
  24898. '});',
  24899. '$mod.DoIt($mod.r, {',
  24900. ' p: $mod,',
  24901. ' get: function () {',
  24902. ' return this.p.p;',
  24903. ' },',
  24904. ' set: function (v) {',
  24905. ' this.p.p = v;',
  24906. ' }',
  24907. '}, {',
  24908. ' p: $mod,',
  24909. ' get: function () {',
  24910. ' return this.p.p;',
  24911. ' },',
  24912. ' set: function (v) {',
  24913. ' this.p.p = v;',
  24914. ' }',
  24915. '});',
  24916. '']));
  24917. end;
  24918. procedure TTestModule.TestJSValue_AssignToJSValue;
  24919. begin
  24920. StartProgram(false);
  24921. Add('var');
  24922. Add(' v: jsvalue;');
  24923. Add(' i: longint;');
  24924. Add(' s: string;');
  24925. Add(' b: boolean;');
  24926. Add(' d: double;');
  24927. Add(' p: pointer;');
  24928. Add('begin');
  24929. Add(' v:=v;');
  24930. Add(' v:=1;');
  24931. Add(' v:=i;');
  24932. Add(' v:='''';');
  24933. Add(' v:=''c'';');
  24934. Add(' v:=''foo'';');
  24935. Add(' v:=s;');
  24936. Add(' v:=false;');
  24937. Add(' v:=true;');
  24938. Add(' v:=b;');
  24939. Add(' v:=0.1;');
  24940. Add(' v:=d;');
  24941. Add(' v:=nil;');
  24942. Add(' v:=p;');
  24943. ConvertProgram;
  24944. CheckSource('TestJSValue_AssignToJSValue',
  24945. LinesToStr([ // statements
  24946. 'this.v = undefined;',
  24947. 'this.i = 0;',
  24948. 'this.s = "";',
  24949. 'this.b = false;',
  24950. 'this.d = 0.0;',
  24951. 'this.p = null;',
  24952. '']),
  24953. LinesToStr([ // $mod.$main
  24954. '$mod.v = $mod.v;',
  24955. '$mod.v = 1;',
  24956. '$mod.v = $mod.i;',
  24957. '$mod.v = "";',
  24958. '$mod.v = "c";',
  24959. '$mod.v = "foo";',
  24960. '$mod.v = $mod.s;',
  24961. '$mod.v = false;',
  24962. '$mod.v = true;',
  24963. '$mod.v = $mod.b;',
  24964. '$mod.v = 0.1;',
  24965. '$mod.v = $mod.d;',
  24966. '$mod.v = null;',
  24967. '$mod.v = $mod.p;',
  24968. '']));
  24969. end;
  24970. procedure TTestModule.TestJSValue_TypeCastToBaseType;
  24971. begin
  24972. StartProgram(false);
  24973. Add('type');
  24974. Add(' integer = longint;');
  24975. Add(' TYesNo = boolean;');
  24976. Add(' TFloat = double;');
  24977. Add(' TCaption = string;');
  24978. Add(' TChar = char;');
  24979. Add('var');
  24980. Add(' v: jsvalue;');
  24981. Add(' i: integer;');
  24982. Add(' s: TCaption;');
  24983. Add(' b: TYesNo;');
  24984. Add(' d: TFloat;');
  24985. Add(' c: char;');
  24986. Add('begin');
  24987. Add(' i:=longint(v);');
  24988. Add(' i:=integer(v);');
  24989. Add(' s:=string(v);');
  24990. Add(' s:=TCaption(v);');
  24991. Add(' b:=boolean(v);');
  24992. Add(' b:=TYesNo(v);');
  24993. Add(' d:=double(v);');
  24994. Add(' d:=TFloat(v);');
  24995. Add(' c:=char(v);');
  24996. Add(' c:=TChar(v);');
  24997. ConvertProgram;
  24998. CheckSource('TestJSValue_TypeCastToBaseType',
  24999. LinesToStr([ // statements
  25000. 'this.v = undefined;',
  25001. 'this.i = 0;',
  25002. 'this.s = "";',
  25003. 'this.b = false;',
  25004. 'this.d = 0.0;',
  25005. 'this.c = "";',
  25006. '']),
  25007. LinesToStr([ // $mod.$main
  25008. '$mod.i = Math.floor($mod.v);',
  25009. '$mod.i = Math.floor($mod.v);',
  25010. '$mod.s = "" + $mod.v;',
  25011. '$mod.s = "" + $mod.v;',
  25012. '$mod.b = !($mod.v == false);',
  25013. '$mod.b = !($mod.v == false);',
  25014. '$mod.d = rtl.getNumber($mod.v);',
  25015. '$mod.d = rtl.getNumber($mod.v);',
  25016. '$mod.c = rtl.getChar($mod.v);',
  25017. '$mod.c = rtl.getChar($mod.v);',
  25018. '']));
  25019. end;
  25020. procedure TTestModule.TestJSValue_TypecastToJSValue;
  25021. begin
  25022. StartProgram(false);
  25023. Add([
  25024. 'type',
  25025. ' TArr = array of word;',
  25026. ' TRec = record end;',
  25027. ' TSet = set of boolean;',
  25028. 'procedure Fly(v: jsvalue);',
  25029. 'begin',
  25030. 'end;',
  25031. 'var',
  25032. ' a: TArr;',
  25033. ' r: TRec;',
  25034. ' s: TSet;',
  25035. 'begin',
  25036. ' Fly(jsvalue(a));',
  25037. ' Fly(jsvalue(r));',
  25038. ' Fly(jsvalue(s));',
  25039. '']);
  25040. ConvertProgram;
  25041. CheckSource('TestJSValue_TypecastToJSValue',
  25042. LinesToStr([ // statements
  25043. 'rtl.recNewT($mod, "TRec", function () {',
  25044. ' this.$eq = function (b) {',
  25045. ' return true;',
  25046. ' };',
  25047. ' this.$assign = function (s) {',
  25048. ' return this;',
  25049. ' };',
  25050. '});',
  25051. 'this.Fly = function (v) {',
  25052. '};',
  25053. 'this.a = [];',
  25054. 'this.r = $mod.TRec.$new();',
  25055. 'this.s = {};',
  25056. '']),
  25057. LinesToStr([ // $mod.$main
  25058. '$mod.Fly($mod.a);',
  25059. '$mod.Fly($mod.r);',
  25060. '$mod.Fly($mod.s);',
  25061. '']));
  25062. end;
  25063. procedure TTestModule.TestJSValue_Equal;
  25064. begin
  25065. StartProgram(false);
  25066. Add('type');
  25067. Add(' integer = longint;');
  25068. Add(' TYesNo = boolean;');
  25069. Add(' TFloat = double;');
  25070. Add(' TCaption = string;');
  25071. Add(' TChar = char;');
  25072. Add(' TMulti = JSValue;');
  25073. Add('var');
  25074. Add(' v: jsvalue;');
  25075. Add(' i: integer;');
  25076. Add(' s: TCaption;');
  25077. Add(' b: TYesNo;');
  25078. Add(' d: TFloat;');
  25079. Add(' c: char;');
  25080. Add(' m: TMulti;');
  25081. Add('begin');
  25082. Add(' b:=v=v;');
  25083. Add(' b:=v<>v;');
  25084. Add(' b:=v=1;');
  25085. Add(' b:=v<>1;');
  25086. Add(' b:=2=v;');
  25087. Add(' b:=2<>v;');
  25088. Add(' b:=v=i;');
  25089. Add(' b:=i=v;');
  25090. Add(' b:=v=nil;');
  25091. Add(' b:=nil=v;');
  25092. Add(' b:=v=false;');
  25093. Add(' b:=true=v;');
  25094. Add(' b:=v=b;');
  25095. Add(' b:=b=v;');
  25096. Add(' b:=v=s;');
  25097. Add(' b:=s=v;');
  25098. Add(' b:=v=''foo'';');
  25099. Add(' b:=''''=v;');
  25100. Add(' b:=v=d;');
  25101. Add(' b:=d=v;');
  25102. Add(' b:=v=3.4;');
  25103. Add(' b:=5.6=v;');
  25104. Add(' b:=v=c;');
  25105. Add(' b:=c=v;');
  25106. Add(' b:=m=m;');
  25107. Add(' b:=v=m;');
  25108. Add(' b:=m=v;');
  25109. ConvertProgram;
  25110. CheckSource('TestJSValue_Equal',
  25111. LinesToStr([ // statements
  25112. 'this.v = undefined;',
  25113. 'this.i = 0;',
  25114. 'this.s = "";',
  25115. 'this.b = false;',
  25116. 'this.d = 0.0;',
  25117. 'this.c = "";',
  25118. 'this.m = undefined;',
  25119. '']),
  25120. LinesToStr([ // $mod.$main
  25121. '$mod.b = $mod.v == $mod.v;',
  25122. '$mod.b = $mod.v != $mod.v;',
  25123. '$mod.b = $mod.v == 1;',
  25124. '$mod.b = $mod.v != 1;',
  25125. '$mod.b = 2 == $mod.v;',
  25126. '$mod.b = 2 != $mod.v;',
  25127. '$mod.b = $mod.v == $mod.i;',
  25128. '$mod.b = $mod.i == $mod.v;',
  25129. '$mod.b = $mod.v == null;',
  25130. '$mod.b = null == $mod.v;',
  25131. '$mod.b = $mod.v == false;',
  25132. '$mod.b = true == $mod.v;',
  25133. '$mod.b = $mod.v == $mod.b;',
  25134. '$mod.b = $mod.b == $mod.v;',
  25135. '$mod.b = $mod.v == $mod.s;',
  25136. '$mod.b = $mod.s == $mod.v;',
  25137. '$mod.b = $mod.v == "foo";',
  25138. '$mod.b = "" == $mod.v;',
  25139. '$mod.b = $mod.v == $mod.d;',
  25140. '$mod.b = $mod.d == $mod.v;',
  25141. '$mod.b = $mod.v == 3.4;',
  25142. '$mod.b = 5.6 == $mod.v;',
  25143. '$mod.b = $mod.v == $mod.c;',
  25144. '$mod.b = $mod.c == $mod.v;',
  25145. '$mod.b = $mod.m == $mod.m;',
  25146. '$mod.b = $mod.v == $mod.m;',
  25147. '$mod.b = $mod.m == $mod.v;',
  25148. '']));
  25149. end;
  25150. procedure TTestModule.TestJSValue_If;
  25151. begin
  25152. StartProgram(false);
  25153. Add([
  25154. 'var',
  25155. ' v: jsvalue;',
  25156. 'begin',
  25157. ' if v then ;',
  25158. ' while v do ;',
  25159. ' repeat until v;',
  25160. '']);
  25161. ConvertProgram;
  25162. CheckSource('TestJSValue_If',
  25163. LinesToStr([ // statements
  25164. 'this.v = undefined;',
  25165. '']),
  25166. LinesToStr([ // $mod.$main
  25167. 'if ($mod.v) ;',
  25168. 'while($mod.v){',
  25169. '};',
  25170. 'do{',
  25171. '} while(!$mod.v);',
  25172. '']));
  25173. end;
  25174. procedure TTestModule.TestJSValue_Not;
  25175. begin
  25176. StartProgram(false);
  25177. Add([
  25178. 'var',
  25179. ' v: jsvalue;',
  25180. ' b: boolean;',
  25181. 'begin',
  25182. ' b:=not v;',
  25183. ' if not v then ;',
  25184. ' while not v do ;',
  25185. ' repeat until not v;',
  25186. '']);
  25187. ConvertProgram;
  25188. CheckSource('TestJSValue_If',
  25189. LinesToStr([ // statements
  25190. 'this.v = undefined;',
  25191. 'this.b = false;',
  25192. '']),
  25193. LinesToStr([ // $mod.$main
  25194. '$mod.b=!$mod.v;',
  25195. 'if (!$mod.v) ;',
  25196. 'while(!$mod.v){',
  25197. '};',
  25198. 'do{',
  25199. '} while($mod.v);',
  25200. '']));
  25201. end;
  25202. procedure TTestModule.TestJSValue_Enum;
  25203. begin
  25204. StartProgram(false);
  25205. Add('type');
  25206. Add(' TColor = (red, blue);');
  25207. Add(' TRedBlue = TColor;');
  25208. Add('var');
  25209. Add(' v: jsvalue;');
  25210. Add(' e: TColor;');
  25211. Add('begin');
  25212. Add(' v:=e;');
  25213. Add(' v:=TColor(e);');
  25214. Add(' v:=TRedBlue(e);');
  25215. Add(' e:=TColor(v);');
  25216. Add(' e:=TRedBlue(v);');
  25217. ConvertProgram;
  25218. CheckSource('TestJSValue_Enum',
  25219. LinesToStr([ // statements
  25220. 'this.TColor = {',
  25221. ' "0": "red",',
  25222. ' red: 0,',
  25223. ' "1": "blue",',
  25224. ' blue: 1',
  25225. '};',
  25226. 'this.v = undefined;',
  25227. 'this.e = 0;',
  25228. '']),
  25229. LinesToStr([ // $mod.$main
  25230. '$mod.v = $mod.e;',
  25231. '$mod.v = $mod.e;',
  25232. '$mod.v = $mod.e;',
  25233. '$mod.e = $mod.v;',
  25234. '$mod.e = $mod.v;',
  25235. '']));
  25236. end;
  25237. procedure TTestModule.TestJSValue_ClassInstance;
  25238. begin
  25239. StartProgram(false);
  25240. Add([
  25241. 'type',
  25242. ' TObject = class',
  25243. ' end;',
  25244. ' TBirdObject = TObject;',
  25245. 'var',
  25246. ' v: jsvalue;',
  25247. ' o: TObject;',
  25248. 'begin',
  25249. ' v:=o;',
  25250. ' v:=TObject(o);',
  25251. ' v:=TBirdObject(o);',
  25252. ' o:=TObject(v);',
  25253. ' o:=TBirdObject(v);',
  25254. ' if v is TObject then ;',
  25255. '']);
  25256. ConvertProgram;
  25257. CheckSource('TestJSValue_ClassInstance',
  25258. LinesToStr([ // statements
  25259. 'rtl.createClass($mod, "TObject", null, function () {',
  25260. ' this.$init = function () {',
  25261. ' };',
  25262. ' this.$final = function () {',
  25263. ' };',
  25264. '});',
  25265. 'this.v = undefined;',
  25266. 'this.o = null;',
  25267. '']),
  25268. LinesToStr([ // $mod.$main
  25269. '$mod.v = $mod.o;',
  25270. '$mod.v = $mod.o;',
  25271. '$mod.v = $mod.o;',
  25272. '$mod.o = rtl.getObject($mod.v);',
  25273. '$mod.o = rtl.getObject($mod.v);',
  25274. 'if (rtl.isExt($mod.v, $mod.TObject, 1)) ;',
  25275. '']));
  25276. end;
  25277. procedure TTestModule.TestJSValue_ClassOf;
  25278. begin
  25279. StartProgram(false);
  25280. Add([
  25281. 'type',
  25282. ' TClass = class of TObject;',
  25283. ' TObject = class',
  25284. ' end;',
  25285. ' TBirds = class of TBird;',
  25286. ' TBird = class(TObject) end;',
  25287. 'var',
  25288. ' v: jsvalue;',
  25289. ' c: TClass;',
  25290. 'begin',
  25291. ' v:=c;',
  25292. ' v:=TObject;',
  25293. ' v:=TClass(c);',
  25294. ' v:=TBirds(c);',
  25295. ' c:=TClass(v);',
  25296. ' c:=TBirds(v);',
  25297. ' if v is TClass then ;',
  25298. '']);
  25299. ConvertProgram;
  25300. CheckSource('TestJSValue_ClassOf',
  25301. LinesToStr([ // statements
  25302. 'rtl.createClass($mod, "TObject", null, function () {',
  25303. ' this.$init = function () {',
  25304. ' };',
  25305. ' this.$final = function () {',
  25306. ' };',
  25307. '});',
  25308. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  25309. '});',
  25310. 'this.v = undefined;',
  25311. 'this.c = null;',
  25312. '']),
  25313. LinesToStr([ // $mod.$main
  25314. '$mod.v = $mod.c;',
  25315. '$mod.v = $mod.TObject;',
  25316. '$mod.v = $mod.c;',
  25317. '$mod.v = $mod.c;',
  25318. '$mod.c = rtl.getObject($mod.v);',
  25319. '$mod.c = rtl.getObject($mod.v);',
  25320. 'if (rtl.isExt($mod.v, $mod.TObject, 2)) ;',
  25321. '']));
  25322. end;
  25323. procedure TTestModule.TestJSValue_ArrayOfJSValue;
  25324. begin
  25325. StartProgram(false);
  25326. Add([
  25327. 'type',
  25328. ' integer = longint;',
  25329. ' TArray = array of JSValue;',
  25330. ' TArrgh = tarray;',
  25331. ' TArrInt = array of integer;',
  25332. 'var',
  25333. ' v: jsvalue;',
  25334. ' TheArray: tarray = (1,''2'');',
  25335. ' Arr: tarrgh;',
  25336. ' i: integer;',
  25337. ' ArrInt: tarrint;',
  25338. 'begin',
  25339. ' arr:=thearray;',
  25340. ' thearray:=arr;',
  25341. ' setlength(arr,2);',
  25342. ' setlength(thearray,3);',
  25343. ' arr[4]:=v;',
  25344. ' arr[5]:=length(thearray);',
  25345. ' arr[6]:=nil;',
  25346. ' arr[7]:=thearray[8];',
  25347. ' arr[low(arr)]:=high(thearray);',
  25348. ' arr:=arrint;',
  25349. ' arrInt:=tarrint(arr);',
  25350. ' if TheArray = nil then ;',
  25351. ' if nil = TheArray then ;',
  25352. ' if TheArray <> nil then ;',
  25353. ' if nil <> TheArray then ;',
  25354. '']);
  25355. ConvertProgram;
  25356. CheckSource('TestJSValue_ArrayOfJSValue',
  25357. LinesToStr([ // statements
  25358. 'this.v = undefined;',
  25359. 'this.TheArray = [1, "2"];',
  25360. 'this.Arr = [];',
  25361. 'this.i = 0;',
  25362. 'this.ArrInt = [];',
  25363. '']),
  25364. LinesToStr([ // $mod.$main
  25365. '$mod.Arr = $mod.TheArray;',
  25366. '$mod.TheArray = $mod.Arr;',
  25367. '$mod.Arr = rtl.arraySetLength($mod.Arr,undefined,2);',
  25368. '$mod.TheArray = rtl.arraySetLength($mod.TheArray,undefined,3);',
  25369. '$mod.Arr[4] = $mod.v;',
  25370. '$mod.Arr[5] = rtl.length($mod.TheArray);',
  25371. '$mod.Arr[6] = null;',
  25372. '$mod.Arr[7] = $mod.TheArray[8];',
  25373. '$mod.Arr[0] = rtl.length($mod.TheArray) - 1;',
  25374. '$mod.Arr = $mod.ArrInt;',
  25375. '$mod.ArrInt = $mod.Arr;',
  25376. 'if (rtl.length($mod.TheArray) === 0) ;',
  25377. 'if (rtl.length($mod.TheArray) === 0) ;',
  25378. 'if (rtl.length($mod.TheArray) > 0) ;',
  25379. 'if (rtl.length($mod.TheArray) > 0) ;',
  25380. '']));
  25381. end;
  25382. procedure TTestModule.TestJSValue_ArrayLit;
  25383. begin
  25384. StartProgram(false);
  25385. Add([
  25386. 'type',
  25387. ' TFlag = (big,small);',
  25388. ' TArray = array of JSValue;',
  25389. ' TObject = class end;',
  25390. ' TClass = class of TObject;',
  25391. 'var',
  25392. ' v: jsvalue;',
  25393. ' a: TArray;',
  25394. ' o: TObject;',
  25395. 'begin',
  25396. ' a:=[];',
  25397. ' a:=[1];',
  25398. ' a:=[1,2];',
  25399. ' a:=[big];',
  25400. ' a:=[1,big];',
  25401. ' a:=[o,nil];',
  25402. '']);
  25403. ConvertProgram;
  25404. CheckSource('TestJSValue_ArrayLit',
  25405. LinesToStr([ // statements
  25406. 'this.TFlag = {',
  25407. ' "0": "big",',
  25408. ' big: 0,',
  25409. ' "1": "small",',
  25410. ' small: 1',
  25411. '};',
  25412. 'rtl.createClass($mod, "TObject", null, function () {',
  25413. ' this.$init = function () {',
  25414. ' };',
  25415. ' this.$final = function () {',
  25416. ' };',
  25417. '});',
  25418. 'this.v = undefined;',
  25419. 'this.a = [];',
  25420. 'this.o = null;',
  25421. '']),
  25422. LinesToStr([ // $mod.$main
  25423. '$mod.a = [];',
  25424. '$mod.a = [1];',
  25425. '$mod.a = [1, 2];',
  25426. '$mod.a = [$mod.TFlag.big];',
  25427. '$mod.a = [1, $mod.TFlag.big];',
  25428. '$mod.a = [$mod.o, null];',
  25429. '']));
  25430. end;
  25431. procedure TTestModule.TestJSValue_Params;
  25432. begin
  25433. StartProgram(false);
  25434. Add('type');
  25435. Add(' integer = longint;');
  25436. Add(' TYesNo = boolean;');
  25437. Add(' TFloat = double;');
  25438. Add(' TCaption = string;');
  25439. Add(' TChar = char;');
  25440. Add('function DoIt(a: jsvalue; const b: jsvalue; var c: jsvalue; out d: jsvalue): jsvalue;');
  25441. Add('var');
  25442. Add(' l: jsvalue;');
  25443. Add('begin');
  25444. Add(' a:=a;');
  25445. Add(' l:=b;');
  25446. Add(' c:=c;');
  25447. Add(' d:=d;');
  25448. Add(' Result:=l;');
  25449. Add('end;');
  25450. Add('function DoSome(a: jsvalue; const b: jsvalue): jsvalue; begin end;');
  25451. Add('var');
  25452. Add(' v: jsvalue;');
  25453. Add(' i: integer;');
  25454. Add(' b: TYesNo;');
  25455. Add(' d: TFloat;');
  25456. Add(' s: TCaption;');
  25457. Add(' c: TChar;');
  25458. Add('begin');
  25459. Add(' v:=doit(v,v,v,v);');
  25460. Add(' i:=integer(dosome(i,i));');
  25461. Add(' b:=TYesNo(dosome(b,b));');
  25462. Add(' d:=TFloat(dosome(d,d));');
  25463. Add(' s:=TCaption(dosome(s,s));');
  25464. Add(' c:=TChar(dosome(c,c));');
  25465. ConvertProgram;
  25466. CheckSource('TestJSValue_Params',
  25467. LinesToStr([ // statements
  25468. 'this.DoIt = function (a, b, c, d) {',
  25469. ' var Result = undefined;',
  25470. ' var l = undefined;',
  25471. ' a = a;',
  25472. ' l = b;',
  25473. ' c.set(c.get());',
  25474. ' d.set(d.get());',
  25475. ' Result = l;',
  25476. ' return Result;',
  25477. '};',
  25478. 'this.DoSome = function (a, b) {',
  25479. ' var Result = undefined;',
  25480. ' return Result;',
  25481. '};',
  25482. 'this.v = undefined;',
  25483. 'this.i = 0;',
  25484. 'this.b = false;',
  25485. 'this.d = 0.0;',
  25486. 'this.s = "";',
  25487. 'this.c = "";',
  25488. '']),
  25489. LinesToStr([ // $mod.$main
  25490. '$mod.v = $mod.DoIt($mod.v, $mod.v, {',
  25491. ' p: $mod,',
  25492. ' get: function () {',
  25493. ' return this.p.v;',
  25494. ' },',
  25495. ' set: function (v) {',
  25496. ' this.p.v = v;',
  25497. ' }',
  25498. '}, {',
  25499. ' p: $mod,',
  25500. ' get: function () {',
  25501. ' return this.p.v;',
  25502. ' },',
  25503. ' set: function (v) {',
  25504. ' this.p.v = v;',
  25505. ' }',
  25506. '});',
  25507. '$mod.i = Math.floor($mod.DoSome($mod.i, $mod.i));',
  25508. '$mod.b = !($mod.DoSome($mod.b, $mod.b) == false);',
  25509. '$mod.d = rtl.getNumber($mod.DoSome($mod.d, $mod.d));',
  25510. '$mod.s = "" + $mod.DoSome($mod.s, $mod.s);',
  25511. '$mod.c = rtl.getChar($mod.DoSome($mod.c, $mod.c));',
  25512. '']));
  25513. end;
  25514. procedure TTestModule.TestJSValue_UntypedParam;
  25515. begin
  25516. StartProgram(false);
  25517. Add('function DoIt(const a; var b; out c): jsvalue;');
  25518. Add('begin');
  25519. Add(' Result:=a;');
  25520. Add(' Result:=b;');
  25521. Add(' Result:=c;');
  25522. Add(' b:=Result;');
  25523. Add(' c:=Result;');
  25524. Add('end;');
  25525. Add('var i: longint;');
  25526. Add('begin');
  25527. Add(' doit(i,i,i);');
  25528. ConvertProgram;
  25529. CheckSource('TestJSValue_UntypedParam',
  25530. LinesToStr([ // statements
  25531. 'this.DoIt = function (a, b, c) {',
  25532. ' var Result = undefined;',
  25533. ' Result = a;',
  25534. ' Result = b.get();',
  25535. ' Result = c.get();',
  25536. ' b.set(Result);',
  25537. ' c.set(Result);',
  25538. ' return Result;',
  25539. '};',
  25540. 'this.i = 0;',
  25541. '']),
  25542. LinesToStr([ // $mod.$main
  25543. '$mod.DoIt($mod.i, {',
  25544. ' p: $mod,',
  25545. ' get: function () {',
  25546. ' return this.p.i;',
  25547. ' },',
  25548. ' set: function (v) {',
  25549. ' this.p.i = v;',
  25550. ' }',
  25551. '}, {',
  25552. ' p: $mod,',
  25553. ' get: function () {',
  25554. ' return this.p.i;',
  25555. ' },',
  25556. ' set: function (v) {',
  25557. ' this.p.i = v;',
  25558. ' }',
  25559. '});',
  25560. '']));
  25561. end;
  25562. procedure TTestModule.TestJSValue_FuncResultType;
  25563. begin
  25564. StartProgram(false);
  25565. Add('type');
  25566. Add(' integer = longint;');
  25567. Add(' TJSValueArray = array of JSValue;');
  25568. Add(' TListSortCompare = function(Item1, Item2: JSValue): Integer;');
  25569. Add('procedure Sort(P: JSValue; aList: TJSValueArray; const Compare: TListSortCompare);');
  25570. Add('begin');
  25571. Add(' while Compare(P,aList[0])>0 do ;');
  25572. Add('end;');
  25573. Add('var');
  25574. Add(' Compare: TListSortCompare;');
  25575. Add(' V: JSValue;');
  25576. Add(' i: integer;');
  25577. Add('begin');
  25578. Add(' if Compare(V,V)>0 then ;');
  25579. Add(' if Compare(i,i)>1 then ;');
  25580. Add(' if Compare(nil,false)>2 then ;');
  25581. Add(' if Compare(1,true)>3 then ;');
  25582. ConvertProgram;
  25583. CheckSource('TestJSValue_UntypedParam',
  25584. LinesToStr([ // statements
  25585. 'this.Sort = function (P, aList, Compare) {',
  25586. ' while (Compare(P, aList[0]) > 0) {',
  25587. ' };',
  25588. '};',
  25589. 'this.Compare = null;',
  25590. 'this.V = undefined;',
  25591. 'this.i = 0;',
  25592. '']),
  25593. LinesToStr([ // $mod.$main
  25594. 'if ($mod.Compare($mod.V, $mod.V) > 0) ;',
  25595. 'if ($mod.Compare($mod.i, $mod.i) > 1) ;',
  25596. 'if ($mod.Compare(null, false) > 2) ;',
  25597. 'if ($mod.Compare(1, true) > 3) ;',
  25598. '']));
  25599. end;
  25600. procedure TTestModule.TestJSValue_ProcType_Assign;
  25601. begin
  25602. StartProgram(false);
  25603. Add('type');
  25604. Add(' integer = longint;');
  25605. Add(' TObject = class');
  25606. Add(' class function GetGlob: integer;');
  25607. Add(' function Getter: integer;');
  25608. Add(' end;');
  25609. Add('class function TObject.GetGlob: integer;');
  25610. Add('var v1: jsvalue;');
  25611. Add('begin');
  25612. Add(' v1:=@GetGlob;');
  25613. Add(' v1:[email protected];');
  25614. Add('end;');
  25615. Add('function TObject.Getter: integer;');
  25616. Add('var v2: jsvalue;');
  25617. Add('begin');
  25618. Add(' v2:=@Getter;');
  25619. Add(' v2:[email protected];');
  25620. Add(' v2:=@GetGlob;');
  25621. Add(' v2:[email protected];');
  25622. Add('end;');
  25623. Add('function GetIt(i: integer): integer;');
  25624. Add('var v3: jsvalue;');
  25625. Add('begin');
  25626. Add(' v3:=@GetIt;');
  25627. Add('end;');
  25628. Add('var');
  25629. Add(' V: JSValue;');
  25630. Add(' o: TObject;');
  25631. Add('begin');
  25632. Add(' v:=@GetIt;');
  25633. Add(' v:[email protected];');
  25634. Add(' v:[email protected];');
  25635. ConvertProgram;
  25636. CheckSource('TestJSValue_ProcType_Assign',
  25637. LinesToStr([ // statements
  25638. 'rtl.createClass($mod, "TObject", null, function () {',
  25639. ' this.$init = function () {',
  25640. ' };',
  25641. ' this.$final = function () {',
  25642. ' };',
  25643. ' this.GetGlob = function () {',
  25644. ' var Result = 0;',
  25645. ' var v1 = undefined;',
  25646. ' v1 = rtl.createCallback(this, "GetGlob");',
  25647. ' v1 = rtl.createCallback(this, "GetGlob");',
  25648. ' return Result;',
  25649. ' };',
  25650. ' this.Getter = function () {',
  25651. ' var Result = 0;',
  25652. ' var v2 = undefined;',
  25653. ' v2 = rtl.createCallback(this, "Getter");',
  25654. ' v2 = rtl.createCallback(this, "Getter");',
  25655. ' v2 = rtl.createCallback(this.$class, "GetGlob");',
  25656. ' v2 = rtl.createCallback(this.$class, "GetGlob");',
  25657. ' return Result;',
  25658. ' };',
  25659. '});',
  25660. 'this.GetIt = function (i) {',
  25661. ' var Result = 0;',
  25662. ' var v3 = undefined;',
  25663. ' v3 = $mod.GetIt;',
  25664. ' return Result;',
  25665. '};',
  25666. 'this.V = undefined;',
  25667. 'this.o = null;',
  25668. '']),
  25669. LinesToStr([ // $mod.$main
  25670. '$mod.V = $mod.GetIt;',
  25671. '$mod.V = rtl.createCallback($mod.o, "Getter");',
  25672. '$mod.V = rtl.createCallback($mod.o.$class, "GetGlob");',
  25673. '']));
  25674. end;
  25675. procedure TTestModule.TestJSValue_ProcType_Equal;
  25676. begin
  25677. StartProgram(false);
  25678. Add('type');
  25679. Add(' integer = longint;');
  25680. Add(' TObject = class');
  25681. Add(' class function GetGlob: integer;');
  25682. Add(' function Getter: integer;');
  25683. Add(' end;');
  25684. Add('class function TObject.GetGlob: integer;');
  25685. Add('var v1: jsvalue;');
  25686. Add('begin');
  25687. Add(' if v1=@GetGlob then;');
  25688. Add(' if [email protected] then ;');
  25689. Add('end;');
  25690. Add('function TObject.Getter: integer;');
  25691. Add('var v2: jsvalue;');
  25692. Add('begin');
  25693. Add(' if v2=@Getter then;');
  25694. Add(' if [email protected] then ;');
  25695. Add(' if v2=@GetGlob then;');
  25696. Add(' if [email protected] then;');
  25697. Add('end;');
  25698. Add('function GetIt(i: integer): integer;');
  25699. Add('var v3: jsvalue;');
  25700. Add('begin');
  25701. Add(' if v3=@GetIt then;');
  25702. Add('end;');
  25703. Add('var');
  25704. Add(' V: JSValue;');
  25705. Add(' o: TObject;');
  25706. Add('begin');
  25707. Add(' if v=@GetIt then;');
  25708. Add(' if [email protected] then;');
  25709. Add(' if [email protected] then;');
  25710. Add(' if @GetIt=v then;');
  25711. Add(' if @o.Getter=v then;');
  25712. Add(' if @o.GetGlob=v then;');
  25713. ConvertProgram;
  25714. CheckSource('TestJSValue_ProcType_Equal',
  25715. LinesToStr([ // statements
  25716. 'rtl.createClass($mod, "TObject", null, function () {',
  25717. ' this.$init = function () {',
  25718. ' };',
  25719. ' this.$final = function () {',
  25720. ' };',
  25721. ' this.GetGlob = function () {',
  25722. ' var Result = 0;',
  25723. ' var v1 = undefined;',
  25724. ' if (rtl.eqCallback(v1, rtl.createCallback(this, "GetGlob"))) ;',
  25725. ' if (rtl.eqCallback(v1, rtl.createCallback(this, "GetGlob"))) ;',
  25726. ' return Result;',
  25727. ' };',
  25728. ' this.Getter = function () {',
  25729. ' var Result = 0;',
  25730. ' var v2 = undefined;',
  25731. ' if (rtl.eqCallback(v2, rtl.createCallback(this, "Getter"))) ;',
  25732. ' if (rtl.eqCallback(v2, rtl.createCallback(this, "Getter"))) ;',
  25733. ' if (rtl.eqCallback(v2, rtl.createCallback(this.$class, "GetGlob"))) ;',
  25734. ' if (rtl.eqCallback(v2, rtl.createCallback(this.$class, "GetGlob"))) ;',
  25735. ' return Result;',
  25736. ' };',
  25737. '});',
  25738. 'this.GetIt = function (i) {',
  25739. ' var Result = 0;',
  25740. ' var v3 = undefined;',
  25741. ' if (rtl.eqCallback(v3, $mod.GetIt)) ;',
  25742. ' return Result;',
  25743. '};',
  25744. 'this.V = undefined;',
  25745. 'this.o = null;',
  25746. '']),
  25747. LinesToStr([ // $mod.$main
  25748. 'if (rtl.eqCallback($mod.V, $mod.GetIt)) ;',
  25749. 'if (rtl.eqCallback($mod.V, rtl.createCallback($mod.o, "Getter"))) ;',
  25750. 'if (rtl.eqCallback($mod.V, rtl.createCallback($mod.o.$class, "GetGlob"))) ;',
  25751. 'if (rtl.eqCallback($mod.GetIt, $mod.V)) ;',
  25752. 'if (rtl.eqCallback(rtl.createCallback($mod.o, "Getter"), $mod.V)) ;',
  25753. 'if (rtl.eqCallback(rtl.createCallback($mod.o.$class, "GetGlob"), $mod.V)) ;',
  25754. '']));
  25755. end;
  25756. procedure TTestModule.TestJSValue_ProcType_Param;
  25757. begin
  25758. StartProgram(false);
  25759. Add([
  25760. 'type',
  25761. ' variant = jsvalue;',
  25762. ' TArrVariant = array of variant;',
  25763. ' TArrVar2 = TArrVariant;',
  25764. ' TFuncInt = function: longint;',
  25765. 'function GetIt: longint;',
  25766. 'begin',
  25767. 'end;',
  25768. 'procedure DoIt(p: jsvalue; Arr: TArrVar2);',
  25769. 'var v: variant;',
  25770. 'begin',
  25771. ' v:=arr[1];',
  25772. 'end;',
  25773. 'var s: string;',
  25774. 'begin',
  25775. ' DoIt(GetIt,[]);',
  25776. ' DoIt(@GetIt,[]);',
  25777. ' DoIt(1,[s,GetIt]);',
  25778. ' DoIt(1,[s,@GetIt]);',
  25779. '']);
  25780. ConvertProgram;
  25781. CheckSource('TestJSValue_ProcType_Param',
  25782. LinesToStr([ // statements
  25783. 'this.GetIt = function () {',
  25784. ' var Result = 0;',
  25785. ' return Result;',
  25786. '};',
  25787. 'this.DoIt = function (p, Arr) {',
  25788. ' var v = undefined;',
  25789. ' v = Arr[1];',
  25790. '};',
  25791. 'this.s = "";',
  25792. '']),
  25793. LinesToStr([ // $mod.$main
  25794. '$mod.DoIt($mod.GetIt(), []);',
  25795. '$mod.DoIt($mod.GetIt, []);',
  25796. '$mod.DoIt(1, [$mod.s, $mod.GetIt()]);',
  25797. '$mod.DoIt(1, [$mod.s, $mod.GetIt]);',
  25798. '']));
  25799. end;
  25800. procedure TTestModule.TestJSValue_AssignToPointerFail;
  25801. begin
  25802. StartProgram(false);
  25803. Add([
  25804. 'var',
  25805. ' v: JSValue;',
  25806. ' p: Pointer;',
  25807. 'begin',
  25808. ' p:=v;',
  25809. '']);
  25810. SetExpectedPasResolverError('Incompatible types: got "JSValue" expected "Pointer"',
  25811. nIncompatibleTypesGotExpected);
  25812. ConvertProgram;
  25813. end;
  25814. procedure TTestModule.TestJSValue_OverloadDouble;
  25815. begin
  25816. StartProgram(false);
  25817. Add([
  25818. 'type',
  25819. ' integer = longint;',
  25820. ' tdatetime = double;',
  25821. 'procedure DoIt(d: double); begin end;',
  25822. 'procedure DoIt(v: jsvalue); begin end;',
  25823. 'var',
  25824. ' d: double;',
  25825. ' dt: tdatetime;',
  25826. ' i: integer;',
  25827. ' b: byte;',
  25828. ' shi: shortint;',
  25829. ' w: word;',
  25830. ' smi: smallint;',
  25831. ' lw: longword;',
  25832. ' li: longint;',
  25833. ' ni: nativeint;',
  25834. ' nu: nativeuint;',
  25835. 'begin',
  25836. ' DoIt(d);',
  25837. ' DoIt(dt);',
  25838. ' DoIt(i);',
  25839. ' DoIt(b);',
  25840. ' DoIt(shi);',
  25841. ' DoIt(w);',
  25842. ' DoIt(smi);',
  25843. ' DoIt(lw);',
  25844. ' DoIt(li);',
  25845. ' DoIt(ni);',
  25846. ' DoIt(nu);',
  25847. '']);
  25848. ConvertProgram;
  25849. CheckSource('TestJSValue_OverloadDouble',
  25850. LinesToStr([ // statements
  25851. 'this.DoIt = function (d) {',
  25852. '};',
  25853. 'this.DoIt$1 = function (v) {',
  25854. '};',
  25855. 'this.d = 0.0;',
  25856. 'this.dt = 0.0;',
  25857. 'this.i = 0;',
  25858. 'this.b = 0;',
  25859. 'this.shi = 0;',
  25860. 'this.w = 0;',
  25861. 'this.smi = 0;',
  25862. 'this.lw = 0;',
  25863. 'this.li = 0;',
  25864. 'this.ni = 0;',
  25865. 'this.nu = 0;',
  25866. '']),
  25867. LinesToStr([ // $mod.$main
  25868. '$mod.DoIt($mod.d);',
  25869. '$mod.DoIt($mod.dt);',
  25870. '$mod.DoIt$1($mod.i);',
  25871. '$mod.DoIt$1($mod.b);',
  25872. '$mod.DoIt$1($mod.shi);',
  25873. '$mod.DoIt$1($mod.w);',
  25874. '$mod.DoIt$1($mod.smi);',
  25875. '$mod.DoIt$1($mod.lw);',
  25876. '$mod.DoIt$1($mod.li);',
  25877. '$mod.DoIt$1($mod.ni);',
  25878. '$mod.DoIt$1($mod.nu);',
  25879. '']));
  25880. end;
  25881. procedure TTestModule.TestJSValue_OverloadNativeInt;
  25882. begin
  25883. StartProgram(false);
  25884. Add([
  25885. 'type',
  25886. ' integer = longint;',
  25887. ' int53 = nativeint;',
  25888. ' tdatetime = double;',
  25889. 'procedure DoIt(n: nativeint); begin end;',
  25890. 'procedure DoIt(v: jsvalue); begin end;',
  25891. 'var',
  25892. ' d: double;',
  25893. ' dt: tdatetime;',
  25894. ' i: integer;',
  25895. ' b: byte;',
  25896. ' shi: shortint;',
  25897. ' w: word;',
  25898. ' smi: smallint;',
  25899. ' lw: longword;',
  25900. ' li: longint;',
  25901. ' ni: nativeint;',
  25902. ' nu: nativeuint;',
  25903. 'begin',
  25904. ' DoIt(d);',
  25905. ' DoIt(dt);',
  25906. ' DoIt(i);',
  25907. ' DoIt(b);',
  25908. ' DoIt(shi);',
  25909. ' DoIt(w);',
  25910. ' DoIt(smi);',
  25911. ' DoIt(lw);',
  25912. ' DoIt(li);',
  25913. ' DoIt(ni);',
  25914. ' DoIt(nu);',
  25915. '']);
  25916. ConvertProgram;
  25917. CheckSource('TestJSValue_OverloadNativeInt',
  25918. LinesToStr([ // statements
  25919. 'this.DoIt = function (n) {',
  25920. '};',
  25921. 'this.DoIt$1 = function (v) {',
  25922. '};',
  25923. 'this.d = 0.0;',
  25924. 'this.dt = 0.0;',
  25925. 'this.i = 0;',
  25926. 'this.b = 0;',
  25927. 'this.shi = 0;',
  25928. 'this.w = 0;',
  25929. 'this.smi = 0;',
  25930. 'this.lw = 0;',
  25931. 'this.li = 0;',
  25932. 'this.ni = 0;',
  25933. 'this.nu = 0;',
  25934. '']),
  25935. LinesToStr([ // $mod.$main
  25936. '$mod.DoIt$1($mod.d);',
  25937. '$mod.DoIt$1($mod.dt);',
  25938. '$mod.DoIt($mod.i);',
  25939. '$mod.DoIt($mod.b);',
  25940. '$mod.DoIt($mod.shi);',
  25941. '$mod.DoIt($mod.w);',
  25942. '$mod.DoIt($mod.smi);',
  25943. '$mod.DoIt($mod.lw);',
  25944. '$mod.DoIt($mod.li);',
  25945. '$mod.DoIt($mod.ni);',
  25946. '$mod.DoIt($mod.nu);',
  25947. '']));
  25948. end;
  25949. procedure TTestModule.TestJSValue_OverloadWord;
  25950. begin
  25951. StartProgram(false);
  25952. Add([
  25953. 'type',
  25954. ' integer = longint;',
  25955. ' int53 = nativeint;',
  25956. ' tdatetime = double;',
  25957. 'procedure DoIt(w: word); begin end;',
  25958. 'procedure DoIt(v: jsvalue); begin end;',
  25959. 'var',
  25960. ' d: double;',
  25961. ' dt: tdatetime;',
  25962. ' i: integer;',
  25963. ' b: byte;',
  25964. ' shi: shortint;',
  25965. ' w: word;',
  25966. ' smi: smallint;',
  25967. ' lw: longword;',
  25968. ' li: longint;',
  25969. ' ni: nativeint;',
  25970. ' nu: nativeuint;',
  25971. 'begin',
  25972. ' DoIt(d);',
  25973. ' DoIt(dt);',
  25974. ' DoIt(i);',
  25975. ' DoIt(b);',
  25976. ' DoIt(shi);',
  25977. ' DoIt(w);',
  25978. ' DoIt(smi);',
  25979. ' DoIt(lw);',
  25980. ' DoIt(li);',
  25981. ' DoIt(ni);',
  25982. ' DoIt(nu);',
  25983. '']);
  25984. ConvertProgram;
  25985. CheckSource('TestJSValue_OverloadWord',
  25986. LinesToStr([ // statements
  25987. 'this.DoIt = function (w) {',
  25988. '};',
  25989. 'this.DoIt$1 = function (v) {',
  25990. '};',
  25991. 'this.d = 0.0;',
  25992. 'this.dt = 0.0;',
  25993. 'this.i = 0;',
  25994. 'this.b = 0;',
  25995. 'this.shi = 0;',
  25996. 'this.w = 0;',
  25997. 'this.smi = 0;',
  25998. 'this.lw = 0;',
  25999. 'this.li = 0;',
  26000. 'this.ni = 0;',
  26001. 'this.nu = 0;',
  26002. '']),
  26003. LinesToStr([ // $mod.$main
  26004. '$mod.DoIt$1($mod.d);',
  26005. '$mod.DoIt$1($mod.dt);',
  26006. '$mod.DoIt$1($mod.i);',
  26007. '$mod.DoIt($mod.b);',
  26008. '$mod.DoIt($mod.shi);',
  26009. '$mod.DoIt($mod.w);',
  26010. '$mod.DoIt$1($mod.smi);',
  26011. '$mod.DoIt$1($mod.lw);',
  26012. '$mod.DoIt$1($mod.li);',
  26013. '$mod.DoIt$1($mod.ni);',
  26014. '$mod.DoIt$1($mod.nu);',
  26015. '']));
  26016. end;
  26017. procedure TTestModule.TestJSValue_OverloadString;
  26018. begin
  26019. StartProgram(false);
  26020. Add([
  26021. 'type',
  26022. ' uni = string;',
  26023. ' WChar = char;',
  26024. 'procedure DoIt(s: string); begin end;',
  26025. 'procedure DoIt(v: jsvalue); begin end;',
  26026. 'var',
  26027. ' s: string;',
  26028. ' c: char;',
  26029. ' u: uni;',
  26030. 'begin',
  26031. ' DoIt(s);',
  26032. ' DoIt(c);',
  26033. ' DoIt(u);',
  26034. '']);
  26035. ConvertProgram;
  26036. CheckSource('TestJSValue_OverloadString',
  26037. LinesToStr([ // statements
  26038. 'this.DoIt = function (s) {',
  26039. '};',
  26040. 'this.DoIt$1 = function (v) {',
  26041. '};',
  26042. 'this.s = "";',
  26043. 'this.c = "";',
  26044. 'this.u = "";',
  26045. '']),
  26046. LinesToStr([ // $mod.$main
  26047. '$mod.DoIt($mod.s);',
  26048. '$mod.DoIt($mod.c);',
  26049. '$mod.DoIt($mod.u);',
  26050. '']));
  26051. end;
  26052. procedure TTestModule.TestJSValue_OverloadChar;
  26053. begin
  26054. StartProgram(false);
  26055. Add([
  26056. 'type',
  26057. ' uni = string;',
  26058. ' WChar = char;',
  26059. 'procedure DoIt(c: char); begin end;',
  26060. 'procedure DoIt(v: jsvalue); begin end;',
  26061. 'var',
  26062. ' s: string;',
  26063. ' c: char;',
  26064. ' u: uni;',
  26065. 'begin',
  26066. ' DoIt(s);',
  26067. ' DoIt(c);',
  26068. ' DoIt(u);',
  26069. '']);
  26070. ConvertProgram;
  26071. CheckSource('TestJSValue_OverloadChar',
  26072. LinesToStr([ // statements
  26073. 'this.DoIt = function (c) {',
  26074. '};',
  26075. 'this.DoIt$1 = function (v) {',
  26076. '};',
  26077. 'this.s = "";',
  26078. 'this.c = "";',
  26079. 'this.u = "";',
  26080. '']),
  26081. LinesToStr([ // $mod.$main
  26082. '$mod.DoIt$1($mod.s);',
  26083. '$mod.DoIt($mod.c);',
  26084. '$mod.DoIt$1($mod.u);',
  26085. '']));
  26086. end;
  26087. procedure TTestModule.TestJSValue_OverloadPointer;
  26088. begin
  26089. StartProgram(false);
  26090. Add([
  26091. 'type',
  26092. ' TObject = class end;',
  26093. 'procedure DoIt(p: pointer); begin end;',
  26094. 'procedure DoIt(v: jsvalue); begin end;',
  26095. 'var',
  26096. ' o: TObject;',
  26097. 'begin',
  26098. ' DoIt(o);',
  26099. '']);
  26100. ConvertProgram;
  26101. CheckSource('TestJSValue_OverloadPointer',
  26102. LinesToStr([ // statements
  26103. 'rtl.createClass($mod, "TObject", null, function () {',
  26104. ' this.$init = function () {',
  26105. ' };',
  26106. ' this.$final = function () {',
  26107. ' };',
  26108. '});',
  26109. 'this.DoIt = function (p) {',
  26110. '};',
  26111. 'this.DoIt$1 = function (v) {',
  26112. '};',
  26113. 'this.o = null;',
  26114. '']),
  26115. LinesToStr([ // $mod.$main
  26116. '$mod.DoIt($mod.o);',
  26117. '']));
  26118. end;
  26119. procedure TTestModule.TestJSValue_ForIn;
  26120. begin
  26121. StartProgram(false);
  26122. Add([
  26123. 'var',
  26124. ' v: JSValue;',
  26125. ' key: string;',
  26126. 'begin',
  26127. ' for key in v do begin',
  26128. ' if key=''abc'' then ;',
  26129. ' end;',
  26130. '']);
  26131. ConvertProgram;
  26132. CheckSource('TestJSValue_ForIn',
  26133. LinesToStr([ // statements
  26134. 'this.v = undefined;',
  26135. 'this.key = "";',
  26136. '']),
  26137. LinesToStr([ // $mod.$main
  26138. 'for ($mod.key in $mod.v) {',
  26139. ' if ($mod.key === "abc") ;',
  26140. '};',
  26141. '']));
  26142. end;
  26143. procedure TTestModule.TestRTTI_IntRange;
  26144. begin
  26145. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26146. StartProgram(false);
  26147. Add([
  26148. '{$modeswitch externalclass}',
  26149. 'type',
  26150. ' TTypeInfo = class external name ''rtl.tTypeInfo''',
  26151. ' end;',
  26152. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
  26153. ' end;',
  26154. ' TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;',
  26155. ' TColor = type TGraphicsColor;',
  26156. 'var',
  26157. ' p: TTypeInfo;',
  26158. 'begin',
  26159. ' p:=typeinfo(TGraphicsColor);',
  26160. ' p:=typeinfo(TColor);',
  26161. '']);
  26162. ConvertProgram;
  26163. CheckSource('TestRTTI_IntRange',
  26164. LinesToStr([ // statements
  26165. '$mod.$rtti.$Int("TGraphicsColor", {',
  26166. ' minvalue: -2147483648,',
  26167. ' maxvalue: 2147483647,',
  26168. ' ordtype: 4',
  26169. '});',
  26170. '$mod.$rtti.$inherited("TColor", $mod.$rtti["TGraphicsColor"], {});',
  26171. 'this.p = null;',
  26172. '']),
  26173. LinesToStr([ // $mod.$main
  26174. '$mod.p = $mod.$rtti["TGraphicsColor"];',
  26175. '$mod.p = $mod.$rtti["TColor"];',
  26176. '']));
  26177. end;
  26178. procedure TTestModule.TestRTTI_Double;
  26179. begin
  26180. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26181. StartProgram(false);
  26182. Add([
  26183. '{$modeswitch externalclass}',
  26184. 'type',
  26185. ' TTypeInfo = class external name ''rtl.tTypeInfo''',
  26186. ' end;',
  26187. ' TFloat = type double;',
  26188. 'var',
  26189. ' p: TTypeInfo;',
  26190. 'begin',
  26191. ' p:=typeinfo(double);',
  26192. ' p:=typeinfo(TFloat);',
  26193. '']);
  26194. ConvertProgram;
  26195. CheckSource('TestRTTI_Double',
  26196. LinesToStr([ // statements
  26197. '$mod.$rtti.$inherited("TFloat", rtl.double, {});',
  26198. 'this.p = null;',
  26199. '']),
  26200. LinesToStr([ // $mod.$main
  26201. '$mod.p = rtl.double;',
  26202. '$mod.p = $mod.$rtti["TFloat"];',
  26203. '']));
  26204. end;
  26205. procedure TTestModule.TestRTTI_ProcType;
  26206. begin
  26207. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26208. StartProgram(false);
  26209. Add('type');
  26210. Add(' TProcA = procedure;');
  26211. Add(' TMethodB = procedure of object;');
  26212. Add(' TProcC = procedure; varargs;');
  26213. Add(' TProcD = procedure(i: longint; const j: string; var c: char; out d: double);');
  26214. Add(' TProcE = function: nativeint;');
  26215. Add(' TProcF = function(const p: TProcA): nativeuint;');
  26216. Add('var p: pointer;');
  26217. Add('begin');
  26218. Add(' p:=typeinfo(tproca);');
  26219. ConvertProgram;
  26220. CheckSource('TestRTTI_ProcType',
  26221. LinesToStr([ // statements
  26222. '$mod.$rtti.$ProcVar("TProcA", {',
  26223. ' procsig: rtl.newTIProcSig(null)',
  26224. '});',
  26225. '$mod.$rtti.$MethodVar("TMethodB", {',
  26226. ' procsig: rtl.newTIProcSig(null),',
  26227. ' methodkind: 0',
  26228. '});',
  26229. '$mod.$rtti.$ProcVar("TProcC", {',
  26230. ' procsig: rtl.newTIProcSig(null, 2)',
  26231. '});',
  26232. '$mod.$rtti.$ProcVar("TProcD", {',
  26233. ' procsig: rtl.newTIProcSig([["i", rtl.longint], ["j", rtl.string, 2], ["c", rtl.char, 1], ["d", rtl.double, 4]])',
  26234. '});',
  26235. '$mod.$rtti.$ProcVar("TProcE", {',
  26236. ' procsig: rtl.newTIProcSig(null, rtl.nativeint)',
  26237. '});',
  26238. '$mod.$rtti.$ProcVar("TProcF", {',
  26239. ' procsig: rtl.newTIProcSig([["p", $mod.$rtti["TProcA"], 2]], rtl.nativeuint)',
  26240. '});',
  26241. 'this.p = null;',
  26242. '']),
  26243. LinesToStr([ // $mod.$main
  26244. '$mod.p = $mod.$rtti["TProcA"];',
  26245. '']));
  26246. end;
  26247. procedure TTestModule.TestRTTI_ProcType_ArgFromOtherUnit;
  26248. begin
  26249. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26250. AddModuleWithIntfImplSrc('unit2.pas',
  26251. LinesToStr([
  26252. 'type',
  26253. ' TObject = class end;'
  26254. ]),
  26255. '');
  26256. StartUnit(true);
  26257. Add('interface');
  26258. Add('uses unit2;');
  26259. Add('type');
  26260. Add(' TProcA = function(o: tobject): tobject;');
  26261. Add('implementation');
  26262. Add('type');
  26263. Add(' TProcB = function(o: tobject): tobject;');
  26264. Add('var p: Pointer;');
  26265. Add('initialization');
  26266. Add(' p:=typeinfo(tproca);');
  26267. Add(' p:=typeinfo(tprocb);');
  26268. ConvertUnit;
  26269. CheckSource('TestRTTI_ProcType_ArgFromOtherUnit',
  26270. LinesToStr([ // statements
  26271. 'var $impl = $mod.$impl;',
  26272. '$mod.$rtti.$ProcVar("TProcA", {',
  26273. ' procsig: rtl.newTIProcSig([["o", pas.unit2.$rtti["TObject"]]], pas.unit2.$rtti["TObject"])',
  26274. '});',
  26275. '']),
  26276. LinesToStr([ // this.$init
  26277. '$impl.p = $mod.$rtti["TProcA"];',
  26278. '$impl.p = $mod.$rtti["TProcB"];',
  26279. '']),
  26280. LinesToStr([ // implementation
  26281. '$mod.$rtti.$ProcVar("TProcB", {',
  26282. ' procsig: rtl.newTIProcSig([["o", pas.unit2.$rtti["TObject"]]], pas.unit2.$rtti["TObject"])',
  26283. '});',
  26284. '$impl.p = null;',
  26285. '']) );
  26286. end;
  26287. procedure TTestModule.TestRTTI_EnumAndSetType;
  26288. begin
  26289. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26290. StartProgram(false);
  26291. Add('type');
  26292. Add(' TFlag = (light,dark);');
  26293. Add(' TFlags = set of TFlag;');
  26294. Add(' TProc = function(f: TFlags): TFlag;');
  26295. Add('var p: pointer;');
  26296. Add('begin');
  26297. Add(' p:=typeinfo(tflag);');
  26298. Add(' p:=typeinfo(tflags);');
  26299. ConvertProgram;
  26300. CheckSource('TestRTTI_EnumAndType',
  26301. LinesToStr([ // statements
  26302. 'this.TFlag = {',
  26303. ' "0": "light",',
  26304. ' light: 0,',
  26305. ' "1": "dark",',
  26306. ' dark: 1',
  26307. '};',
  26308. '$mod.$rtti.$Enum("TFlag", {',
  26309. ' minvalue: 0,',
  26310. ' maxvalue: 1,',
  26311. ' ordtype: 1,',
  26312. ' enumtype: this.TFlag',
  26313. '});',
  26314. '$mod.$rtti.$Set("TFlags", {',
  26315. ' comptype: $mod.$rtti["TFlag"]',
  26316. '});',
  26317. '$mod.$rtti.$ProcVar("TProc", {',
  26318. ' procsig: rtl.newTIProcSig([["f", $mod.$rtti["TFlags"]]], $mod.$rtti["TFlag"])',
  26319. '});',
  26320. 'this.p = null;',
  26321. '']),
  26322. LinesToStr([ // $mod.$main
  26323. '$mod.p = $mod.$rtti["TFlag"];',
  26324. '$mod.p = $mod.$rtti["TFlags"];',
  26325. '']));
  26326. end;
  26327. procedure TTestModule.TestRTTI_EnumRange;
  26328. begin
  26329. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26330. StartProgram(false);
  26331. Add([
  26332. 'type',
  26333. ' TCol = (red,green,blue);',
  26334. ' TColRg = green..blue;',
  26335. ' TSetOfColRg = set of TColRg;',
  26336. 'var p: pointer;',
  26337. 'begin',
  26338. ' p:=typeinfo(tcolrg);',
  26339. ' p:=typeinfo(tsetofcolrg);',
  26340. '']);
  26341. ConvertProgram;
  26342. end;
  26343. procedure TTestModule.TestRTTI_AnonymousEnumType;
  26344. begin
  26345. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26346. StartProgram(false);
  26347. Add('type');
  26348. Add(' TFlags = set of (red, green);');
  26349. Add('var');
  26350. Add(' f: TFlags;');
  26351. Add('begin');
  26352. Add(' Include(f,red);');
  26353. ConvertProgram;
  26354. CheckSource('TestRTTI_AnonymousEnumType',
  26355. LinesToStr([ // statements
  26356. 'this.TFlags$a = {',
  26357. ' "0": "red",',
  26358. ' red: 0,',
  26359. ' "1": "green",',
  26360. ' green: 1',
  26361. '};',
  26362. '$mod.$rtti.$Enum("TFlags$a", {',
  26363. ' minvalue: 0,',
  26364. ' maxvalue: 1,',
  26365. ' ordtype: 1,',
  26366. ' enumtype: this.TFlags$a',
  26367. '});',
  26368. '$mod.$rtti.$Set("TFlags", {',
  26369. ' comptype: $mod.$rtti["TFlags$a"]',
  26370. '});',
  26371. 'this.f = {};',
  26372. '']),
  26373. LinesToStr([
  26374. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  26375. '']));
  26376. end;
  26377. procedure TTestModule.TestRTTI_StaticArray;
  26378. begin
  26379. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26380. StartProgram(false);
  26381. Add('type');
  26382. Add(' TFlag = (light,dark);');
  26383. Add(' TFlagNames = array[TFlag] of string;');
  26384. Add(' TBoolNames = array[boolean] of string;');
  26385. Add(' TByteArray = array[1..32768] of byte;');
  26386. Add(' TProc = function(f: TBoolNames): TFlagNames;');
  26387. Add('var p: pointer;');
  26388. Add('begin');
  26389. Add(' p:=typeinfo(TFlagNames);');
  26390. Add(' p:=typeinfo(TBoolNames);');
  26391. ConvertProgram;
  26392. CheckSource('TestRTTI_StaticArray',
  26393. LinesToStr([ // statements
  26394. 'this.TFlag = {',
  26395. ' "0": "light",',
  26396. ' light: 0,',
  26397. ' "1": "dark",',
  26398. ' dark: 1',
  26399. '};',
  26400. '$mod.$rtti.$Enum("TFlag", {',
  26401. ' minvalue: 0,',
  26402. ' maxvalue: 1,',
  26403. ' ordtype: 1,',
  26404. ' enumtype: this.TFlag',
  26405. '});',
  26406. '$mod.$rtti.$StaticArray("TFlagNames", {',
  26407. ' dims: [2],',
  26408. ' eltype: rtl.string',
  26409. '});',
  26410. '$mod.$rtti.$StaticArray("TBoolNames", {',
  26411. ' dims: [2],',
  26412. ' eltype: rtl.string',
  26413. '});',
  26414. '$mod.$rtti.$StaticArray("TByteArray", {',
  26415. ' dims: [32768],',
  26416. ' eltype: rtl.byte',
  26417. '});',
  26418. '$mod.$rtti.$ProcVar("TProc", {',
  26419. ' procsig: rtl.newTIProcSig([["f", $mod.$rtti["TBoolNames"]]], $mod.$rtti["TFlagNames"])',
  26420. '});',
  26421. 'this.p = null;',
  26422. '']),
  26423. LinesToStr([ // $mod.$main
  26424. '$mod.p = $mod.$rtti["TFlagNames"];',
  26425. '$mod.p = $mod.$rtti["TBoolNames"];',
  26426. '']));
  26427. end;
  26428. procedure TTestModule.TestRTTI_DynArray;
  26429. begin
  26430. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26431. StartProgram(false);
  26432. Add('type');
  26433. Add(' TArrStr = array of string;');
  26434. Add(' TArr2Dim = array of tarrstr;');
  26435. Add(' TProc = function(f: TArrStr): TArr2Dim;');
  26436. Add('var p: pointer;');
  26437. Add('begin');
  26438. Add(' p:=typeinfo(tarrstr);');
  26439. Add(' p:=typeinfo(tarr2dim);');
  26440. ConvertProgram;
  26441. CheckSource('TestRTTI_DynArray',
  26442. LinesToStr([ // statements
  26443. '$mod.$rtti.$DynArray("TArrStr", {',
  26444. ' eltype: rtl.string',
  26445. '});',
  26446. '$mod.$rtti.$DynArray("TArr2Dim", {',
  26447. ' eltype: $mod.$rtti["TArrStr"]',
  26448. '});',
  26449. '$mod.$rtti.$ProcVar("TProc", {',
  26450. ' procsig: rtl.newTIProcSig([["f", $mod.$rtti["TArrStr"]]], $mod.$rtti["TArr2Dim"])',
  26451. '});',
  26452. 'this.p = null;',
  26453. '']),
  26454. LinesToStr([ // $mod.$main
  26455. '$mod.p = $mod.$rtti["TArrStr"];',
  26456. '$mod.p = $mod.$rtti["TArr2Dim"];',
  26457. '']));
  26458. end;
  26459. procedure TTestModule.TestRTTI_ArrayNestedAnonymous;
  26460. begin
  26461. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26462. StartProgram(false);
  26463. Add('type');
  26464. Add(' TArr = array of array of longint;');
  26465. Add('var a: TArr;');
  26466. Add('begin');
  26467. ConvertProgram;
  26468. CheckSource('TestRTTI_ArrayNestedAnonymous',
  26469. LinesToStr([ // statements
  26470. '$mod.$rtti.$DynArray("TArr$a", {',
  26471. ' eltype: rtl.longint',
  26472. '});',
  26473. '$mod.$rtti.$DynArray("TArr", {',
  26474. ' eltype: $mod.$rtti["TArr$a"]',
  26475. '});',
  26476. 'this.a = [];',
  26477. '']),
  26478. LinesToStr([ // $mod.$main
  26479. ]));
  26480. end;
  26481. procedure TTestModule.TestRTTI_PublishedMethodOverloadFail;
  26482. begin
  26483. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26484. StartProgram(false);
  26485. Add('type');
  26486. Add(' TObject = class');
  26487. Add(' published');
  26488. Add(' procedure Proc; virtual; abstract;');
  26489. Add(' procedure Proc(Sender: tobject); virtual; abstract;');
  26490. Add(' end;');
  26491. Add('begin');
  26492. SetExpectedPasResolverError('Duplicate identifier "Proc" at test1.pp(6,19)',
  26493. nDuplicateIdentifier);
  26494. ConvertProgram;
  26495. end;
  26496. procedure TTestModule.TestRTTI_PublishedMethodExternalFail;
  26497. begin
  26498. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26499. StartProgram(false);
  26500. Add('type');
  26501. Add(' TObject = class');
  26502. Add(' published');
  26503. Add(' procedure Proc; external name ''foo'';');
  26504. Add(' end;');
  26505. Add('begin');
  26506. SetExpectedPasResolverError(sPublishedNameMustMatchExternal,
  26507. nPublishedNameMustMatchExternal);
  26508. ConvertProgram;
  26509. end;
  26510. procedure TTestModule.TestRTTI_PublishedClassPropertyFail;
  26511. begin
  26512. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26513. StartProgram(false);
  26514. Add('type');
  26515. Add(' TObject = class');
  26516. Add(' class var FA: longint;');
  26517. Add(' published');
  26518. Add(' class property A: longint read FA;');
  26519. Add(' end;');
  26520. Add('begin');
  26521. SetExpectedPasResolverError('Invalid published property modifier "class"',
  26522. nInvalidXModifierY);
  26523. ConvertProgram;
  26524. end;
  26525. procedure TTestModule.TestRTTI_PublishedClassFieldFail;
  26526. begin
  26527. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26528. StartProgram(false);
  26529. Add('type');
  26530. Add(' TObject = class');
  26531. Add(' published');
  26532. Add(' class var FA: longint;');
  26533. Add(' end;');
  26534. Add('begin');
  26535. SetExpectedPasResolverError(sSymbolCannotBePublished,
  26536. nSymbolCannotBePublished);
  26537. ConvertProgram;
  26538. end;
  26539. procedure TTestModule.TestRTTI_PublishedFieldExternalFail;
  26540. begin
  26541. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26542. StartProgram(false);
  26543. Add('{$modeswitch externalclass}');
  26544. Add('type');
  26545. Add(' TObject = class');
  26546. Add(' published');
  26547. Add(' V: longint; external name ''foo'';');
  26548. Add(' end;');
  26549. Add('begin');
  26550. SetExpectedPasResolverError(sPublishedNameMustMatchExternal,
  26551. nPublishedNameMustMatchExternal);
  26552. ConvertProgram;
  26553. end;
  26554. procedure TTestModule.TestRTTI_Class_Field;
  26555. begin
  26556. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26557. StartProgram(false);
  26558. Add('{$modeswitch externalclass}');
  26559. Add('type');
  26560. Add(' TObject = class');
  26561. Add(' private');
  26562. Add(' FPropA: string;');
  26563. Add(' published');
  26564. Add(' VarLI: longint;');
  26565. Add(' VarC: char;');
  26566. Add(' VarS: string;');
  26567. Add(' VarD: double;');
  26568. Add(' VarB: boolean;');
  26569. Add(' VarLW: longword;');
  26570. Add(' VarSmI: smallint;');
  26571. Add(' VarW: word;');
  26572. Add(' VarShI: shortint;');
  26573. Add(' VarBy: byte;');
  26574. Add(' VarExt: longint external name ''VarExt'';');
  26575. Add(' end;');
  26576. Add('var p: pointer;');
  26577. Add(' Obj: tobject;');
  26578. Add('begin');
  26579. Add(' p:=typeinfo(tobject);');
  26580. Add(' p:=typeinfo(p);');
  26581. Add(' p:=typeinfo(obj);');
  26582. ConvertProgram;
  26583. CheckSource('TestRTTI_Class_Field',
  26584. LinesToStr([ // statements
  26585. 'rtl.createClass($mod, "TObject", null, function () {',
  26586. ' this.$init = function () {',
  26587. ' this.FPropA = "";',
  26588. ' this.VarLI = 0;',
  26589. ' this.VarC = "";',
  26590. ' this.VarS = "";',
  26591. ' this.VarD = 0.0;',
  26592. ' this.VarB = false;',
  26593. ' this.VarLW = 0;',
  26594. ' this.VarSmI = 0;',
  26595. ' this.VarW = 0;',
  26596. ' this.VarShI = 0;',
  26597. ' this.VarBy = 0;',
  26598. ' };',
  26599. ' this.$final = function () {',
  26600. ' };',
  26601. ' var $r = this.$rtti;',
  26602. ' $r.addField("VarLI", rtl.longint);',
  26603. ' $r.addField("VarC", rtl.char);',
  26604. ' $r.addField("VarS", rtl.string);',
  26605. ' $r.addField("VarD", rtl.double);',
  26606. ' $r.addField("VarB", rtl.boolean);',
  26607. ' $r.addField("VarLW", rtl.longword);',
  26608. ' $r.addField("VarSmI", rtl.smallint);',
  26609. ' $r.addField("VarW", rtl.word);',
  26610. ' $r.addField("VarShI", rtl.shortint);',
  26611. ' $r.addField("VarBy", rtl.byte);',
  26612. ' $r.addField("VarExt", rtl.longint);',
  26613. '});',
  26614. 'this.p = null;',
  26615. 'this.Obj = null;',
  26616. '']),
  26617. LinesToStr([ // $mod.$main
  26618. '$mod.p = $mod.$rtti["TObject"];',
  26619. '$mod.p = rtl.pointer;',
  26620. '$mod.p = $mod.Obj.$rtti;',
  26621. '']));
  26622. end;
  26623. procedure TTestModule.TestRTTI_Class_Method;
  26624. begin
  26625. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26626. StartProgram(false);
  26627. Add('type');
  26628. Add(' TObject = class');
  26629. Add(' private');
  26630. Add(' procedure Internal; external name ''$intern'';');
  26631. Add(' published');
  26632. Add(' procedure Click; virtual; abstract;');
  26633. Add(' procedure Notify(Sender: TObject); virtual; abstract;');
  26634. Add(' function GetNotify: boolean; external name ''GetNotify'';');
  26635. Add(' procedure Println(a,b: longint); varargs; virtual; abstract;');
  26636. Add(' end;');
  26637. Add('begin');
  26638. ConvertProgram;
  26639. CheckSource('TestRTTI_Class_Method',
  26640. LinesToStr([ // statements
  26641. 'rtl.createClass($mod, "TObject", null, function () {',
  26642. ' this.$init = function () {',
  26643. ' };',
  26644. ' this.$final = function () {',
  26645. ' };',
  26646. ' var $r = this.$rtti;',
  26647. ' $r.addMethod("Click", 0, null);',
  26648. ' $r.addMethod("Notify", 0, [["Sender", $r]]);',
  26649. ' $r.addMethod("GetNotify", 1, null, rtl.boolean,{flags: 4});',
  26650. ' $r.addMethod("Println", 0, [["a", rtl.longint], ["b", rtl.longint]], null, {',
  26651. ' flags: 2',
  26652. ' });',
  26653. '});',
  26654. '']),
  26655. LinesToStr([ // $mod.$main
  26656. '']));
  26657. end;
  26658. procedure TTestModule.TestRTTI_Class_MethodArgFlags;
  26659. begin
  26660. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26661. StartProgram(false);
  26662. Add('type');
  26663. Add(' TObject = class');
  26664. Add(' published');
  26665. Add(' procedure OpenArray(const Args: array of string); virtual; abstract;');
  26666. Add(' procedure ByRef(var Value: longint; out Item: longint); virtual; abstract;');
  26667. Add(' procedure Untyped(var Value; out Item); virtual; abstract;');
  26668. Add(' end;');
  26669. Add('begin');
  26670. ConvertProgram;
  26671. CheckSource('TestRTTI_Class_MethodOpenArray',
  26672. LinesToStr([ // statements
  26673. 'rtl.createClass($mod, "TObject", null, function () {',
  26674. ' this.$init = function () {',
  26675. ' };',
  26676. ' this.$final = function () {',
  26677. ' };',
  26678. ' var $r = this.$rtti;',
  26679. '$r.addMethod("OpenArray", 0, [["Args", rtl.string, 10]]);',
  26680. '$r.addMethod("ByRef", 0, [["Value", rtl.longint, 1], ["Item", rtl.longint, 4]]);',
  26681. '$r.addMethod("Untyped", 0, [["Value", null, 1], ["Item", null, 4]]);',
  26682. '});',
  26683. '']),
  26684. LinesToStr([ // $mod.$main
  26685. '']));
  26686. end;
  26687. procedure TTestModule.TestRTTI_Class_Property;
  26688. begin
  26689. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26690. StartProgram(false);
  26691. Add('{$modeswitch externalclass}');
  26692. Add('type');
  26693. Add(' TObject = class');
  26694. Add(' private');
  26695. Add(' FColor: longint;');
  26696. Add(' FColorStored: boolean;');
  26697. Add(' procedure SetColor(Value: longint); virtual; abstract;');
  26698. Add(' function GetColor: longint; virtual; abstract;');
  26699. Add(' function GetColorStored: boolean; virtual; abstract;');
  26700. Add(' FExtSize: longint external name ''$extSize'';');
  26701. Add(' FExtSizeStored: boolean external name ''$extSizeStored'';');
  26702. Add(' procedure SetExtSize(Value: longint); external name ''$setSize'';');
  26703. Add(' function GetExtSize: longint; external name ''$getSize'';');
  26704. Add(' function GetExtSizeStored: boolean; external name ''$getExtSizeStored'';');
  26705. Add(' published');
  26706. Add(' property ColorA: longint read FColor;');
  26707. Add(' property ColorB: longint write FColor;');
  26708. Add(' property ColorC: longint read GetColor write SetColor;');
  26709. Add(' property ColorD: longint read FColor write FColor stored FColorStored;');
  26710. Add(' property ExtSizeA: longint read FExtSize write FExtSize;');
  26711. Add(' property ExtSizeB: longint read GetExtSize write SetExtSize stored FExtSizeStored;');
  26712. Add(' property ExtSizeC: longint read FExtSize write FExtSize stored GetExtSizeStored;');
  26713. Add(' end;');
  26714. Add('begin');
  26715. ConvertProgram;
  26716. CheckSource('TestRTTI_Class_Property',
  26717. LinesToStr([ // statements
  26718. 'rtl.createClass($mod, "TObject", null, function () {',
  26719. ' this.$init = function () {',
  26720. ' this.FColor = 0;',
  26721. ' this.FColorStored = false;',
  26722. ' };',
  26723. ' this.$final = function () {',
  26724. ' };',
  26725. ' var $r = this.$rtti;',
  26726. ' $r.addProperty("ColorA", 0, rtl.longint, "FColor", "");',
  26727. ' $r.addProperty("ColorB", 0, rtl.longint, "", "FColor");',
  26728. ' $r.addProperty("ColorC", 3, rtl.longint, "GetColor", "SetColor");',
  26729. ' $r.addProperty(',
  26730. ' "ColorD",',
  26731. ' 8,',
  26732. ' rtl.longint,',
  26733. ' "FColor",',
  26734. ' "FColor",',
  26735. ' {',
  26736. ' stored: "FColorStored"',
  26737. ' }',
  26738. ' );',
  26739. ' $r.addProperty("ExtSizeA", 0, rtl.longint, "$extSize", "$extSize");',
  26740. ' $r.addProperty(',
  26741. ' "ExtSizeB",',
  26742. ' 11,',
  26743. ' rtl.longint,',
  26744. ' "$getSize",',
  26745. ' "$setSize",',
  26746. ' {',
  26747. ' stored: "$extSizeStored"',
  26748. ' }',
  26749. ' );',
  26750. ' $r.addProperty(',
  26751. ' "ExtSizeC",',
  26752. ' 12,',
  26753. ' rtl.longint,',
  26754. ' "$extSize",',
  26755. ' "$extSize",',
  26756. ' {',
  26757. ' stored: "$getExtSizeStored"',
  26758. ' }',
  26759. ' );',
  26760. '});',
  26761. '']),
  26762. LinesToStr([ // $mod.$main
  26763. '']));
  26764. end;
  26765. procedure TTestModule.TestRTTI_Class_PropertyParams;
  26766. begin
  26767. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26768. StartProgram(false);
  26769. Add('{$modeswitch externalclass}');
  26770. Add('type');
  26771. Add(' integer = longint;');
  26772. Add(' TObject = class');
  26773. Add(' private');
  26774. Add(' function GetItems(i: integer): tobject; virtual; abstract;');
  26775. Add(' procedure SetItems(i: integer; value: tobject); virtual; abstract;');
  26776. Add(' function GetValues(const i: integer; var b: boolean): char; virtual; abstract;');
  26777. Add(' procedure SetValues(const i: integer; var b: boolean; value: char); virtual; abstract;');
  26778. Add(' published');
  26779. Add(' property Items[Index: integer]: tobject read getitems write setitems;');
  26780. Add(' property Values[const keya: integer; var keyb: boolean]: char read getvalues write setvalues;');
  26781. Add(' end;');
  26782. Add('begin');
  26783. ConvertProgram;
  26784. CheckSource('TestRTTI_Class_PropertyParams',
  26785. LinesToStr([ // statements
  26786. 'rtl.createClass($mod, "TObject", null, function () {',
  26787. ' this.$init = function () {',
  26788. ' };',
  26789. ' this.$final = function () {',
  26790. ' };',
  26791. ' var $r = this.$rtti;',
  26792. ' $r.addProperty("Items", 3, $r, "GetItems", "SetItems");',
  26793. ' $r.addProperty("Values", 3, rtl.char, "GetValues", "SetValues");',
  26794. '});',
  26795. '']),
  26796. LinesToStr([ // $mod.$main
  26797. '']));
  26798. end;
  26799. procedure TTestModule.TestRTTI_Class_OtherUnit_TypeAlias;
  26800. begin
  26801. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26802. AddModuleWithIntfImplSrc('unit1.pas',
  26803. 'type TColor = -5..5;',
  26804. '');
  26805. StartProgram(true);
  26806. Add([
  26807. 'uses unit1;',
  26808. 'type',
  26809. ' TColorAlias = TColor;',
  26810. ' TColorTypeAlias = type TColor;',
  26811. ' TObject = class',
  26812. ' private',
  26813. ' fColor: TColor;',
  26814. ' fAlias: TColorAlias;',
  26815. ' fTypeAlias: TColorTypeAlias;',
  26816. ' published',
  26817. ' property Color: TColor read fcolor;',
  26818. ' property Alias: TColorAlias read falias;',
  26819. ' property TypeAlias: TColorTypeAlias read ftypealias;',
  26820. ' end;',
  26821. 'begin',
  26822. '']);
  26823. ConvertProgram;
  26824. CheckSource('TestRTTI_Class_OtherUnit_TypeAlias',
  26825. LinesToStr([ // statements
  26826. '$mod.$rtti.$inherited("TColorTypeAlias", pas.unit1.$rtti["TColor"], {});',
  26827. 'rtl.createClass($mod, "TObject", null, function () {',
  26828. ' this.$init = function () {',
  26829. ' this.fColor = 0;',
  26830. ' this.fAlias = 0;',
  26831. ' this.fTypeAlias = 0;',
  26832. ' };',
  26833. ' this.$final = function () {',
  26834. ' };',
  26835. ' var $r = this.$rtti;',
  26836. ' $r.addProperty("Color", 0, pas.unit1.$rtti["TColor"], "fColor", "");',
  26837. ' $r.addProperty("Alias", 0, pas.unit1.$rtti["TColor"], "fAlias", "");',
  26838. ' $r.addProperty("TypeAlias", 0, $mod.$rtti["TColorTypeAlias"], "fTypeAlias", "");',
  26839. '});',
  26840. '']),
  26841. LinesToStr([ // $mod.$main
  26842. '']));
  26843. end;
  26844. procedure TTestModule.TestRTTI_Class_OmitRTTI;
  26845. begin
  26846. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26847. StartProgram(false);
  26848. Add([
  26849. '{$modeswitch omitrtti}',
  26850. 'type',
  26851. ' TObject = class',
  26852. ' private',
  26853. ' FA: byte;',
  26854. ' published',
  26855. ' property A: byte read FA write FA;',
  26856. ' end;',
  26857. 'begin']);
  26858. ConvertProgram;
  26859. CheckSource('TestRTTI_Class_OmitRTTI',
  26860. LinesToStr([ // statements
  26861. 'rtl.createClass($mod, "TObject", null, function () {',
  26862. ' this.$init = function () {',
  26863. ' this.FA = 0;',
  26864. ' };',
  26865. ' this.$final = function () {',
  26866. ' };',
  26867. '});',
  26868. '']),
  26869. LinesToStr([ // $mod.$main
  26870. '']));
  26871. end;
  26872. procedure TTestModule.TestRTTI_IndexModifier;
  26873. begin
  26874. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26875. StartProgram(false);
  26876. Add([
  26877. 'type',
  26878. ' TEnum = (red, blue);',
  26879. ' TObject = class',
  26880. ' FB: boolean;',
  26881. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  26882. ' function GetBoolBool(Index: boolean): boolean; virtual; abstract;',
  26883. ' procedure SetBoolBool(Index: boolean; b: boolean); virtual; abstract;',
  26884. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  26885. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  26886. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  26887. ' published',
  26888. ' property B1: boolean index 1 read FB write SetIntBool;',
  26889. ' property B2: boolean index TEnum.blue read GetEnumBool write FB;',
  26890. ' property I1[A: String]: boolean index 2 read GetStrIntBool write SetStrIntBool;',
  26891. ' end;',
  26892. 'begin']);
  26893. ConvertProgram;
  26894. CheckSource('TestRTTI_IndexModifier',
  26895. LinesToStr([ // statements
  26896. 'this.TEnum = {',
  26897. ' "0": "red",',
  26898. ' red: 0,',
  26899. ' "1": "blue",',
  26900. ' blue: 1',
  26901. '};',
  26902. '$mod.$rtti.$Enum("TEnum", {',
  26903. ' minvalue: 0,',
  26904. ' maxvalue: 1,',
  26905. ' ordtype: 1,',
  26906. ' enumtype: this.TEnum',
  26907. '});',
  26908. 'rtl.createClass($mod, "TObject", null, function () {',
  26909. ' this.$init = function () {',
  26910. ' this.FB = false;',
  26911. ' };',
  26912. ' this.$final = function () {',
  26913. ' };',
  26914. ' var $r = this.$rtti;',
  26915. ' $r.addProperty(',
  26916. ' "B1",',
  26917. ' 18,',
  26918. ' rtl.boolean,',
  26919. ' "FB",',
  26920. ' "SetIntBool",',
  26921. ' {',
  26922. ' index: 1',
  26923. ' }',
  26924. ' );',
  26925. ' $r.addProperty(',
  26926. ' "B2",',
  26927. ' 17,',
  26928. ' rtl.boolean,',
  26929. ' "GetEnumBool",',
  26930. ' "FB",',
  26931. ' {',
  26932. ' index: $mod.TEnum.blue',
  26933. ' }',
  26934. ' );',
  26935. ' $r.addProperty(',
  26936. ' "I1",',
  26937. ' 19,',
  26938. ' rtl.boolean,',
  26939. ' "GetStrIntBool",',
  26940. ' "SetStrIntBool",',
  26941. ' {',
  26942. ' index: 2',
  26943. ' }',
  26944. ' );',
  26945. '});',
  26946. '']),
  26947. LinesToStr([ // $mod.$main
  26948. '']));
  26949. end;
  26950. procedure TTestModule.TestRTTI_StoredModifier;
  26951. begin
  26952. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26953. StartProgram(false);
  26954. Add([
  26955. 'const',
  26956. ' ConstB = true;',
  26957. 'type',
  26958. ' TObject = class',
  26959. ' private',
  26960. ' FB: boolean;',
  26961. ' function IsBStored: boolean; virtual; abstract;',
  26962. ' published',
  26963. ' property BoolA: boolean read FB stored true;',
  26964. ' property BoolB: boolean read FB stored false;',
  26965. ' property BoolC: boolean read FB stored FB;',
  26966. ' property BoolD: boolean read FB stored ConstB;',
  26967. ' property BoolE: boolean read FB stored IsBStored;',
  26968. ' end;',
  26969. 'begin']);
  26970. ConvertProgram;
  26971. CheckSource('TestRTTI_StoredModifier',
  26972. LinesToStr([ // statements
  26973. 'this.ConstB = true;',
  26974. 'rtl.createClass($mod, "TObject", null, function () {',
  26975. ' this.$init = function () {',
  26976. ' this.FB = false;',
  26977. ' };',
  26978. ' this.$final = function () {',
  26979. ' };',
  26980. ' var $r = this.$rtti;',
  26981. ' $r.addProperty("BoolA", 0, rtl.boolean, "FB", "");',
  26982. ' $r.addProperty("BoolB", 4, rtl.boolean, "FB", "");',
  26983. ' $r.addProperty(',
  26984. ' "BoolC",',
  26985. ' 8,',
  26986. ' rtl.boolean,',
  26987. ' "FB",',
  26988. ' "",',
  26989. ' {',
  26990. ' stored: "FB"',
  26991. ' }',
  26992. ' );',
  26993. ' $r.addProperty("BoolD", 0, rtl.boolean, "FB", "");',
  26994. ' $r.addProperty(',
  26995. ' "BoolE",',
  26996. ' 12,',
  26997. ' rtl.boolean,',
  26998. ' "FB",',
  26999. ' "",',
  27000. ' {',
  27001. ' stored: "IsBStored"',
  27002. ' }',
  27003. ' );',
  27004. '});',
  27005. '']),
  27006. LinesToStr([ // $mod.$main
  27007. '']));
  27008. end;
  27009. procedure TTestModule.TestRTTI_DefaultValue;
  27010. begin
  27011. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27012. StartProgram(false);
  27013. Add([
  27014. 'type',
  27015. ' TEnum = (red, blue);',
  27016. 'const',
  27017. ' CB = true or false;',
  27018. ' CI = 1+2;',
  27019. 'type',
  27020. ' TObject = class',
  27021. ' FB: boolean;',
  27022. ' FI: longint;',
  27023. ' FE: TEnum;',
  27024. ' published',
  27025. ' property B1: boolean read FB default true;',
  27026. ' property B2: boolean read FB default CB;',
  27027. ' property B3: boolean read FB default test1.cb;',
  27028. ' property I1: longint read FI default 2;',
  27029. ' property I2: longint read FI default CI;',
  27030. ' property E1: TEnum read FE default red;',
  27031. ' property E2: TEnum read FE default TEnum.blue;',
  27032. ' end;',
  27033. 'begin']);
  27034. ConvertProgram;
  27035. CheckSource('TestRTTI_DefaultValue',
  27036. LinesToStr([ // statements
  27037. 'this.TEnum = {',
  27038. ' "0": "red",',
  27039. ' red: 0,',
  27040. ' "1": "blue",',
  27041. ' blue: 1',
  27042. '};',
  27043. '$mod.$rtti.$Enum("TEnum", {',
  27044. ' minvalue: 0,',
  27045. ' maxvalue: 1,',
  27046. ' ordtype: 1,',
  27047. ' enumtype: this.TEnum',
  27048. '});',
  27049. 'this.CB = true || false;',
  27050. 'this.CI = 1 + 2;',
  27051. 'rtl.createClass($mod, "TObject", null, function () {',
  27052. ' this.$init = function () {',
  27053. ' this.FB = false;',
  27054. ' this.FI = 0;',
  27055. ' this.FE = 0;',
  27056. ' };',
  27057. ' this.$final = function () {',
  27058. ' };',
  27059. ' var $r = this.$rtti;',
  27060. ' $r.addProperty(',
  27061. ' "B1",',
  27062. ' 0,',
  27063. ' rtl.boolean,',
  27064. ' "FB",',
  27065. ' "",',
  27066. ' {',
  27067. ' Default: true',
  27068. ' }',
  27069. ' );',
  27070. ' $r.addProperty(',
  27071. ' "B2",',
  27072. ' 0,',
  27073. ' rtl.boolean,',
  27074. ' "FB",',
  27075. ' "",',
  27076. ' {',
  27077. ' Default: true',
  27078. ' }',
  27079. ' );',
  27080. ' $r.addProperty(',
  27081. ' "B3",',
  27082. ' 0,',
  27083. ' rtl.boolean,',
  27084. ' "FB",',
  27085. ' "",',
  27086. ' {',
  27087. ' Default: true',
  27088. ' }',
  27089. ' );',
  27090. ' $r.addProperty(',
  27091. ' "I1",',
  27092. ' 0,',
  27093. ' rtl.longint,',
  27094. ' "FI",',
  27095. ' "",',
  27096. ' {',
  27097. ' Default: 2',
  27098. ' }',
  27099. ' );',
  27100. ' $r.addProperty(',
  27101. ' "I2",',
  27102. ' 0,',
  27103. ' rtl.longint,',
  27104. ' "FI",',
  27105. ' "",',
  27106. ' {',
  27107. ' Default: 3',
  27108. ' }',
  27109. ' );',
  27110. ' $r.addProperty(',
  27111. ' "E1",',
  27112. ' 0,',
  27113. ' $mod.$rtti["TEnum"],',
  27114. ' "FE",',
  27115. ' "",',
  27116. ' {',
  27117. ' Default: $mod.TEnum.red',
  27118. ' }',
  27119. ' );',
  27120. ' $r.addProperty(',
  27121. ' "E2",',
  27122. ' 0,',
  27123. ' $mod.$rtti["TEnum"],',
  27124. ' "FE",',
  27125. ' "",',
  27126. ' {',
  27127. ' Default: $mod.TEnum.blue',
  27128. ' }',
  27129. ' );',
  27130. '});',
  27131. '']),
  27132. LinesToStr([ // $mod.$main
  27133. '']));
  27134. end;
  27135. procedure TTestModule.TestRTTI_DefaultValueSet;
  27136. begin
  27137. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27138. StartProgram(false);
  27139. Add([
  27140. 'type',
  27141. ' TEnum = (red, blue);',
  27142. ' TSet = set of TEnum;',
  27143. 'const',
  27144. ' CSet = [red,blue];',
  27145. 'type',
  27146. ' TObject = class',
  27147. ' FSet: TSet;',
  27148. ' published',
  27149. ' property Set1: TSet read FSet default [];',
  27150. ' property Set2: TSet read FSet default [red];',
  27151. ' property Set3: TSet read FSet default [red,blue];',
  27152. ' property Set4: TSet read FSet default CSet;',
  27153. ' end;',
  27154. 'begin']);
  27155. ConvertProgram;
  27156. CheckSource('TestRTTI_DefaultValueSet',
  27157. LinesToStr([ // statements
  27158. 'this.TEnum = {',
  27159. ' "0": "red",',
  27160. ' red: 0,',
  27161. ' "1": "blue",',
  27162. ' blue: 1',
  27163. '};',
  27164. '$mod.$rtti.$Enum("TEnum", {',
  27165. ' minvalue: 0,',
  27166. ' maxvalue: 1,',
  27167. ' ordtype: 1,',
  27168. ' enumtype: this.TEnum',
  27169. '});',
  27170. '$mod.$rtti.$Set("TSet", {',
  27171. ' comptype: $mod.$rtti["TEnum"]',
  27172. '});',
  27173. 'this.CSet = rtl.createSet($mod.TEnum.red, $mod.TEnum.blue);',
  27174. 'rtl.createClass($mod, "TObject", null, function () {',
  27175. ' this.$init = function () {',
  27176. ' this.FSet = {};',
  27177. ' };',
  27178. ' this.$final = function () {',
  27179. ' this.FSet = undefined;',
  27180. ' };',
  27181. ' var $r = this.$rtti;',
  27182. ' $r.addProperty(',
  27183. ' "Set1",',
  27184. ' 0,',
  27185. ' $mod.$rtti["TSet"],',
  27186. ' "FSet",',
  27187. ' "",',
  27188. ' {',
  27189. ' Default: {}',
  27190. ' }',
  27191. ' );',
  27192. ' $r.addProperty(',
  27193. ' "Set2",',
  27194. ' 0,',
  27195. ' $mod.$rtti["TSet"],',
  27196. ' "FSet",',
  27197. ' "",',
  27198. ' {',
  27199. ' Default: rtl.createSet($mod.TEnum.red)',
  27200. ' }',
  27201. ' );',
  27202. ' $r.addProperty(',
  27203. ' "Set3",',
  27204. ' 0,',
  27205. ' $mod.$rtti["TSet"],',
  27206. ' "FSet",',
  27207. ' "",',
  27208. ' {',
  27209. ' Default: rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)',
  27210. ' }',
  27211. ' );',
  27212. ' $r.addProperty(',
  27213. ' "Set4",',
  27214. ' 0,',
  27215. ' $mod.$rtti["TSet"],',
  27216. ' "FSet",',
  27217. ' "",',
  27218. ' {',
  27219. ' Default: $mod.CSet',
  27220. ' }',
  27221. ' );',
  27222. '});',
  27223. '']),
  27224. LinesToStr([ // $mod.$main
  27225. '']));
  27226. end;
  27227. procedure TTestModule.TestRTTI_DefaultValueRangeType;
  27228. begin
  27229. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27230. StartProgram(false);
  27231. Add([
  27232. 'type',
  27233. ' TRg = -1..1;',
  27234. 'const',
  27235. ' l = low(TRg);',
  27236. ' h = high(TRg);',
  27237. 'type',
  27238. ' TObject = class',
  27239. ' FV: TRg;',
  27240. ' published',
  27241. ' property V1: TRg read FV default -1;',
  27242. ' end;',
  27243. 'begin']);
  27244. ConvertProgram;
  27245. CheckSource('TestRTTI_DefaultValueRangeType',
  27246. LinesToStr([ // statements
  27247. '$mod.$rtti.$Int("TRg", {',
  27248. ' minvalue: -1,',
  27249. ' maxvalue: 1,',
  27250. ' ordtype: 0',
  27251. '});',
  27252. 'this.l = -1;',
  27253. 'this.h = 1;',
  27254. 'rtl.createClass($mod, "TObject", null, function () {',
  27255. ' this.$init = function () {',
  27256. ' this.FV = 0;',
  27257. ' };',
  27258. ' this.$final = function () {',
  27259. ' };',
  27260. ' var $r = this.$rtti;',
  27261. ' $r.addProperty(',
  27262. ' "V1",',
  27263. ' 0,',
  27264. ' $mod.$rtti["TRg"],',
  27265. ' "FV",',
  27266. ' "",',
  27267. ' {',
  27268. ' Default: -1',
  27269. ' }',
  27270. ' );',
  27271. '});',
  27272. '']),
  27273. LinesToStr([ // $mod.$main
  27274. '']));
  27275. end;
  27276. procedure TTestModule.TestRTTI_DefaultValueInherit;
  27277. begin
  27278. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27279. StartProgram(false);
  27280. Add([
  27281. 'type',
  27282. ' TObject = class',
  27283. ' FA, FB: byte;',
  27284. ' property A: byte read FA default 1;',
  27285. ' property B: byte read FB default 2;',
  27286. ' end;',
  27287. ' TBird = class',
  27288. ' published',
  27289. ' property A;',
  27290. ' property B nodefault;',
  27291. ' end;',
  27292. 'begin']);
  27293. ConvertProgram;
  27294. CheckSource('TestRTTI_DefaultValueInherit',
  27295. LinesToStr([ // statements
  27296. 'rtl.createClass($mod, "TObject", null, function () {',
  27297. ' this.$init = function () {',
  27298. ' this.FA = 0;',
  27299. ' this.FB = 0;',
  27300. ' };',
  27301. ' this.$final = function () {',
  27302. ' };',
  27303. '});',
  27304. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  27305. ' var $r = this.$rtti;',
  27306. ' $r.addProperty(',
  27307. ' "A",',
  27308. ' 0,',
  27309. ' rtl.byte,',
  27310. ' "FA",',
  27311. ' "",',
  27312. ' {',
  27313. ' Default: 1',
  27314. ' }',
  27315. ' );',
  27316. ' $r.addProperty("B", 0, rtl.byte, "FB", "");',
  27317. '});',
  27318. '']),
  27319. LinesToStr([ // $mod.$main
  27320. '']));
  27321. end;
  27322. procedure TTestModule.TestRTTI_OverrideMethod;
  27323. begin
  27324. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27325. StartProgram(false);
  27326. Add('type');
  27327. Add(' TObject = class');
  27328. Add(' published');
  27329. Add(' procedure DoIt; virtual; abstract;');
  27330. Add(' end;');
  27331. Add(' TSky = class');
  27332. Add(' published');
  27333. Add(' procedure DoIt; override;');
  27334. Add(' end;');
  27335. Add('procedure TSky.DoIt; begin end;');
  27336. Add('begin');
  27337. ConvertProgram;
  27338. CheckSource('TestRTTI_OverrideMethod',
  27339. LinesToStr([ // statements
  27340. 'rtl.createClass($mod, "TObject", null, function () {',
  27341. ' this.$init = function () {',
  27342. ' };',
  27343. ' this.$final = function () {',
  27344. ' };',
  27345. ' var $r = this.$rtti;',
  27346. ' $r.addMethod("DoIt", 0, null);',
  27347. '});',
  27348. 'rtl.createClass($mod, "TSky", $mod.TObject, function () {',
  27349. ' this.DoIt = function () {',
  27350. ' };',
  27351. '});',
  27352. '']),
  27353. LinesToStr([ // $mod.$main
  27354. '']));
  27355. end;
  27356. procedure TTestModule.TestRTTI_OverloadProperty;
  27357. begin
  27358. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27359. StartProgram(false);
  27360. Add('type');
  27361. Add(' TObject = class');
  27362. Add(' protected');
  27363. Add(' FFlag: longint;');
  27364. Add(' published');
  27365. Add(' property Flag: longint read fflag;');
  27366. Add(' end;');
  27367. Add(' TSky = class');
  27368. Add(' published');
  27369. Add(' property FLAG: longint write fflag;');
  27370. Add(' end;');
  27371. Add('begin');
  27372. ConvertProgram;
  27373. CheckSource('TestRTTI_OverrideMethod',
  27374. LinesToStr([ // statements
  27375. 'rtl.createClass($mod, "TObject", null, function () {',
  27376. ' this.$init = function () {',
  27377. ' this.FFlag = 0;',
  27378. ' };',
  27379. ' this.$final = function () {',
  27380. ' };',
  27381. ' var $r = this.$rtti;',
  27382. ' $r.addProperty("Flag", 0, rtl.longint, "FFlag", "");',
  27383. '});',
  27384. 'rtl.createClass($mod, "TSky", $mod.TObject, function () {',
  27385. ' var $r = this.$rtti;',
  27386. ' $r.addProperty("Flag", 0, rtl.longint, "", "FFlag");',
  27387. '});',
  27388. '']),
  27389. LinesToStr([ // $mod.$main
  27390. '']));
  27391. end;
  27392. procedure TTestModule.TestRTTI_ClassForward;
  27393. begin
  27394. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27395. StartProgram(false);
  27396. Add('type');
  27397. Add(' TObject = class end;');
  27398. Add(' tbridge = class;');
  27399. Add(' TProc = function: tbridge;');
  27400. Add(' TOger = class');
  27401. Add(' published');
  27402. Add(' FBridge: tbridge;');
  27403. Add(' procedure SetBridge(Value: tbridge); virtual; abstract;');
  27404. Add(' property Bridge: tbridge read fbridge write setbridge;');
  27405. Add(' end;');
  27406. Add(' TBridge = class');
  27407. Add(' FOger: toger;');
  27408. Add(' end;');
  27409. Add('var p: Pointer;');
  27410. Add(' b: tbridge;');
  27411. Add('begin');
  27412. Add(' p:=typeinfo(tbridge);');
  27413. Add(' p:=typeinfo(b);');
  27414. ConvertProgram;
  27415. CheckSource('TestRTTI_ClassForward',
  27416. LinesToStr([ // statements
  27417. 'rtl.createClass($mod, "TObject", null, function () {',
  27418. ' this.$init = function () {',
  27419. ' };',
  27420. ' this.$final = function () {',
  27421. ' };',
  27422. '});',
  27423. '$mod.$rtti.$Class("TBridge");',
  27424. '$mod.$rtti.$ProcVar("TProc", {',
  27425. ' procsig: rtl.newTIProcSig(null, $mod.$rtti["TBridge"])',
  27426. '});',
  27427. 'rtl.createClass($mod, "TOger", $mod.TObject, function () {',
  27428. ' this.$init = function () {',
  27429. ' $mod.TObject.$init.call(this);',
  27430. ' this.FBridge = null;',
  27431. ' };',
  27432. ' this.$final = function () {',
  27433. ' this.FBridge = undefined;',
  27434. ' $mod.TObject.$final.call(this);',
  27435. ' };',
  27436. ' var $r = this.$rtti;',
  27437. ' $r.addField("FBridge", $mod.$rtti["TBridge"]);',
  27438. ' $r.addMethod("SetBridge", 0, [["Value", $mod.$rtti["TBridge"]]]);',
  27439. ' $r.addProperty("Bridge", 2, $mod.$rtti["TBridge"], "FBridge", "SetBridge");',
  27440. '});',
  27441. 'rtl.createClass($mod, "TBridge", $mod.TObject, function () {',
  27442. ' this.$init = function () {',
  27443. ' $mod.TObject.$init.call(this);',
  27444. ' this.FOger = null;',
  27445. ' };',
  27446. ' this.$final = function () {',
  27447. ' this.FOger = undefined;',
  27448. ' $mod.TObject.$final.call(this);',
  27449. ' };',
  27450. '});',
  27451. 'this.p = null;',
  27452. 'this.b = null;',
  27453. '']),
  27454. LinesToStr([ // $mod.$main
  27455. '$mod.p = $mod.$rtti["TBridge"];',
  27456. '$mod.p = $mod.b.$rtti;',
  27457. '']));
  27458. end;
  27459. procedure TTestModule.TestRTTI_ClassOf;
  27460. begin
  27461. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27462. StartProgram(false);
  27463. Add('type');
  27464. Add(' TClass = class of tobject;');
  27465. Add(' TProcA = function: TClass;');
  27466. Add(' TObject = class');
  27467. Add(' published');
  27468. Add(' C: tclass;');
  27469. Add(' end;');
  27470. Add(' tfox = class;');
  27471. Add(' TBird = class end;');
  27472. Add(' TBirds = class of tbird;');
  27473. Add(' TFox = class end;');
  27474. Add(' TFoxes = class of tfox;');
  27475. Add(' TCows = class of TCow;');
  27476. Add(' TCow = class;');
  27477. Add(' TCow = class end;');
  27478. Add('begin');
  27479. ConvertProgram;
  27480. CheckSource('TestRTTI_ClassOf',
  27481. LinesToStr([ // statements
  27482. '$mod.$rtti.$Class("TObject");',
  27483. '$mod.$rtti.$ClassRef("TClass", {',
  27484. ' instancetype: $mod.$rtti["TObject"]',
  27485. '});',
  27486. '$mod.$rtti.$ProcVar("TProcA", {',
  27487. ' procsig: rtl.newTIProcSig(null, $mod.$rtti["TClass"])',
  27488. '});',
  27489. 'rtl.createClass($mod, "TObject", null, function () {',
  27490. ' this.$init = function () {',
  27491. ' this.C = null;',
  27492. ' };',
  27493. ' this.$final = function () {',
  27494. ' this.C = undefined;',
  27495. ' };',
  27496. ' var $r = this.$rtti;',
  27497. ' $r.addField("C", $mod.$rtti["TClass"]);',
  27498. '});',
  27499. '$mod.$rtti.$Class("TFox");',
  27500. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  27501. '});',
  27502. '$mod.$rtti.$ClassRef("TBirds", {',
  27503. ' instancetype: $mod.$rtti["TBird"]',
  27504. '});',
  27505. 'rtl.createClass($mod, "TFox", $mod.TObject, function () {',
  27506. '});',
  27507. '$mod.$rtti.$ClassRef("TFoxes", {',
  27508. ' instancetype: $mod.$rtti["TFox"]',
  27509. '});',
  27510. '$mod.$rtti.$Class("TCow");',
  27511. '$mod.$rtti.$ClassRef("TCows", {',
  27512. ' instancetype: $mod.$rtti["TCow"]',
  27513. '});',
  27514. 'rtl.createClass($mod, "TCow", $mod.TObject, function () {',
  27515. '});',
  27516. '']),
  27517. LinesToStr([ // $mod.$main
  27518. '']));
  27519. end;
  27520. procedure TTestModule.TestRTTI_Record;
  27521. begin
  27522. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27523. StartProgram(false);
  27524. Add('type');
  27525. Add(' integer = longint;');
  27526. Add(' TPoint = record');
  27527. Add(' x,y: integer;');
  27528. Add(' end;');
  27529. Add('var p: pointer;');
  27530. Add(' r: tpoint;');
  27531. Add('begin');
  27532. Add(' p:=typeinfo(tpoint);');
  27533. Add(' p:=typeinfo(r);');
  27534. Add(' p:=typeinfo(r.x);');
  27535. ConvertProgram;
  27536. CheckSource('TestRTTI_Record',
  27537. LinesToStr([ // statements
  27538. 'rtl.recNewT($mod, "TPoint", function () {',
  27539. ' this.x = 0;',
  27540. ' this.y = 0;',
  27541. ' this.$eq = function (b) {',
  27542. ' return (this.x === b.x) && (this.y === b.y);',
  27543. ' };',
  27544. ' this.$assign = function (s) {',
  27545. ' this.x = s.x;',
  27546. ' this.y = s.y;',
  27547. ' return this;',
  27548. ' };',
  27549. ' var $r = $mod.$rtti.$Record("TPoint", {});',
  27550. ' $r.addField("x", rtl.longint);',
  27551. ' $r.addField("y", rtl.longint);',
  27552. '});',
  27553. 'this.p = null;',
  27554. 'this.r = $mod.TPoint.$new();',
  27555. '']),
  27556. LinesToStr([ // $mod.$main
  27557. '$mod.p = $mod.$rtti["TPoint"];',
  27558. '$mod.p = $mod.$rtti["TPoint"];',
  27559. '$mod.p = rtl.longint;',
  27560. '']));
  27561. end;
  27562. procedure TTestModule.TestRTTI_RecordAnonymousArray;
  27563. begin
  27564. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27565. StartProgram(false);
  27566. Add('type');
  27567. Add(' TFloatRec = record');
  27568. Add(' d: array of char;');
  27569. // Add(' i: array of array of longint;');
  27570. Add(' end;');
  27571. Add('var p: pointer;');
  27572. Add(' r: tfloatrec;');
  27573. Add('begin');
  27574. Add(' p:=typeinfo(tfloatrec);');
  27575. Add(' p:=typeinfo(r);');
  27576. Add(' p:=typeinfo(r.d);');
  27577. ConvertProgram;
  27578. CheckSource('TestRTTI_Record',
  27579. LinesToStr([ // statements
  27580. 'rtl.recNewT($mod, "TFloatRec", function () {',
  27581. ' this.d = [];',
  27582. ' this.$eq = function (b) {',
  27583. ' return this.d === b.d;',
  27584. ' };',
  27585. ' this.$assign = function (s) {',
  27586. ' this.d = s.d;',
  27587. ' return this;',
  27588. ' };',
  27589. ' $mod.$rtti.$DynArray("TFloatRec.d$a", {',
  27590. ' eltype: rtl.char',
  27591. ' });',
  27592. ' var $r = $mod.$rtti.$Record("TFloatRec", {});',
  27593. ' $r.addField("d", $mod.$rtti["TFloatRec.d$a"]);',
  27594. '});',
  27595. 'this.p = null;',
  27596. 'this.r = $mod.TFloatRec.$new();',
  27597. '']),
  27598. LinesToStr([ // $mod.$main
  27599. '$mod.p = $mod.$rtti["TFloatRec"];',
  27600. '$mod.p = $mod.$rtti["TFloatRec"];',
  27601. '$mod.p = $mod.$rtti["TFloatRec.d$a"];',
  27602. '']));
  27603. end;
  27604. procedure TTestModule.TestRTTI_LocalTypes;
  27605. begin
  27606. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27607. StartProgram(false);
  27608. Add([
  27609. 'procedure DoIt;',
  27610. 'type',
  27611. ' integer = longint;',
  27612. ' TPoint = record',
  27613. ' x,y: integer;',
  27614. ' end;',
  27615. 'var p: TPoint;',
  27616. 'begin',
  27617. 'end;',
  27618. 'begin']);
  27619. ConvertProgram;
  27620. CheckSource('TestRTTI_LocalTypes',
  27621. LinesToStr([ // statements
  27622. 'var TPoint = rtl.recNewT(null, "", function () {',
  27623. ' this.x = 0;',
  27624. ' this.y = 0;',
  27625. ' this.$eq = function (b) {',
  27626. ' return (this.x === b.x) && (this.y === b.y);',
  27627. ' };',
  27628. ' this.$assign = function (s) {',
  27629. ' this.x = s.x;',
  27630. ' this.y = s.y;',
  27631. ' return this;',
  27632. ' };',
  27633. '});',
  27634. 'this.DoIt = function () {',
  27635. ' var p = TPoint.$new();',
  27636. '};',
  27637. '']),
  27638. LinesToStr([ // $mod.$main
  27639. '']));
  27640. end;
  27641. procedure TTestModule.TestRTTI_TypeInfo_BaseTypes;
  27642. begin
  27643. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27644. StartProgram(false);
  27645. Add([
  27646. 'type',
  27647. ' TCaption = string;',
  27648. ' TYesNo = boolean;',
  27649. ' TLetter = char;',
  27650. ' TFloat = double;',
  27651. ' TPtr = pointer;',
  27652. ' TShortInt = shortint;',
  27653. ' TByte = byte;',
  27654. ' TSmallInt = smallint;',
  27655. ' TWord = word;',
  27656. ' TInt32 = longint;',
  27657. ' TDWord = longword;',
  27658. ' TValue = jsvalue;',
  27659. 'var p: TPtr;',
  27660. 'begin',
  27661. ' p:=typeinfo(string);',
  27662. ' p:=typeinfo(tcaption);',
  27663. ' p:=typeinfo(boolean);',
  27664. ' p:=typeinfo(tyesno);',
  27665. ' p:=typeinfo(char);',
  27666. ' p:=typeinfo(tletter);',
  27667. ' p:=typeinfo(double);',
  27668. ' p:=typeinfo(tfloat);',
  27669. ' p:=typeinfo(pointer);',
  27670. ' p:=typeinfo(tptr);',
  27671. ' p:=typeinfo(shortint);',
  27672. ' p:=typeinfo(tshortint);',
  27673. ' p:=typeinfo(byte);',
  27674. ' p:=typeinfo(tbyte);',
  27675. ' p:=typeinfo(smallint);',
  27676. ' p:=typeinfo(tsmallint);',
  27677. ' p:=typeinfo(word);',
  27678. ' p:=typeinfo(tword);',
  27679. ' p:=typeinfo(longword);',
  27680. ' p:=typeinfo(tdword);',
  27681. ' p:=typeinfo(jsvalue);',
  27682. ' p:=typeinfo(tvalue);',
  27683. '']);
  27684. ConvertProgram;
  27685. CheckSource('TestRTTI_TypeInfo_BaseTypes',
  27686. LinesToStr([ // statements
  27687. 'this.p = null;',
  27688. '']),
  27689. LinesToStr([ // $mod.$main
  27690. '$mod.p = rtl.string;',
  27691. '$mod.p = rtl.string;',
  27692. '$mod.p = rtl.boolean;',
  27693. '$mod.p = rtl.boolean;',
  27694. '$mod.p = rtl.char;',
  27695. '$mod.p = rtl.char;',
  27696. '$mod.p = rtl.double;',
  27697. '$mod.p = rtl.double;',
  27698. '$mod.p = rtl.pointer;',
  27699. '$mod.p = rtl.pointer;',
  27700. '$mod.p = rtl.shortint;',
  27701. '$mod.p = rtl.shortint;',
  27702. '$mod.p = rtl.byte;',
  27703. '$mod.p = rtl.byte;',
  27704. '$mod.p = rtl.smallint;',
  27705. '$mod.p = rtl.smallint;',
  27706. '$mod.p = rtl.word;',
  27707. '$mod.p = rtl.word;',
  27708. '$mod.p = rtl.longword;',
  27709. '$mod.p = rtl.longword;',
  27710. '$mod.p = rtl.jsvalue;',
  27711. '$mod.p = rtl.jsvalue;',
  27712. '']));
  27713. end;
  27714. procedure TTestModule.TestRTTI_TypeInfo_Type_BaseTypes;
  27715. begin
  27716. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27717. StartProgram(false);
  27718. Add([
  27719. 'type',
  27720. ' TCaption = type string;',
  27721. ' TYesNo = type boolean;',
  27722. ' TLetter = type char;',
  27723. ' TFloat = type double;',
  27724. ' TPtr = type pointer;',
  27725. ' TShortInt = type shortint;',
  27726. ' TByte = type byte;',
  27727. ' TSmallInt = type smallint;',
  27728. ' TWord = type word;',
  27729. ' TInt32 = type longint;',
  27730. ' TDWord = type longword;',
  27731. ' TValue = type jsvalue;',
  27732. ' TAliasValue = type TValue;',
  27733. 'var',
  27734. ' p: TPtr;',
  27735. ' a: TAliasValue;',
  27736. 'begin',
  27737. ' p:=typeinfo(tcaption);',
  27738. ' p:=typeinfo(tyesno);',
  27739. ' p:=typeinfo(tletter);',
  27740. ' p:=typeinfo(tfloat);',
  27741. ' p:=typeinfo(tptr);',
  27742. ' p:=typeinfo(tshortint);',
  27743. ' p:=typeinfo(tbyte);',
  27744. ' p:=typeinfo(tsmallint);',
  27745. ' p:=typeinfo(tword);',
  27746. ' p:=typeinfo(tdword);',
  27747. ' p:=typeinfo(tvalue);',
  27748. ' p:=typeinfo(taliasvalue);',
  27749. ' p:=typeinfo(a);',
  27750. '']);
  27751. ConvertProgram;
  27752. CheckSource('TestRTTI_TypeInfo_Type_BaseTypes',
  27753. LinesToStr([ // statements
  27754. '$mod.$rtti.$inherited("TCaption", rtl.string, {});',
  27755. '$mod.$rtti.$inherited("TYesNo", rtl.boolean, {});',
  27756. '$mod.$rtti.$inherited("TLetter", rtl.char, {});',
  27757. '$mod.$rtti.$inherited("TFloat", rtl.double, {});',
  27758. '$mod.$rtti.$inherited("TPtr", rtl.pointer, {});',
  27759. '$mod.$rtti.$inherited("TShortInt", rtl.shortint, {});',
  27760. '$mod.$rtti.$inherited("TByte", rtl.byte, {});',
  27761. '$mod.$rtti.$inherited("TSmallInt", rtl.smallint, {});',
  27762. '$mod.$rtti.$inherited("TWord", rtl.word, {});',
  27763. '$mod.$rtti.$inherited("TInt32", rtl.longint, {});',
  27764. '$mod.$rtti.$inherited("TDWord", rtl.longword, {});',
  27765. '$mod.$rtti.$inherited("TValue", rtl.jsvalue, {});',
  27766. '$mod.$rtti.$inherited("TAliasValue", $mod.$rtti["TValue"], {});',
  27767. 'this.p = null;',
  27768. 'this.a = undefined;',
  27769. '']),
  27770. LinesToStr([ // $mod.$main
  27771. '$mod.p = $mod.$rtti["TCaption"];',
  27772. '$mod.p = $mod.$rtti["TYesNo"];',
  27773. '$mod.p = $mod.$rtti["TLetter"];',
  27774. '$mod.p = $mod.$rtti["TFloat"];',
  27775. '$mod.p = $mod.$rtti["TPtr"];',
  27776. '$mod.p = $mod.$rtti["TShortInt"];',
  27777. '$mod.p = $mod.$rtti["TByte"];',
  27778. '$mod.p = $mod.$rtti["TSmallInt"];',
  27779. '$mod.p = $mod.$rtti["TWord"];',
  27780. '$mod.p = $mod.$rtti["TDWord"];',
  27781. '$mod.p = $mod.$rtti["TValue"];',
  27782. '$mod.p = $mod.$rtti["TAliasValue"];',
  27783. '$mod.p = $mod.$rtti["TAliasValue"];',
  27784. '']));
  27785. end;
  27786. procedure TTestModule.TestRTTI_TypeInfo_LocalFail;
  27787. begin
  27788. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27789. StartProgram(false);
  27790. Add('procedure DoIt;');
  27791. Add('type');
  27792. Add(' integer = longint;');
  27793. Add(' TPoint = record');
  27794. Add(' x,y: integer;');
  27795. Add(' end;');
  27796. Add('var p: pointer;');
  27797. Add('begin');
  27798. Add(' p:=typeinfo(tpoint);');
  27799. Add('end;');
  27800. Add('begin');
  27801. SetExpectedPasResolverError(sSymbolCannotBePublished,nSymbolCannotBePublished);
  27802. ConvertProgram;
  27803. end;
  27804. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses1;
  27805. begin
  27806. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27807. StartProgram(false);
  27808. Add([
  27809. '{$modeswitch externalclass}',
  27810. 'type',
  27811. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  27812. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo) end;',
  27813. ' TFlag = (up,down);',
  27814. ' TTypeInfoEnum = class external name ''rtl.tTypeInfoEnum''(TTypeInfoInteger) end;',
  27815. ' TFlags = set of TFlag;',
  27816. ' TTypeInfoSet = class external name ''rtl.tTypeInfoSet''(TTypeInfo) end;',
  27817. 'var',
  27818. ' ti: TTypeInfo;',
  27819. ' tiInt: TTypeInfoInteger;',
  27820. ' tiEnum: TTypeInfoEnum;',
  27821. ' tiSet: TTypeInfoSet;',
  27822. 'begin',
  27823. ' ti:=typeinfo(string);',
  27824. ' ti:=typeinfo(boolean);',
  27825. ' ti:=typeinfo(char);',
  27826. ' ti:=typeinfo(double);',
  27827. ' tiInt:=typeinfo(shortint);',
  27828. ' tiInt:=typeinfo(byte);',
  27829. ' tiInt:=typeinfo(smallint);',
  27830. ' tiInt:=typeinfo(word);',
  27831. ' tiInt:=typeinfo(longint);',
  27832. ' tiInt:=typeinfo(longword);',
  27833. ' ti:=typeinfo(jsvalue);',
  27834. ' tiEnum:=typeinfo(tflag);',
  27835. ' tiSet:=typeinfo(tflags);']);
  27836. ConvertProgram;
  27837. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses1',
  27838. LinesToStr([ // statements
  27839. 'this.TFlag = {',
  27840. ' "0": "up",',
  27841. ' up: 0,',
  27842. ' "1": "down",',
  27843. ' down: 1',
  27844. '};',
  27845. '$mod.$rtti.$Enum("TFlag", {',
  27846. ' minvalue: 0,',
  27847. ' maxvalue: 1,',
  27848. ' ordtype: 1,',
  27849. ' enumtype: this.TFlag',
  27850. '});',
  27851. '$mod.$rtti.$Set("TFlags", {',
  27852. ' comptype: $mod.$rtti["TFlag"]',
  27853. '});',
  27854. 'this.ti = null;',
  27855. 'this.tiInt = null;',
  27856. 'this.tiEnum = null;',
  27857. 'this.tiSet = null;',
  27858. '']),
  27859. LinesToStr([ // $mod.$main
  27860. '$mod.ti = rtl.string;',
  27861. '$mod.ti = rtl.boolean;',
  27862. '$mod.ti = rtl.char;',
  27863. '$mod.ti = rtl.double;',
  27864. '$mod.tiInt = rtl.shortint;',
  27865. '$mod.tiInt = rtl.byte;',
  27866. '$mod.tiInt = rtl.smallint;',
  27867. '$mod.tiInt = rtl.word;',
  27868. '$mod.tiInt = rtl.longint;',
  27869. '$mod.tiInt = rtl.longword;',
  27870. '$mod.ti = rtl.jsvalue;',
  27871. '$mod.tiEnum = $mod.$rtti["TFlag"];',
  27872. '$mod.tiSet = $mod.$rtti["TFlags"];',
  27873. '']));
  27874. end;
  27875. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses2;
  27876. begin
  27877. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27878. StartProgram(false);
  27879. Add('{$modeswitch externalclass}');
  27880. Add('type');
  27881. Add(' TTypeInfo = class external name ''rtl.tTypeInfo'' end;');
  27882. Add(' TStaticArr = array[boolean] of string;');
  27883. Add(' TTypeInfoStaticArray = class external name ''rtl.tTypeInfoStaticArray''(TTypeInfo) end;');
  27884. Add(' TDynArr = array of string;');
  27885. Add(' TTypeInfoDynArray = class external name ''rtl.tTypeInfoDynArray''(TTypeInfo) end;');
  27886. Add(' TProc = procedure;');
  27887. Add(' TTypeInfoProcVar = class external name ''rtl.tTypeInfoProcVar''(TTypeInfo) end;');
  27888. Add(' TMethod = procedure of object;');
  27889. Add(' TTypeInfoMethodVar = class external name ''rtl.tTypeInfoMethodVar''(TTypeInfoProcVar) end;');
  27890. Add('var');
  27891. Add(' StaticArray: TStaticArr;');
  27892. Add(' tiStaticArray: TTypeInfoStaticArray;');
  27893. Add(' DynArray: TDynArr;');
  27894. Add(' tiDynArray: TTypeInfoDynArray;');
  27895. Add(' ProcVar: TProc;');
  27896. Add(' tiProcVar: TTypeInfoProcVar;');
  27897. Add(' MethodVar: TMethod;');
  27898. Add(' tiMethodVar: TTypeInfoMethodVar;');
  27899. Add('begin');
  27900. Add(' tiStaticArray:=typeinfo(StaticArray);');
  27901. Add(' tiStaticArray:=typeinfo(TStaticArr);');
  27902. Add(' tiDynArray:=typeinfo(DynArray);');
  27903. Add(' tiDynArray:=typeinfo(TDynArr);');
  27904. Add(' tiProcVar:=typeinfo(ProcVar);');
  27905. Add(' tiProcVar:=typeinfo(TProc);');
  27906. Add(' tiMethodVar:=typeinfo(MethodVar);');
  27907. Add(' tiMethodVar:=typeinfo(TMethod);');
  27908. ConvertProgram;
  27909. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses2',
  27910. LinesToStr([ // statements
  27911. ' $mod.$rtti.$StaticArray("TStaticArr", {',
  27912. ' dims: [2],',
  27913. ' eltype: rtl.string',
  27914. '});',
  27915. '$mod.$rtti.$DynArray("TDynArr", {',
  27916. ' eltype: rtl.string',
  27917. '});',
  27918. '$mod.$rtti.$ProcVar("TProc", {',
  27919. ' procsig: rtl.newTIProcSig(null)',
  27920. '});',
  27921. '$mod.$rtti.$MethodVar("TMethod", {',
  27922. ' procsig: rtl.newTIProcSig(null),',
  27923. ' methodkind: 0',
  27924. '});',
  27925. 'this.StaticArray = rtl.arraySetLength(null,"",2);',
  27926. 'this.tiStaticArray = null;',
  27927. 'this.DynArray = [];',
  27928. 'this.tiDynArray = null;',
  27929. 'this.ProcVar = null;',
  27930. 'this.tiProcVar = null;',
  27931. 'this.MethodVar = null;',
  27932. 'this.tiMethodVar = null;',
  27933. '']),
  27934. LinesToStr([ // $mod.$main
  27935. '$mod.tiStaticArray = $mod.$rtti["TStaticArr"];',
  27936. '$mod.tiStaticArray = $mod.$rtti["TStaticArr"];',
  27937. '$mod.tiDynArray = $mod.$rtti["TDynArr"];',
  27938. '$mod.tiDynArray = $mod.$rtti["TDynArr"];',
  27939. '$mod.tiProcVar = $mod.$rtti["TProc"];',
  27940. '$mod.tiProcVar = $mod.$rtti["TProc"];',
  27941. '$mod.tiMethodVar = $mod.$rtti["TMethod"];',
  27942. '$mod.tiMethodVar = $mod.$rtti["TMethod"];',
  27943. '']));
  27944. end;
  27945. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses3;
  27946. begin
  27947. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27948. StartProgram(false);
  27949. Add('{$modeswitch externalclass}');
  27950. Add('type');
  27951. Add(' TTypeInfo = class external name ''rtl.tTypeInfo'' end;');
  27952. Add(' TRec = record end;');
  27953. Add(' TTypeInfoRecord = class external name ''rtl.tTypeInfoRecord''(TTypeInfo) end;');
  27954. // ToDo: ^PRec
  27955. Add(' TObject = class end;');
  27956. Add(' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;');
  27957. Add(' TClass = class of tobject;');
  27958. Add(' TTypeInfoClassRef = class external name ''rtl.tTypeInfoClassRef''(TTypeInfo) end;');
  27959. Add(' TTypeInfoPointer = class external name ''rtl.tTypeInfoPointer''(TTypeInfo) end;');
  27960. Add('var');
  27961. Add(' Rec: trec;');
  27962. Add(' tiRecord: ttypeinforecord;');
  27963. Add(' Obj: tobject;');
  27964. Add(' tiClass: ttypeinfoclass;');
  27965. Add(' aClass: tclass;');
  27966. Add(' tiClassRef: ttypeinfoclassref;');
  27967. // ToDo: ^PRec
  27968. Add(' tiPointer: ttypeinfopointer;');
  27969. Add('begin');
  27970. Add(' tirecord:=typeinfo(trec);');
  27971. Add(' tirecord:=typeinfo(trec);');
  27972. Add(' ticlass:=typeinfo(obj);');
  27973. Add(' ticlass:=typeinfo(tobject);');
  27974. Add(' ticlass:=typeinfo(aclass);');
  27975. Add(' ticlassref:=typeinfo(tclass);');
  27976. ConvertProgram;
  27977. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses3',
  27978. LinesToStr([ // statements
  27979. 'rtl.recNewT($mod, "TRec", function () {',
  27980. ' this.$eq = function (b) {',
  27981. ' return true;',
  27982. ' };',
  27983. ' this.$assign = function (s) {',
  27984. ' return this;',
  27985. ' };',
  27986. ' $mod.$rtti.$Record("TRec", {});',
  27987. '});',
  27988. 'rtl.createClass($mod, "TObject", null, function () {',
  27989. ' this.$init = function () {',
  27990. ' };',
  27991. ' this.$final = function () {',
  27992. ' };',
  27993. '});',
  27994. '$mod.$rtti.$ClassRef("TClass", {',
  27995. ' instancetype: $mod.$rtti["TObject"]',
  27996. '});',
  27997. 'this.Rec = $mod.TRec.$new();',
  27998. 'this.tiRecord = null;',
  27999. 'this.Obj = null;',
  28000. 'this.tiClass = null;',
  28001. 'this.aClass = null;',
  28002. 'this.tiClassRef = null;',
  28003. 'this.tiPointer = null;',
  28004. '']),
  28005. LinesToStr([ // $mod.$main
  28006. '$mod.tiRecord = $mod.$rtti["TRec"];',
  28007. '$mod.tiRecord = $mod.$rtti["TRec"];',
  28008. '$mod.tiClass = $mod.Obj.$rtti;',
  28009. '$mod.tiClass = $mod.$rtti["TObject"];',
  28010. '$mod.tiClass = $mod.aClass.$rtti;',
  28011. '$mod.tiClassRef = $mod.$rtti["TClass"];',
  28012. '']));
  28013. end;
  28014. procedure TTestModule.TestRTTI_TypeInfo_FunctionClassType;
  28015. begin
  28016. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28017. StartProgram(false);
  28018. Add([
  28019. '{$modeswitch externalclass}',
  28020. 'type',
  28021. ' TClass = class of tobject;',
  28022. ' TObject = class',
  28023. ' function MyClass: TClass;',
  28024. ' class function ClassType: TClass;',
  28025. ' end;',
  28026. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28027. ' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;',
  28028. 'function TObject.MyClass: TClass;',
  28029. 'var t: TTypeInfoClass;',
  28030. 'begin',
  28031. ' t:=TypeInfo(Self);',
  28032. ' t:=TypeInfo(Result);',
  28033. ' t:=TypeInfo(TObject);',
  28034. 'end;',
  28035. 'class function TObject.ClassType: TClass;',
  28036. 'var t: TTypeInfoClass;',
  28037. 'begin',
  28038. ' t:=TypeInfo(Self);',
  28039. ' t:=TypeInfo(Result);',
  28040. 'end;',
  28041. 'var',
  28042. ' Obj: TObject;',
  28043. ' t: TTypeInfoClass;',
  28044. 'begin',
  28045. ' t:=TypeInfo(TObject.ClassType);',
  28046. ' t:=TypeInfo(Obj.ClassType);',
  28047. ' t:=TypeInfo(Obj.MyClass);',
  28048. '']);
  28049. ConvertProgram;
  28050. CheckSource('TestRTTI_TypeInfo_FunctionClassType',
  28051. LinesToStr([ // statements
  28052. '$mod.$rtti.$Class("TObject");',
  28053. '$mod.$rtti.$ClassRef("TClass", {',
  28054. ' instancetype: $mod.$rtti["TObject"]',
  28055. '});',
  28056. 'rtl.createClass($mod, "TObject", null, function () {',
  28057. ' this.$init = function () {',
  28058. ' };',
  28059. ' this.$final = function () {',
  28060. ' };',
  28061. ' this.MyClass = function () {',
  28062. ' var Result = null;',
  28063. ' var t = null;',
  28064. ' t = this.$rtti;',
  28065. ' t = Result.$rtti;',
  28066. ' t = $mod.$rtti["TObject"];',
  28067. ' return Result;',
  28068. ' };',
  28069. ' this.ClassType = function () {',
  28070. ' var Result = null;',
  28071. ' var t = null;',
  28072. ' t = this.$rtti;',
  28073. ' t = Result.$rtti;',
  28074. ' return Result;',
  28075. ' };',
  28076. '});',
  28077. 'this.Obj = null;',
  28078. 'this.t = null;',
  28079. '']),
  28080. LinesToStr([ // $mod.$main
  28081. '$mod.t = $mod.TObject.ClassType().$rtti;',
  28082. '$mod.t = $mod.Obj.$class.ClassType().$rtti;',
  28083. '$mod.t = $mod.Obj.MyClass().$rtti;',
  28084. '']));
  28085. end;
  28086. procedure TTestModule.TestRTTI_TypeInfo_MixedUnits_PointerAndClass;
  28087. begin
  28088. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28089. AddModuleWithIntfImplSrc('typinfo.pas',
  28090. LinesToStr([
  28091. '{$modeswitch externalclass}',
  28092. 'type',
  28093. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28094. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo) end;',
  28095. '']),
  28096. '');
  28097. AddModuleWithIntfImplSrc('unit2.pas',
  28098. LinesToStr([
  28099. 'uses typinfo;',
  28100. 'type PTypeInfo = TTypeInfo;', // delphi compatibility code
  28101. 'procedure DoPtr(p: PTypeInfo);',
  28102. 'procedure DoInfo(t: TTypeInfo);',
  28103. 'procedure DoInt(t: TTypeInfoInteger);',
  28104. '']),
  28105. LinesToStr([
  28106. 'procedure DoPtr(p: PTypeInfo);',
  28107. 'begin end;',
  28108. 'procedure DoInfo(t: TTypeInfo);',
  28109. 'begin end;',
  28110. 'procedure DoInt(t: TTypeInfoInteger);',
  28111. 'begin end;',
  28112. '']));
  28113. StartUnit(true);
  28114. Add([
  28115. 'interface',
  28116. 'uses unit2;', // does not use unit typinfo
  28117. 'implementation',
  28118. 'var',
  28119. ' i: byte;',
  28120. ' p: pointer;',
  28121. ' t: PTypeInfo;',
  28122. 'initialization',
  28123. ' p:=typeinfo(i);',
  28124. ' t:=typeinfo(i);',
  28125. ' if p=t then ;',
  28126. ' if p=typeinfo(i) then ;',
  28127. ' if typeinfo(i)=p then ;',
  28128. ' if t=typeinfo(i) then ;',
  28129. ' if typeinfo(i)=t then ;',
  28130. ' DoPtr(p);',
  28131. ' DoPtr(t);',
  28132. ' DoPtr(typeinfo(i));',
  28133. ' DoInfo(p);',
  28134. ' DoInfo(t);',
  28135. ' DoInfo(typeinfo(i));',
  28136. ' DoInt(typeinfo(i));',
  28137. '']);
  28138. ConvertUnit;
  28139. CheckSource('TestRTTI_TypeInfo_MixedUnits_PointerAndClass',
  28140. LinesToStr([ // statements
  28141. 'var $impl = $mod.$impl;',
  28142. '']),
  28143. LinesToStr([ // this.$init
  28144. '$impl.p = rtl.byte;',
  28145. '$impl.t = rtl.byte;',
  28146. 'if ($impl.p === $impl.t) ;',
  28147. 'if ($impl.p === rtl.byte) ;',
  28148. 'if (rtl.byte === $impl.p) ;',
  28149. 'if ($impl.t === rtl.byte) ;',
  28150. 'if (rtl.byte === $impl.t) ;',
  28151. 'pas.unit2.DoPtr($impl.p);',
  28152. 'pas.unit2.DoPtr($impl.t);',
  28153. 'pas.unit2.DoPtr(rtl.byte);',
  28154. 'pas.unit2.DoInfo($impl.p);',
  28155. 'pas.unit2.DoInfo($impl.t);',
  28156. 'pas.unit2.DoInfo(rtl.byte);',
  28157. 'pas.unit2.DoInt(rtl.byte);',
  28158. '']),
  28159. LinesToStr([ // implementation
  28160. '$impl.i = 0;',
  28161. '$impl.p = null;',
  28162. '$impl.t = null;',
  28163. '']) );
  28164. end;
  28165. procedure TTestModule.TestRTTI_Interface_Corba;
  28166. begin
  28167. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28168. StartProgram(false);
  28169. Add([
  28170. '{$interfaces corba}',
  28171. '{$modeswitch externalclass}',
  28172. 'type',
  28173. ' IUnknown = interface',
  28174. ' end;',
  28175. ' IBird = interface',
  28176. ' function GetItem: longint;',
  28177. ' procedure SetItem(Value: longint);',
  28178. ' property Item: longint read GetItem write SetItem;',
  28179. ' end;',
  28180. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28181. ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
  28182. 'procedure DoIt(t: TTypeInfoInterface); begin end;',
  28183. 'var',
  28184. ' i: IBird;',
  28185. ' t: TTypeInfoInterface;',
  28186. 'begin',
  28187. ' t:=TypeInfo(IBird);',
  28188. ' t:=TypeInfo(i);',
  28189. ' DoIt(t);',
  28190. ' DoIt(TypeInfo(IBird));',
  28191. '']);
  28192. ConvertProgram;
  28193. CheckSource('TestRTTI_Interface_Corba',
  28194. LinesToStr([ // statements
  28195. 'rtl.createInterface(',
  28196. ' $mod,',
  28197. ' "IUnknown",',
  28198. ' "{B92D5841-758A-322B-B800-000000000000}",',
  28199. ' [],',
  28200. ' null,',
  28201. ' function () {',
  28202. ' }',
  28203. ');',
  28204. 'rtl.createInterface(',
  28205. ' $mod,',
  28206. ' "IBird",',
  28207. ' "{D32D5841-6264-3AE3-A2C9-B91CE922C9B9}",',
  28208. ' ["GetItem", "SetItem"],',
  28209. ' null,',
  28210. ' function () {',
  28211. ' var $r = this.$rtti;',
  28212. ' $r.addMethod("GetItem", 1, null, rtl.longint);',
  28213. ' $r.addMethod("SetItem", 0, [["Value", rtl.longint]]);',
  28214. ' $r.addProperty("Item", 3, rtl.longint, "GetItem", "SetItem");',
  28215. ' }',
  28216. ');',
  28217. 'this.DoIt = function (t) {',
  28218. '}; ',
  28219. 'this.i = null;',
  28220. 'this.t = null;',
  28221. '']),
  28222. LinesToStr([ // $mod.$main
  28223. '$mod.t = $mod.$rtti["IBird"];',
  28224. '$mod.t = $mod.i.$rtti;',
  28225. '$mod.DoIt($mod.t);',
  28226. '$mod.DoIt($mod.$rtti["IBird"]);',
  28227. '']));
  28228. end;
  28229. procedure TTestModule.TestRTTI_Interface_COM;
  28230. begin
  28231. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28232. StartProgram(false);
  28233. Add([
  28234. '{$interfaces com}',
  28235. '{$modeswitch externalclass}',
  28236. 'type',
  28237. ' TGuid = record end;',
  28238. ' integer = longint;',
  28239. ' IUnknown = interface',
  28240. ' function QueryInterface(const iid: TGuid; out obj): Integer;',
  28241. ' function _AddRef: Integer;',
  28242. ' function _Release: Integer;',
  28243. ' end;',
  28244. ' IBird = interface',
  28245. ' function GetItem: longint;',
  28246. ' procedure SetItem(Value: longint);',
  28247. ' property Item: longint read GetItem write SetItem;',
  28248. ' end;',
  28249. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28250. ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
  28251. 'var',
  28252. ' i: IBird;',
  28253. ' t: TTypeInfoInterface;',
  28254. 'begin',
  28255. ' t:=TypeInfo(IBird);',
  28256. ' t:=TypeInfo(i);',
  28257. '']);
  28258. ConvertProgram;
  28259. CheckSource('TestRTTI_Interface_COM',
  28260. LinesToStr([ // statements
  28261. 'rtl.recNewT($mod, "TGuid", function () {',
  28262. ' this.$eq = function (b) {',
  28263. ' return true;',
  28264. ' };',
  28265. ' this.$assign = function (s) {',
  28266. ' return this;',
  28267. ' };',
  28268. ' $mod.$rtti.$Record("TGuid", {});',
  28269. '});',
  28270. 'rtl.createInterface(',
  28271. ' $mod,',
  28272. ' "IUnknown",',
  28273. ' "{D7ADB00D-1A9B-3EDC-B123-730E661DDFA9}",',
  28274. ' ["QueryInterface", "_AddRef", "_Release"],',
  28275. ' null,',
  28276. ' function () {',
  28277. ' this.$kind = "com";',
  28278. ' var $r = this.$rtti;',
  28279. ' $r.addMethod("QueryInterface", 1, [["iid", $mod.$rtti["TGuid"], 2], ["obj", null, 4]], rtl.longint);',
  28280. ' $r.addMethod("_AddRef", 1, null, rtl.longint);',
  28281. ' $r.addMethod("_Release", 1, null, rtl.longint);',
  28282. ' }',
  28283. ');',
  28284. 'rtl.createInterface(',
  28285. ' $mod,',
  28286. ' "IBird",',
  28287. ' "{9CC77572-0E45-3594-9A88-9E8D865C9E0A}",',
  28288. ' ["GetItem", "SetItem"],',
  28289. ' $mod.IUnknown,',
  28290. ' function () {',
  28291. ' var $r = this.$rtti;',
  28292. ' $r.addMethod("GetItem", 1, null, rtl.longint);',
  28293. ' $r.addMethod("SetItem", 0, [["Value", rtl.longint]]);',
  28294. ' $r.addProperty("Item", 3, rtl.longint, "GetItem", "SetItem");',
  28295. ' }',
  28296. ');',
  28297. 'this.i = null;',
  28298. 'this.t = null;',
  28299. '']),
  28300. LinesToStr([ // $mod.$main
  28301. '$mod.t = $mod.$rtti["IBird"];',
  28302. '$mod.t = $mod.i.$rtti;',
  28303. '']));
  28304. end;
  28305. procedure TTestModule.TestRTTI_ClassHelper;
  28306. begin
  28307. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28308. StartProgram(false);
  28309. Add([
  28310. '{$interfaces com}',
  28311. '{$modeswitch externalclass}',
  28312. 'type',
  28313. ' TObject = class',
  28314. ' end;',
  28315. ' THelper = class helper for TObject',
  28316. ' published',
  28317. ' function GetItem: longint;',
  28318. ' property Item: longint read GetItem;',
  28319. ' end;',
  28320. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28321. ' TTypeInfoHelper = class external name ''rtl.tTypeInfoHelper''(TTypeInfo) end;',
  28322. 'function THelper.GetItem: longint;',
  28323. 'begin',
  28324. 'end;',
  28325. 'var',
  28326. ' t: TTypeInfoHelper;',
  28327. 'begin',
  28328. ' t:=TypeInfo(THelper);',
  28329. '']);
  28330. ConvertProgram;
  28331. CheckSource('TestRTTI_ClassHelper',
  28332. LinesToStr([ // statements
  28333. 'rtl.createClass($mod, "TObject", null, function () {',
  28334. ' this.$init = function () {',
  28335. ' };',
  28336. ' this.$final = function () {',
  28337. ' };',
  28338. '});',
  28339. 'rtl.createHelper($mod, "THelper", null, function () {',
  28340. ' this.GetItem = function () {',
  28341. ' var Result = 0;',
  28342. ' return Result;',
  28343. ' };',
  28344. ' var $r = this.$rtti;',
  28345. ' $r.addMethod("GetItem", 1, null, rtl.longint);',
  28346. ' $r.addProperty("Item", 1, rtl.longint, "GetItem", "");',
  28347. '});',
  28348. 'this.t = null;',
  28349. '']),
  28350. LinesToStr([ // $mod.$main
  28351. '$mod.t = $mod.$rtti["THelper"];',
  28352. '']));
  28353. end;
  28354. procedure TTestModule.TestResourcestringProgram;
  28355. begin
  28356. StartProgram(false);
  28357. Add([
  28358. 'const Bar = ''bar'';',
  28359. 'resourcestring',
  28360. ' Red = ''red'';',
  28361. ' Foobar = ''fOo''+bar;',
  28362. 'var s: string;',
  28363. ' c: char;',
  28364. 'begin',
  28365. ' s:=red;',
  28366. ' s:=test1.red;',
  28367. ' c:=red[1];',
  28368. ' c:=test1.red[2];',
  28369. ' if red=foobar then ;',
  28370. ' if red[3]=red[4] then ;']);
  28371. ConvertProgram;
  28372. CheckSource('TestResourcestringProgram',
  28373. LinesToStr([ // statements
  28374. 'this.Bar = "bar";',
  28375. 'this.s = "";',
  28376. 'this.c = "";',
  28377. '$mod.$resourcestrings = {',
  28378. ' Red: {',
  28379. ' org: "red"',
  28380. ' },',
  28381. ' Foobar: {',
  28382. ' org: "fOobar"',
  28383. ' }',
  28384. '};',
  28385. '']),
  28386. LinesToStr([ // $mod.$main
  28387. '$mod.s = rtl.getResStr(pas.program, "Red");',
  28388. '$mod.s = rtl.getResStr(pas.program, "Red");',
  28389. '$mod.c = rtl.getResStr(pas.program, "Red").charAt(0);',
  28390. '$mod.c = rtl.getResStr(pas.program, "Red").charAt(1);',
  28391. 'if (rtl.getResStr(pas.program, "Red") === rtl.getResStr(pas.program, "Foobar")) ;',
  28392. 'if (rtl.getResStr(pas.program, "Red").charAt(2) === rtl.getResStr(pas.program, "Red").charAt(3)) ;',
  28393. '']));
  28394. end;
  28395. procedure TTestModule.TestResourcestringUnit;
  28396. begin
  28397. StartUnit(false);
  28398. Add([
  28399. 'interface',
  28400. 'const Red = ''rEd'';',
  28401. 'resourcestring',
  28402. ' Blue = ''blue'';',
  28403. ' NotRed = ''not''+Red;',
  28404. 'var s: string;',
  28405. 'implementation',
  28406. 'resourcestring',
  28407. ' ImplGreen = ''green'';',
  28408. 'initialization',
  28409. ' s:=blue+ImplGreen;',
  28410. ' s:=test1.blue+test1.implgreen;',
  28411. ' s:=blue[1]+implgreen[2];']);
  28412. ConvertUnit;
  28413. CheckSource('TestResourcestringUnit',
  28414. LinesToStr([ // statements
  28415. 'this.Red = "rEd";',
  28416. 'this.s = "";',
  28417. '$mod.$resourcestrings = {',
  28418. ' Blue: {',
  28419. ' org: "blue"',
  28420. ' },',
  28421. ' NotRed: {',
  28422. ' org: "notrEd"',
  28423. ' },',
  28424. ' ImplGreen: {',
  28425. ' org: "green"',
  28426. ' }',
  28427. '};',
  28428. '']),
  28429. LinesToStr([ // $mod.$main
  28430. '$mod.s = rtl.getResStr(pas.Test1, "Blue") + rtl.getResStr(pas.Test1, "ImplGreen");',
  28431. '$mod.s = rtl.getResStr(pas.Test1, "Blue") + rtl.getResStr(pas.Test1, "ImplGreen");',
  28432. '$mod.s = rtl.getResStr(pas.Test1, "Blue").charAt(0) + rtl.getResStr(pas.Test1, "ImplGreen").charAt(1);',
  28433. '']));
  28434. end;
  28435. procedure TTestModule.TestResourcestringImplementation;
  28436. begin
  28437. StartUnit(false);
  28438. Add([
  28439. 'interface',
  28440. 'implementation',
  28441. 'resourcestring',
  28442. ' ImplRed = ''red'';']);
  28443. ConvertUnit;
  28444. CheckSource('TestResourcestringImplementation',
  28445. LinesToStr([ // intf statements
  28446. 'var $impl = $mod.$impl;']),
  28447. LinesToStr([ // $mod.$init
  28448. '']),
  28449. LinesToStr([ // impl statements
  28450. '$mod.$resourcestrings = {',
  28451. ' ImplRed: {',
  28452. ' org: "red"',
  28453. ' }',
  28454. '};',
  28455. '']));
  28456. end;
  28457. procedure TTestModule.TestAttributes_Members;
  28458. begin
  28459. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28460. StartProgram(false);
  28461. Add([
  28462. '{$modeswitch PrefixedAttributes}',
  28463. 'type',
  28464. ' TObject = class',
  28465. ' constructor Create;',
  28466. ' end;',
  28467. ' TCustomAttribute = class',
  28468. ' constructor Create(Id: word);',
  28469. ' end;',
  28470. ' [Missing]',
  28471. ' TBird = class',
  28472. ' published',
  28473. ' [Tcustom]',
  28474. ' FField: word;',
  28475. ' [tcustom(14)]',
  28476. ' property Size: word read FField;',
  28477. ' [Tcustom(15)]',
  28478. ' procedure Fly; virtual; abstract;',
  28479. ' end;',
  28480. ' TRec = record',
  28481. ' [Tcustom,tcustom(14)]',
  28482. ' Size: word;',
  28483. ' end;',
  28484. 'constructor TObject.Create; begin end;',
  28485. 'constructor TCustomAttribute.Create(Id: word); begin end;',
  28486. 'begin',
  28487. '']);
  28488. ConvertProgram;
  28489. CheckSource('TestAttributes_Members',
  28490. LinesToStr([ // statements
  28491. 'rtl.createClass($mod, "TObject", null, function () {',
  28492. ' this.$init = function () {',
  28493. ' };',
  28494. ' this.$final = function () {',
  28495. ' };',
  28496. ' this.Create = function () {',
  28497. ' return this;',
  28498. ' };',
  28499. '});',
  28500. 'rtl.createClass($mod, "TCustomAttribute", $mod.TObject, function () {',
  28501. ' this.Create$1 = function (Id) {',
  28502. ' return this;',
  28503. ' };',
  28504. '});',
  28505. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  28506. ' this.$init = function () {',
  28507. ' $mod.TObject.$init.call(this);',
  28508. ' this.FField = 0;',
  28509. ' };',
  28510. ' var $r = this.$rtti;',
  28511. ' $r.addField("FField", rtl.word, {',
  28512. ' attr: [$mod.TCustomAttribute, "Create"]',
  28513. ' });',
  28514. ' $r.addProperty(',
  28515. ' "Size",',
  28516. ' 0,',
  28517. ' rtl.word,',
  28518. ' "FField",',
  28519. ' "",',
  28520. ' {',
  28521. ' attr: [$mod.TCustomAttribute, "Create$1", [14]]',
  28522. ' }',
  28523. ' );',
  28524. ' $r.addMethod("Fly", 0, null, null, {',
  28525. ' attr: [$mod.TCustomAttribute, "Create$1", [15]]',
  28526. ' });',
  28527. '});',
  28528. 'rtl.recNewT($mod, "TRec", function () {',
  28529. ' this.Size = 0;',
  28530. ' this.$eq = function (b) {',
  28531. ' return this.Size === b.Size;',
  28532. ' };',
  28533. ' this.$assign = function (s) {',
  28534. ' this.Size = s.Size;',
  28535. ' return this;',
  28536. ' };',
  28537. ' var $r = $mod.$rtti.$Record("TRec", {});',
  28538. ' $r.addField("Size", rtl.word, {',
  28539. ' attr: [',
  28540. ' $mod.TCustomAttribute,',
  28541. ' "Create",',
  28542. ' $mod.TCustomAttribute,',
  28543. ' "Create$1",',
  28544. ' [14]',
  28545. ' ]',
  28546. ' });',
  28547. '});',
  28548. '']),
  28549. LinesToStr([ // $mod.$main
  28550. '']));
  28551. end;
  28552. procedure TTestModule.TestAttributes_Types;
  28553. begin
  28554. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28555. StartProgram(false);
  28556. Add([
  28557. '{$modeswitch PrefixedAttributes}',
  28558. 'type',
  28559. ' TObject = class',
  28560. ' constructor Create(Id: word);',
  28561. ' end;',
  28562. ' TCustomAttribute = class',
  28563. ' end;',
  28564. ' [TCustom(1)]',
  28565. ' TMyClass = class',
  28566. ' end;',
  28567. ' [TCustom(2)]',
  28568. ' TRec = record',
  28569. ' end;',
  28570. ' [TCustom(3)]',
  28571. ' TInt = type word;',
  28572. 'constructor TObject.Create(Id: word);',
  28573. 'begin',
  28574. 'end;',
  28575. 'var p: pointer;',
  28576. 'begin',
  28577. ' p:=typeinfo(TMyClass);',
  28578. ' p:=typeinfo(TRec);',
  28579. ' p:=typeinfo(TInt);',
  28580. '']);
  28581. ConvertProgram;
  28582. CheckSource('TestAttributes_Types',
  28583. LinesToStr([ // statements
  28584. 'rtl.createClass($mod, "TObject", null, function () {',
  28585. ' this.$init = function () {',
  28586. ' };',
  28587. ' this.$final = function () {',
  28588. ' };',
  28589. ' this.Create = function (Id) {',
  28590. ' return this;',
  28591. ' };',
  28592. '});',
  28593. 'rtl.createClass($mod, "TCustomAttribute", $mod.TObject, function () {',
  28594. '});',
  28595. 'rtl.createClass($mod, "TMyClass", $mod.TObject, function () {',
  28596. ' var $r = this.$rtti;',
  28597. ' $r.attr = [$mod.TCustomAttribute, "Create", [1]];',
  28598. '});',
  28599. 'rtl.recNewT($mod, "TRec", function () {',
  28600. ' this.$eq = function (b) {',
  28601. ' return true;',
  28602. ' };',
  28603. ' this.$assign = function (s) {',
  28604. ' return this;',
  28605. ' };',
  28606. ' $mod.$rtti.$Record("TRec", {',
  28607. ' attr: [$mod.TCustomAttribute, "Create", [2]]',
  28608. ' });',
  28609. '});',
  28610. '$mod.$rtti.$inherited("TInt", rtl.word, {',
  28611. ' attr: [$mod.TCustomAttribute, "Create", [3]]',
  28612. '});',
  28613. 'this.p = null;',
  28614. '']),
  28615. LinesToStr([ // $mod.$main
  28616. '$mod.p = $mod.$rtti["TMyClass"];',
  28617. '$mod.p = $mod.$rtti["TRec"];',
  28618. '$mod.p = $mod.$rtti["TInt"];',
  28619. '']));
  28620. end;
  28621. procedure TTestModule.TestAttributes_HelperConstructor_Fail;
  28622. begin
  28623. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28624. StartProgram(false);
  28625. Add([
  28626. '{$modeswitch PrefixedAttributes}',
  28627. 'type',
  28628. ' TObject = class',
  28629. ' constructor Create;',
  28630. ' end;',
  28631. ' TCustomAttribute = class',
  28632. ' end;',
  28633. ' THelper = class helper for TCustomAttribute',
  28634. ' constructor Create(Id: word);',
  28635. ' end;',
  28636. ' [TCustom(3)]',
  28637. ' TMyInt = word;',
  28638. 'constructor TObject.Create; begin end;',
  28639. 'constructor THelper.Create(Id: word); begin end;',
  28640. 'begin',
  28641. ' if typeinfo(TMyInt)=nil then ;']);
  28642. //SetExpectedConverterError('aaa',123);
  28643. ConvertProgram;
  28644. end;
  28645. procedure TTestModule.TestAssert;
  28646. begin
  28647. StartProgram(false);
  28648. Add([
  28649. 'procedure DoIt;',
  28650. 'var',
  28651. ' b: boolean;',
  28652. ' s: string;',
  28653. 'begin',
  28654. ' {$Assertions on}',
  28655. ' Assert(b);',
  28656. 'end;',
  28657. 'begin',
  28658. ' DoIt;',
  28659. '']);
  28660. ConvertProgram;
  28661. CheckSource('TestAssert',
  28662. LinesToStr([ // statements
  28663. 'this.DoIt = function () {',
  28664. ' var b = false;',
  28665. ' var s = "";',
  28666. ' if (!b) throw "assert failed";',
  28667. '};',
  28668. '']),
  28669. LinesToStr([ // $mod.$main
  28670. '$mod.DoIt();',
  28671. '']));
  28672. end;
  28673. procedure TTestModule.TestAssert_SysUtils;
  28674. begin
  28675. AddModuleWithIntfImplSrc('SysUtils.pas',
  28676. LinesToStr([
  28677. 'type',
  28678. ' TObject = class',
  28679. ' constructor Create;',
  28680. ' end;',
  28681. ' EAssertionFailed = class',
  28682. ' constructor Create(s: string);',
  28683. ' end;',
  28684. '']),
  28685. LinesToStr([
  28686. 'constructor TObject.Create;',
  28687. 'begin end;',
  28688. 'constructor EAssertionFailed.Create(s: string);',
  28689. 'begin end;',
  28690. '']) );
  28691. StartProgram(true);
  28692. Add([
  28693. 'uses sysutils;',
  28694. 'procedure DoIt;',
  28695. 'var',
  28696. ' b: boolean;',
  28697. ' s: string;',
  28698. 'begin',
  28699. ' {$Assertions on}',
  28700. ' Assert(b);',
  28701. ' Assert(b,''msg'');',
  28702. 'end;',
  28703. 'begin',
  28704. ' DoIt;',
  28705. '']);
  28706. ConvertProgram;
  28707. CheckSource('TestAssert_SysUtils',
  28708. LinesToStr([ // statements
  28709. 'this.DoIt = function () {',
  28710. ' var b = false;',
  28711. ' var s = "";',
  28712. ' if (!b) throw pas.SysUtils.EAssertionFailed.$create("Create");',
  28713. ' if (!b) throw pas.SysUtils.EAssertionFailed.$create("Create$1", ["msg"]);',
  28714. '};',
  28715. '']),
  28716. LinesToStr([ // $mod.$main
  28717. '$mod.DoIt();',
  28718. '']));
  28719. end;
  28720. procedure TTestModule.TestObjectChecks;
  28721. begin
  28722. Scanner.CurrentBoolSwitches:=Scanner.CurrentBoolSwitches+[bsObjectChecks];
  28723. StartProgram(false);
  28724. Add([
  28725. 'type',
  28726. ' TObject = class',
  28727. ' procedure DoIt;',
  28728. ' end;',
  28729. ' TClass = class of tobject;',
  28730. ' TBird = class',
  28731. ' end;',
  28732. ' TBirdClass = class of TBird;',
  28733. 'var',
  28734. ' o : TObject;',
  28735. ' c: TClass;',
  28736. ' b: TBird;',
  28737. ' bc: TBirdClass;',
  28738. 'procedure TObject.DoIt;',
  28739. 'begin',
  28740. ' b:=TBird(o);',
  28741. 'end;',
  28742. 'begin',
  28743. ' o.DoIt;',
  28744. ' b:=TBird(o);',
  28745. ' bc:=TBirdClass(c);',
  28746. '']);
  28747. ConvertProgram;
  28748. CheckSource('TestCheckMethodCall',
  28749. LinesToStr([ // statements
  28750. 'rtl.createClass($mod, "TObject", null, function () {',
  28751. ' this.$init = function () {',
  28752. ' };',
  28753. ' this.$final = function () {',
  28754. ' };',
  28755. ' this.DoIt = function () {',
  28756. ' rtl.checkMethodCall(this,$mod.TObject);',
  28757. ' $mod.b = rtl.asExt($mod.o, $mod.TBird, 1);',
  28758. ' };',
  28759. '});',
  28760. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  28761. '});',
  28762. 'this.o = null;',
  28763. 'this.c = null;',
  28764. 'this.b = null;',
  28765. 'this.bc = null;',
  28766. '']),
  28767. LinesToStr([ // $mod.$main
  28768. '$mod.o.DoIt();',
  28769. '$mod.b = rtl.asExt($mod.o,$mod.TBird, 1);',
  28770. '$mod.bc = rtl.asExt($mod.c, $mod.TBird, 2);',
  28771. '']));
  28772. end;
  28773. procedure TTestModule.TestOverflowChecks_Int;
  28774. begin
  28775. Scanner.CurrentBoolSwitches:=Scanner.CurrentBoolSwitches+[bsOverflowChecks];
  28776. StartProgram(false);
  28777. Add([
  28778. 'procedure DoIt;',
  28779. 'var',
  28780. ' b: byte;',
  28781. ' n: nativeint;',
  28782. ' u: nativeuint;',
  28783. ' c: currency;',
  28784. 'begin',
  28785. ' n:=n+n;',
  28786. ' n:=n-n;',
  28787. ' n:=n+b;',
  28788. ' n:=b-n;',
  28789. ' n:=n*n;',
  28790. ' n:=n*u;',
  28791. ' c:=c+b;',
  28792. ' c:=b+c;',
  28793. ' c:=c*b;',
  28794. ' c:=b*c;',
  28795. 'end;',
  28796. 'begin',
  28797. '']);
  28798. ConvertProgram;
  28799. CheckSource('TestOverflowChecks_Int',
  28800. LinesToStr([ // statements
  28801. 'this.DoIt = function () {',
  28802. ' var b = 0;',
  28803. ' var n = 0;',
  28804. ' var u = 0;',
  28805. ' var c = 0;',
  28806. ' n = rtl.oc(n + n);',
  28807. ' n = rtl.oc(n - n);',
  28808. ' n = rtl.oc(n + b);',
  28809. ' n = rtl.oc(b - n);',
  28810. ' n = rtl.oc(n * n);',
  28811. ' n = rtl.oc(n * u);',
  28812. ' c = rtl.oc(c + (b * 10000));',
  28813. ' c = rtl.oc((b * 10000) + c);',
  28814. ' c = rtl.oc(c * b);',
  28815. ' c = rtl.oc(b * c);',
  28816. '};',
  28817. '']),
  28818. LinesToStr([ // $mod.$main
  28819. '']));
  28820. end;
  28821. procedure TTestModule.TestRangeChecks_AssignInt;
  28822. begin
  28823. Scanner.Options:=Scanner.Options+[po_CAssignments];
  28824. StartProgram(false);
  28825. Add([
  28826. '{$R+}',
  28827. 'var',
  28828. ' b: byte = 2;',
  28829. ' w: word = 3;',
  28830. 'procedure DoIt(p: byte);',
  28831. 'begin',
  28832. ' b:=w;',
  28833. ' b+=w;',
  28834. ' b:=1;',
  28835. 'end;',
  28836. '{$R-}',
  28837. 'procedure DoSome;',
  28838. 'begin',
  28839. ' DoIt(w);',
  28840. ' b:=w;',
  28841. ' b:=2;',
  28842. 'end;',
  28843. 'begin',
  28844. '{$R+}',
  28845. '']);
  28846. ConvertProgram;
  28847. CheckSource('TestRangeChecks_AssignInt',
  28848. LinesToStr([ // statements
  28849. 'this.b = 2;',
  28850. 'this.w = 3;',
  28851. 'this.DoIt = function (p) {',
  28852. ' rtl.rc(p, 0, 255);',
  28853. ' $mod.b = rtl.rc($mod.w,0,255);',
  28854. ' rtl.rc($mod.b += $mod.w, 0, 255);',
  28855. ' $mod.b = 1;',
  28856. '};',
  28857. 'this.DoSome = function () {',
  28858. ' $mod.DoIt($mod.w);',
  28859. ' $mod.b = $mod.w;',
  28860. ' $mod.b = 2;',
  28861. '};',
  28862. '']),
  28863. LinesToStr([ // $mod.$main
  28864. '']));
  28865. end;
  28866. procedure TTestModule.TestRangeChecks_AssignIntRange;
  28867. begin
  28868. Scanner.Options:=Scanner.Options+[po_CAssignments];
  28869. StartProgram(false);
  28870. Add([
  28871. '{$R+}',
  28872. 'type Ten = 1..10;',
  28873. 'var',
  28874. ' b: Ten = 2;',
  28875. ' w: Ten = 3;',
  28876. 'procedure DoIt(p: Ten);',
  28877. 'begin',
  28878. ' b:=w;',
  28879. ' b+=w;',
  28880. ' b:=1;',
  28881. 'end;',
  28882. '{$R-}',
  28883. 'procedure DoSome;',
  28884. 'begin',
  28885. ' DoIt(w);',
  28886. ' b:=w;',
  28887. ' b:=2;',
  28888. 'end;',
  28889. 'begin',
  28890. '{$R+}',
  28891. '']);
  28892. ConvertProgram;
  28893. CheckSource('TestRangeChecks_AssignIntRange',
  28894. LinesToStr([ // statements
  28895. 'this.b = 2;',
  28896. 'this.w = 3;',
  28897. 'this.DoIt = function (p) {',
  28898. ' rtl.rc(p, 1, 10);',
  28899. ' $mod.b = rtl.rc($mod.w, 1, 10);',
  28900. ' rtl.rc($mod.b += $mod.w, 1, 10);',
  28901. ' $mod.b = 1;',
  28902. '};',
  28903. 'this.DoSome = function () {',
  28904. ' $mod.DoIt($mod.w);',
  28905. ' $mod.b = $mod.w;',
  28906. ' $mod.b = 2;',
  28907. '};',
  28908. '']),
  28909. LinesToStr([ // $mod.$main
  28910. '']));
  28911. end;
  28912. procedure TTestModule.TestRangeChecks_AssignEnum;
  28913. begin
  28914. StartProgram(false);
  28915. Add([
  28916. '{$R+}',
  28917. 'type TEnum = (red,green);',
  28918. 'var',
  28919. ' e: TEnum = red;',
  28920. 'procedure DoIt(p: TEnum);',
  28921. 'begin',
  28922. ' e:=p;',
  28923. ' p:=TEnum(0);',
  28924. ' p:=succ(e);',
  28925. 'end;',
  28926. '{$R-}',
  28927. 'procedure DoSome;',
  28928. 'begin',
  28929. ' DoIt(e);',
  28930. ' e:=TEnum(1);',
  28931. ' e:=pred(e);',
  28932. 'end;',
  28933. 'begin',
  28934. '{$R+}',
  28935. '']);
  28936. ConvertProgram;
  28937. CheckSource('TestRangeChecks_AssignEnum',
  28938. LinesToStr([ // statements
  28939. 'this.TEnum = {',
  28940. ' "0": "red",',
  28941. ' red: 0,',
  28942. ' "1": "green",',
  28943. ' green: 1',
  28944. '};',
  28945. 'this.e = $mod.TEnum.red;',
  28946. 'this.DoIt = function (p) {',
  28947. ' rtl.rc(p, 0, 1);',
  28948. ' $mod.e = rtl.rc(p, 0, 1);',
  28949. ' p = 0;',
  28950. ' p = rtl.rc($mod.e + 1, 0, 1);',
  28951. '};',
  28952. 'this.DoSome = function () {',
  28953. ' $mod.DoIt($mod.e);',
  28954. ' $mod.e = 1;',
  28955. ' $mod.e = $mod.e - 1;',
  28956. '};',
  28957. '']),
  28958. LinesToStr([ // $mod.$main
  28959. '']));
  28960. end;
  28961. procedure TTestModule.TestRangeChecks_AssignEnumRange;
  28962. begin
  28963. StartProgram(false);
  28964. Add([
  28965. '{$R+}',
  28966. 'type',
  28967. ' TEnum = (red,green);',
  28968. ' TEnumRg = red..green;',
  28969. 'var',
  28970. ' e: TEnumRg = red;',
  28971. 'procedure DoIt(p: TEnumRg);',
  28972. 'begin',
  28973. ' e:=p;',
  28974. ' p:=TEnumRg(0);',
  28975. ' p:=succ(e);',
  28976. 'end;',
  28977. '{$R-}',
  28978. 'procedure DoSome;',
  28979. 'begin',
  28980. ' DoIt(e);',
  28981. ' e:=TEnum(1);',
  28982. ' e:=pred(e);',
  28983. 'end;',
  28984. 'begin',
  28985. '{$R+}',
  28986. '']);
  28987. ConvertProgram;
  28988. CheckSource('TestRangeChecks_AssignEnumRange',
  28989. LinesToStr([ // statements
  28990. 'this.TEnum = {',
  28991. ' "0": "red",',
  28992. ' red: 0,',
  28993. ' "1": "green",',
  28994. ' green: 1',
  28995. '};',
  28996. 'this.e = $mod.TEnum.red;',
  28997. 'this.DoIt = function (p) {',
  28998. ' rtl.rc(p, 0, 1);',
  28999. ' $mod.e = rtl.rc(p, 0, 1);',
  29000. ' p = 0;',
  29001. ' p = rtl.rc($mod.e + 1, 0, 1);',
  29002. '};',
  29003. 'this.DoSome = function () {',
  29004. ' $mod.DoIt($mod.e);',
  29005. ' $mod.e = 1;',
  29006. ' $mod.e = $mod.e - 1;',
  29007. '};',
  29008. '']),
  29009. LinesToStr([ // $mod.$main
  29010. '']));
  29011. end;
  29012. procedure TTestModule.TestRangeChecks_AssignChar;
  29013. begin
  29014. StartProgram(false);
  29015. Add([
  29016. '{$R+}',
  29017. 'type',
  29018. ' TLetter = char;',
  29019. 'var',
  29020. ' b: TLetter = ''2'';',
  29021. ' w: TLetter = ''3'';',
  29022. 'procedure DoIt(p: TLetter);',
  29023. 'begin',
  29024. ' b:=w;',
  29025. ' b:=''1'';',
  29026. 'end;',
  29027. '{$R-}',
  29028. 'procedure DoSome;',
  29029. 'begin',
  29030. ' DoIt(w);',
  29031. ' b:=w;',
  29032. ' b:=''2'';',
  29033. 'end;',
  29034. 'begin',
  29035. '{$R+}',
  29036. '']);
  29037. ConvertProgram;
  29038. CheckSource('TestRangeChecks_AssignChar',
  29039. LinesToStr([ // statements
  29040. 'this.b = "2";',
  29041. 'this.w = "3";',
  29042. 'this.DoIt = function (p) {',
  29043. ' rtl.rcc(p, 0, 65535);',
  29044. ' $mod.b = rtl.rcc($mod.w, 0, 65535);',
  29045. ' $mod.b = "1";',
  29046. '};',
  29047. 'this.DoSome = function () {',
  29048. ' $mod.DoIt($mod.w);',
  29049. ' $mod.b = $mod.w;',
  29050. ' $mod.b = "2";',
  29051. '};',
  29052. '']),
  29053. LinesToStr([ // $mod.$main
  29054. '']));
  29055. end;
  29056. procedure TTestModule.TestRangeChecks_AssignCharRange;
  29057. begin
  29058. StartProgram(false);
  29059. Add([
  29060. '{$R+}',
  29061. 'type TDigit = ''0''..''9'';',
  29062. 'var',
  29063. ' b: TDigit = ''2'';',
  29064. ' w: TDigit = ''3'';',
  29065. 'procedure DoIt(p: TDigit);',
  29066. 'begin',
  29067. ' b:=w;',
  29068. ' b:=''1'';',
  29069. 'end;',
  29070. '{$R-}',
  29071. 'procedure DoSome;',
  29072. 'begin',
  29073. ' DoIt(w);',
  29074. ' b:=w;',
  29075. ' b:=''2'';',
  29076. 'end;',
  29077. 'begin',
  29078. '{$R+}',
  29079. '']);
  29080. ConvertProgram;
  29081. CheckSource('TestRangeChecks_AssignCharRange',
  29082. LinesToStr([ // statements
  29083. 'this.b = "2";',
  29084. 'this.w = "3";',
  29085. 'this.DoIt = function (p) {',
  29086. ' rtl.rcc(p, 48, 57);',
  29087. ' $mod.b = rtl.rcc($mod.w, 48, 57);',
  29088. ' $mod.b = "1";',
  29089. '};',
  29090. 'this.DoSome = function () {',
  29091. ' $mod.DoIt($mod.w);',
  29092. ' $mod.b = $mod.w;',
  29093. ' $mod.b = "2";',
  29094. '};',
  29095. '']),
  29096. LinesToStr([ // $mod.$main
  29097. '']));
  29098. end;
  29099. procedure TTestModule.TestRangeChecks_ArrayIndex;
  29100. begin
  29101. StartProgram(false);
  29102. Add([
  29103. '{$R+}',
  29104. 'type',
  29105. ' Ten = 1..10;',
  29106. ' TArr = array of Ten;',
  29107. ' TArrArr = array of TArr;',
  29108. ' TArrByte = array[byte] of Ten;',
  29109. ' TArrChar = array[''0''..''9''] of Ten;',
  29110. ' TArrByteChar = array[byte,''0''..''9''] of Ten;',
  29111. ' TObject = class',
  29112. ' A: TArr;',
  29113. ' end;',
  29114. 'procedure DoIt;',
  29115. 'var',
  29116. ' Arr: TArr;',
  29117. ' ArrArr: TArrArr;',
  29118. ' ArrByte: TArrByte;',
  29119. ' ArrChar: TArrChar;',
  29120. ' ArrByteChar: TArrByteChar;',
  29121. ' i: Ten;',
  29122. ' c: char;',
  29123. ' o: tobject;',
  29124. 'begin',
  29125. ' i:=Arr[1];',
  29126. ' i:=ArrByteChar[1,''2''];',
  29127. ' Arr[1]:=Arr[1];',
  29128. ' Arr[i]:=Arr[i];',
  29129. ' ArrByte[3]:=ArrByte[3];',
  29130. ' ArrByte[i]:=ArrByte[i];',
  29131. ' ArrChar[''5'']:=ArrChar[''5''];',
  29132. ' ArrChar[c]:=ArrChar[c];',
  29133. ' ArrByteChar[7,''7'']:=ArrByteChar[7,''7''];',
  29134. ' ArrByteChar[i,c]:=ArrByteChar[i,c];',
  29135. ' o.a[i]:=o.a[i];',
  29136. 'end;',
  29137. 'begin',
  29138. '']);
  29139. ConvertProgram;
  29140. CheckSource('TestRangeChecks_ArrayIndex',
  29141. LinesToStr([ // statements
  29142. 'rtl.createClass($mod, "TObject", null, function () {',
  29143. ' this.$init = function () {',
  29144. ' this.A = [];',
  29145. ' };',
  29146. ' this.$final = function () {',
  29147. ' this.A = undefined;',
  29148. ' };',
  29149. '});',
  29150. 'this.DoIt = function () {',
  29151. ' var Arr = [];',
  29152. ' var ArrArr = [];',
  29153. ' var ArrByte = rtl.arraySetLength(null, 0, 256);',
  29154. ' var ArrChar = rtl.arraySetLength(null, 0, 10);',
  29155. ' var ArrByteChar = rtl.arraySetLength(null, 0, 256, 10);',
  29156. ' var i = 0;',
  29157. ' var c = "";',
  29158. ' var o = null;',
  29159. ' i = rtl.rc(Arr[1], 1, 10);',
  29160. ' i = rtl.rc(ArrByteChar[1][2], 1, 10);',
  29161. ' Arr[1] = rtl.rc(Arr[1], 1, 10);',
  29162. ' rtl.rcArrW(Arr, i, rtl.rcArrR(Arr, i));',
  29163. ' ArrByte[3] = rtl.rc(ArrByte[3], 1, 10);',
  29164. ' rtl.rcArrW(ArrByte, i, rtl.rcArrR(ArrByte, i));',
  29165. ' ArrChar[5] = rtl.rc(ArrChar[5], 1, 10);',
  29166. ' rtl.rcArrW(ArrChar, c.charCodeAt() - 48, rtl.rcArrR(ArrChar, c.charCodeAt() - 48));',
  29167. ' ArrByteChar[7][7] = rtl.rc(ArrByteChar[7][7], 1, 10);',
  29168. ' rtl.rcArrW(ArrByteChar, i, c.charCodeAt() - 48, rtl.rcArrR(ArrByteChar, i, c.charCodeAt() - 48));',
  29169. ' rtl.rcArrW(o.A, i, rtl.rcArrR(o.A, i));',
  29170. '};',
  29171. '']),
  29172. LinesToStr([ // $mod.$main
  29173. '']));
  29174. end;
  29175. procedure TTestModule.TestRangeChecks_ArrayOfRecIndex;
  29176. begin
  29177. StartProgram(false);
  29178. Add([
  29179. '{$R+}',
  29180. 'type',
  29181. ' Ten = 1..10;',
  29182. ' TRec = record x: Ten end;',
  29183. ' TArr = array of TRec;',
  29184. ' TArrArr = array of TArr;',
  29185. ' TObject = class',
  29186. ' A: TArr;',
  29187. ' end;',
  29188. 'procedure DoIt;',
  29189. 'var',
  29190. ' Arr: TArr;',
  29191. ' ArrArr: TArrArr;',
  29192. ' i: Ten;',
  29193. ' o: tobject;',
  29194. 'begin',
  29195. ' Arr[1]:=Arr[1];',
  29196. ' Arr[i]:=Arr[i+1];',
  29197. ' o.a[i]:=o.a[i+2];',
  29198. 'end;',
  29199. 'begin',
  29200. '']);
  29201. ConvertProgram;
  29202. CheckSource('TestRangeChecks_ArrayOfRecIndex',
  29203. LinesToStr([ // statements
  29204. 'rtl.recNewT($mod, "TRec", function () {',
  29205. ' this.x = 0;',
  29206. ' this.$eq = function (b) {',
  29207. ' return this.x === b.x;',
  29208. ' };',
  29209. ' this.$assign = function (s) {',
  29210. ' this.x = s.x;',
  29211. ' return this;',
  29212. ' };',
  29213. '});',
  29214. 'rtl.createClass($mod, "TObject", null, function () {',
  29215. ' this.$init = function () {',
  29216. ' this.A = [];',
  29217. ' };',
  29218. ' this.$final = function () {',
  29219. ' this.A = undefined;',
  29220. ' };',
  29221. '});',
  29222. 'this.DoIt = function () {',
  29223. ' var Arr = [];',
  29224. ' var ArrArr = [];',
  29225. ' var i = 0;',
  29226. ' var o = null;',
  29227. ' Arr[1].$assign(Arr[1]);',
  29228. ' rtl.rcArrR(Arr, i).$assign(rtl.rcArrR(Arr, i + 1));',
  29229. ' rtl.rcArrR(o.A, i).$assign(rtl.rcArrR(o.A, i + 2));',
  29230. '};',
  29231. '']),
  29232. LinesToStr([ // $mod.$main
  29233. '']));
  29234. end;
  29235. procedure TTestModule.TestRangeChecks_StringIndex;
  29236. begin
  29237. StartProgram(false);
  29238. Add([
  29239. 'type',
  29240. ' TObject = class',
  29241. ' S: string;',
  29242. ' end;',
  29243. '{$R+}',
  29244. 'procedure DoIt(var h: string);',
  29245. 'var',
  29246. ' s: string;',
  29247. ' i: longint;',
  29248. ' c: char;',
  29249. ' o: tobject;',
  29250. 'begin',
  29251. ' c:=s[1];',
  29252. ' s[i]:=s[i];',
  29253. ' h[i]:=h[i];',
  29254. ' c:=o.s[i];',
  29255. ' o.s[i]:=c;',
  29256. 'end;',
  29257. 'begin',
  29258. '']);
  29259. ConvertProgram;
  29260. CheckSource('TestRangeChecks_StringIndex',
  29261. LinesToStr([ // statements
  29262. 'rtl.createClass($mod, "TObject", null, function () {',
  29263. ' this.$init = function () {',
  29264. ' this.S = "";',
  29265. ' };',
  29266. ' this.$final = function () {',
  29267. ' };',
  29268. '});',
  29269. 'this.DoIt = function (h) {',
  29270. ' var s = "";',
  29271. ' var i = 0;',
  29272. ' var c = "";',
  29273. ' var o = null;',
  29274. ' c = rtl.rcc(rtl.rcCharAt(s, 0), 0, 65535);',
  29275. ' s = rtl.rcSetCharAt(s, i - 1, rtl.rcCharAt(s, i - 1));',
  29276. ' h.set(rtl.rcSetCharAt(h.get(), i - 1, rtl.rcCharAt(h.get(), i - 1)));',
  29277. ' c = rtl.rcc(rtl.rcCharAt(o.S, i - 1), 0, 65535);',
  29278. ' o.S = rtl.rcSetCharAt(o.S, i - 1, c);',
  29279. '};',
  29280. '']),
  29281. LinesToStr([ // $mod.$main
  29282. '']));
  29283. end;
  29284. procedure TTestModule.TestRangeChecks_TypecastInt;
  29285. begin
  29286. StartProgram(false);
  29287. Add([
  29288. '{$R+}',
  29289. 'var',
  29290. ' i: nativeint;',
  29291. ' b: byte;',
  29292. ' sh: shortint;',
  29293. ' w: word;',
  29294. ' sm: smallint;',
  29295. ' lw: longword;',
  29296. ' li: longint;',
  29297. 'begin',
  29298. ' b:=12+byte(i);',
  29299. ' sh:=12+shortint(i);',
  29300. ' w:=12+word(i);',
  29301. ' sm:=12+smallint(i);',
  29302. ' lw:=12+longword(i);',
  29303. ' li:=12+longint(i);',
  29304. '']);
  29305. ConvertProgram;
  29306. CheckSource('TestRangeChecks_TypecastInt',
  29307. LinesToStr([
  29308. 'this.i = 0;',
  29309. 'this.b = 0;',
  29310. 'this.sh = 0;',
  29311. 'this.w = 0;',
  29312. 'this.sm = 0;',
  29313. 'this.lw = 0;',
  29314. 'this.li = 0;',
  29315. '']),
  29316. LinesToStr([
  29317. '$mod.b = rtl.rc(12 + rtl.rc($mod.i, 0, 255), 0, 255);',
  29318. '$mod.sh = rtl.rc(12 + rtl.rc($mod.i, -128, 127), -128, 127);',
  29319. '$mod.w = rtl.rc(12 + rtl.rc($mod.i, 0, 65535), 0, 65535);',
  29320. '$mod.sm = rtl.rc(12 + rtl.rc($mod.i, -32768, 32767), -32768, 32767);',
  29321. '$mod.lw = rtl.rc(12 + rtl.rc($mod.i, 0, 4294967295), 0, 4294967295);',
  29322. '$mod.li = rtl.rc(12 + rtl.rc($mod.i, -2147483648, 2147483647), -2147483648, 2147483647);',
  29323. '']));
  29324. end;
  29325. procedure TTestModule.TestRangeChecks_TypeHelperInt;
  29326. begin
  29327. Scanner.Options:=Scanner.Options+[po_CAssignments];
  29328. StartProgram(false);
  29329. Add([
  29330. '{$modeswitch typehelpers}',
  29331. '{$R+}',
  29332. 'type',
  29333. ' TObject = class',
  29334. ' FSize: byte;',
  29335. ' property Size: byte read FSize;',
  29336. ' end;',
  29337. ' THelper = type helper for byte',
  29338. ' procedure SetIt(w: word);',
  29339. ' end;',
  29340. 'procedure THelper.SetIt(w: word);',
  29341. 'begin',
  29342. ' Self:=w;',
  29343. 'end;',
  29344. 'function GetIt: byte;',
  29345. 'begin',
  29346. ' Result.SetIt(2);',
  29347. 'end;',
  29348. 'var',
  29349. ' b: byte = 3;',
  29350. ' o: TObject;',
  29351. 'begin',
  29352. ' b.SetIt(14);',
  29353. ' with b do SetIt(15);',
  29354. ' o.Size.SetIt(16);',
  29355. '']);
  29356. ConvertProgram;
  29357. CheckSource('TestRangeChecks_AssignInt',
  29358. LinesToStr([ // statements
  29359. 'rtl.createClass($mod, "TObject", null, function () {',
  29360. ' this.$init = function () {',
  29361. ' this.FSize = 0;',
  29362. ' };',
  29363. ' this.$final = function () {',
  29364. ' };',
  29365. '});',
  29366. 'rtl.createHelper($mod, "THelper", null, function () {',
  29367. ' this.SetIt = function (w) {',
  29368. ' rtl.rc(w, 0, 65535);',
  29369. ' this.set(w);',
  29370. ' };',
  29371. '});',
  29372. 'this.GetIt = function () {',
  29373. ' var Result = 0;',
  29374. ' $mod.THelper.SetIt.call({',
  29375. ' get: function () {',
  29376. ' return Result;',
  29377. ' },',
  29378. ' set: function (v) {',
  29379. ' rtl.rc(v, 0, 255);',
  29380. ' Result = v;',
  29381. ' }',
  29382. ' }, 2);',
  29383. ' return Result;',
  29384. '};',
  29385. 'this.b = 3;',
  29386. 'this.o = null;',
  29387. '']),
  29388. LinesToStr([ // $mod.$main
  29389. '$mod.THelper.SetIt.call({',
  29390. ' p: $mod,',
  29391. ' get: function () {',
  29392. ' return this.p.b;',
  29393. ' },',
  29394. ' set: function (v) {',
  29395. ' rtl.rc(v, 0, 255);',
  29396. ' this.p.b = v;',
  29397. ' }',
  29398. '}, 14);',
  29399. 'var $with1 = $mod.b;',
  29400. '$mod.THelper.SetIt.call({',
  29401. ' get: function () {',
  29402. ' return $with1;',
  29403. ' },',
  29404. ' set: function (v) {',
  29405. ' rtl.rc(v, 0, 255);',
  29406. ' $with1 = v;',
  29407. ' }',
  29408. '}, 15);',
  29409. '$mod.THelper.SetIt.call({',
  29410. ' p: $mod.o,',
  29411. ' get: function () {',
  29412. ' return this.p.FSize;',
  29413. ' },',
  29414. ' set: function (v) {',
  29415. ' rtl.rc(v, 0, 255);',
  29416. ' this.p.FSize = v;',
  29417. ' }',
  29418. '}, 16);',
  29419. '']));
  29420. end;
  29421. Initialization
  29422. RegisterTests([TTestModule]);
  29423. end.