tcmodules.pas 796 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073
  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_ReservedWords;
  312. // anonymous functions
  313. Procedure TestAnonymousProc_Assign_ObjFPC;
  314. Procedure TestAnonymousProc_Assign_Delphi;
  315. Procedure TestAnonymousProc_Arg;
  316. Procedure TestAnonymousProc_Typecast;
  317. Procedure TestAnonymousProc_With;
  318. Procedure TestAnonymousProc_ExceptOn;
  319. Procedure TestAnonymousProc_Nested;
  320. Procedure TestAnonymousProc_NestedAssignResult;
  321. Procedure TestAnonymousProc_Class;
  322. // enums, sets
  323. Procedure TestEnum_Name;
  324. Procedure TestEnum_Number;
  325. Procedure TestEnum_ConstFail;
  326. Procedure TestEnum_Functions;
  327. Procedure TestEnum_AsParams;
  328. Procedure TestEnumRange_Array;
  329. Procedure TestEnum_ForIn;
  330. Procedure TestEnum_ScopedNumber;
  331. Procedure TestEnum_InFunction;
  332. Procedure TestSet_Enum;
  333. Procedure TestSet_Operators;
  334. Procedure TestSet_Operator_In;
  335. Procedure TestSet_Functions;
  336. Procedure TestSet_PassAsArgClone;
  337. Procedure TestSet_AsParams;
  338. Procedure TestSet_Property;
  339. Procedure TestSet_EnumConst;
  340. Procedure TestSet_IntConst;
  341. Procedure TestSet_AnonymousEnumType;
  342. Procedure TestSet_AnonymousEnumTypeChar; // ToDo
  343. Procedure TestSet_ConstEnum;
  344. Procedure TestSet_ConstChar;
  345. Procedure TestSet_ConstInt;
  346. Procedure TestSet_InFunction;
  347. Procedure TestSet_ForIn;
  348. // statements
  349. Procedure TestNestBegin;
  350. Procedure TestIncDec;
  351. Procedure TestLoHiFpcMode;
  352. Procedure TestLoHiDelphiMode;
  353. Procedure TestAssignments;
  354. Procedure TestArithmeticOperators1;
  355. Procedure TestLogicalOperators;
  356. Procedure TestBitwiseOperators;
  357. Procedure TestFunctionInt;
  358. Procedure TestFunctionString;
  359. Procedure TestIfThen;
  360. Procedure TestForLoop;
  361. Procedure TestForLoopInsideFunction;
  362. Procedure TestForLoop_ReadVarAfter;
  363. Procedure TestForLoop_Nested;
  364. Procedure TestRepeatUntil;
  365. Procedure TestAsmBlock;
  366. Procedure TestAsmPas_Impl; // ToDo
  367. Procedure TestTryFinally;
  368. Procedure TestTryExcept;
  369. Procedure TestTryExcept_ReservedWords;
  370. Procedure TestIfThenRaiseElse;
  371. Procedure TestCaseOf;
  372. Procedure TestCaseOf_UseSwitch;
  373. Procedure TestCaseOfNoElse;
  374. Procedure TestCaseOfNoElse_UseSwitch;
  375. Procedure TestCaseOfRange;
  376. Procedure TestCaseOfString;
  377. Procedure TestCaseOfChar;
  378. Procedure TestCaseOfExternalClassConst;
  379. Procedure TestDebugger;
  380. // arrays
  381. Procedure TestArray_Dynamic;
  382. Procedure TestArray_Dynamic_Nil;
  383. Procedure TestArray_DynMultiDimensional;
  384. Procedure TestArray_StaticInt;
  385. Procedure TestArray_StaticBool;
  386. Procedure TestArray_StaticChar;
  387. Procedure TestArray_StaticMultiDim;
  388. Procedure TestArray_StaticInFunction;
  389. Procedure TestArrayOfRecord;
  390. Procedure TestArray_StaticRecord;
  391. Procedure TestArrayOfSet;
  392. Procedure TestArray_DynAsParam;
  393. Procedure TestArray_StaticAsParam;
  394. Procedure TestArrayElement_AsParams;
  395. Procedure TestArrayElementFromFuncResult_AsParams;
  396. Procedure TestArrayEnumTypeRange;
  397. Procedure TestArray_SetLengthOutArg;
  398. Procedure TestArray_SetLengthProperty;
  399. Procedure TestArray_SetLengthMultiDim;
  400. Procedure TestArray_OpenArrayOfString;
  401. Procedure TestArray_Concat;
  402. Procedure TestArray_Copy;
  403. Procedure TestArray_InsertDelete;
  404. Procedure TestArray_DynArrayConstObjFPC;
  405. Procedure TestArray_DynArrayConstDelphi;
  406. Procedure TestArray_ArrayLitAsParam;
  407. Procedure TestArray_ArrayLitMultiDimAsParam;
  408. Procedure TestArray_ArrayLitStaticAsParam;
  409. Procedure TestArray_ForInArrOfString;
  410. Procedure TestExternalClass_TypeCastArrayToExternalClass;
  411. Procedure TestExternalClass_TypeCastArrayFromExternalClass;
  412. Procedure TestArrayOfConst_TVarRec;
  413. Procedure TestArrayOfConst_PassBaseTypes;
  414. Procedure TestArrayOfConst_PassObj;
  415. // record
  416. Procedure TestRecord_Empty;
  417. Procedure TestRecord_Var;
  418. Procedure TestRecord_VarExternal;
  419. Procedure TestRecord_WithDo;
  420. Procedure TestRecord_Assign;
  421. Procedure TestRecord_AsParams;
  422. Procedure TestRecordElement_AsParams;
  423. Procedure TestRecordElementFromFuncResult_AsParams;
  424. Procedure TestRecordElementFromWith_AsParams;
  425. Procedure TestRecord_Equal;
  426. Procedure TestRecord_JSValue;
  427. Procedure TestRecord_VariantFail;
  428. Procedure TestRecord_FieldArray;
  429. Procedure TestRecord_Const;
  430. Procedure TestRecord_TypecastFail;
  431. Procedure TestRecord_InFunction;
  432. Procedure TestRecord_AnonymousFail;
  433. // ToDo: RTTI of local record
  434. // ToDo: pcu local record, name clash and rtti
  435. // advanced record
  436. Procedure TestAdvRecord_Function;
  437. Procedure TestAdvRecord_Property;
  438. Procedure TestAdvRecord_PropertyDefault;
  439. Procedure TestAdvRecord_Property_ClassMethod;
  440. Procedure TestAdvRecord_Const;
  441. Procedure TestAdvRecord_ExternalField;
  442. Procedure TestAdvRecord_SubRecord;
  443. Procedure TestAdvRecord_SubClass;
  444. Procedure TestAdvRecord_SubInterfaceFail;
  445. Procedure TestAdvRecord_Constructor;
  446. Procedure TestAdvRecord_ClassConstructor_Program;
  447. Procedure TestAdvRecord_ClassConstructor_Unit;
  448. // classes
  449. Procedure TestClass_TObjectDefaultConstructor;
  450. Procedure TestClass_TObjectConstructorWithParams;
  451. Procedure TestClass_TObjectConstructorWithDefaultParam;
  452. Procedure TestClass_Var;
  453. Procedure TestClass_Method;
  454. Procedure TestClass_Implementation;
  455. Procedure TestClass_Inheritance;
  456. Procedure TestClass_TypeAlias;
  457. Procedure TestClass_AbstractMethod;
  458. Procedure TestClass_CallInherited_ProcNoParams;
  459. Procedure TestClass_CallInherited_WithParams;
  460. Procedure TestClasS_CallInheritedConstructor;
  461. Procedure TestClass_ClassVar_Assign;
  462. Procedure TestClass_CallClassMethod;
  463. Procedure TestClass_Property;
  464. Procedure TestClass_Property_ClassMethod;
  465. Procedure TestClass_Property_Indexed;
  466. Procedure TestClass_Property_IndexSpec;
  467. Procedure TestClass_PropertyOfTypeArray;
  468. Procedure TestClass_PropertyDefault;
  469. Procedure TestClass_PropertyDefault2;
  470. Procedure TestClass_PropertyOverride;
  471. Procedure TestClass_PropertyIncVisibility;
  472. Procedure TestClass_Assigned;
  473. Procedure TestClass_WithClassDoCreate;
  474. Procedure TestClass_WithClassInstDoProperty;
  475. Procedure TestClass_WithClassInstDoPropertyWithParams;
  476. Procedure TestClass_WithClassInstDoFunc;
  477. Procedure TestClass_TypeCast;
  478. Procedure TestClass_TypeCastUntypedParam;
  479. Procedure TestClass_Overloads;
  480. Procedure TestClass_OverloadsAncestor;
  481. Procedure TestClass_OverloadConstructor;
  482. Procedure TestClass_OverloadDelphiOverride;
  483. Procedure TestClass_ReintroducedVar;
  484. Procedure TestClass_RaiseDescendant;
  485. Procedure TestClass_ExternalMethod;
  486. Procedure TestClass_ExternalVirtualNameMismatchFail;
  487. Procedure TestClass_ExternalOverrideFail;
  488. Procedure TestClass_ExternalVar;
  489. Procedure TestClass_Const;
  490. Procedure TestClass_LocalVarSelfFail;
  491. Procedure TestClass_ArgSelfFail;
  492. Procedure TestClass_NestedProcSelf;
  493. Procedure TestClass_NestedProcSelf2;
  494. Procedure TestClass_NestedProcClassSelf;
  495. Procedure TestClass_NestedProcCallInherited;
  496. Procedure TestClass_TObjectFree;
  497. Procedure TestClass_TObjectFree_VarArg;
  498. Procedure TestClass_TObjectFreeNewInstance;
  499. Procedure TestClass_TObjectFreeLowerCase;
  500. Procedure TestClass_TObjectFreeFunctionFail;
  501. Procedure TestClass_TObjectFreePropertyFail;
  502. Procedure TestClass_ForIn;
  503. Procedure TestClass_DispatchMessage;
  504. Procedure TestClass_Message_DuplicateIntFail;
  505. Procedure TestClass_DispatchMessage_WrongFieldNameFail;
  506. // class of
  507. Procedure TestClassOf_Create;
  508. Procedure TestClassOf_Call;
  509. Procedure TestClassOf_Assign;
  510. Procedure TestClassOf_Is;
  511. Procedure TestClassOf_Compare;
  512. Procedure TestClassOf_ClassVar;
  513. Procedure TestClassOf_ClassMethod;
  514. Procedure TestClassOf_ClassProperty;
  515. Procedure TestClassOf_ClassMethodSelf;
  516. Procedure TestClassOf_TypeCast;
  517. Procedure TestClassOf_ImplicitFunctionCall;
  518. Procedure TestClassOf_Const;
  519. // nested class
  520. Procedure TestNestedClass_Alias;
  521. Procedure TestNestedClass_Record;
  522. Procedure TestNestedClass_Class;
  523. // external class
  524. Procedure TestExternalClass_Var;
  525. Procedure TestExternalClass_Const;
  526. Procedure TestExternalClass_Dollar;
  527. Procedure TestExternalClass_DuplicateVarFail;
  528. Procedure TestExternalClass_Method;
  529. Procedure TestExternalClass_ClassMethod;
  530. Procedure TestExternalClass_FunctionResultInTypeCast;
  531. Procedure TestExternalClass_NonExternalOverride;
  532. Procedure TestExternalClass_OverloadHint;
  533. Procedure TestExternalClass_SameNamePublishedProperty;
  534. Procedure TestExternalClass_Property;
  535. Procedure TestExternalClass_PropertyDate;
  536. Procedure TestExternalClass_ClassProperty;
  537. Procedure TestExternalClass_ClassOf;
  538. Procedure TestExternalClass_ClassOtherUnit;
  539. Procedure TestExternalClass_Is;
  540. Procedure TestExternalClass_As;
  541. Procedure TestExternalClass_DestructorFail;
  542. Procedure TestExternalClass_New;
  543. Procedure TestExternalClass_ClassOf_New;
  544. Procedure TestExternalClass_FuncClassOf_New;
  545. Procedure TestExternalClass_New_PasClassFail;
  546. Procedure TestExternalClass_New_PasClassBracketsFail;
  547. Procedure TestExternalClass_LocalConstSameName;
  548. Procedure TestExternalClass_ReintroduceOverload;
  549. Procedure TestExternalClass_Inherited;
  550. Procedure TestExternalClass_PascalAncestorFail;
  551. Procedure TestExternalClass_NewInstance;
  552. Procedure TestExternalClass_NewInstance_NonVirtualFail;
  553. Procedure TestExternalClass_NewInstance_FirstParamNotString_Fail;
  554. Procedure TestExternalClass_NewInstance_SecondParamTyped_Fail;
  555. Procedure TestExternalClass_PascalProperty;
  556. Procedure TestExternalClass_TypeCastToRootClass;
  557. Procedure TestExternalClass_TypeCastToJSObject;
  558. Procedure TestExternalClass_TypeCastStringToExternalString;
  559. Procedure TestExternalClass_TypeCastToJSFunction;
  560. Procedure TestExternalClass_TypeCastDelphiUnrelated;
  561. Procedure TestExternalClass_CallClassFunctionOfInstanceFail;
  562. Procedure TestExternalClass_BracketAccessor;
  563. Procedure TestExternalClass_BracketAccessor_Call;
  564. Procedure TestExternalClass_BracketAccessor_2ParamsFail;
  565. Procedure TestExternalClass_BracketAccessor_ReadOnly;
  566. Procedure TestExternalClass_BracketAccessor_WriteOnly;
  567. Procedure TestExternalClass_BracketAccessor_MultiType;
  568. Procedure TestExternalClass_BracketAccessor_Index;
  569. Procedure TestExternalClass_ForInJSObject;
  570. Procedure TestExternalClass_ForInJSArray;
  571. Procedure TestExternalClass_IncompatibleArgDuplicateIdentifier;
  572. // class interfaces
  573. Procedure TestClassInterface_Corba;
  574. Procedure TestClassInterface_ProcExternalFail;
  575. Procedure TestClassInterface_Overloads;
  576. Procedure TestClassInterface_DuplicateGUIInIntfListFail;
  577. Procedure TestClassInterface_DuplicateGUIInAncestorFail;
  578. Procedure TestClassInterface_AncestorImpl;
  579. Procedure TestClassInterface_ImplReintroduce;
  580. Procedure TestClassInterface_MethodResolution;
  581. Procedure TestClassInterface_AncestorMoreInterfaces;
  582. Procedure TestClassInterface_MethodOverride;
  583. Procedure TestClassInterface_Corba_Delegation;
  584. Procedure TestClassInterface_Corba_DelegationStatic;
  585. Procedure TestClassInterface_Corba_Operators;
  586. Procedure TestClassInterface_Corba_Args;
  587. Procedure TestClassInterface_Corba_ForIn;
  588. Procedure TestClassInterface_COM_AssignVar;
  589. Procedure TestClassInterface_COM_AssignArg;
  590. Procedure TestClassInterface_COM_FunctionResult;
  591. Procedure TestClassInterface_COM_InheritedFuncResult;
  592. Procedure TestClassInterface_COM_IsAsTypeCasts;
  593. Procedure TestClassInterface_COM_PassAsArg;
  594. Procedure TestClassInterface_COM_PassToUntypedParam;
  595. Procedure TestClassInterface_COM_FunctionInExpr;
  596. Procedure TestClassInterface_COM_Property;
  597. Procedure TestClassInterface_COM_IntfProperty;
  598. Procedure TestClassInterface_COM_Delegation;
  599. Procedure TestClassInterface_COM_With;
  600. Procedure TestClassInterface_COM_ForIn;
  601. Procedure TestClassInterface_COM_ArrayOfIntfFail;
  602. Procedure TestClassInterface_COM_RecordIntfFail;
  603. Procedure TestClassInterface_COM_UnitInitialization;
  604. Procedure TestClassInterface_GUID;
  605. Procedure TestClassInterface_GUIDProperty;
  606. // helpers
  607. Procedure TestClassHelper_ClassVar;
  608. Procedure TestClassHelper_Method_AccessInstanceFields;
  609. Procedure TestClassHelper_Method_Call;
  610. Procedure TestClassHelper_Method_Nested_Call;
  611. Procedure TestClassHelper_ClassMethod_Call;
  612. Procedure TestClassHelper_ClassOf;
  613. Procedure TestClassHelper_MethodRefObjFPC;
  614. Procedure TestClassHelper_Constructor;
  615. Procedure TestClassHelper_InheritedObjFPC;
  616. Procedure TestClassHelper_Property;
  617. Procedure TestClassHelper_Property_Array;
  618. Procedure TestClassHelper_Property_Array_Default;
  619. Procedure TestClassHelper_Property_Array_DefaultDefault;
  620. Procedure TestClassHelper_ClassProperty;
  621. Procedure TestClassHelper_ClassPropertyStatic;
  622. Procedure TestClassHelper_ClassProperty_Array;
  623. Procedure TestClassHelper_ForIn;
  624. Procedure TestClassHelper_PassProperty;
  625. Procedure TestExtClassHelper_ClassVar;
  626. Procedure TestExtClassHelper_Method_Call;
  627. Procedure TestRecordHelper_ClassVar;
  628. Procedure TestRecordHelper_Method_Call;
  629. Procedure TestRecordHelper_Constructor;
  630. Procedure TestTypeHelper_ClassVar;
  631. Procedure TestTypeHelper_PassResultElement;
  632. Procedure TestTypeHelper_PassArgs;
  633. Procedure TestTypeHelper_PassVarConst;
  634. Procedure TestTypeHelper_PassFuncResult;
  635. Procedure TestTypeHelper_PassPropertyField;
  636. Procedure TestTypeHelper_PassPropertyGetter;
  637. Procedure TestTypeHelper_PassClassPropertyField;
  638. Procedure TestTypeHelper_PassClassPropertyGetterStatic;
  639. Procedure TestTypeHelper_PassClassPropertyGetterNonStatic;
  640. Procedure TestTypeHelper_Property;
  641. Procedure TestTypeHelper_Property_Array;
  642. Procedure TestTypeHelper_ClassProperty;
  643. Procedure TestTypeHelper_ClassProperty_Array;
  644. Procedure TestTypeHelper_ClassMethod;
  645. Procedure TestTypeHelper_ExtClassMethodFail;
  646. Procedure TestTypeHelper_Constructor;
  647. Procedure TestTypeHelper_Word;
  648. Procedure TestTypeHelper_Double;
  649. Procedure TestTypeHelper_StringChar;
  650. Procedure TestTypeHelper_Array;
  651. Procedure TestTypeHelper_EnumType;
  652. Procedure TestTypeHelper_SetType;
  653. Procedure TestTypeHelper_InterfaceType;
  654. // proc types
  655. Procedure TestProcType;
  656. Procedure TestProcType_Arg;
  657. Procedure TestProcType_FunctionFPC;
  658. Procedure TestProcType_FunctionDelphi;
  659. Procedure TestProcType_ProcedureDelphi;
  660. Procedure TestProcType_AsParam;
  661. Procedure TestProcType_MethodFPC;
  662. Procedure TestProcType_MethodDelphi;
  663. Procedure TestProcType_PropertyFPC;
  664. Procedure TestProcType_PropertyDelphi;
  665. Procedure TestProcType_WithClassInstDoPropertyFPC;
  666. Procedure TestProcType_Nested;
  667. Procedure TestProcType_NestedOfObject;
  668. Procedure TestProcType_ReferenceToProc;
  669. Procedure TestProcType_ReferenceToMethod;
  670. Procedure TestProcType_Typecast;
  671. Procedure TestProcType_PassProcToUntyped;
  672. Procedure TestProcType_PassProcToArray;
  673. // pointer
  674. Procedure TestPointer;
  675. Procedure TestPointer_Proc;
  676. Procedure TestPointer_AssignRecordFail;
  677. Procedure TestPointer_AssignStaticArrayFail;
  678. Procedure TestPointer_TypeCastJSValueToPointer;
  679. Procedure TestPointer_NonRecordFail;
  680. Procedure TestPointer_AnonymousArgTypeFail;
  681. Procedure TestPointer_AnonymousVarTypeFail;
  682. Procedure TestPointer_AnonymousResultTypeFail;
  683. Procedure TestPointer_AddrOperatorFail;
  684. Procedure TestPointer_ArrayParamsFail;
  685. Procedure TestPointer_PointerAddFail;
  686. Procedure TestPointer_IncPointerFail;
  687. Procedure TestPointer_Record;
  688. Procedure TestPointer_RecordArg;
  689. // jsvalue
  690. Procedure TestJSValue_AssignToJSValue;
  691. Procedure TestJSValue_TypeCastToBaseType;
  692. Procedure TestJSValue_TypecastToJSValue;
  693. Procedure TestJSValue_Equal;
  694. Procedure TestJSValue_If;
  695. Procedure TestJSValue_Not;
  696. Procedure TestJSValue_Enum;
  697. Procedure TestJSValue_ClassInstance;
  698. Procedure TestJSValue_ClassOf;
  699. Procedure TestJSValue_ArrayOfJSValue;
  700. Procedure TestJSValue_ArrayLit;
  701. Procedure TestJSValue_Params;
  702. Procedure TestJSValue_UntypedParam;
  703. Procedure TestJSValue_FuncResultType;
  704. Procedure TestJSValue_ProcType_Assign;
  705. Procedure TestJSValue_ProcType_Equal;
  706. Procedure TestJSValue_ProcType_Param;
  707. Procedure TestJSValue_AssignToPointerFail;
  708. Procedure TestJSValue_OverloadDouble;
  709. Procedure TestJSValue_OverloadNativeInt;
  710. Procedure TestJSValue_OverloadWord;
  711. Procedure TestJSValue_OverloadString;
  712. Procedure TestJSValue_OverloadChar;
  713. Procedure TestJSValue_OverloadPointer;
  714. Procedure TestJSValue_ForIn;
  715. // RTTI
  716. Procedure TestRTTI_IntRange;
  717. Procedure TestRTTI_Double;
  718. Procedure TestRTTI_ProcType;
  719. Procedure TestRTTI_ProcType_ArgFromOtherUnit;
  720. Procedure TestRTTI_EnumAndSetType;
  721. Procedure TestRTTI_EnumRange;
  722. Procedure TestRTTI_AnonymousEnumType;
  723. Procedure TestRTTI_StaticArray;
  724. Procedure TestRTTI_DynArray;
  725. Procedure TestRTTI_ArrayNestedAnonymous;
  726. Procedure TestRTTI_PublishedMethodOverloadFail;
  727. Procedure TestRTTI_PublishedMethodExternalFail;
  728. Procedure TestRTTI_PublishedClassPropertyFail;
  729. Procedure TestRTTI_PublishedClassFieldFail;
  730. Procedure TestRTTI_PublishedFieldExternalFail;
  731. Procedure TestRTTI_Class_Field;
  732. Procedure TestRTTI_Class_Method;
  733. Procedure TestRTTI_Class_MethodArgFlags;
  734. Procedure TestRTTI_Class_Property;
  735. Procedure TestRTTI_Class_PropertyParams;
  736. Procedure TestRTTI_Class_OtherUnit_TypeAlias;
  737. Procedure TestRTTI_Class_OmitRTTI;
  738. Procedure TestRTTI_IndexModifier;
  739. Procedure TestRTTI_StoredModifier;
  740. Procedure TestRTTI_DefaultValue;
  741. Procedure TestRTTI_DefaultValueSet;
  742. Procedure TestRTTI_DefaultValueRangeType;
  743. Procedure TestRTTI_DefaultValueInherit;
  744. Procedure TestRTTI_OverrideMethod;
  745. Procedure TestRTTI_OverloadProperty;
  746. // ToDo: array argument
  747. Procedure TestRTTI_ClassForward;
  748. Procedure TestRTTI_ClassOf;
  749. Procedure TestRTTI_Record;
  750. Procedure TestRTTI_RecordAnonymousArray;
  751. Procedure TestRTTI_LocalTypes;
  752. Procedure TestRTTI_TypeInfo_BaseTypes;
  753. Procedure TestRTTI_TypeInfo_Type_BaseTypes;
  754. Procedure TestRTTI_TypeInfo_LocalFail;
  755. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses1;
  756. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses2;
  757. Procedure TestRTTI_TypeInfo_ExtTypeInfoClasses3;
  758. Procedure TestRTTI_TypeInfo_FunctionClassType;
  759. Procedure TestRTTI_TypeInfo_MixedUnits_PointerAndClass;
  760. Procedure TestRTTI_Interface_Corba;
  761. Procedure TestRTTI_Interface_COM;
  762. Procedure TestRTTI_ClassHelper;
  763. // Resourcestring
  764. Procedure TestResourcestringProgram;
  765. Procedure TestResourcestringUnit;
  766. Procedure TestResourcestringImplementation;
  767. // Attributes
  768. Procedure TestAttributes_Members;
  769. Procedure TestAttributes_Types;
  770. Procedure TestAttributes_HelperConstructor_Fail;
  771. // Assertions, checks
  772. procedure TestAssert;
  773. procedure TestAssert_SysUtils;
  774. procedure TestObjectChecks;
  775. procedure TestOverflowChecks_Int;
  776. procedure TestRangeChecks_AssignInt;
  777. procedure TestRangeChecks_AssignIntRange;
  778. procedure TestRangeChecks_AssignEnum;
  779. procedure TestRangeChecks_AssignEnumRange;
  780. procedure TestRangeChecks_AssignChar;
  781. procedure TestRangeChecks_AssignCharRange;
  782. procedure TestRangeChecks_ArrayIndex;
  783. procedure TestRangeChecks_ArrayOfRecIndex;
  784. procedure TestRangeChecks_StringIndex;
  785. procedure TestRangeChecks_TypecastInt;
  786. procedure TestRangeChecks_TypeHelperInt;
  787. end;
  788. function LinesToStr(Args: array of const): string;
  789. function ExtractFileUnitName(aFilename: string): string;
  790. function JSToStr(El: TJSElement): string;
  791. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  792. implementation
  793. function LinesToStr(Args: array of const): string;
  794. var
  795. s: String;
  796. i: Integer;
  797. begin
  798. s:='';
  799. for i:=Low(Args) to High(Args) do
  800. case Args[i].VType of
  801. vtChar: s += Args[i].VChar+LineEnding;
  802. vtString: s += Args[i].VString^+LineEnding;
  803. vtPChar: s += Args[i].VPChar+LineEnding;
  804. vtWideChar: s += AnsiString(Args[i].VWideChar)+LineEnding;
  805. vtPWideChar: s += AnsiString(Args[i].VPWideChar)+LineEnding;
  806. vtAnsiString: s += AnsiString(Args[i].VAnsiString)+LineEnding;
  807. vtWidestring: s += AnsiString(WideString(Args[i].VWideString))+LineEnding;
  808. vtUnicodeString:s += AnsiString(UnicodeString(Args[i].VUnicodeString))+LineEnding;
  809. end;
  810. Result:=s;
  811. end;
  812. function ExtractFileUnitName(aFilename: string): string;
  813. var
  814. p: Integer;
  815. begin
  816. Result:=ExtractFileName(aFilename);
  817. if Result='' then exit;
  818. for p:=length(Result) downto 1 do
  819. case Result[p] of
  820. '/','\': exit;
  821. '.':
  822. begin
  823. Delete(Result,p,length(Result));
  824. exit;
  825. end;
  826. end;
  827. end;
  828. function JSToStr(El: TJSElement): string;
  829. var
  830. aWriter: TBufferWriter;
  831. aJSWriter: TJSWriter;
  832. begin
  833. aJSWriter:=nil;
  834. aWriter:=TBufferWriter.Create(1000);
  835. try
  836. aJSWriter:=TJSWriter.Create(aWriter);
  837. aJSWriter.IndentSize:=2;
  838. aJSWriter.WriteJS(El);
  839. Result:=aWriter.AsString;
  840. finally
  841. aJSWriter.Free;
  842. aWriter.Free;
  843. end;
  844. end;
  845. function CheckSrcDiff(Expected, Actual: string; out Msg: string): boolean;
  846. // search diff, ignore changes in spaces
  847. const
  848. SpaceChars = [#9,#10,#13,' '];
  849. var
  850. ExpectedP, ActualP: PChar;
  851. function FindLineEnd(p: PChar): PChar;
  852. begin
  853. Result:=p;
  854. while not (Result^ in [#0,#10,#13]) do inc(Result);
  855. end;
  856. function FindLineStart(p, MinP: PChar): PChar;
  857. begin
  858. while (p>MinP) and not (p[-1] in [#10,#13]) do dec(p);
  859. Result:=p;
  860. end;
  861. procedure SkipLineEnd(var p: PChar);
  862. begin
  863. if p^ in [#10,#13] then
  864. begin
  865. if (p[1] in [#10,#13]) and (p^<>p[1]) then
  866. inc(p,2)
  867. else
  868. inc(p);
  869. end;
  870. end;
  871. procedure DiffFound;
  872. var
  873. ActLineStartP, ActLineEndP, p, StartPos: PChar;
  874. ExpLine, ActLine: String;
  875. i, LineNo, DiffLineNo: Integer;
  876. begin
  877. writeln('Diff found "',Msg,'". Lines:');
  878. // write correct lines
  879. p:=PChar(Expected);
  880. LineNo:=0;
  881. DiffLineNo:=0;
  882. repeat
  883. StartPos:=p;
  884. while not (p^ in [#0,#10,#13]) do inc(p);
  885. ExpLine:=copy(Expected,StartPos-PChar(Expected)+1,p-StartPos);
  886. SkipLineEnd(p);
  887. inc(LineNo);
  888. if (p<=ExpectedP) and (p^<>#0) then
  889. begin
  890. writeln('= ',ExpLine);
  891. end else begin
  892. // diff line
  893. if DiffLineNo=0 then DiffLineNo:=LineNo;
  894. // write actual line
  895. ActLineStartP:=FindLineStart(ActualP,PChar(Actual));
  896. ActLineEndP:=FindLineEnd(ActualP);
  897. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  898. writeln('- ',ActLine);
  899. // write expected line
  900. writeln('+ ',ExpLine);
  901. // write empty line with pointer ^
  902. for i:=1 to 2+ExpectedP-StartPos do write(' ');
  903. writeln('^');
  904. Msg:='expected "'+ExpLine+'", but got "'+ActLine+'".';
  905. CheckSrcDiff:=false;
  906. // write up to three following actual lines to get some context
  907. for i:=1 to 3 do begin
  908. ActLineStartP:=ActLineEndP;
  909. SkipLineEnd(ActLineStartP);
  910. if ActLineStartP^=#0 then break;
  911. ActLineEndP:=FindLineEnd(ActLineStartP);
  912. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  913. writeln('~ ',ActLine);
  914. end;
  915. exit;
  916. end;
  917. until p^=#0;
  918. writeln('DiffFound Actual:-----------------------');
  919. writeln(Actual);
  920. writeln('DiffFound Expected:---------------------');
  921. writeln(Expected);
  922. writeln('DiffFound ------------------------------');
  923. Msg:='diff found, but lines are the same, internal error';
  924. CheckSrcDiff:=false;
  925. end;
  926. var
  927. IsSpaceNeeded: Boolean;
  928. LastChar, Quote: Char;
  929. begin
  930. Result:=true;
  931. Msg:='';
  932. if Expected='' then Expected:=' ';
  933. if Actual='' then Actual:=' ';
  934. ExpectedP:=PChar(Expected);
  935. ActualP:=PChar(Actual);
  936. repeat
  937. //writeln('TTestModule.CheckDiff Exp="',ExpectedP^,'" Act="',ActualP^,'"');
  938. case ExpectedP^ of
  939. #0:
  940. begin
  941. // check that rest of Actual has only spaces
  942. while ActualP^ in SpaceChars do inc(ActualP);
  943. if ActualP^<>#0 then
  944. begin
  945. DiffFound;
  946. exit;
  947. end;
  948. exit(true);
  949. end;
  950. ' ',#9,#10,#13:
  951. begin
  952. // skip space in Expected
  953. IsSpaceNeeded:=false;
  954. if ExpectedP>PChar(Expected) then
  955. LastChar:=ExpectedP[-1]
  956. else
  957. LastChar:=#0;
  958. while ExpectedP^ in SpaceChars do inc(ExpectedP);
  959. if (LastChar in ['a'..'z','A'..'Z','0'..'9','_','$'])
  960. and (ExpectedP^ in ['a'..'z','A'..'Z','0'..'9','_','$']) then
  961. IsSpaceNeeded:=true;
  962. if IsSpaceNeeded and (not (ActualP^ in SpaceChars)) then
  963. begin
  964. DiffFound;
  965. exit;
  966. end;
  967. while ActualP^ in SpaceChars do inc(ActualP);
  968. end;
  969. '''','"':
  970. begin
  971. while ActualP^ in SpaceChars do inc(ActualP);
  972. if ExpectedP^<>ActualP^ then
  973. begin
  974. DiffFound;
  975. exit;
  976. end;
  977. Quote:=ExpectedP^;
  978. repeat
  979. inc(ExpectedP);
  980. inc(ActualP);
  981. if ExpectedP^<>ActualP^ then
  982. begin
  983. DiffFound;
  984. exit;
  985. end;
  986. if (ExpectedP^ in [#0,#10,#13]) then
  987. break
  988. else if (ExpectedP^=Quote) then
  989. begin
  990. inc(ExpectedP);
  991. inc(ActualP);
  992. break;
  993. end;
  994. until false;
  995. end;
  996. else
  997. while ActualP^ in SpaceChars do inc(ActualP);
  998. if ExpectedP^<>ActualP^ then
  999. begin
  1000. DiffFound;
  1001. exit;
  1002. end;
  1003. inc(ExpectedP);
  1004. inc(ActualP);
  1005. end;
  1006. until false;
  1007. end;
  1008. { TTestEnginePasResolver }
  1009. destructor TTestEnginePasResolver.Destroy;
  1010. begin
  1011. FreeAndNil(FStreamResolver);
  1012. FreeAndNil(FParser);
  1013. FreeAndNil(FScanner);
  1014. FreeAndNil(FStreamResolver);
  1015. if Module<>nil then
  1016. begin
  1017. Module.Release{$IFDEF CheckPasTreeRefCount}('CreateElement'){$ENDIF};
  1018. FModule:=nil;
  1019. end;
  1020. inherited Destroy;
  1021. end;
  1022. function TTestEnginePasResolver.FindUnit(const AName, InFilename: String;
  1023. NameExpr, InFileExpr: TPasExpr): TPasModule;
  1024. begin
  1025. Result:=nil;
  1026. if InFilename<>'' then
  1027. RaiseNotYetImplemented(20180224101926,InFileExpr,'Use testcase tcunitsearch instead');
  1028. if Assigned(OnFindUnit) then
  1029. Result:=OnFindUnit(AName);
  1030. if NameExpr=nil then ;
  1031. end;
  1032. procedure TTestEnginePasResolver.UsedInterfacesFinished(Section: TPasSection);
  1033. begin
  1034. // do not parse recursively
  1035. // parse via the queue
  1036. if Section=nil then ;
  1037. end;
  1038. { TCustomTestModule }
  1039. function TCustomTestModule.GetMsgCount: integer;
  1040. begin
  1041. Result:=FHintMsgs.Count;
  1042. end;
  1043. function TCustomTestModule.GetMsgs(Index: integer): TTestHintMessage;
  1044. begin
  1045. Result:=TTestHintMessage(FHintMsgs[Index]);
  1046. end;
  1047. function TCustomTestModule.GetResolverCount: integer;
  1048. begin
  1049. Result:=FModules.Count;
  1050. end;
  1051. function TCustomTestModule.GetResolvers(Index: integer
  1052. ): TTestEnginePasResolver;
  1053. begin
  1054. Result:=TTestEnginePasResolver(FModules[Index]);
  1055. end;
  1056. function TCustomTestModule.OnPasResolverFindUnit(const aUnitName: String
  1057. ): TPasModule;
  1058. var
  1059. DefNamespace: String;
  1060. begin
  1061. //writeln('TTestModule.OnPasResolverFindUnit START Unit="',aUnitName,'"');
  1062. if (Pos('.',aUnitName)<1) then
  1063. begin
  1064. DefNamespace:=GetDefaultNamespace;
  1065. if DefNamespace<>'' then
  1066. begin
  1067. Result:=LoadUnit(DefNamespace+'.'+aUnitName);
  1068. if Result<>nil then exit;
  1069. end;
  1070. end;
  1071. Result:=LoadUnit(aUnitName);
  1072. if Result<>nil then exit;
  1073. {$IFDEF VerbosePas2JS}
  1074. writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"');
  1075. {$ENDIF}
  1076. Fail('can''t find unit "'+aUnitName+'"');
  1077. end;
  1078. procedure TCustomTestModule.OnParserLog(Sender: TObject; const Msg: String);
  1079. var
  1080. aParser: TPasParser;
  1081. Item: TTestHintMessage;
  1082. begin
  1083. aParser:=Sender as TPasParser;
  1084. Item:=TTestHintMessage.Create;
  1085. Item.Id:=aParser.LastMsgNumber;
  1086. Item.MsgType:=aParser.LastMsgType;
  1087. Item.MsgNumber:=aParser.LastMsgNumber;
  1088. Item.Msg:=Msg;
  1089. Item.SourcePos:=aParser.Scanner.CurSourcePos;
  1090. {$IFDEF VerbosePas2JS}
  1091. writeln('TCustomTestModule.OnParserLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1092. {$ENDIF}
  1093. FHintMsgs.Add(Item);
  1094. end;
  1095. procedure TCustomTestModule.OnPasResolverLog(Sender: TObject; const Msg: String
  1096. );
  1097. var
  1098. aResolver: TTestEnginePasResolver;
  1099. Item: TTestHintMessage;
  1100. begin
  1101. aResolver:=Sender as TTestEnginePasResolver;
  1102. Item:=TTestHintMessage.Create;
  1103. Item.Id:=aResolver.LastMsgId;
  1104. Item.MsgType:=aResolver.LastMsgType;
  1105. Item.MsgNumber:=aResolver.LastMsgNumber;
  1106. Item.Msg:=Msg;
  1107. Item.SourcePos:=aResolver.LastSourcePos;
  1108. {$IFDEF VerbosePas2JS}
  1109. writeln('TCustomTestModule.OnPasResolverLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1110. {$ENDIF}
  1111. FHintMsgs.Add(Item);
  1112. end;
  1113. procedure TCustomTestModule.OnScannerLog(Sender: TObject; const Msg: String);
  1114. var
  1115. Item: TTestHintMessage;
  1116. aScanner: TPas2jsPasScanner;
  1117. begin
  1118. aScanner:=Sender as TPas2jsPasScanner;
  1119. Item:=TTestHintMessage.Create;
  1120. Item.Id:=aScanner.LastMsgNumber;
  1121. Item.MsgType:=aScanner.LastMsgType;
  1122. Item.MsgNumber:=aScanner.LastMsgNumber;
  1123. Item.Msg:=Msg;
  1124. Item.SourcePos:=aScanner.CurSourcePos;
  1125. {$IFDEF VerbosePas2JS}
  1126. writeln('TCustomTestModule.OnScannerLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  1127. {$ENDIF}
  1128. FHintMsgs.Add(Item);
  1129. end;
  1130. function TCustomTestModule.LoadUnit(const aUnitName: String): TPasModule;
  1131. var
  1132. i: Integer;
  1133. CurEngine: TTestEnginePasResolver;
  1134. CurUnitName: String;
  1135. begin
  1136. //writeln('TTestModule.FindUnit START Unit="',aUnitName,'"');
  1137. Result:=nil;
  1138. if (Module.ClassType=TPasModule)
  1139. and (CompareText(Module.Name,aUnitName)=0) then
  1140. exit(Module);
  1141. for i:=0 to ResolverCount-1 do
  1142. begin
  1143. CurEngine:=Resolvers[i];
  1144. CurUnitName:=ExtractFileUnitName(CurEngine.Filename);
  1145. //writeln('TTestModule.FindUnit Checking ',i,'/',ResolverCount,' ',CurEngine.Filename,' ',CurUnitName);
  1146. if CompareText(aUnitName,CurUnitName)=0 then
  1147. begin
  1148. Result:=CurEngine.Module;
  1149. if Result<>nil then exit;
  1150. //writeln('TTestModule.FindUnit PARSING unit "',CurEngine.Filename,'"');
  1151. FileResolver.FindSourceFile(aUnitName);
  1152. CurEngine.StreamResolver:=TStreamResolver.Create;
  1153. CurEngine.StreamResolver.OwnsStreams:=True;
  1154. //writeln('TTestModule.FindUnit SOURCE=',CurEngine.Source);
  1155. CurEngine.StreamResolver.AddStream(CurEngine.FileName,TStringStream.Create(CurEngine.Source));
  1156. CurEngine.Scanner:=TPas2jsPasScanner.Create(CurEngine.StreamResolver);
  1157. InitScanner(CurEngine.Scanner);
  1158. CurEngine.Parser:=TTestPasParser.Create(CurEngine.Scanner,CurEngine.StreamResolver,CurEngine);
  1159. CurEngine.Parser.Options:=po_tcmodules;
  1160. if CompareText(CurUnitName,'System')=0 then
  1161. CurEngine.Parser.ImplicitUses.Clear;
  1162. CurEngine.Scanner.OpenFile(CurEngine.Filename);
  1163. try
  1164. CurEngine.Parser.NextToken;
  1165. CurEngine.Parser.ParseUnit(CurEngine.FModule);
  1166. except
  1167. on E: Exception do
  1168. HandleException(E);
  1169. end;
  1170. //writeln('TTestModule.FindUnit END ',CurUnitName);
  1171. Result:=CurEngine.Module;
  1172. exit;
  1173. end;
  1174. end;
  1175. end;
  1176. procedure TCustomTestModule.SetUp;
  1177. begin
  1178. {$IFDEF EnablePasTreeGlobalRefCount}
  1179. FElementRefCountAtSetup:=TPasElement.GlobalRefCount;
  1180. {$ENDIF}
  1181. if FModules<>nil then
  1182. begin
  1183. writeln('TCustomTestModule.SetUp FModules<>nil');
  1184. Halt;
  1185. end;
  1186. inherited SetUp;
  1187. FSkipTests:=false;
  1188. FSource:=TStringList.Create;
  1189. FModules:=TObjectList.Create(true);
  1190. FFilename:='test1.pp';
  1191. FFileResolver:=TStreamResolver.Create;
  1192. FFileResolver.OwnsStreams:=True;
  1193. FScanner:=TPas2jsPasScanner.Create(FFileResolver);
  1194. InitScanner(FScanner);
  1195. FEngine:=AddModule(Filename);
  1196. FEngine.Scanner:=FScanner;
  1197. FScanner.Resolver:=FEngine;
  1198. FParser:=TTestPasParser.Create(FScanner,FFileResolver,FEngine);
  1199. FParser.OnLog:=@OnParserLog;
  1200. FEngine.Parser:=FParser;
  1201. Parser.Options:=po_tcmodules;
  1202. FModule:=Nil;
  1203. FConverter:=CreateConverter;
  1204. FExpectedErrorClass:=nil;
  1205. end;
  1206. function TCustomTestModule.CreateConverter: TPasToJSConverter;
  1207. begin
  1208. Result:=TPasToJSConverter.Create;
  1209. Result.Options:=co_tcmodules;
  1210. Result.Globals:=TPasToJSConverterGlobals.Create(Result);
  1211. end;
  1212. procedure TCustomTestModule.InitScanner(aScanner: TPas2jsPasScanner);
  1213. begin
  1214. aScanner.AllowedModeSwitches:=msAllPas2jsModeSwitches;
  1215. aScanner.ReadOnlyModeSwitches:=msAllPas2jsModeSwitchesReadOnly;
  1216. aScanner.CurrentModeSwitches:=OBJFPCModeSwitches*msAllPas2jsModeSwitches+msAllPas2jsModeSwitchesReadOnly;
  1217. aScanner.AllowedBoolSwitches:=bsAllPas2jsBoolSwitches;
  1218. aScanner.ReadOnlyBoolSwitches:=bsAllPas2jsBoolSwitchesReadOnly;
  1219. aScanner.CurrentBoolSwitches:=bsAllPas2jsBoolSwitchesReadOnly+[bsHints,bsNotes,bsWarnings,bsWriteableConst];
  1220. aScanner.AllowedValueSwitches:=vsAllPas2jsValueSwitches;
  1221. aScanner.ReadOnlyValueSwitches:=vsAllPas2jsValueSwitchesReadOnly;
  1222. aScanner.OnLog:=@OnScannerLog;
  1223. aScanner.CompilerVersion:='Comp.Ver.tcmodules';
  1224. end;
  1225. procedure TCustomTestModule.TearDown;
  1226. {$IFDEF CheckPasTreeRefCount}
  1227. var
  1228. El: TPasElement;
  1229. {$ENDIF}
  1230. var
  1231. i: Integer;
  1232. CurModule: TPasModule;
  1233. begin
  1234. FHintMsgs.Clear;
  1235. FHintMsgsGood.Clear;
  1236. FSkipTests:=false;
  1237. FJSRegModuleCall:=nil;
  1238. FJSModuleCallArgs:=nil;
  1239. FJSImplentationUses:=nil;
  1240. FJSInterfaceUses:=nil;
  1241. FJSModuleSrc:=nil;
  1242. FJSInitBody:=nil;
  1243. FreeAndNil(FJSSource);
  1244. FreeAndNil(FJSModule);
  1245. FreeAndNil(FConverter);
  1246. Engine.Clear;
  1247. FreeAndNil(FSource);
  1248. FreeAndNil(FFileResolver);
  1249. if FModules<>nil then
  1250. begin
  1251. for i:=0 to FModules.Count-1 do
  1252. begin
  1253. CurModule:=TTestEnginePasResolver(FModules[i]).Module;
  1254. if CurModule=nil then continue;
  1255. //writeln('TCustomTestModule.TearDown ReleaseUsedUnits ',CurModule.Name,' ',CurModule.RefCount,' ',CurModule.RefIds.Text);
  1256. CurModule.ReleaseUsedUnits;
  1257. end;
  1258. if FModule<>nil then
  1259. FModule.ReleaseUsedUnits;
  1260. for i:=0 to FModules.Count-1 do
  1261. begin
  1262. CurModule:=TTestEnginePasResolver(FModules[i]).Module;
  1263. if CurModule=nil then continue;
  1264. //writeln('TCustomTestModule.TearDown UsesReleased ',CurModule.Name,' ',CurModule.RefCount,' ',CurModule.RefIds.Text);
  1265. end;
  1266. FreeAndNil(FModules);
  1267. ReleaseAndNil(TPasElement(FModule){$IFDEF CheckPasTreeRefCount},'CreateElement'{$ENDIF});
  1268. FEngine:=nil;
  1269. end;
  1270. inherited TearDown;
  1271. {$IFDEF EnablePasTreeGlobalRefCount}
  1272. if FElementRefCountAtSetup<>TPasElement.GlobalRefCount then
  1273. begin
  1274. writeln('TCustomTestModule.TearDown GlobalRefCount Was='+IntToStr(FElementRefCountAtSetup)+' Now='+IntToStr(TPasElement.GlobalRefCount));
  1275. {$IFDEF CheckPasTreeRefCount}
  1276. El:=TPasElement.FirstRefEl;
  1277. while El<>nil do
  1278. begin
  1279. writeln(' ',GetObjName(El),' RefIds.Count=',El.RefIds.Count,':');
  1280. for i:=0 to El.RefIds.Count-1 do
  1281. writeln(' ',El.RefIds[i]);
  1282. El:=El.NextRefEl;
  1283. end;
  1284. {$ENDIF}
  1285. Halt;
  1286. Fail('TCustomTestModule.TearDown Was='+IntToStr(FElementRefCountAtSetup)+' Now='+IntToStr(TPasElement.GlobalRefCount));
  1287. end;
  1288. {$ENDIF}
  1289. end;
  1290. procedure TCustomTestModule.Add(Line: string);
  1291. begin
  1292. Source.Add(Line);
  1293. end;
  1294. procedure TCustomTestModule.Add(const Lines: array of string);
  1295. var
  1296. i: Integer;
  1297. begin
  1298. for i:=low(Lines) to high(Lines) do
  1299. Add(Lines[i]);
  1300. end;
  1301. procedure TCustomTestModule.StartParsing;
  1302. var
  1303. Src: String;
  1304. begin
  1305. Src:=Source.Text;
  1306. FEngine.Source:=Src;
  1307. FileResolver.AddStream(FileName,TStringStream.Create(Src));
  1308. Scanner.OpenFile(FileName);
  1309. Writeln('// Test : ',Self.TestName);
  1310. Writeln(Src);
  1311. end;
  1312. procedure TCustomTestModule.ParseModuleQueue;
  1313. var
  1314. i: Integer;
  1315. CurResolver: TTestEnginePasResolver;
  1316. Found: Boolean;
  1317. Section: TPasSection;
  1318. begin
  1319. // parse til exception or all modules finished
  1320. while not SkipTests do
  1321. begin
  1322. Found:=false;
  1323. for i:=0 to ResolverCount-1 do
  1324. begin
  1325. CurResolver:=Resolvers[i];
  1326. if CurResolver.CurrentParser=nil then continue;
  1327. if not CurResolver.CurrentParser.CanParseContinue(Section) then
  1328. continue;
  1329. CurResolver.Parser.ParseContinue;
  1330. Found:=true;
  1331. break;
  1332. end;
  1333. if not Found then break;
  1334. end;
  1335. for i:=0 to ResolverCount-1 do
  1336. begin
  1337. CurResolver:=Resolvers[i];
  1338. if CurResolver.Parser=nil then
  1339. begin
  1340. if CurResolver.CurrentParser<>nil then
  1341. Fail('TCustomTestModule.ParseModuleQueue '+CurResolver.Filename+' '+GetObjName(CurResolver.Parser)+'=Parser<>CurrentParser='+GetObjName(CurResolver.CurrentParser));
  1342. continue;
  1343. end;
  1344. if CurResolver.Parser.CurModule<>nil then
  1345. Fail('TCustomTestModule.ParseModuleQueue '+CurResolver.Filename+' NOT FINISHED CurModule='+GetObjName(CurResolver.Parser.CurModule));
  1346. end;
  1347. end;
  1348. procedure TCustomTestModule.ParseModule;
  1349. begin
  1350. if SkipTests then exit;
  1351. FFirstPasStatement:=nil;
  1352. try
  1353. StartParsing;
  1354. Parser.ParseMain(FModule);
  1355. ParseModuleQueue;
  1356. except
  1357. on E: Exception do
  1358. HandleException(E);
  1359. end;
  1360. if SkipTests then exit;
  1361. AssertNotNull('Module resulted in Module',Module);
  1362. AssertEquals('modulename',lowercase(ChangeFileExt(FFileName,'')),lowercase(Module.Name));
  1363. TAssert.AssertSame('Has resolver',Engine,Parser.Engine);
  1364. end;
  1365. procedure TCustomTestModule.ParseProgram;
  1366. begin
  1367. if SkipTests then exit;
  1368. ParseModule;
  1369. if SkipTests then exit;
  1370. AssertEquals('Has program',TPasProgram,Module.ClassType);
  1371. FPasProgram:=TPasProgram(Module);
  1372. AssertNotNull('Has program section',PasProgram.ProgramSection);
  1373. AssertNotNull('Has initialization section',PasProgram.InitializationSection);
  1374. if (PasProgram.InitializationSection.Elements.Count>0) then
  1375. if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
  1376. FFirstPasStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
  1377. end;
  1378. procedure TCustomTestModule.ParseUnit;
  1379. begin
  1380. if SkipTests then exit;
  1381. ParseModule;
  1382. if SkipTests then exit;
  1383. AssertEquals('Has unit (TPasModule)',TPasModule,Module.ClassType);
  1384. AssertNotNull('Has interface section',Module.InterfaceSection);
  1385. AssertNotNull('Has implementation section',Module.ImplementationSection);
  1386. if (Module.InitializationSection<>nil)
  1387. and (Module.InitializationSection.Elements.Count>0)
  1388. and (TObject(Module.InitializationSection.Elements[0]) is TPasImplBlock) then
  1389. FFirstPasStatement:=TPasImplBlock(Module.InitializationSection.Elements[0]);
  1390. end;
  1391. function TCustomTestModule.FindModuleWithFilename(aFilename: string
  1392. ): TTestEnginePasResolver;
  1393. var
  1394. i: Integer;
  1395. begin
  1396. for i:=0 to ResolverCount-1 do
  1397. if CompareText(Resolvers[i].Filename,aFilename)=0 then
  1398. exit(Resolvers[i]);
  1399. Result:=nil;
  1400. end;
  1401. function TCustomTestModule.AddModule(aFilename: string
  1402. ): TTestEnginePasResolver;
  1403. begin
  1404. //writeln('TTestModuleConverter.AddModule ',aFilename);
  1405. if FindModuleWithFilename(aFilename)<>nil then
  1406. Fail('TTestModuleConverter.AddModule: file "'+aFilename+'" already exists');
  1407. Result:=TTestEnginePasResolver.Create;
  1408. Result.Filename:=aFilename;
  1409. Result.AddObjFPCBuiltInIdentifiers(btAllJSBaseTypes,bfAllJSBaseProcs);
  1410. Result.OnFindUnit:=@OnPasResolverFindUnit;
  1411. Result.OnLog:=@OnPasResolverLog;
  1412. FModules.Add(Result);
  1413. end;
  1414. function TCustomTestModule.AddModuleWithSrc(aFilename, Src: string
  1415. ): TTestEnginePasResolver;
  1416. begin
  1417. Result:=AddModule(aFilename);
  1418. Result.Source:=Src;
  1419. end;
  1420. function TCustomTestModule.AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  1421. ImplementationSrc: string): TTestEnginePasResolver;
  1422. var
  1423. Src: String;
  1424. begin
  1425. Src:='unit '+ExtractFileUnitName(aFilename)+';'+LineEnding;
  1426. Src+=LineEnding;
  1427. Src+='interface'+LineEnding;
  1428. Src+=LineEnding;
  1429. Src+=InterfaceSrc;
  1430. Src+='implementation'+LineEnding;
  1431. Src+=LineEnding;
  1432. Src+=ImplementationSrc;
  1433. Src+='end.'+LineEnding;
  1434. Result:=AddModuleWithSrc(aFilename,Src);
  1435. end;
  1436. procedure TCustomTestModule.AddSystemUnit(Parts: TSystemUnitParts);
  1437. var
  1438. Intf, Impl: TStringList;
  1439. begin
  1440. Intf:=TStringList.Create;
  1441. // interface
  1442. if supTVarRec in Parts then
  1443. Intf.Add('{$modeswitch externalclass}');
  1444. Intf.Add('type');
  1445. Intf.Add(' integer=longint;');
  1446. Intf.Add(' sizeint=nativeint;');
  1447. //'const',
  1448. //' LineEnding = #10;',
  1449. //' DirectorySeparator = ''/'';',
  1450. //' DriveSeparator = '''';',
  1451. //' AllowDirectorySeparators : set of char = [''\'',''/''];',
  1452. //' AllowDriveSeparators : set of char = [];',
  1453. if supTObject in Parts then
  1454. Intf.AddStrings([
  1455. 'type',
  1456. ' TClass = class of TObject;',
  1457. ' TObject = class',
  1458. ' constructor Create;',
  1459. ' destructor Destroy; virtual;',
  1460. ' class function ClassType: TClass; assembler;',
  1461. ' class function ClassName: String; assembler;',
  1462. ' class function ClassNameIs(const Name: string): boolean;',
  1463. ' class function ClassParent: TClass; assembler;',
  1464. ' class function InheritsFrom(aClass: TClass): boolean; assembler;',
  1465. ' class function UnitName: String; assembler;',
  1466. ' procedure AfterConstruction; virtual;',
  1467. ' procedure BeforeDestruction;virtual;',
  1468. ' function Equals(Obj: TObject): boolean; virtual;',
  1469. ' function ToString: String; virtual;',
  1470. ' end;']);
  1471. if supTVarRec in Parts then
  1472. Intf.AddStrings([
  1473. 'const',
  1474. ' vtInteger = 0;',
  1475. ' vtBoolean = 1;',
  1476. ' vtJSValue = 19;',
  1477. 'type',
  1478. ' PVarRec = ^TVarRec;',
  1479. ' TVarRec = record',
  1480. ' VType : byte;',
  1481. ' VJSValue: JSValue;',
  1482. ' vInteger: longint external name ''VJSValue'';',
  1483. ' vBoolean: boolean external name ''VJSValue'';',
  1484. ' end;',
  1485. ' TVarRecArray = array of TVarRec;',
  1486. 'function VarRecs: TVarRecArray; varargs;',
  1487. '']);
  1488. Intf.Add('var');
  1489. Intf.Add(' ExitCode: Longint = 0;');
  1490. // implementation
  1491. Impl:=TStringList.Create;
  1492. if supTObject in Parts then
  1493. Impl.AddStrings([
  1494. '// needed by ClassNameIs, the real SameText is in SysUtils',
  1495. 'function SameText(const s1, s2: String): Boolean; assembler;',
  1496. 'asm',
  1497. 'end;',
  1498. 'constructor TObject.Create; begin end;',
  1499. 'destructor TObject.Destroy; begin end;',
  1500. 'class function TObject.ClassType: TClass; assembler;',
  1501. 'asm',
  1502. 'end;',
  1503. 'class function TObject.ClassName: String; assembler;',
  1504. 'asm',
  1505. 'end;',
  1506. 'class function TObject.ClassNameIs(const Name: string): boolean;',
  1507. 'begin',
  1508. ' Result:=SameText(Name,ClassName);',
  1509. 'end;',
  1510. 'class function TObject.ClassParent: TClass; assembler;',
  1511. 'asm',
  1512. 'end;',
  1513. 'class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;',
  1514. 'asm',
  1515. 'end;',
  1516. 'class function TObject.UnitName: String; assembler;',
  1517. 'asm',
  1518. 'end;',
  1519. 'procedure TObject.AfterConstruction; begin end;',
  1520. 'procedure TObject.BeforeDestruction; begin end;',
  1521. 'function TObject.Equals(Obj: TObject): boolean;',
  1522. 'begin',
  1523. ' Result:=Obj=Self;',
  1524. 'end;',
  1525. 'function TObject.ToString: String;',
  1526. 'begin',
  1527. ' Result:=ClassName;',
  1528. 'end;'
  1529. ]);
  1530. if supTVarRec in Parts then
  1531. Impl.AddStrings([
  1532. 'function VarRecs: TVarRecArray; varargs;',
  1533. 'var',
  1534. ' v: PVarRec;',
  1535. 'begin',
  1536. ' v^.VType:=1;',
  1537. ' v^.VJSValue:=2;',
  1538. 'end;',
  1539. '']);
  1540. try
  1541. AddModuleWithIntfImplSrc('system.pp',Intf.Text,Impl.Text);
  1542. finally
  1543. Intf.Free;
  1544. Impl.Free;
  1545. end;
  1546. end;
  1547. procedure TCustomTestModule.StartProgram(NeedSystemUnit: boolean;
  1548. SystemUnitParts: TSystemUnitParts);
  1549. begin
  1550. if NeedSystemUnit then
  1551. AddSystemUnit(SystemUnitParts)
  1552. else
  1553. Parser.ImplicitUses.Clear;
  1554. Add('program '+ExtractFileUnitName(Filename)+';');
  1555. Add('');
  1556. end;
  1557. procedure TCustomTestModule.StartUnit(NeedSystemUnit: boolean;
  1558. SystemUnitParts: TSystemUnitParts);
  1559. begin
  1560. if NeedSystemUnit then
  1561. AddSystemUnit(SystemUnitParts)
  1562. else
  1563. Parser.ImplicitUses.Clear;
  1564. Add('unit Test1;');
  1565. Add('');
  1566. end;
  1567. procedure TCustomTestModule.ConvertModule;
  1568. procedure CheckUsesList(UsesName: String; Arg: TJSArrayLiteralElement;
  1569. out UsesLit: TJSArrayLiteral);
  1570. var
  1571. i: Integer;
  1572. Item: TJSElement;
  1573. Lit: TJSLiteral;
  1574. begin
  1575. UsesLit:=nil;
  1576. AssertNotNull(UsesName+' uses section',Arg.Expr);
  1577. if (Arg.Expr.ClassType=TJSLiteral) and TJSLiteral(Arg.Expr).Value.IsNull then
  1578. exit; // null is ok
  1579. AssertEquals(UsesName+' uses section param is array',TJSArrayLiteral,Arg.Expr.ClassType);
  1580. FJSInterfaceUses:=TJSArrayLiteral(Arg.Expr);
  1581. for i:=0 to FJSInterfaceUses.Elements.Count-1 do
  1582. begin
  1583. Item:=FJSInterfaceUses.Elements.Elements[i].Expr;
  1584. AssertNotNull(UsesName+' uses section item['+IntToStr(i)+'].Expr',Item);
  1585. AssertEquals(UsesName+' uses section item['+IntToStr(i)+'] is lit',TJSLiteral,Item.ClassType);
  1586. Lit:=TJSLiteral(Item);
  1587. AssertEquals(UsesName+' uses section item['+IntToStr(i)+'] is string lit',
  1588. ord(jsbase.jstString),ord(Lit.Value.ValueType));
  1589. end;
  1590. end;
  1591. procedure CheckFunctionParam(ParamName: string; Arg: TJSArrayLiteralElement;
  1592. out Src: TJSSourceElements);
  1593. var
  1594. FunDecl: TJSFunctionDeclarationStatement;
  1595. FunDef: TJSFuncDef;
  1596. FunBody: TJSFunctionBody;
  1597. begin
  1598. Src:=nil;
  1599. AssertNotNull(ParamName,Arg.Expr);
  1600. AssertEquals(ParamName+' Arg.Expr type',TJSFunctionDeclarationStatement,Arg.Expr.ClassType);
  1601. FunDecl:=Arg.Expr as TJSFunctionDeclarationStatement;
  1602. AssertNotNull(ParamName+' FunDecl.AFunction',FunDecl.AFunction);
  1603. AssertEquals(ParamName+' FunDecl.AFunction type',TJSFuncDef,FunDecl.AFunction.ClassType);
  1604. FunDef:=FunDecl.AFunction as TJSFuncDef;
  1605. AssertEquals(ParamName+' name empty','',String(FunDef.Name));
  1606. AssertNotNull(ParamName+' body',FunDef.Body);
  1607. AssertEquals(ParamName+' body type',TJSFunctionBody,FunDef.Body.ClassType);
  1608. FunBody:=FunDef.Body as TJSFunctionBody;
  1609. AssertNotNull(ParamName+' body.A',FunBody.A);
  1610. AssertEquals(ParamName+' body.A type',TJSSourceElements,FunBody.A.ClassType);
  1611. Src:=FunBody.A as TJSSourceElements;
  1612. end;
  1613. var
  1614. ModuleNameExpr: TJSLiteral;
  1615. InitFunction: TJSFunctionDeclarationStatement;
  1616. InitAssign: TJSSimpleAssignStatement;
  1617. InitName: String;
  1618. LastNode: TJSElement;
  1619. Arg: TJSArrayLiteralElement;
  1620. begin
  1621. if SkipTests then exit;
  1622. try
  1623. FJSModule:=FConverter.ConvertPasElement(Module,Engine) as TJSSourceElements;
  1624. except
  1625. on E: Exception do
  1626. HandleException(E);
  1627. end;
  1628. if SkipTests then exit;
  1629. if ExpectedErrorClass<>nil then
  1630. Fail('Missing '+ExpectedErrorClass.ClassName+' error {'+ExpectedErrorMsg+'} ('+IntToStr(ExpectedErrorNumber)+')');
  1631. FJSSource:=TStringList.Create;
  1632. FJSSource.Text:=ConvertJSModuleToString(JSModule);
  1633. {$IFDEF VerbosePas2JS}
  1634. writeln('TTestModule.ConvertModule JS:');
  1635. write(FJSSource.Text);
  1636. {$ENDIF}
  1637. // rtl.module(...
  1638. AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
  1639. AssertNotNull('register module call',JSModule.Statements.Nodes[0].Node);
  1640. AssertEquals('register module call',TJSCallExpression,JSModule.Statements.Nodes[0].Node.ClassType);
  1641. FJSRegModuleCall:=JSModule.Statements.Nodes[0].Node as TJSCallExpression;
  1642. AssertNotNull('register module rtl.module expr',JSRegModuleCall.Expr);
  1643. AssertNotNull('register module rtl.module args',JSRegModuleCall.Args);
  1644. AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
  1645. FJSModuleCallArgs:=JSRegModuleCall.Args as TJSArguments;
  1646. // parameter 'unitname'
  1647. if JSModuleCallArgs.Elements.Count<1 then
  1648. Fail('rtl.module first param unit missing');
  1649. Arg:=JSModuleCallArgs.Elements.Elements[0];
  1650. AssertNotNull('module name param',Arg.Expr);
  1651. ModuleNameExpr:=Arg.Expr as TJSLiteral;
  1652. AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
  1653. if Module is TPasProgram then
  1654. AssertEquals('module name','program',String(ModuleNameExpr.Value.AsString))
  1655. else
  1656. AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
  1657. // main uses section
  1658. if JSModuleCallArgs.Elements.Count<2 then
  1659. Fail('rtl.module second param main uses missing');
  1660. Arg:=JSModuleCallArgs.Elements.Elements[1];
  1661. CheckUsesList('interface',Arg,FJSInterfaceUses);
  1662. // program/library/interface function()
  1663. if JSModuleCallArgs.Elements.Count<3 then
  1664. Fail('rtl.module third param intf-function missing');
  1665. Arg:=JSModuleCallArgs.Elements.Elements[2];
  1666. CheckFunctionParam('module intf-function',Arg,FJSModuleSrc);
  1667. // search for $mod.$init or $mod.$main - the last statement
  1668. if Module is TPasProgram then
  1669. begin
  1670. InitName:='$main';
  1671. AssertEquals('$mod.'+InitName+' function 1',true,JSModuleSrc.Statements.Count>0);
  1672. end
  1673. else
  1674. InitName:='$init';
  1675. FJSInitBody:=nil;
  1676. if JSModuleSrc.Statements.Count>0 then
  1677. begin
  1678. LastNode:=JSModuleSrc.Statements.Nodes[JSModuleSrc.Statements.Count-1].Node;
  1679. if LastNode is TJSSimpleAssignStatement then
  1680. begin
  1681. InitAssign:=LastNode as TJSSimpleAssignStatement;
  1682. if GetDottedIdentifier(InitAssign.LHS)='$mod.'+InitName then
  1683. begin
  1684. InitFunction:=InitAssign.Expr as TJSFunctionDeclarationStatement;
  1685. FJSInitBody:=InitFunction.AFunction.Body as TJSFunctionBody;
  1686. end
  1687. else if Module is TPasProgram then
  1688. CheckDottedIdentifier('init function',InitAssign.LHS,'$mod.'+InitName);
  1689. end;
  1690. end;
  1691. // optional: implementation uses section
  1692. if JSModuleCallArgs.Elements.Count<4 then
  1693. exit;
  1694. Arg:=JSModuleCallArgs.Elements.Elements[3];
  1695. CheckUsesList('implementation',Arg,FJSImplentationUses);
  1696. // optional: implementation function()
  1697. if JSModuleCallArgs.Elements.Count<5 then
  1698. exit;
  1699. Arg:=JSModuleCallArgs.Elements.Elements[4];
  1700. CheckFunctionParam('module impl-function',Arg,FJSImplementationSrc);
  1701. end;
  1702. procedure TCustomTestModule.ConvertProgram;
  1703. begin
  1704. Add('end.');
  1705. ParseProgram;
  1706. ConvertModule;
  1707. end;
  1708. procedure TCustomTestModule.ConvertUnit;
  1709. begin
  1710. Add('end.');
  1711. ParseUnit;
  1712. ConvertModule;
  1713. end;
  1714. function TCustomTestModule.ConvertJSModuleToString(El: TJSElement): string;
  1715. begin
  1716. Result:=tcmodules.JSToStr(El);
  1717. end;
  1718. procedure TCustomTestModule.CheckDottedIdentifier(Msg: string; El: TJSElement;
  1719. DottedName: string);
  1720. begin
  1721. if DottedName='' then
  1722. begin
  1723. AssertNull(Msg,El);
  1724. end
  1725. else
  1726. begin
  1727. AssertNotNull(Msg,El);
  1728. AssertEquals(Msg,DottedName,GetDottedIdentifier(El));
  1729. end;
  1730. end;
  1731. function TCustomTestModule.GetDottedIdentifier(El: TJSElement): string;
  1732. begin
  1733. if El=nil then
  1734. Result:=''
  1735. else if El is TJSPrimaryExpressionIdent then
  1736. Result:=String(TJSPrimaryExpressionIdent(El).Name)
  1737. else if El is TJSDotMemberExpression then
  1738. Result:=GetDottedIdentifier(TJSDotMemberExpression(El).MExpr)+'.'+String(TJSDotMemberExpression(El).Name)
  1739. else
  1740. AssertEquals('GetDottedIdentifier',TJSPrimaryExpressionIdent,El.ClassType);
  1741. end;
  1742. procedure TCustomTestModule.CheckSource(Msg, Statements: String;
  1743. InitStatements: string; ImplStatements: string);
  1744. var
  1745. ActualSrc, ExpectedSrc, InitName: String;
  1746. begin
  1747. ActualSrc:=JSToStr(JSModuleSrc);
  1748. ExpectedSrc:=
  1749. 'var $mod = this;'+LineEnding
  1750. +Statements;
  1751. if coUseStrict in Converter.Options then
  1752. ExpectedSrc:='"use strict";'+LineEnding+ExpectedSrc;
  1753. if Module is TPasProgram then
  1754. InitName:='$main'
  1755. else
  1756. InitName:='$init';
  1757. if (Module is TPasProgram) or (Trim(InitStatements)<>'') then
  1758. ExpectedSrc:=ExpectedSrc+LineEnding
  1759. +'$mod.'+InitName+' = function () {'+LineEnding
  1760. +InitStatements
  1761. +'};'+LineEnding;
  1762. //writeln('TCustomTestModule.CheckSource ExpectedIntf="',ExpectedSrc,'"');
  1763. //writeln('TTestModule.CheckSource InitStatements="',Trim(InitStatements),'"');
  1764. CheckDiff(Msg,ExpectedSrc,ActualSrc);
  1765. if (JSImplementationSrc<>nil) then
  1766. begin
  1767. ActualSrc:=JSToStr(JSImplementationSrc);
  1768. ExpectedSrc:=
  1769. 'var $mod = this;'+LineEnding
  1770. +'var $impl = $mod.$impl;'+LineEnding
  1771. +ImplStatements;
  1772. end
  1773. else
  1774. begin
  1775. ActualSrc:='';
  1776. ExpectedSrc:=ImplStatements;
  1777. end;
  1778. //writeln('TTestModule.CheckSource InitStatements="',InitStatements,'"');
  1779. //writeln('TCustomTestModule.CheckSource Expected: ',ExpectedSrc);
  1780. CheckDiff(Msg,ExpectedSrc,ActualSrc);
  1781. end;
  1782. procedure TCustomTestModule.CheckDiff(Msg, Expected, Actual: string);
  1783. // search diff, ignore changes in spaces
  1784. var
  1785. s: string;
  1786. begin
  1787. if CheckSrcDiff(Expected,Actual,s) then exit;
  1788. Fail(Msg+': '+s);
  1789. end;
  1790. procedure TCustomTestModule.CheckUnit(Filename, ExpectedSrc: string);
  1791. var
  1792. aResolver: TTestEnginePasResolver;
  1793. aConverter: TPasToJSConverter;
  1794. aJSModule: TJSSourceElements;
  1795. ActualSrc: String;
  1796. begin
  1797. aResolver:=GetResolver(Filename);
  1798. AssertNotNull('missing resolver of unit '+Filename,aResolver);
  1799. {$IFDEF VerbosePas2JS}
  1800. writeln('CheckUnit '+Filename+' converting ...');
  1801. {$ENDIF}
  1802. aConverter:=CreateConverter;
  1803. aJSModule:=nil;
  1804. try
  1805. try
  1806. aJSModule:=aConverter.ConvertPasElement(aResolver.Module,aResolver) as TJSSourceElements;
  1807. except
  1808. on E: Exception do
  1809. HandleException(E);
  1810. end;
  1811. ActualSrc:=ConvertJSModuleToString(aJSModule);
  1812. {$IFDEF VerbosePas2JS}
  1813. writeln('TTestModule.CheckUnit ',Filename,' Pas:');
  1814. write(aResolver.Source);
  1815. writeln('TTestModule.CheckUnit ',Filename,' JS:');
  1816. write(ActualSrc);
  1817. {$ENDIF}
  1818. CheckDiff('Converted unit: "'+ChangeFileExt(Filename,'.js')+'"',ExpectedSrc,ActualSrc);
  1819. finally
  1820. aJSModule.Free;
  1821. aConverter.Free;
  1822. end;
  1823. end;
  1824. procedure TCustomTestModule.CheckHint(MsgType: TMessageType;
  1825. MsgNumber: integer; Msg: string; Marker: PSrcMarker);
  1826. var
  1827. i: Integer;
  1828. Item: TTestHintMessage;
  1829. Expected,Actual: string;
  1830. begin
  1831. //writeln('TCustomTestModule.CheckHint MsgCount=',MsgCount);
  1832. for i:=0 to MsgCount-1 do
  1833. begin
  1834. Item:=Msgs[i];
  1835. if (Item.MsgNumber<>MsgNumber) or (Item.Msg<>Msg) then continue;
  1836. if (Marker<>nil) then
  1837. begin
  1838. if Item.SourcePos.Row<>cardinal(Marker^.Row) then continue;
  1839. if (Item.SourcePos.Column<cardinal(Marker^.StartCol))
  1840. or (Item.SourcePos.Column>cardinal(Marker^.EndCol)) then continue;
  1841. end;
  1842. // found
  1843. FHintMsgsGood.Add(Item);
  1844. str(Item.MsgType,Actual);
  1845. str(MsgType,Expected);
  1846. AssertEquals('MsgType',Expected,Actual);
  1847. exit;
  1848. end;
  1849. // needed message missing -> show emitted messages
  1850. WriteSources('',0,0);
  1851. for i:=0 to MsgCount-1 do
  1852. begin
  1853. Item:=Msgs[i];
  1854. write('TCustomTestModule.CheckHint ',i,'/',MsgCount,' ',Item.MsgType,
  1855. ' ('+IntToStr(Item.MsgNumber),')');
  1856. if Marker<>nil then
  1857. write(' '+ExtractFileName(Item.SourcePos.FileName),'(',Item.SourcePos.Row,',',Item.SourcePos.Column,')');
  1858. writeln(' {',Item.Msg,'}');
  1859. end;
  1860. str(MsgType,Expected);
  1861. Actual:='Missing '+Expected+' ('+IntToStr(MsgNumber)+')';
  1862. if Marker<>nil then
  1863. Actual:=Actual+' '+ExtractFileName(Marker^.Filename)+'('+IntToStr(Marker^.Row)+','+IntToStr(Marker^.StartCol)+'..'+IntToStr(Marker^.EndCol)+')';
  1864. Actual:=Actual+' '+Msg;
  1865. Fail(Actual);
  1866. end;
  1867. procedure TCustomTestModule.CheckResolverUnexpectedHints(WithSourcePos: boolean
  1868. );
  1869. var
  1870. i: Integer;
  1871. s, Txt: String;
  1872. Msg: TTestHintMessage;
  1873. begin
  1874. for i:=0 to MsgCount-1 do
  1875. begin
  1876. Msg:=Msgs[i];
  1877. if FHintMsgsGood.IndexOf(Msg)>=0 then continue;
  1878. s:='';
  1879. str(Msg.MsgType,s);
  1880. Txt:='Unexpected resolver message found ['+IntToStr(Msg.Id)+'] '
  1881. +s+': ('+IntToStr(Msg.MsgNumber)+')';
  1882. if WithSourcePos then
  1883. Txt:=Txt+' '+ExtractFileName(Msg.SourcePos.FileName)+'('+IntToStr(Msg.SourcePos.Row)+','+IntToStr(Msg.SourcePos.Column)+')';
  1884. Txt:=Txt+' {'+Msg.Msg+'}';
  1885. Fail(Txt);
  1886. end;
  1887. end;
  1888. procedure TCustomTestModule.SetExpectedScannerError(Msg: string;
  1889. MsgNumber: integer);
  1890. begin
  1891. ExpectedErrorClass:=EScannerError;
  1892. ExpectedErrorMsg:=Msg;
  1893. ExpectedErrorNumber:=MsgNumber;
  1894. end;
  1895. procedure TCustomTestModule.SetExpectedParserError(Msg: string;
  1896. MsgNumber: integer);
  1897. begin
  1898. ExpectedErrorClass:=EParserError;
  1899. ExpectedErrorMsg:=Msg;
  1900. ExpectedErrorNumber:=MsgNumber;
  1901. end;
  1902. procedure TCustomTestModule.SetExpectedPasResolverError(Msg: string;
  1903. MsgNumber: integer);
  1904. begin
  1905. ExpectedErrorClass:=EPasResolve;
  1906. ExpectedErrorMsg:=Msg;
  1907. ExpectedErrorNumber:=MsgNumber;
  1908. end;
  1909. procedure TCustomTestModule.SetExpectedConverterError(Msg: string;
  1910. MsgNumber: integer);
  1911. begin
  1912. ExpectedErrorClass:=EPas2JS;
  1913. ExpectedErrorMsg:=Msg;
  1914. ExpectedErrorNumber:=MsgNumber;
  1915. end;
  1916. function TCustomTestModule.IsErrorExpected(E: Exception): boolean;
  1917. var
  1918. MsgNumber: Integer;
  1919. Msg: String;
  1920. begin
  1921. Result:=false;
  1922. if (ExpectedErrorClass=nil) or (ExpectedErrorClass<>E.ClassType) then exit;
  1923. Msg:=E.Message;
  1924. if E is EPas2JS then
  1925. MsgNumber:=EPas2JS(E).MsgNumber
  1926. else if E is EPasResolve then
  1927. MsgNumber:=EPasResolve(E).MsgNumber
  1928. else if E is EParserError then
  1929. MsgNumber:=Parser.LastMsgNumber
  1930. else if E is EScannerError then
  1931. begin
  1932. MsgNumber:=Scanner.LastMsgNumber;
  1933. Msg:=Scanner.LastMsg;
  1934. end
  1935. else
  1936. MsgNumber:=0;
  1937. Result:=(MsgNumber=ExpectedErrorNumber) and (Msg=ExpectedErrorMsg);
  1938. if Result then
  1939. SkipTests:=true;
  1940. end;
  1941. procedure TCustomTestModule.HandleScannerError(E: EScannerError);
  1942. begin
  1943. if IsErrorExpected(E) then exit;
  1944. WriteSources(Scanner.CurFilename,Scanner.CurRow,Scanner.CurColumn);
  1945. writeln('ERROR: TCustomTestModule.HandleScannerError '+E.ClassName+':'+E.Message
  1946. +' '+Scanner.CurFilename
  1947. +'('+IntToStr(Scanner.CurRow)+','+IntToStr(Scanner.CurColumn)+')');
  1948. FailException(E);
  1949. end;
  1950. procedure TCustomTestModule.HandleParserError(E: EParserError);
  1951. begin
  1952. if IsErrorExpected(E) then exit;
  1953. WriteSources(E.Filename,E.Row,E.Column);
  1954. writeln('ERROR: TCustomTestModule.HandleParserError '+E.ClassName+':'+E.Message
  1955. +' '+E.Filename+'('+IntToStr(E.Row)+','+IntToStr(E.Column)+')'
  1956. +' MainModuleScannerLine="'+Scanner.CurLine+'"'
  1957. );
  1958. FailException(E);
  1959. end;
  1960. procedure TCustomTestModule.HandlePasResolveError(E: EPasResolve);
  1961. var
  1962. P: TPasSourcePos;
  1963. begin
  1964. if IsErrorExpected(E) then exit;
  1965. P:=E.SourcePos;
  1966. WriteSources(P.FileName,P.Row,P.Column);
  1967. writeln('ERROR: TCustomTestModule.HandlePasResolveError '+E.ClassName+':'+E.Message
  1968. +' '+P.FileName+'('+IntToStr(P.Row)+','+IntToStr(P.Column)+')');
  1969. FailException(E);
  1970. end;
  1971. procedure TCustomTestModule.HandlePas2JSError(E: EPas2JS);
  1972. var
  1973. Row, Col: integer;
  1974. begin
  1975. if IsErrorExpected(E) then exit;
  1976. Engine.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,Row,Col);
  1977. WriteSources(E.PasElement.SourceFilename,Row,Col);
  1978. writeln('ERROR: TCustomTestModule.HandlePas2JSError '+E.ClassName+':'+E.Message
  1979. +' '+E.PasElement.SourceFilename
  1980. +'('+IntToStr(Row)+','+IntToStr(Col)+')');
  1981. FailException(E);
  1982. end;
  1983. procedure TCustomTestModule.HandleException(E: Exception);
  1984. begin
  1985. if E is EScannerError then
  1986. HandleScannerError(EScannerError(E))
  1987. else if E is EParserError then
  1988. HandleParserError(EParserError(E))
  1989. else if E is EPasResolve then
  1990. HandlePasResolveError(EPasResolve(E))
  1991. else if E is EPas2JS then
  1992. HandlePas2JSError(EPas2JS(E))
  1993. else
  1994. begin
  1995. if IsErrorExpected(E) then exit;
  1996. if not (E is EAssertionFailedError) then
  1997. begin
  1998. WriteSources('',0,0);
  1999. writeln('ERROR: TCustomTestModule.HandleException '+E.ClassName+':'+E.Message);
  2000. end;
  2001. FailException(E);
  2002. end;
  2003. end;
  2004. procedure TCustomTestModule.FailException(E: Exception);
  2005. var
  2006. MsgNumber: Integer;
  2007. begin
  2008. if ExpectedErrorClass<>nil then
  2009. begin
  2010. if FExpectedErrorClass=E.ClassType then
  2011. begin
  2012. if E is EPas2JS then
  2013. MsgNumber:=EPas2JS(E).MsgNumber
  2014. else if E is EPasResolve then
  2015. MsgNumber:=EPasResolve(E).MsgNumber
  2016. else if E is EParserError then
  2017. MsgNumber:=Parser.LastMsgNumber
  2018. else if E is EScannerError then
  2019. MsgNumber:=Scanner.LastMsgNumber
  2020. else
  2021. MsgNumber:=0;
  2022. AssertEquals('Expected error message ('+IntToStr(ExpectedErrorNumber)+')','{'+ExpectedErrorMsg+'}','{'+E.Message+'}');
  2023. AssertEquals('Expected {'+ExpectedErrorMsg+'}, but got msg {'+E.Message+'} number',
  2024. ExpectedErrorNumber,MsgNumber);
  2025. end else begin
  2026. AssertEquals('Wrong exception class',ExpectedErrorClass.ClassName,E.ClassName);
  2027. end;
  2028. end;
  2029. Fail(E.Message);
  2030. end;
  2031. procedure TCustomTestModule.WriteSources(const aFilename: string; aRow,
  2032. aCol: integer);
  2033. var
  2034. IsSrc: Boolean;
  2035. i, j: Integer;
  2036. SrcLines: TStringList;
  2037. Line: string;
  2038. aModule: TTestEnginePasResolver;
  2039. begin
  2040. writeln('TCustomTestModule.WriteSources File="',aFilename,'" Row=',aRow,' Col=',aCol);
  2041. for i:=0 to ResolverCount-1 do
  2042. begin
  2043. aModule:=Resolvers[i];
  2044. SrcLines:=TStringList.Create;
  2045. try
  2046. SrcLines.Text:=aModule.Source;
  2047. IsSrc:=ExtractFilename(aModule.Filename)=ExtractFileName(aFilename);
  2048. writeln('Testcode:-File="',aModule.Filename,'"----------------------------------:');
  2049. for j:=1 to SrcLines.Count do
  2050. begin
  2051. Line:=SrcLines[j-1];
  2052. if IsSrc and (j=aRow) then
  2053. begin
  2054. write('*');
  2055. Line:=LeftStr(Line,aCol-1)+'|'+copy(Line,aCol,length(Line));
  2056. end;
  2057. writeln(Format('%:4d: ',[j]),Line);
  2058. end;
  2059. finally
  2060. SrcLines.Free;
  2061. end;
  2062. end;
  2063. end;
  2064. function TCustomTestModule.IndexOfResolver(const Filename: string): integer;
  2065. var
  2066. i: Integer;
  2067. begin
  2068. for i:=0 to ResolverCount-1 do
  2069. if Filename=Resolvers[i].Filename then exit(i);
  2070. Result:=-1;
  2071. end;
  2072. function TCustomTestModule.GetResolver(const Filename: string
  2073. ): TTestEnginePasResolver;
  2074. var
  2075. i: Integer;
  2076. begin
  2077. i:=IndexOfResolver(Filename);
  2078. if i<0 then exit(nil);
  2079. Result:=Resolvers[i];
  2080. end;
  2081. function TCustomTestModule.GetDefaultNamespace: string;
  2082. var
  2083. C: TClass;
  2084. begin
  2085. Result:='';
  2086. if FModule=nil then exit;
  2087. C:=FModule.ClassType;
  2088. if (C=TPasProgram) or (C=TPasLibrary) or (C=TPasPackage) then
  2089. Result:=Engine.DefaultNameSpace;
  2090. end;
  2091. constructor TCustomTestModule.Create;
  2092. begin
  2093. inherited Create;
  2094. FHintMsgs:=TObjectList.Create(true);
  2095. FHintMsgsGood:=TFPList.Create;
  2096. end;
  2097. destructor TCustomTestModule.Destroy;
  2098. begin
  2099. FreeAndNil(FHintMsgs);
  2100. FreeAndNil(FHintMsgsGood);
  2101. inherited Destroy;
  2102. end;
  2103. { TTestModule }
  2104. procedure TTestModule.TestReservedWords;
  2105. var
  2106. i: integer;
  2107. begin
  2108. for i:=low(JSReservedWords) to High(JSReservedWords)-1 do
  2109. if CompareStr(JSReservedWords[i],JSReservedWords[i+1])>=0 then
  2110. Fail('20170203135442 '+JSReservedWords[i]+' >= '+JSReservedWords[i+1]);
  2111. for i:=low(JSReservedGlobalWords) to High(JSReservedGlobalWords)-1 do
  2112. if CompareStr(JSReservedGlobalWords[i],JSReservedGlobalWords[i+1])>=0 then
  2113. Fail('20170203135443 '+JSReservedGlobalWords[i]+' >= '+JSReservedGlobalWords[i+1]);
  2114. end;
  2115. procedure TTestModule.TestEmptyProgram;
  2116. begin
  2117. StartProgram(false);
  2118. Add('begin');
  2119. ConvertProgram;
  2120. CheckSource('TestEmptyProgram','','');
  2121. end;
  2122. procedure TTestModule.TestEmptyProgramUseStrict;
  2123. begin
  2124. Converter.Options:=Converter.Options+[coUseStrict];
  2125. StartProgram(false);
  2126. Add('begin');
  2127. ConvertProgram;
  2128. CheckSource('TestEmptyProgramUseStrict','','');
  2129. end;
  2130. procedure TTestModule.TestEmptyUnit;
  2131. begin
  2132. StartUnit(false);
  2133. Add('interface');
  2134. Add('implementation');
  2135. ConvertUnit;
  2136. CheckSource('TestEmptyUnit',
  2137. LinesToStr([
  2138. ]),
  2139. '');
  2140. end;
  2141. procedure TTestModule.TestEmptyUnitUseStrict;
  2142. begin
  2143. Converter.Options:=Converter.Options+[coUseStrict];
  2144. StartUnit(false);
  2145. Add('interface');
  2146. Add('implementation');
  2147. ConvertUnit;
  2148. CheckSource('TestEmptyUnitUseStrict',
  2149. LinesToStr([
  2150. ''
  2151. ]),
  2152. '');
  2153. end;
  2154. procedure TTestModule.TestDottedUnitNames;
  2155. begin
  2156. AddModuleWithIntfImplSrc('NS1.Unit2.pas',
  2157. LinesToStr([
  2158. 'var iV: longint;'
  2159. ]),
  2160. '');
  2161. FFilename:='ns1.test1.pp';
  2162. StartProgram(true);
  2163. Add('uses unIt2;');
  2164. Add('implementation');
  2165. Add('var');
  2166. Add(' i: longint;');
  2167. Add('begin');
  2168. Add(' i:=iv;');
  2169. Add(' i:=uNit2.iv;');
  2170. Add(' i:=Ns1.TEst1.i;');
  2171. ConvertProgram;
  2172. CheckSource('TestDottedUnitNames',
  2173. LinesToStr([
  2174. 'this.i = 0;',
  2175. '']),
  2176. LinesToStr([ // this.$init
  2177. '$mod.i = pas["NS1.Unit2"].iV;',
  2178. '$mod.i = pas["NS1.Unit2"].iV;',
  2179. '$mod.i = $mod.i;',
  2180. '']) );
  2181. end;
  2182. procedure TTestModule.TestDottedUnitNameImpl;
  2183. begin
  2184. AddModuleWithIntfImplSrc('TEST.UnitA.pas',
  2185. LinesToStr([
  2186. 'type',
  2187. ' TObject = class end;',
  2188. ' TTestA = class',
  2189. ' end;'
  2190. ]),
  2191. LinesToStr(['uses TEST.UnitB;'])
  2192. );
  2193. AddModuleWithIntfImplSrc('TEST.UnitB.pas',
  2194. LinesToStr([
  2195. 'uses TEST.UnitA;',
  2196. 'type TTestB = class(TTestA);'
  2197. ]),
  2198. ''
  2199. );
  2200. StartProgram(true);
  2201. Add('uses TEST.UnitA;');
  2202. Add('begin');
  2203. ConvertProgram;
  2204. CheckSource('TestDottedUnitNameImpl',
  2205. LinesToStr([
  2206. '']),
  2207. LinesToStr([ // this.$init
  2208. '']) );
  2209. CheckUnit('TEST.UnitA.pas',
  2210. LinesToStr([
  2211. 'rtl.module("TEST.UnitA", ["system"], function () {',
  2212. ' var $mod = this;',
  2213. ' rtl.createClass($mod, "TObject", null, function () {',
  2214. ' this.$init = function () {',
  2215. ' };',
  2216. ' this.$final = function () {',
  2217. ' };',
  2218. ' });',
  2219. ' rtl.createClass($mod, "TTestA", $mod.TObject, function () {',
  2220. ' });',
  2221. '}, ["TEST.UnitB"]);'
  2222. ]));
  2223. CheckUnit('TEST.UnitB.pas',
  2224. LinesToStr([
  2225. 'rtl.module("TEST.UnitB", ["system","TEST.UnitA"], function () {',
  2226. ' var $mod = this;',
  2227. ' rtl.createClass($mod, "TTestB", pas["TEST.UnitA"].TTestA, function () {',
  2228. ' });',
  2229. '});'
  2230. ]));
  2231. end;
  2232. procedure TTestModule.TestDottedUnitExpr;
  2233. begin
  2234. AddModuleWithIntfImplSrc('NS2.SubNs2.Unit2.pas',
  2235. LinesToStr([
  2236. 'procedure DoIt;'
  2237. ]),
  2238. 'procedure DoIt; begin end;');
  2239. FFilename:='Ns1.SubNs1.Test1.pp';
  2240. StartProgram(true);
  2241. Add('uses Ns2.sUbnS2.unIt2;');
  2242. Add('implementation');
  2243. Add('var');
  2244. Add(' i: longint;');
  2245. Add('begin');
  2246. Add(' ns2.subns2.unit2.doit;');
  2247. Add(' i:=Ns1.SubNS1.TEst1.i;');
  2248. ConvertProgram;
  2249. CheckSource('TestDottedUnitExpr',
  2250. LinesToStr([
  2251. 'this.i = 0;',
  2252. '']),
  2253. LinesToStr([ // this.$init
  2254. 'pas["NS2.SubNs2.Unit2"].DoIt();',
  2255. '$mod.i = $mod.i;',
  2256. '']) );
  2257. end;
  2258. procedure TTestModule.Test_ModeFPCFail;
  2259. begin
  2260. StartProgram(false);
  2261. Add('{$mode FPC}');
  2262. Add('begin');
  2263. SetExpectedScannerError('Invalid mode: "FPC"',nErrInvalidMode);
  2264. ConvertProgram;
  2265. end;
  2266. procedure TTestModule.Test_ModeSwitchCBlocksFail;
  2267. begin
  2268. StartProgram(false);
  2269. Add('{$modeswitch cblocks-}');
  2270. Add('begin');
  2271. SetExpectedScannerError('Invalid mode switch: "cblocks-"',nErrInvalidModeSwitch);
  2272. ConvertProgram;
  2273. end;
  2274. procedure TTestModule.TestUnit_UseSystem;
  2275. begin
  2276. StartUnit(true);
  2277. Add([
  2278. 'interface',
  2279. 'var i: integer;',
  2280. 'implementation']);
  2281. ConvertUnit;
  2282. CheckSource('TestUnit_UseSystem',
  2283. LinesToStr([
  2284. 'this.i = 0;',
  2285. '']),
  2286. LinesToStr([
  2287. '']) );
  2288. end;
  2289. procedure TTestModule.TestUnit_Intf1Impl2Intf1;
  2290. begin
  2291. AddModuleWithIntfImplSrc('unit1.pp',
  2292. LinesToStr([
  2293. 'type number = longint;']),
  2294. LinesToStr([
  2295. 'uses test1;',
  2296. 'procedure DoIt;',
  2297. 'begin',
  2298. ' i:=3;',
  2299. 'end;']));
  2300. StartUnit(true);
  2301. Add([
  2302. 'interface',
  2303. 'uses unit1;',
  2304. 'var i: number;',
  2305. 'implementation']);
  2306. ConvertUnit;
  2307. CheckSource('TestUnit_Intf1Impl2Intf1',
  2308. LinesToStr([
  2309. 'this.i = 0;',
  2310. '']),
  2311. LinesToStr([
  2312. '']) );
  2313. end;
  2314. procedure TTestModule.TestIncludeVersion;
  2315. begin
  2316. StartProgram(false);
  2317. Add([
  2318. 'var',
  2319. ' s: string;',
  2320. ' i: word;',
  2321. 'begin',
  2322. ' s:={$I %line%};',
  2323. ' i:={$I %linenum%};',
  2324. ' s:={$I %currentroutine%};',
  2325. ' s:={$I %pas2jsversion%};',
  2326. ' s:={$I %pas2jstarget%};',
  2327. ' s:={$I %pas2jstargetos%};',
  2328. ' s:={$I %pas2jstargetcpu%};',
  2329. ' s:={$I %file%};',
  2330. '']);
  2331. ConvertProgram;
  2332. CheckSource('TestIncludeVersion',
  2333. LinesToStr([
  2334. 'this.s="";',
  2335. 'this.i = 0;']),
  2336. LinesToStr([
  2337. '$mod.s = "7";',
  2338. '$mod.i = 8;',
  2339. '$mod.s = "<anonymous>";',
  2340. '$mod.s = "Comp.Ver.tcmodules";',
  2341. '$mod.s = "Browser";',
  2342. '$mod.s = "Browser";',
  2343. '$mod.s = "ECMAScript5";',
  2344. '$mod.s = "test1.pp";',
  2345. '']));
  2346. end;
  2347. procedure TTestModule.TestVarInt;
  2348. begin
  2349. StartProgram(false);
  2350. Add('var MyI: longint;');
  2351. Add('begin');
  2352. ConvertProgram;
  2353. CheckSource('TestVarInt','this.MyI=0;','');
  2354. end;
  2355. procedure TTestModule.TestVarBaseTypes;
  2356. begin
  2357. StartProgram(false);
  2358. Add('var');
  2359. Add(' i: longint;');
  2360. Add(' s: string;');
  2361. Add(' c: char;');
  2362. Add(' b: boolean;');
  2363. Add(' d: double;');
  2364. Add(' i2: longint = 3;');
  2365. Add(' s2: string = ''foo'';');
  2366. Add(' c2: char = ''4'';');
  2367. Add(' b2: boolean = true;');
  2368. Add(' d2: double = 5.6;');
  2369. Add(' i3: longint = $707;');
  2370. Add(' i4: nativeint = 9007199254740991;');
  2371. Add(' i5: nativeint = -9007199254740991-1;');
  2372. Add(' i6: nativeint = $fffffffffffff;');
  2373. Add(' i7: nativeint = -$fffffffffffff-1;');
  2374. Add(' i8: byte = 00;');
  2375. Add(' u8: nativeuint = $fffffffffffff;');
  2376. Add(' u9: nativeuint = $0000000000000;');
  2377. Add(' u10: nativeuint = $00ff00;');
  2378. Add('begin');
  2379. ConvertProgram;
  2380. CheckSource('TestVarBaseTypes',
  2381. LinesToStr([
  2382. 'this.i = 0;',
  2383. 'this.s = "";',
  2384. 'this.c = "";',
  2385. 'this.b = false;',
  2386. 'this.d = 0.0;',
  2387. 'this.i2 = 3;',
  2388. 'this.s2 = "foo";',
  2389. 'this.c2 = "4";',
  2390. 'this.b2 = true;',
  2391. 'this.d2 = 5.6;',
  2392. 'this.i3 = 0x707;',
  2393. 'this.i4 = 9007199254740991;',
  2394. 'this.i5 = -9007199254740991-1;',
  2395. 'this.i6 = 0xfffffffffffff;',
  2396. 'this.i7 =-0xfffffffffffff-1;',
  2397. 'this.i8 = 0;',
  2398. 'this.u8 = 0xfffffffffffff;',
  2399. 'this.u9 = 0x0;',
  2400. 'this.u10 = 0xff00;'
  2401. ]),
  2402. '');
  2403. end;
  2404. procedure TTestModule.TestBaseTypeSingleFail;
  2405. begin
  2406. StartProgram(false);
  2407. Add('var s: single;');
  2408. SetExpectedPasResolverError('identifier not found "single"',PasResolveEval.nIdentifierNotFound);
  2409. ConvertProgram;
  2410. end;
  2411. procedure TTestModule.TestBaseTypeExtendedFail;
  2412. begin
  2413. StartProgram(false);
  2414. Add('var e: extended;');
  2415. SetExpectedPasResolverError('identifier not found "extended"',PasResolveEval.nIdentifierNotFound);
  2416. ConvertProgram;
  2417. end;
  2418. procedure TTestModule.TestConstBaseTypes;
  2419. begin
  2420. StartProgram(false);
  2421. Add('const');
  2422. Add(' i: longint = 3;');
  2423. Add(' s: string = ''foo'';');
  2424. Add(' c: char = ''4'';');
  2425. Add(' b: boolean = true;');
  2426. Add(' d: double = 5.6;');
  2427. Add(' e = low(word);');
  2428. Add(' f = high(word);');
  2429. Add('begin');
  2430. ConvertProgram;
  2431. CheckSource('TestVarBaseTypes',
  2432. LinesToStr([
  2433. 'this.i=3;',
  2434. 'this.s="foo";',
  2435. 'this.c="4";',
  2436. 'this.b=true;',
  2437. 'this.d=5.6;',
  2438. 'this.e = 0;',
  2439. 'this.f = 65535;'
  2440. ]),
  2441. '');
  2442. end;
  2443. procedure TTestModule.TestAliasTypeRef;
  2444. begin
  2445. StartProgram(false);
  2446. Add('type');
  2447. Add(' a=longint;');
  2448. Add(' b=a;');
  2449. Add('var');
  2450. Add(' c: A;');
  2451. Add(' d: B;');
  2452. Add('begin');
  2453. ConvertProgram;
  2454. CheckSource('TestAliasTypeRef',
  2455. LinesToStr([ // statements
  2456. 'this.c = 0;',
  2457. 'this.d = 0;'
  2458. ]),
  2459. LinesToStr([ // this.$main
  2460. ''
  2461. ]));
  2462. end;
  2463. procedure TTestModule.TestTypeCast_BaseTypes;
  2464. begin
  2465. StartProgram(false);
  2466. Add([
  2467. 'var',
  2468. ' i: longint;',
  2469. ' b: boolean;',
  2470. ' d: double;',
  2471. ' s: string;',
  2472. ' c: char;',
  2473. 'begin',
  2474. ' i:=longint(i);',
  2475. ' i:=longint(b);',
  2476. ' b:=boolean(b);',
  2477. ' b:=boolean(i);',
  2478. ' d:=double(d);',
  2479. ' d:=double(i);',
  2480. ' s:=string(s);',
  2481. ' s:=string(c);',
  2482. ' c:=char(c);',
  2483. ' c:=char(i);',
  2484. ' c:=char(65);',
  2485. ' c:=char(#10);',
  2486. ' c:=char(#$E000);',
  2487. '']);
  2488. ConvertProgram;
  2489. CheckSource('TestAliasTypeRef',
  2490. LinesToStr([ // statements
  2491. 'this.i = 0;',
  2492. 'this.b = false;',
  2493. 'this.d = 0.0;',
  2494. 'this.s = "";',
  2495. 'this.c = "";',
  2496. '']),
  2497. LinesToStr([ // this.$main
  2498. '$mod.i = $mod.i;',
  2499. '$mod.i = ($mod.b ? 1 : 0);',
  2500. '$mod.b = $mod.b;',
  2501. '$mod.b = $mod.i != 0;',
  2502. '$mod.d = $mod.d;',
  2503. '$mod.d = $mod.i;',
  2504. '$mod.s = $mod.s;',
  2505. '$mod.s = $mod.c;',
  2506. '$mod.c = $mod.c;',
  2507. '$mod.c = String.fromCharCode($mod.i);',
  2508. '$mod.c = "A";',
  2509. '$mod.c = "\n";',
  2510. '$mod.c = "";',
  2511. '']));
  2512. end;
  2513. procedure TTestModule.TestTypeCast_AliasBaseTypes;
  2514. begin
  2515. StartProgram(false);
  2516. Add('type');
  2517. Add(' integer = longint;');
  2518. Add(' TYesNo = boolean;');
  2519. Add(' TFloat = double;');
  2520. Add(' TCaption = string;');
  2521. Add(' TChar = char;');
  2522. Add('var');
  2523. Add(' i: integer;');
  2524. Add(' b: TYesNo;');
  2525. Add(' d: TFloat;');
  2526. Add(' s: TCaption;');
  2527. Add(' c: TChar;');
  2528. Add('begin');
  2529. Add(' i:=integer(i);');
  2530. Add(' i:=integer(b);');
  2531. Add(' b:=TYesNo(b);');
  2532. Add(' b:=TYesNo(i);');
  2533. Add(' d:=TFloat(d);');
  2534. Add(' d:=TFloat(i);');
  2535. Add(' s:=TCaption(s);');
  2536. Add(' s:=TCaption(c);');
  2537. Add(' c:=TChar(c);');
  2538. ConvertProgram;
  2539. CheckSource('TestAliasTypeRef',
  2540. LinesToStr([ // statements
  2541. 'this.i = 0;',
  2542. 'this.b = false;',
  2543. 'this.d = 0.0;',
  2544. 'this.s = "";',
  2545. 'this.c = "";',
  2546. '']),
  2547. LinesToStr([ // this.$main
  2548. '$mod.i = $mod.i;',
  2549. '$mod.i = ($mod.b ? 1 : 0);',
  2550. '$mod.b = $mod.b;',
  2551. '$mod.b = $mod.i != 0;',
  2552. '$mod.d = $mod.d;',
  2553. '$mod.d = $mod.i;',
  2554. '$mod.s = $mod.s;',
  2555. '$mod.s = $mod.c;',
  2556. '$mod.c = $mod.c;',
  2557. '']));
  2558. end;
  2559. procedure TTestModule.TestEmptyProc;
  2560. begin
  2561. StartProgram(false);
  2562. Add('procedure Test;');
  2563. Add('begin');
  2564. Add('end;');
  2565. Add('begin');
  2566. ConvertProgram;
  2567. CheckSource('TestEmptyProc',
  2568. LinesToStr([ // statements
  2569. 'this.Test = function () {',
  2570. '};'
  2571. ]),
  2572. LinesToStr([ // this.$main
  2573. ''
  2574. ]));
  2575. end;
  2576. procedure TTestModule.TestProcOneParam;
  2577. begin
  2578. StartProgram(false);
  2579. Add('procedure ProcA(i: longint);');
  2580. Add('begin');
  2581. Add('end;');
  2582. Add('begin');
  2583. Add(' PROCA(3);');
  2584. ConvertProgram;
  2585. CheckSource('TestProcOneParam',
  2586. LinesToStr([ // statements
  2587. 'this.ProcA = function (i) {',
  2588. '};'
  2589. ]),
  2590. LinesToStr([ // this.$main
  2591. '$mod.ProcA(3);'
  2592. ]));
  2593. end;
  2594. procedure TTestModule.TestFunctionWithoutParams;
  2595. begin
  2596. StartProgram(false);
  2597. Add('function FuncA: longint;');
  2598. Add('begin');
  2599. Add('end;');
  2600. Add('var i: longint;');
  2601. Add('begin');
  2602. Add(' I:=FUNCA();');
  2603. Add(' I:=FUNCA;');
  2604. Add(' FUNCA();');
  2605. Add(' FUNCA;');
  2606. ConvertProgram;
  2607. CheckSource('TestProcWithoutParams',
  2608. LinesToStr([ // statements
  2609. 'this.FuncA = function () {',
  2610. ' var Result = 0;',
  2611. ' return Result;',
  2612. '};',
  2613. 'this.i=0;'
  2614. ]),
  2615. LinesToStr([ // this.$main
  2616. '$mod.i=$mod.FuncA();',
  2617. '$mod.i=$mod.FuncA();',
  2618. '$mod.FuncA();',
  2619. '$mod.FuncA();'
  2620. ]));
  2621. end;
  2622. procedure TTestModule.TestProcedureWithoutParams;
  2623. begin
  2624. StartProgram(false);
  2625. Add('procedure ProcA;');
  2626. Add('begin');
  2627. Add('end;');
  2628. Add('begin');
  2629. Add(' PROCA();');
  2630. Add(' PROCA;');
  2631. ConvertProgram;
  2632. CheckSource('TestProcWithoutParams',
  2633. LinesToStr([ // statements
  2634. 'this.ProcA = function () {',
  2635. '};'
  2636. ]),
  2637. LinesToStr([ // this.$main
  2638. '$mod.ProcA();',
  2639. '$mod.ProcA();'
  2640. ]));
  2641. end;
  2642. procedure TTestModule.TestIncDec;
  2643. begin
  2644. StartProgram(false);
  2645. Add([
  2646. 'procedure DoIt(var i: longint);',
  2647. 'begin',
  2648. ' inc(i);',
  2649. ' inc(i,2);',
  2650. 'end;',
  2651. 'var',
  2652. ' Bar: longint;',
  2653. 'begin',
  2654. ' inc(bar);',
  2655. ' inc(bar,2);',
  2656. ' dec(bar);',
  2657. ' dec(bar,3);',
  2658. '']);
  2659. ConvertProgram;
  2660. CheckSource('TestIncDec',
  2661. LinesToStr([ // statements
  2662. 'this.DoIt = function (i) {',
  2663. ' i.set(i.get()+1);',
  2664. ' i.set(i.get()+2);',
  2665. '};',
  2666. 'this.Bar = 0;'
  2667. ]),
  2668. LinesToStr([ // this.$main
  2669. '$mod.Bar+=1;',
  2670. '$mod.Bar+=2;',
  2671. '$mod.Bar-=1;',
  2672. '$mod.Bar-=3;'
  2673. ]));
  2674. end;
  2675. procedure TTestModule.TestLoHiFpcMode;
  2676. begin
  2677. StartProgram(false);
  2678. Add([
  2679. '{$mode objfpc}',
  2680. 'const',
  2681. ' LoByte1 = Lo(Word($1234));',
  2682. ' HiByte1 = Hi(Word($1234));',
  2683. ' LoByte2 = Lo(SmallInt($1234));',
  2684. ' HiByte2 = Hi(SmallInt($1234));',
  2685. ' LoWord1 = Lo($1234CDEF);',
  2686. ' HiWord1 = Hi($1234CDEF);',
  2687. ' LoWord2 = Lo(-$1234CDEF);',
  2688. ' HiWord2 = Hi(-$1234CDEF);',
  2689. ' lo4:byte=lo(byte($34));',
  2690. ' hi4:byte=hi(byte($34));',
  2691. ' lo5:byte=lo(shortint(-$34));',
  2692. ' hi5:byte=hi(shortint(-$34));',
  2693. ' lo6:longword=lo($123456789ABCD);',
  2694. ' hi6:longword=hi($123456789ABCD);',
  2695. ' lo7:longword=lo(-$123456789ABCD);',
  2696. ' hi7:longword=hi(-$123456789ABCD);',
  2697. 'var',
  2698. ' b: Byte;',
  2699. ' ss: shortint;',
  2700. ' w: Word;',
  2701. ' si: SmallInt;',
  2702. ' lw: LongWord;',
  2703. ' li: LongInt;',
  2704. ' b2: Byte;',
  2705. ' ni: nativeint;',
  2706. 'begin',
  2707. ' w := $1234;',
  2708. ' ss := -$12;',
  2709. ' b := lo(ss);',
  2710. ' b := HI(ss);',
  2711. ' b := lo(w);',
  2712. ' b := HI(w);',
  2713. ' b2 := lo(b);',
  2714. ' b2 := hi(b);',
  2715. ' lw := $1234CDEF;',
  2716. ' w := lo(lw);',
  2717. ' w := hi(lw);',
  2718. ' ni := $123456789ABCD;',
  2719. ' lw := lo(ni);',
  2720. ' lw := hi(ni);',
  2721. '']);
  2722. ConvertProgram;
  2723. CheckSource('TestLoHiFpcMode',
  2724. LinesToStr([ // statements
  2725. 'this.LoByte1 = 0x1234 & 0xFF;',
  2726. 'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
  2727. 'this.LoByte2 = 0x1234 & 0xFF;',
  2728. 'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
  2729. 'this.LoWord1 = 0x1234CDEF & 0xFFFF;',
  2730. 'this.HiWord1 = (0x1234CDEF >> 16) & 0xFFFF;',
  2731. 'this.LoWord2 = -0x1234CDEF & 0xFFFF;',
  2732. 'this.HiWord2 = (-0x1234CDEF >> 16) & 0xFFFF;',
  2733. 'this.lo4 = 0x34 & 0xF;',
  2734. 'this.hi4 = (0x34 >> 4) & 0xF;',
  2735. 'this.lo5 = (((-0x34 & 255) << 24) >> 24) & 0xFF;',
  2736. 'this.hi5 = ((((-0x34 & 255) << 24) >> 24) >> 8) & 0xFF;',
  2737. 'this.lo6 = 0x123456789ABCD >>> 0;',
  2738. 'this.hi6 = 74565 >>> 0;',
  2739. 'this.lo7 = -0x123456789ABCD >>> 0;',
  2740. 'this.hi7 = Math.floor(-0x123456789ABCD / 4294967296) >>> 0;',
  2741. 'this.b = 0;',
  2742. 'this.ss = 0;',
  2743. 'this.w = 0;',
  2744. 'this.si = 0;',
  2745. 'this.lw = 0;',
  2746. 'this.li = 0;',
  2747. 'this.b2 = 0;',
  2748. 'this.ni = 0;',
  2749. '']),
  2750. LinesToStr([ // this.$main
  2751. '$mod.w = 0x1234;',
  2752. '$mod.ss = -0x12;',
  2753. '$mod.b = $mod.ss & 0xFF;',
  2754. '$mod.b = ($mod.ss >> 8) & 0xFF;',
  2755. '$mod.b = $mod.w & 0xFF;',
  2756. '$mod.b = ($mod.w >> 8) & 0xFF;',
  2757. '$mod.b2 = $mod.b & 0xF;',
  2758. '$mod.b2 = ($mod.b >> 4) & 0xF;',
  2759. '$mod.lw = 0x1234CDEF;',
  2760. '$mod.w = $mod.lw & 0xFFFF;',
  2761. '$mod.w = ($mod.lw >> 16) & 0xFFFF;',
  2762. '$mod.ni = 0x123456789ABCD;',
  2763. '$mod.lw = $mod.ni >>> 0;',
  2764. '$mod.lw = Math.floor($mod.ni / 4294967296) >>> 0;',
  2765. '']));
  2766. end;
  2767. procedure TTestModule.TestLoHiDelphiMode;
  2768. begin
  2769. StartProgram(false);
  2770. Add([
  2771. '{$mode delphi}',
  2772. 'const',
  2773. ' LoByte1 = Lo(Word($1234));',
  2774. ' HiByte1 = Hi(Word($1234));',
  2775. ' LoByte2 = Lo(SmallInt($1234));',
  2776. ' HiByte2 = Hi(SmallInt($1234));',
  2777. ' LoByte3 = Lo($1234CDEF);',
  2778. ' HiByte3 = Hi($1234CDEF);',
  2779. ' LoByte4 = Lo(-$1234CDEF);',
  2780. ' HiByte4 = Hi(-$1234CDEF);',
  2781. 'var',
  2782. ' b: Byte;',
  2783. ' w: Word;',
  2784. ' si: SmallInt;',
  2785. ' lw: LongWord;',
  2786. ' li: LongInt;',
  2787. 'begin',
  2788. ' w := $1234;',
  2789. ' b := lo(w);',
  2790. ' b := HI(w);',
  2791. ' lw := $1234CDEF;',
  2792. ' b := lo(lw);',
  2793. ' b := hi(lw);',
  2794. '']);
  2795. ConvertProgram;
  2796. CheckSource('TestLoHiDelphiMode',
  2797. LinesToStr([ // statements
  2798. 'this.LoByte1 = 0x1234 & 0xFF;',
  2799. 'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
  2800. 'this.LoByte2 = 0x1234 & 0xFF;',
  2801. 'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
  2802. 'this.LoByte3 = 0x1234CDEF & 0xFF;',
  2803. 'this.HiByte3 = (0x1234CDEF >> 8) & 0xFF;',
  2804. 'this.LoByte4 = -0x1234CDEF & 0xFF;',
  2805. 'this.HiByte4 = (-0x1234CDEF >> 8) & 0xFF;',
  2806. 'this.b = 0;',
  2807. 'this.w = 0;',
  2808. 'this.si = 0;',
  2809. 'this.lw = 0;',
  2810. 'this.li = 0;'
  2811. ]),
  2812. LinesToStr([ // this.$main
  2813. '$mod.w = 0x1234;',
  2814. '$mod.b = $mod.w & 0xFF;',
  2815. '$mod.b = ($mod.w >> 8) & 0xFF;',
  2816. '$mod.lw = 0x1234CDEF;',
  2817. '$mod.b = $mod.lw & 0xFF;',
  2818. '$mod.b = ($mod.lw >> 8) & 0xFF;'
  2819. ]));
  2820. end;
  2821. procedure TTestModule.TestAssignments;
  2822. begin
  2823. StartProgram(false);
  2824. Parser.Options:=Parser.Options+[po_cassignments];
  2825. Add('var');
  2826. Add(' Bar:longint;');
  2827. Add('begin');
  2828. Add(' bar:=3;');
  2829. Add(' bar+=4;');
  2830. Add(' bar-=5;');
  2831. Add(' bar*=6;');
  2832. ConvertProgram;
  2833. CheckSource('TestAssignments',
  2834. LinesToStr([ // statements
  2835. 'this.Bar = 0;'
  2836. ]),
  2837. LinesToStr([ // this.$main
  2838. '$mod.Bar=3;',
  2839. '$mod.Bar+=4;',
  2840. '$mod.Bar-=5;',
  2841. '$mod.Bar*=6;'
  2842. ]));
  2843. end;
  2844. procedure TTestModule.TestArithmeticOperators1;
  2845. begin
  2846. StartProgram(false);
  2847. Add('var');
  2848. Add(' vA,vB,vC:longint;');
  2849. Add('begin');
  2850. Add(' va:=1;');
  2851. Add(' vb:=va+va;');
  2852. Add(' vb:=va div vb;');
  2853. Add(' vb:=va mod vb;');
  2854. Add(' vb:=va+va*vb+va div vb;');
  2855. Add(' vc:=-va;');
  2856. Add(' va:=va-vb;');
  2857. Add(' vb:=va;');
  2858. Add(' if va<vb then vc:=va else vc:=vb;');
  2859. ConvertProgram;
  2860. CheckSource('TestArithmeticOperators1',
  2861. LinesToStr([ // statements
  2862. 'this.vA = 0;',
  2863. 'this.vB = 0;',
  2864. 'this.vC = 0;'
  2865. ]),
  2866. LinesToStr([ // this.$main
  2867. '$mod.vA = 1;',
  2868. '$mod.vB = $mod.vA + $mod.vA;',
  2869. '$mod.vB = Math.floor($mod.vA / $mod.vB);',
  2870. '$mod.vB = $mod.vA % $mod.vB;',
  2871. '$mod.vB = $mod.vA + ($mod.vA * $mod.vB) + Math.floor($mod.vA / $mod.vB);',
  2872. '$mod.vC = -$mod.vA;',
  2873. '$mod.vA = $mod.vA - $mod.vB;',
  2874. '$mod.vB = $mod.vA;',
  2875. 'if ($mod.vA < $mod.vB){ $mod.vC = $mod.vA } else $mod.vC = $mod.vB;'
  2876. ]));
  2877. end;
  2878. procedure TTestModule.TestLogicalOperators;
  2879. begin
  2880. StartProgram(false);
  2881. Add('var');
  2882. Add(' vA,vB,vC:boolean;');
  2883. Add('begin');
  2884. Add(' va:=vb and vc;');
  2885. Add(' va:=vb or vc;');
  2886. Add(' va:=vb xor vc;');
  2887. Add(' va:=true and vc;');
  2888. Add(' va:=(vb and vc) or (va and vb);');
  2889. Add(' va:=not vb;');
  2890. ConvertProgram;
  2891. CheckSource('TestLogicalOperators',
  2892. LinesToStr([ // statements
  2893. 'this.vA = false;',
  2894. 'this.vB = false;',
  2895. 'this.vC = false;'
  2896. ]),
  2897. LinesToStr([ // this.$main
  2898. '$mod.vA = $mod.vB && $mod.vC;',
  2899. '$mod.vA = $mod.vB || $mod.vC;',
  2900. '$mod.vA = $mod.vB ^ $mod.vC;',
  2901. '$mod.vA = true && $mod.vC;',
  2902. '$mod.vA = ($mod.vB && $mod.vC) || ($mod.vA && $mod.vB);',
  2903. '$mod.vA = !$mod.vB;'
  2904. ]));
  2905. end;
  2906. procedure TTestModule.TestBitwiseOperators;
  2907. begin
  2908. StartProgram(false);
  2909. Add([
  2910. 'var',
  2911. ' vA,vB,vC:longint;',
  2912. ' X,Y,Z: nativeint;',
  2913. 'begin',
  2914. ' va:=vb and vc;',
  2915. ' va:=vb or vc;',
  2916. ' va:=vb xor vc;',
  2917. ' va:=vb shl vc;',
  2918. ' va:=vb shr vc;',
  2919. ' va:=3 and vc;',
  2920. ' va:=(vb and vc) or (va and vb);',
  2921. ' va:=not vb;',
  2922. ' X:=Y and Z;',
  2923. ' X:=Y and va;',
  2924. ' X:=Y or Z;',
  2925. ' X:=Y or va;',
  2926. ' X:=Y xor Z;',
  2927. ' X:=Y xor va;',
  2928. '']);
  2929. ConvertProgram;
  2930. CheckSource('TestBitwiseOperators',
  2931. LinesToStr([ // statements
  2932. 'this.vA = 0;',
  2933. 'this.vB = 0;',
  2934. 'this.vC = 0;',
  2935. 'this.X = 0;',
  2936. 'this.Y = 0;',
  2937. 'this.Z = 0;',
  2938. '']),
  2939. LinesToStr([ // this.$main
  2940. '$mod.vA = $mod.vB & $mod.vC;',
  2941. '$mod.vA = $mod.vB | $mod.vC;',
  2942. '$mod.vA = $mod.vB ^ $mod.vC;',
  2943. '$mod.vA = $mod.vB << $mod.vC;',
  2944. '$mod.vA = $mod.vB >>> $mod.vC;',
  2945. '$mod.vA = 3 & $mod.vC;',
  2946. '$mod.vA = ($mod.vB & $mod.vC) | ($mod.vA & $mod.vB);',
  2947. '$mod.vA = ~$mod.vB;',
  2948. '$mod.X = rtl.and($mod.Y, $mod.Z);',
  2949. '$mod.X = $mod.Y & $mod.vA;',
  2950. '$mod.X = rtl.or($mod.Y, $mod.Z);',
  2951. '$mod.X = rtl.or($mod.Y, $mod.vA);',
  2952. '$mod.X = rtl.xor($mod.Y, $mod.Z);',
  2953. '$mod.X = rtl.xor($mod.Y, $mod.vA);',
  2954. '']));
  2955. end;
  2956. procedure TTestModule.TestPrgProcVar;
  2957. begin
  2958. StartProgram(false);
  2959. Add('procedure Proc1;');
  2960. Add('type');
  2961. Add(' t1=longint;');
  2962. Add('var');
  2963. Add(' vA:t1;');
  2964. Add('begin');
  2965. Add('end;');
  2966. Add('begin');
  2967. ConvertProgram;
  2968. CheckSource('TestPrgProcVar',
  2969. LinesToStr([ // statements
  2970. 'this.Proc1 = function () {',
  2971. ' var vA=0;',
  2972. '};'
  2973. ]),
  2974. LinesToStr([ // this.$main
  2975. ''
  2976. ]));
  2977. end;
  2978. procedure TTestModule.TestUnitProcVar;
  2979. begin
  2980. StartUnit(false);
  2981. Add('interface');
  2982. Add('');
  2983. Add('type tA=string; // unit scope');
  2984. Add('procedure Proc1;');
  2985. Add('');
  2986. Add('implementation');
  2987. Add('');
  2988. Add('procedure Proc1;');
  2989. Add('type tA=longint; // local proc scope');
  2990. Add('var v1:tA; // using local tA');
  2991. Add('begin');
  2992. Add('end;');
  2993. Add('var v2:tA; // using interface tA');
  2994. ConvertUnit;
  2995. CheckSource('TestUnitProcVar',
  2996. LinesToStr([ // statements
  2997. 'var $impl = $mod.$impl;',
  2998. 'this.Proc1 = function () {',
  2999. ' var v1 = 0;',
  3000. '};',
  3001. '']),
  3002. // this.$init
  3003. '',
  3004. // implementation
  3005. LinesToStr([
  3006. '$impl.v2 = "";',
  3007. '']));
  3008. end;
  3009. procedure TTestModule.TestImplProc;
  3010. begin
  3011. StartUnit(false);
  3012. Add('interface');
  3013. Add('');
  3014. Add('procedure Proc1;');
  3015. Add('');
  3016. Add('implementation');
  3017. Add('');
  3018. Add('procedure Proc1; begin end;');
  3019. Add('procedure Proc2; begin end;');
  3020. Add('initialization');
  3021. Add(' Proc1;');
  3022. Add(' Proc2;');
  3023. ConvertUnit;
  3024. CheckSource('TestImplProc',
  3025. LinesToStr([ // statements
  3026. 'var $impl = $mod.$impl;',
  3027. 'this.Proc1 = function () {',
  3028. '};',
  3029. '']),
  3030. LinesToStr([ // this.$init
  3031. '$mod.Proc1();',
  3032. '$impl.Proc2();',
  3033. '']),
  3034. LinesToStr([ // implementation
  3035. '$impl.Proc2 = function () {',
  3036. '};',
  3037. ''])
  3038. );
  3039. end;
  3040. procedure TTestModule.TestFunctionResult;
  3041. begin
  3042. StartProgram(false);
  3043. Add('function Func1: longint;');
  3044. Add('begin');
  3045. Add(' Result:=3;');
  3046. Add(' Func1:=4;');
  3047. Add('end;');
  3048. Add('begin');
  3049. ConvertProgram;
  3050. CheckSource('TestFunctionResult',
  3051. LinesToStr([ // statements
  3052. 'this.Func1 = function () {',
  3053. ' var Result = 0;',
  3054. ' Result = 3;',
  3055. ' Result = 4;',
  3056. ' return Result;',
  3057. '};'
  3058. ]),
  3059. '');
  3060. end;
  3061. procedure TTestModule.TestNestedProc;
  3062. begin
  3063. StartProgram(false);
  3064. Add([
  3065. 'var vInUnit: longint;',
  3066. 'function DoIt(pA,pD: longint): longint;',
  3067. 'var',
  3068. ' vB: longint;',
  3069. ' vC: longint;',
  3070. ' function Nesty(pA: longint): longint; ',
  3071. ' var vB: longint;',
  3072. ' begin',
  3073. ' Result:=pa+vb+vc+pd+vInUnit;',
  3074. ' nesty:=3;',
  3075. ' doit:=4;',
  3076. ' exit;',
  3077. ' end;',
  3078. 'begin',
  3079. ' Result:=pa+vb+vc;',
  3080. ' doit:=6;',
  3081. ' exit;',
  3082. 'end;',
  3083. 'begin']);
  3084. ConvertProgram;
  3085. CheckSource('TestNestedProc',
  3086. LinesToStr([ // statements
  3087. 'this.vInUnit = 0;',
  3088. 'this.DoIt = function (pA, pD) {',
  3089. ' var Result = 0;',
  3090. ' var vB = 0;',
  3091. ' var vC = 0;',
  3092. ' function Nesty(pA) {',
  3093. ' var Result$1 = 0;',
  3094. ' var vB = 0;',
  3095. ' Result$1 = pA + vB + vC + pD + $mod.vInUnit;',
  3096. ' Result$1 = 3;',
  3097. ' Result = 4;',
  3098. ' return Result$1;',
  3099. ' return Result$1;',
  3100. ' };',
  3101. ' Result = pA + vB + vC;',
  3102. ' Result = 6;',
  3103. ' return Result;',
  3104. ' return Result;',
  3105. '};'
  3106. ]),
  3107. '');
  3108. end;
  3109. procedure TTestModule.TestNestedProc_ResultString;
  3110. begin
  3111. StartProgram(false);
  3112. Add([
  3113. 'function DoIt: string;',
  3114. ' function Nesty: string; ',
  3115. ' begin',
  3116. ' nesty:=#65#66;',
  3117. ' nesty[1]:=#67;',
  3118. ' doit:=#68;',
  3119. ' doit[2]:=#69;',
  3120. ' end;',
  3121. 'begin',
  3122. ' doit:=#70;',
  3123. ' doit[3]:=#71;',
  3124. 'end;',
  3125. 'begin']);
  3126. ConvertProgram;
  3127. CheckSource('TestNestedProc_ResultString',
  3128. LinesToStr([ // statements
  3129. 'this.DoIt = function () {',
  3130. ' var Result = "";',
  3131. ' function Nesty() {',
  3132. ' var Result$1 = "";',
  3133. ' Result$1 = "AB";',
  3134. ' Result$1 = rtl.setCharAt(Result$1, 0, "C");',
  3135. ' Result = "D";',
  3136. ' Result = rtl.setCharAt(Result, 1, "E");',
  3137. ' return Result$1;',
  3138. ' };',
  3139. ' Result = "F";',
  3140. ' Result = rtl.setCharAt(Result, 2, "G");',
  3141. ' return Result;',
  3142. '};'
  3143. ]),
  3144. '');
  3145. end;
  3146. procedure TTestModule.TestForwardProc;
  3147. begin
  3148. StartProgram(false);
  3149. Add('procedure FuncA(Bar: longint); forward;');
  3150. Add('procedure FuncB(Bar: longint);');
  3151. Add('begin');
  3152. Add(' funca(bar);');
  3153. Add('end;');
  3154. Add('procedure funca(bar: longint);');
  3155. Add('begin');
  3156. Add(' if bar=3 then ;');
  3157. Add('end;');
  3158. Add('begin');
  3159. Add(' funca(4);');
  3160. Add(' funcb(5);');
  3161. ConvertProgram;
  3162. CheckSource('TestForwardProc',
  3163. LinesToStr([ // statements'
  3164. 'this.FuncB = function (Bar) {',
  3165. ' $mod.FuncA(Bar);',
  3166. '};',
  3167. 'this.FuncA = function (Bar) {',
  3168. ' if (Bar === 3);',
  3169. '};'
  3170. ]),
  3171. LinesToStr([
  3172. '$mod.FuncA(4);',
  3173. '$mod.FuncB(5);'
  3174. ])
  3175. );
  3176. end;
  3177. procedure TTestModule.TestNestedForwardProc;
  3178. begin
  3179. StartProgram(false);
  3180. Add('procedure FuncA;');
  3181. Add(' procedure FuncB(i: longint); forward;');
  3182. Add(' procedure FuncC(i: longint);');
  3183. Add(' begin');
  3184. Add(' funcb(i);');
  3185. Add(' end;');
  3186. Add(' procedure FuncB(i: longint);');
  3187. Add(' begin');
  3188. Add(' if i=3 then ;');
  3189. Add(' end;');
  3190. Add('begin');
  3191. Add(' funcc(4)');
  3192. Add('end;');
  3193. Add('begin');
  3194. Add(' funca;');
  3195. ConvertProgram;
  3196. CheckSource('TestNestedForwardProc',
  3197. LinesToStr([ // statements'
  3198. 'this.FuncA = function () {',
  3199. ' function FuncC(i) {',
  3200. ' FuncB(i);',
  3201. ' };',
  3202. ' function FuncB(i) {',
  3203. ' if (i === 3);',
  3204. ' };',
  3205. ' FuncC(4);',
  3206. '};'
  3207. ]),
  3208. LinesToStr([
  3209. '$mod.FuncA();'
  3210. ])
  3211. );
  3212. end;
  3213. procedure TTestModule.TestAssignFunctionResult;
  3214. begin
  3215. StartProgram(false);
  3216. Add('function Func1: longint;');
  3217. Add('begin');
  3218. Add('end;');
  3219. Add('var i: longint;');
  3220. Add('begin');
  3221. Add(' i:=func1();');
  3222. Add(' i:=func1()+func1();');
  3223. ConvertProgram;
  3224. CheckSource('TestAssignFunctionResult',
  3225. LinesToStr([ // statements
  3226. 'this.Func1 = function () {',
  3227. ' var Result = 0;',
  3228. ' return Result;',
  3229. '};',
  3230. 'this.i = 0;'
  3231. ]),
  3232. LinesToStr([
  3233. '$mod.i = $mod.Func1();',
  3234. '$mod.i = $mod.Func1() + $mod.Func1();'
  3235. ]));
  3236. end;
  3237. procedure TTestModule.TestFunctionResultInCondition;
  3238. begin
  3239. StartProgram(false);
  3240. Add('function Func1: longint;');
  3241. Add('begin');
  3242. Add('end;');
  3243. Add('function Func2: boolean;');
  3244. Add('begin');
  3245. Add('end;');
  3246. Add('var i: longint;');
  3247. Add('begin');
  3248. Add(' if func2 then ;');
  3249. Add(' if i=func1() then ;');
  3250. Add(' if i=func1 then ;');
  3251. ConvertProgram;
  3252. CheckSource('TestFunctionResultInCondition',
  3253. LinesToStr([ // statements
  3254. 'this.Func1 = function () {',
  3255. ' var Result = 0;',
  3256. ' return Result;',
  3257. '};',
  3258. 'this.Func2 = function () {',
  3259. ' var Result = false;',
  3260. ' return Result;',
  3261. '};',
  3262. 'this.i = 0;'
  3263. ]),
  3264. LinesToStr([
  3265. 'if ($mod.Func2());',
  3266. 'if ($mod.i === $mod.Func1());',
  3267. 'if ($mod.i === $mod.Func1());'
  3268. ]));
  3269. end;
  3270. procedure TTestModule.TestFunctionResultInForLoop;
  3271. begin
  3272. StartProgram(false);
  3273. Add([
  3274. 'function Func1(a: array of longint): longint;',
  3275. 'begin',
  3276. ' for Result:=High(a) downto Low(a) do if a[Result]=0 then exit;',
  3277. ' for Result in a do if a[Result]=0 then exit;',
  3278. 'end;',
  3279. 'begin',
  3280. ' Func1([1,2,3])']);
  3281. ConvertProgram;
  3282. CheckSource('TestFunctionResultInForLoop',
  3283. LinesToStr([ // statements
  3284. 'this.Func1 = function (a) {',
  3285. ' var Result = 0;',
  3286. ' for (var $l1 = rtl.length(a) - 1; $l1 >= 0; $l1--) {',
  3287. ' Result = $l1;',
  3288. ' if (a[Result] === 0) return Result;',
  3289. ' };',
  3290. ' for (var $in2 = a, $l3 = 0, $end4 = rtl.length($in2) - 1; $l3 <= $end4; $l3++) {',
  3291. ' Result = $in2[$l3];',
  3292. ' if (a[Result] === 0) return Result;',
  3293. ' };',
  3294. ' return Result;',
  3295. '};',
  3296. '']),
  3297. LinesToStr([
  3298. '$mod.Func1([1, 2, 3]);'
  3299. ]));
  3300. end;
  3301. procedure TTestModule.TestFunctionResultInTypeCast;
  3302. begin
  3303. StartProgram(false);
  3304. Add([
  3305. 'function GetInt: longint;',
  3306. 'begin',
  3307. 'end;',
  3308. 'begin',
  3309. ' if Byte(GetInt)=0 then ;',
  3310. '']);
  3311. ConvertProgram;
  3312. CheckSource('TestFunctionResultInTypeCast',
  3313. LinesToStr([ // statements
  3314. 'this.GetInt = function () {',
  3315. ' var Result = 0;',
  3316. ' return Result;',
  3317. '};',
  3318. '']),
  3319. LinesToStr([
  3320. 'if (($mod.GetInt() & 255) === 0) ;'
  3321. ]));
  3322. end;
  3323. procedure TTestModule.TestExit;
  3324. begin
  3325. StartProgram(false);
  3326. Add('procedure ProcA;');
  3327. Add('begin');
  3328. Add(' exit;');
  3329. Add('end;');
  3330. Add('function FuncB: longint;');
  3331. Add('begin');
  3332. Add(' exit;');
  3333. Add(' exit(3);');
  3334. Add('end;');
  3335. Add('function FuncC: string;');
  3336. Add('begin');
  3337. Add(' exit;');
  3338. Add(' exit(''a'');');
  3339. Add(' exit(''abc'');');
  3340. Add('end;');
  3341. Add('begin');
  3342. Add(' exit;');
  3343. Add(' exit(1);');
  3344. ConvertProgram;
  3345. CheckSource('TestExit',
  3346. LinesToStr([ // statements
  3347. 'this.ProcA = function () {',
  3348. ' return;',
  3349. '};',
  3350. 'this.FuncB = function () {',
  3351. ' var Result = 0;',
  3352. ' return Result;',
  3353. ' return 3;',
  3354. ' return Result;',
  3355. '};',
  3356. 'this.FuncC = function () {',
  3357. ' var Result = "";',
  3358. ' return Result;',
  3359. ' return "a";',
  3360. ' return "abc";',
  3361. ' return Result;',
  3362. '};'
  3363. ]),
  3364. LinesToStr([
  3365. 'return;',
  3366. 'return 1;',
  3367. '']));
  3368. end;
  3369. procedure TTestModule.TestBreak;
  3370. begin
  3371. StartProgram(false);
  3372. Add([
  3373. 'var',
  3374. ' i: longint;',
  3375. 'begin',
  3376. ' repeat',
  3377. ' break;',
  3378. ' until true;',
  3379. ' while true do',
  3380. ' break;',
  3381. ' for i:=1 to 2 do',
  3382. ' break;']);
  3383. ConvertProgram;
  3384. CheckSource('TestBreak',
  3385. LinesToStr([ // statements
  3386. 'this.i = 0;'
  3387. ]),
  3388. LinesToStr([
  3389. 'do {',
  3390. ' break;',
  3391. '} while (!true);',
  3392. 'while (true) break;',
  3393. 'for ($mod.i = 1; $mod.i <= 2; $mod.i++) break;',
  3394. '']));
  3395. end;
  3396. procedure TTestModule.TestBreakAsVar;
  3397. begin
  3398. StartProgram(false);
  3399. Add([
  3400. 'procedure DoIt(break: boolean);',
  3401. 'begin',
  3402. ' if break then ;',
  3403. 'end;',
  3404. 'var',
  3405. ' break: boolean;',
  3406. 'begin',
  3407. ' if break then ;']);
  3408. ConvertProgram;
  3409. CheckSource('TestBreakAsVar',
  3410. LinesToStr([ // statements
  3411. 'this.DoIt = function (Break) {',
  3412. ' if (Break) ;',
  3413. '};',
  3414. 'this.Break = false;',
  3415. '']),
  3416. LinesToStr([
  3417. 'if($mod.Break) ;',
  3418. '']));
  3419. end;
  3420. procedure TTestModule.TestContinue;
  3421. begin
  3422. StartProgram(false);
  3423. Add('var i: longint;');
  3424. Add('begin');
  3425. Add(' repeat');
  3426. Add(' continue;');
  3427. Add(' until true;');
  3428. Add(' while true do');
  3429. Add(' continue;');
  3430. Add(' for i:=1 to 2 do');
  3431. Add(' continue;');
  3432. ConvertProgram;
  3433. CheckSource('TestContinue',
  3434. LinesToStr([ // statements
  3435. 'this.i = 0;'
  3436. ]),
  3437. LinesToStr([
  3438. 'do {',
  3439. ' continue;',
  3440. '} while (!true);',
  3441. 'while (true) continue;',
  3442. 'for ($mod.i = 1; $mod.i <= 2; $mod.i++) continue;',
  3443. '']));
  3444. end;
  3445. procedure TTestModule.TestProc_External;
  3446. begin
  3447. StartProgram(false);
  3448. Add('procedure Foo; external name ''console.log'';');
  3449. Add('function Bar: longint; external name ''get.item'';');
  3450. Add('function Bla(s: string): longint; external name ''apply.something'';');
  3451. Add('var');
  3452. Add(' i: longint;');
  3453. Add('begin');
  3454. Add(' Foo;');
  3455. Add(' i:=Bar;');
  3456. Add(' i:=Bla(''abc'');');
  3457. ConvertProgram;
  3458. CheckSource('TestProc_External',
  3459. LinesToStr([ // statements
  3460. 'this.i = 0;'
  3461. ]),
  3462. LinesToStr([
  3463. 'console.log();',
  3464. '$mod.i = get.item();',
  3465. '$mod.i = apply.something("abc");'
  3466. ]));
  3467. end;
  3468. procedure TTestModule.TestProc_ExternalOtherUnit;
  3469. begin
  3470. AddModuleWithIntfImplSrc('unit2.pas',
  3471. LinesToStr([
  3472. 'procedure Now; external name ''Date.now'';',
  3473. 'procedure DoIt;'
  3474. ]),
  3475. 'procedure doit; begin end;');
  3476. StartUnit(true);
  3477. Add('interface');
  3478. Add('uses unit2;');
  3479. Add('implementation');
  3480. Add('begin');
  3481. Add(' now;');
  3482. Add(' now();');
  3483. Add(' uNit2.now;');
  3484. Add(' uNit2.now();');
  3485. Add(' doit;');
  3486. Add(' uNit2.doit;');
  3487. ConvertUnit;
  3488. CheckSource('TestProc_ExternalOtherUnit',
  3489. LinesToStr([
  3490. '']),
  3491. LinesToStr([
  3492. 'Date.now();',
  3493. 'Date.now();',
  3494. 'Date.now();',
  3495. 'Date.now();',
  3496. 'pas.unit2.DoIt();',
  3497. 'pas.unit2.DoIt();',
  3498. '']));
  3499. end;
  3500. procedure TTestModule.TestProc_Asm;
  3501. begin
  3502. StartProgram(false);
  3503. Add([
  3504. '{$mode delphi}',
  3505. 'function DoIt: longint;',
  3506. 'begin;',
  3507. ' asm',
  3508. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3509. ' end;',
  3510. ' asm console.log(); end;',
  3511. ' asm',
  3512. ' s = "'' ";',
  3513. ' s = ''" '';',
  3514. ' s = s + "world" + "''";',
  3515. ' // end',
  3516. ' s = ''end'';',
  3517. ' s = "end";',
  3518. ' s = "foo\"bar";',
  3519. ' s = ''a\''b'';',
  3520. ' s = `${expr}\`-"-''-`;',
  3521. ' s = `multi',
  3522. 'line`;',
  3523. ' end;',
  3524. 'end;',
  3525. 'procedure Fly;',
  3526. 'asm',
  3527. ' return;',
  3528. 'end;',
  3529. 'begin']);
  3530. ConvertProgram;
  3531. CheckSource('TestProc_Asm',
  3532. LinesToStr([ // statements
  3533. 'this.DoIt = function () {',
  3534. ' var Result = 0;',
  3535. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3536. ' console.log();',
  3537. ' s = "'' ";',
  3538. ' s = ''" '';',
  3539. ' s = s + "world" + "''";',
  3540. ' // end',
  3541. ' s = ''end'';',
  3542. ' s = "end";',
  3543. ' s = "foo\"bar";',
  3544. ' s = ''a\''b'';',
  3545. ' s = `${expr}\`-"-''-`;',
  3546. ' s = `multi',
  3547. 'line`;',
  3548. ' return Result;',
  3549. '};',
  3550. 'this.Fly = function () {',
  3551. ' return;',
  3552. '};',
  3553. '']),
  3554. LinesToStr([
  3555. ''
  3556. ]));
  3557. end;
  3558. procedure TTestModule.TestProc_Assembler;
  3559. begin
  3560. StartProgram(false);
  3561. Add('function DoIt: longint; assembler;');
  3562. Add('asm');
  3563. Add('{ a:{ b:{}, c:[]}, d:''1'' };');
  3564. Add('end;');
  3565. Add('begin');
  3566. ConvertProgram;
  3567. CheckSource('TestProc_Assembler',
  3568. LinesToStr([ // statements
  3569. 'this.DoIt = function () {',
  3570. ' { a:{ b:{}, c:[]}, d:''1'' };',
  3571. '};'
  3572. ]),
  3573. LinesToStr([
  3574. ''
  3575. ]));
  3576. end;
  3577. procedure TTestModule.TestProc_VarParam;
  3578. begin
  3579. StartProgram(false);
  3580. Add('type integer = longint;');
  3581. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  3582. Add('var vJ: integer;');
  3583. Add('begin');
  3584. Add(' vg:=vg+1;');
  3585. Add(' vj:=vh+2;');
  3586. Add(' vi:=vi+3;');
  3587. Add(' doit(vg,vg,vg);');
  3588. Add(' doit(vh,vh,vj);');
  3589. Add(' doit(vi,vi,vi);');
  3590. Add(' doit(vj,vj,vj);');
  3591. Add('end;');
  3592. Add('var i: integer;');
  3593. Add('begin');
  3594. Add(' doit(i,i,i);');
  3595. ConvertProgram;
  3596. CheckSource('TestProc_VarParam',
  3597. LinesToStr([ // statements
  3598. 'this.DoIt = function (vG,vH,vI) {',
  3599. ' var vJ = 0;',
  3600. ' vG = vG + 1;',
  3601. ' vJ = vH + 2;',
  3602. ' vI.set(vI.get()+3);',
  3603. ' $mod.DoIt(vG, vG, {',
  3604. ' get: function () {',
  3605. ' return vG;',
  3606. ' },',
  3607. ' set: function (v) {',
  3608. ' vG = v;',
  3609. ' }',
  3610. ' });',
  3611. ' $mod.DoIt(vH, vH, {',
  3612. ' get: function () {',
  3613. ' return vJ;',
  3614. ' },',
  3615. ' set: function (v) {',
  3616. ' vJ = v;',
  3617. ' }',
  3618. ' });',
  3619. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  3620. ' $mod.DoIt(vJ, vJ, {',
  3621. ' get: function () {',
  3622. ' return vJ;',
  3623. ' },',
  3624. ' set: function (v) {',
  3625. ' vJ = v;',
  3626. ' }',
  3627. ' });',
  3628. '};',
  3629. 'this.i = 0;'
  3630. ]),
  3631. LinesToStr([
  3632. '$mod.DoIt($mod.i,$mod.i,{',
  3633. ' p: $mod,',
  3634. ' get: function () {',
  3635. ' return this.p.i;',
  3636. ' },',
  3637. ' set: function (v) {',
  3638. ' this.p.i = v;',
  3639. ' }',
  3640. '});'
  3641. ]));
  3642. end;
  3643. procedure TTestModule.TestProc_VarParamString;
  3644. begin
  3645. StartProgram(false);
  3646. Add(['type TCaption = string;',
  3647. 'procedure DoIt(vA: TCaption; var vB: TCaption; out vC: TCaption);',
  3648. 'var c: char;',
  3649. 'begin',
  3650. ' va[1]:=c;',
  3651. ' vb[2]:=c;',
  3652. ' vc[3]:=c;',
  3653. 'end;',
  3654. 'begin']);
  3655. ConvertProgram;
  3656. CheckSource('TestProc_VarParamString',
  3657. LinesToStr([ // statements
  3658. 'this.DoIt = function (vA,vB,vC) {',
  3659. ' var c = "";',
  3660. ' vA = rtl.setCharAt(vA, 0, c);',
  3661. ' vB.set(rtl.setCharAt(vB.get(), 1, c));',
  3662. ' vC.set(rtl.setCharAt(vC.get(), 2, c));',
  3663. '};',
  3664. '']),
  3665. LinesToStr([
  3666. ]));
  3667. end;
  3668. procedure TTestModule.TestProc_VarParamV;
  3669. begin
  3670. StartProgram(false);
  3671. Add([
  3672. 'procedure Inc2(var i: longint);',
  3673. 'begin',
  3674. ' i:=i+2;',
  3675. 'end;',
  3676. 'procedure DoIt(v: longint);',
  3677. 'var p: array of longint;',
  3678. 'begin',
  3679. ' Inc2(v);',
  3680. ' Inc2(p[v]);',
  3681. 'end;',
  3682. 'begin']);
  3683. ConvertProgram;
  3684. CheckSource('TestProc_VarParamV',
  3685. LinesToStr([ // statements
  3686. 'this.Inc2 = function (i) {',
  3687. ' i.set(i.get()+2);',
  3688. '};',
  3689. 'this.DoIt = function (v) {',
  3690. ' var p = [];',
  3691. ' $mod.Inc2({get: function () {',
  3692. ' return v;',
  3693. ' }, set: function (w) {',
  3694. ' v = w;',
  3695. ' }});',
  3696. ' $mod.Inc2({',
  3697. ' a: v,',
  3698. ' p: p,',
  3699. ' get: function () {',
  3700. ' return this.p[this.a];',
  3701. ' },',
  3702. ' set: function (v) {',
  3703. ' this.p[this.a] = v;',
  3704. ' }',
  3705. ' });',
  3706. '};',
  3707. '']),
  3708. LinesToStr([
  3709. '']));
  3710. end;
  3711. procedure TTestModule.TestProc_Overload;
  3712. begin
  3713. StartProgram(false);
  3714. Add('procedure DoIt(vI: longint); begin end;');
  3715. Add('procedure DoIt(vI, vJ: longint); begin end;');
  3716. Add('procedure DoIt(vD: double); begin end;');
  3717. Add('begin');
  3718. Add(' DoIt(1);');
  3719. Add(' DoIt(2,3);');
  3720. Add(' DoIt(4.5);');
  3721. ConvertProgram;
  3722. CheckSource('TestProcedureOverload',
  3723. LinesToStr([ // statements
  3724. 'this.DoIt = function (vI) {',
  3725. '};',
  3726. 'this.DoIt$1 = function (vI, vJ) {',
  3727. '};',
  3728. 'this.DoIt$2 = function (vD) {',
  3729. '};',
  3730. '']),
  3731. LinesToStr([
  3732. '$mod.DoIt(1);',
  3733. '$mod.DoIt$1(2, 3);',
  3734. '$mod.DoIt$2(4.5);',
  3735. '']));
  3736. end;
  3737. procedure TTestModule.TestProc_OverloadForward;
  3738. begin
  3739. StartProgram(false);
  3740. Add('procedure DoIt(vI: longint); forward;');
  3741. Add('procedure DoIt(vI, vJ: longint); begin end;');
  3742. Add('procedure doit(vi: longint); begin end;');
  3743. Add('begin');
  3744. Add(' doit(1);');
  3745. Add(' doit(2,3);');
  3746. ConvertProgram;
  3747. CheckSource('TestProcedureOverloadForward',
  3748. LinesToStr([ // statements
  3749. 'this.DoIt$1 = function (vI, vJ) {',
  3750. '};',
  3751. 'this.DoIt = function (vI) {',
  3752. '};',
  3753. '']),
  3754. LinesToStr([
  3755. '$mod.DoIt(1);',
  3756. '$mod.DoIt$1(2, 3);',
  3757. '']));
  3758. end;
  3759. procedure TTestModule.TestProc_OverloadIntfImpl;
  3760. begin
  3761. StartUnit(false);
  3762. Add('interface');
  3763. Add('procedure DoIt(vI: longint);');
  3764. Add('procedure DoIt(vI, vJ: longint);');
  3765. Add('implementation');
  3766. Add('procedure DoIt(vI, vJ, vK, vL, vM: longint); forward;');
  3767. Add('procedure DoIt(vI, vJ, vK: longint); begin end;');
  3768. Add('procedure DoIt(vi: longint); begin end;');
  3769. Add('procedure DoIt(vI, vJ, vK, vL: longint); begin end;');
  3770. Add('procedure DoIt(vi, vj: longint); begin end;');
  3771. Add('procedure DoIt(vi, vj, vk, vl, vm: longint); begin end;');
  3772. Add('begin');
  3773. Add(' doit(1);');
  3774. Add(' doit(2,3);');
  3775. Add(' doit(4,5,6);');
  3776. Add(' doit(7,8,9,10);');
  3777. Add(' doit(11,12,13,14,15);');
  3778. ConvertUnit;
  3779. CheckSource('TestProcedureOverloadUnit',
  3780. LinesToStr([ // statements
  3781. 'var $impl = $mod.$impl;',
  3782. 'this.DoIt = function (vI) {',
  3783. '};',
  3784. 'this.DoIt$1 = function (vI, vJ) {',
  3785. '};',
  3786. '']),
  3787. LinesToStr([ // this.$init
  3788. '$mod.DoIt(1);',
  3789. '$mod.DoIt$1(2, 3);',
  3790. '$impl.DoIt$3(4,5,6);',
  3791. '$impl.DoIt$4(7,8,9,10);',
  3792. '$impl.DoIt$2(11,12,13,14,15);',
  3793. '']),
  3794. LinesToStr([ // implementation
  3795. '$impl.DoIt$3 = function (vI, vJ, vK) {',
  3796. '};',
  3797. '$impl.DoIt$4 = function (vI, vJ, vK, vL) {',
  3798. '};',
  3799. '$impl.DoIt$2 = function (vI, vJ, vK, vL, vM) {',
  3800. '};',
  3801. '']));
  3802. end;
  3803. procedure TTestModule.TestProc_OverloadNested;
  3804. begin
  3805. StartProgram(false);
  3806. Add([
  3807. 'procedure DoIt(vA: longint); overload; forward;',
  3808. 'procedure DoIt(vB, vC: longint); overload;',
  3809. 'begin // 2 param overload',
  3810. ' doit(1);',
  3811. ' doit(1,2);',
  3812. 'end;',
  3813. 'procedure doit(vA: longint);',
  3814. ' procedure DoIt(vA, vB, vC: longint); overload; forward;',
  3815. ' procedure DoIt(vA, vB, vC, vD: longint); overload;',
  3816. ' begin // 4 param overload',
  3817. ' doit(1);',
  3818. ' doit(1,2);',
  3819. ' doit(1,2,3);',
  3820. ' doit(1,2,3,4);',
  3821. ' end;',
  3822. ' procedure doit(vA, vB, vC: longint);',
  3823. ' procedure DoIt(vA, vB, vC, vD, vE: longint); overload; forward;',
  3824. ' procedure DoIt(vA, vB, vC, vD, vE, vF: longint); overload;',
  3825. ' begin // 6 param overload',
  3826. ' doit(1);',
  3827. ' doit(1,2);',
  3828. ' doit(1,2,3);',
  3829. ' doit(1,2,3,4);',
  3830. ' doit(1,2,3,4,5);',
  3831. ' doit(1,2,3,4,5,6);',
  3832. ' end;',
  3833. ' procedure doit(vA, vB, vC, vD, vE: longint);',
  3834. ' begin // 5 param overload',
  3835. ' doit(1);',
  3836. ' doit(1,2);',
  3837. ' doit(1,2,3);',
  3838. ' doit(1,2,3,4);',
  3839. ' doit(1,2,3,4,5);',
  3840. ' doit(1,2,3,4,5,6);',
  3841. ' end;',
  3842. ' begin // 3 param overload',
  3843. ' doit(1);',
  3844. ' doit(1,2);',
  3845. ' doit(1,2,3);',
  3846. ' doit(1,2,3,4);',
  3847. ' doit(1,2,3,4,5);',
  3848. ' doit(1,2,3,4,5,6);',
  3849. ' end;',
  3850. 'begin // 1 param overload',
  3851. ' doit(1);',
  3852. ' doit(1,2);',
  3853. ' doit(1,2,3);',
  3854. ' doit(1,2,3,4);',
  3855. 'end;',
  3856. 'begin // main',
  3857. ' doit(1);',
  3858. ' doit(1,2);']);
  3859. ConvertProgram;
  3860. CheckSource('TestProcedureOverloadNested',
  3861. LinesToStr([ // statements
  3862. 'this.DoIt$1 = function (vB, vC) {',
  3863. ' $mod.DoIt(1);',
  3864. ' $mod.DoIt$1(1, 2);',
  3865. '};',
  3866. 'this.DoIt = function (vA) {',
  3867. ' function DoIt$3(vA, vB, vC, vD) {',
  3868. ' $mod.DoIt(1);',
  3869. ' $mod.DoIt$1(1, 2);',
  3870. ' DoIt$2(1, 2, 3);',
  3871. ' DoIt$3(1, 2, 3, 4);',
  3872. ' };',
  3873. ' function DoIt$2(vA, vB, vC) {',
  3874. ' function DoIt$5(vA, vB, vC, vD, vE, vF) {',
  3875. ' $mod.DoIt(1);',
  3876. ' $mod.DoIt$1(1, 2);',
  3877. ' DoIt$2(1, 2, 3);',
  3878. ' DoIt$3(1, 2, 3, 4);',
  3879. ' DoIt$4(1, 2, 3, 4, 5);',
  3880. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  3881. ' };',
  3882. ' function DoIt$4(vA, vB, vC, vD, vE) {',
  3883. ' $mod.DoIt(1);',
  3884. ' $mod.DoIt$1(1, 2);',
  3885. ' DoIt$2(1, 2, 3);',
  3886. ' DoIt$3(1, 2, 3, 4);',
  3887. ' DoIt$4(1, 2, 3, 4, 5);',
  3888. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  3889. ' };',
  3890. ' $mod.DoIt(1);',
  3891. ' $mod.DoIt$1(1, 2);',
  3892. ' DoIt$2(1, 2, 3);',
  3893. ' DoIt$3(1, 2, 3, 4);',
  3894. ' DoIt$4(1, 2, 3, 4, 5);',
  3895. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  3896. ' };',
  3897. ' $mod.DoIt(1);',
  3898. ' $mod.DoIt$1(1, 2);',
  3899. ' DoIt$2(1, 2, 3);',
  3900. ' DoIt$3(1, 2, 3, 4);',
  3901. '};',
  3902. '']),
  3903. LinesToStr([
  3904. '$mod.DoIt(1);',
  3905. '$mod.DoIt$1(1, 2);',
  3906. '']));
  3907. end;
  3908. procedure TTestModule.TestProc_OverloadUnitCycle;
  3909. begin
  3910. AddModuleWithIntfImplSrc('Unit2.pas',
  3911. LinesToStr([
  3912. 'type',
  3913. ' TObject = class',
  3914. ' procedure DoIt(b: boolean); virtual; abstract;',
  3915. ' procedure DoIt(i: longint); virtual; abstract;',
  3916. ' end;',
  3917. '']),
  3918. 'uses test1;');
  3919. StartUnit(true);
  3920. Add([
  3921. 'interface',
  3922. 'uses unit2;',
  3923. 'type',
  3924. ' TEagle = class(TObject)',
  3925. ' procedure DoIt(b: boolean); override;',
  3926. ' procedure DoIt(i: longint); override;',
  3927. ' end;',
  3928. 'implementation',
  3929. 'procedure TEagle.DoIt(b: boolean); begin end;',
  3930. 'procedure TEagle.DoIt(i: longint); begin end;',
  3931. '']);
  3932. ConvertUnit;
  3933. CheckSource('TestProc_OverloadUnitCycle',
  3934. LinesToStr([ // statements
  3935. 'rtl.createClass($mod, "TEagle", pas.Unit2.TObject, function () {',
  3936. ' this.DoIt = function (b) {',
  3937. ' };',
  3938. ' this.DoIt$1 = function (i) {',
  3939. ' };',
  3940. '});',
  3941. '']),
  3942. '',
  3943. LinesToStr([
  3944. '']));
  3945. end;
  3946. procedure TTestModule.TestProc_Varargs;
  3947. begin
  3948. StartProgram(false);
  3949. Add([
  3950. 'procedure ProcA(i:longint); varargs; external name ''ProcA'';',
  3951. 'procedure ProcB; varargs; external name ''ProcB'';',
  3952. 'procedure ProcC(i: longint = 17); varargs; external name ''ProcC'';',
  3953. 'function GetIt: longint; begin end;',
  3954. 'begin',
  3955. ' ProcA(1);',
  3956. ' ProcA(1,2);',
  3957. ' ProcA(1,2.0);',
  3958. ' ProcA(1,2,3);',
  3959. ' ProcA(1,''2'');',
  3960. ' ProcA(2,'''');',
  3961. ' ProcA(3,false);',
  3962. ' ProcB;',
  3963. ' ProcB();',
  3964. ' ProcB(4);',
  3965. ' ProcB(''foo'');',
  3966. ' ProcC;',
  3967. ' ProcC();',
  3968. ' ProcC(4);',
  3969. ' ProcC(5,''foo'');',
  3970. ' ProcB(GetIt);',
  3971. ' ProcB(GetIt());',
  3972. ' ProcB(GetIt,GetIt());']);
  3973. ConvertProgram;
  3974. CheckSource('TestProc_Varargs',
  3975. LinesToStr([ // statements
  3976. 'this.GetIt = function () {',
  3977. ' var Result = 0;',
  3978. ' return Result;',
  3979. '};',
  3980. '']),
  3981. LinesToStr([
  3982. 'ProcA(1);',
  3983. 'ProcA(1, 2);',
  3984. 'ProcA(1, 2.0);',
  3985. 'ProcA(1, 2, 3);',
  3986. 'ProcA(1, "2");',
  3987. 'ProcA(2, "");',
  3988. 'ProcA(3, false);',
  3989. 'ProcB();',
  3990. 'ProcB();',
  3991. 'ProcB(4);',
  3992. 'ProcB("foo");',
  3993. 'ProcC(17);',
  3994. 'ProcC(17);',
  3995. 'ProcC(4);',
  3996. 'ProcC(5, "foo");',
  3997. 'ProcB($mod.GetIt());',
  3998. 'ProcB($mod.GetIt());',
  3999. 'ProcB($mod.GetIt(), $mod.GetIt());',
  4000. '']));
  4001. end;
  4002. procedure TTestModule.TestProc_ConstOrder;
  4003. begin
  4004. StartProgram(false);
  4005. Add([
  4006. 'const A = 3;',
  4007. 'const B = A+1;',
  4008. 'procedure DoIt;',
  4009. 'const C = A+1;',
  4010. 'const D = B+1;',
  4011. 'const E = D+C+B+A;',
  4012. 'begin',
  4013. 'end;',
  4014. 'begin'
  4015. ]);
  4016. ConvertProgram;
  4017. CheckSource('TestProc_ConstOrder',
  4018. LinesToStr([ // statements
  4019. 'this.A = 3;',
  4020. 'this.B = 3 + 1;',
  4021. 'var C = 3 + 1;',
  4022. 'var D = 4 + 1;',
  4023. 'var E = 5 + 4 + 4 + 3;',
  4024. 'this.DoIt = function () {',
  4025. '};',
  4026. '']),
  4027. LinesToStr([
  4028. ''
  4029. ]));
  4030. end;
  4031. procedure TTestModule.TestProc_DuplicateConst;
  4032. begin
  4033. StartProgram(false);
  4034. Add([
  4035. 'const A = 1;',
  4036. 'procedure DoIt;',
  4037. 'const A = 2;',
  4038. ' procedure SubIt;',
  4039. ' const A = 21;',
  4040. ' begin',
  4041. ' end;',
  4042. 'begin',
  4043. 'end;',
  4044. 'procedure DoSome;',
  4045. 'const A = 3;',
  4046. 'begin',
  4047. 'end;',
  4048. 'begin'
  4049. ]);
  4050. ConvertProgram;
  4051. CheckSource('TestProc_DuplicateConst',
  4052. LinesToStr([ // statements
  4053. 'this.A = 1;',
  4054. 'var A$1 = 2;',
  4055. 'var A$2 = 21;',
  4056. 'this.DoIt = function () {',
  4057. ' function SubIt() {',
  4058. ' };',
  4059. '};',
  4060. 'var A$3 = 3;',
  4061. 'this.DoSome = function () {',
  4062. '};',
  4063. '']),
  4064. LinesToStr([
  4065. ''
  4066. ]));
  4067. end;
  4068. procedure TTestModule.TestProc_LocalVarAbsolute;
  4069. begin
  4070. StartProgram(false);
  4071. Add([
  4072. 'type',
  4073. ' TObject = class',
  4074. ' Index: longint;',
  4075. ' procedure DoAbs(Item: pointer);',
  4076. ' end;',
  4077. 'procedure TObject.DoAbs(Item: pointer);',
  4078. 'var',
  4079. ' o: TObject absolute Item;',
  4080. 'begin',
  4081. ' if o.Index<o.Index then o.Index:=o.Index;',
  4082. 'end;',
  4083. 'procedure DoIt(i: longint; p: pointer);',
  4084. 'var',
  4085. ' d: double absolute i;',
  4086. ' s: string absolute d;',
  4087. ' oi: TObject absolute i;',
  4088. ' op: TObject absolute p;',
  4089. 'begin',
  4090. ' if d=d then d:=d;',
  4091. ' if s=s then s:=s;',
  4092. ' if oi.Index<oi.Index then oi.Index:=oi.Index;',
  4093. ' if op.Index=op.Index then op.Index:=op.Index;',
  4094. 'end;',
  4095. 'begin']);
  4096. ConvertProgram;
  4097. CheckSource('TestProc_LocalVarAbsolute',
  4098. LinesToStr([ // statements
  4099. 'rtl.createClass($mod, "TObject", null, function () {',
  4100. ' this.$init = function () {',
  4101. ' this.Index = 0;',
  4102. ' };',
  4103. ' this.$final = function () {',
  4104. ' };',
  4105. ' this.DoAbs = function (Item) {',
  4106. ' if (Item.Index < Item.Index) Item.Index = Item.Index;',
  4107. ' };',
  4108. '});',
  4109. 'this.DoIt = function (i, p) {',
  4110. ' if (i === i) i = i;',
  4111. ' if (i === i) i = i;',
  4112. ' if (i.Index < i.Index) i.Index = i.Index;',
  4113. ' if (p.Index === p.Index) p.Index = p.Index;',
  4114. '};'
  4115. ]),
  4116. LinesToStr([
  4117. ]));
  4118. end;
  4119. procedure TTestModule.TestProc_ReservedWords;
  4120. begin
  4121. StartProgram(false);
  4122. Add([
  4123. 'procedure Date(ArrayBuffer: longint);',
  4124. 'const',
  4125. ' NaN: longint = 3;',
  4126. 'var',
  4127. ' &Boolean: longint;',
  4128. ' procedure Error(ArrayBuffer: longint);',
  4129. ' begin',
  4130. ' end;',
  4131. 'begin',
  4132. ' Nan:=&bOolean;',
  4133. 'end;',
  4134. 'begin',
  4135. ' Date(1);']);
  4136. ConvertProgram;
  4137. CheckSource('TestProc_ReservedWords',
  4138. LinesToStr([ // statements
  4139. 'var naN = 3;',
  4140. 'this.Date = function (arrayBuffer) {',
  4141. ' var boolean = 0;',
  4142. ' function error(arrayBuffer) {',
  4143. ' };',
  4144. ' naN = boolean;',
  4145. '};',
  4146. '']),
  4147. LinesToStr([
  4148. ' $mod.Date(1);'
  4149. ]));
  4150. end;
  4151. procedure TTestModule.TestAnonymousProc_Assign_ObjFPC;
  4152. begin
  4153. StartProgram(false);
  4154. Add([
  4155. '{$mode objfpc}',
  4156. 'type',
  4157. ' TFunc = reference to function(x: word): word;',
  4158. 'var Func: TFunc;',
  4159. 'procedure DoIt(a: word);',
  4160. 'begin',
  4161. ' Func:=function(b:word): word',
  4162. ' begin',
  4163. ' Result:=a+b;',
  4164. ' exit(b);',
  4165. ' exit(Result);',
  4166. ' end;',// test semicolon
  4167. ' a:=3;',
  4168. 'end;',
  4169. 'begin',
  4170. ' Func:=function(c:word):word begin',
  4171. ' Result:=3+c;',
  4172. ' exit(c);',
  4173. ' exit(Result);',
  4174. ' end;']);
  4175. ConvertProgram;
  4176. CheckSource('TestAnonymousProc_Assign_ObjFPC',
  4177. LinesToStr([ // statements
  4178. 'this.Func = null;',
  4179. 'this.DoIt = function (a) {',
  4180. ' $mod.Func = function (b) {',
  4181. ' var Result = 0;',
  4182. ' Result = a + b;',
  4183. ' return b;',
  4184. ' return Result;',
  4185. ' return Result;',
  4186. ' };',
  4187. ' a = 3;',
  4188. '};',
  4189. '']),
  4190. LinesToStr([
  4191. '$mod.Func = function (c) {',
  4192. ' var Result = 0;',
  4193. ' Result = 3 + c;',
  4194. ' return c;',
  4195. ' return Result;',
  4196. ' return Result;',
  4197. '};',
  4198. '']));
  4199. end;
  4200. procedure TTestModule.TestAnonymousProc_Assign_Delphi;
  4201. begin
  4202. StartProgram(false);
  4203. Add([
  4204. '{$mode delphi}',
  4205. 'type',
  4206. ' TProc = reference to procedure(x: word);',
  4207. 'procedure DoIt(a: word);',
  4208. 'var Proc: TProc;',
  4209. 'begin',
  4210. ' Proc:=procedure(b:word) begin end;',
  4211. 'end;',
  4212. 'var Proc: TProc;',
  4213. 'begin',
  4214. ' Proc:=procedure(c:word) begin end;',
  4215. '']);
  4216. ConvertProgram;
  4217. CheckSource('TestAnonymousProc_Assign_Delphi',
  4218. LinesToStr([ // statements
  4219. 'this.DoIt = function (a) {',
  4220. ' var Proc = null;',
  4221. ' Proc = function (b) {',
  4222. ' };',
  4223. '};',
  4224. 'this.Proc = null;',
  4225. '']),
  4226. LinesToStr([
  4227. '$mod.Proc = function (c) {',
  4228. '};',
  4229. '']));
  4230. end;
  4231. procedure TTestModule.TestAnonymousProc_Arg;
  4232. begin
  4233. StartProgram(false);
  4234. Add([
  4235. 'type',
  4236. ' TProc = reference to procedure;',
  4237. ' TFunc = reference to function(x: word): word;',
  4238. 'procedure DoMore(f,g: TProc);',
  4239. 'begin',
  4240. 'end;',
  4241. 'procedure DoOdd(v: jsvalue);',
  4242. 'begin',
  4243. 'end;',
  4244. 'procedure DoIt(f: TFunc);',
  4245. 'begin',
  4246. ' DoIt(function(b:word): word',
  4247. ' begin',
  4248. ' Result:=1+b;',
  4249. ' end);',
  4250. ' DoMore(procedure begin end, procedure begin end);',
  4251. ' DoOdd(procedure begin end);',
  4252. 'end;',
  4253. 'begin',
  4254. ' DoMore(procedure begin end,',
  4255. ' procedure assembler asm',
  4256. ' console.log("c");',
  4257. ' end);',
  4258. '']);
  4259. ConvertProgram;
  4260. CheckSource('TestAnonymousProc_Arg',
  4261. LinesToStr([ // statements
  4262. 'this.DoMore = function (f, g) {',
  4263. '};',
  4264. 'this.DoOdd = function (v) {',
  4265. '};',
  4266. 'this.DoIt = function (f) {',
  4267. ' $mod.DoIt(function (b) {',
  4268. ' var Result = 0;',
  4269. ' Result = 1 + b;',
  4270. ' return Result;',
  4271. ' });',
  4272. ' $mod.DoMore(function () {',
  4273. ' }, function () {',
  4274. ' });',
  4275. ' $mod.DoOdd(function () {',
  4276. ' });',
  4277. '};',
  4278. '']),
  4279. LinesToStr([
  4280. '$mod.DoMore(function () {',
  4281. '}, function () {',
  4282. ' console.log("c");',
  4283. '});',
  4284. '']));
  4285. end;
  4286. procedure TTestModule.TestAnonymousProc_Typecast;
  4287. begin
  4288. StartProgram(false);
  4289. Add([
  4290. 'type',
  4291. ' TProc = reference to procedure(w: word);',
  4292. ' TArr = array of word;',
  4293. ' TFuncArr = reference to function: TArr;',
  4294. 'procedure DoIt(p: TProc);',
  4295. 'var',
  4296. ' w: word;',
  4297. ' a: TArr;',
  4298. 'begin',
  4299. ' p:=TProc(procedure(b: smallint) begin end);',
  4300. ' a:=TFuncArr(function: TArr begin end)();',
  4301. ' w:=TFuncArr(function: TArr begin end)()[3];',
  4302. 'end;',
  4303. 'begin']);
  4304. ConvertProgram;
  4305. CheckSource('TestAnonymousProc_Typecast',
  4306. LinesToStr([ // statements
  4307. 'this.DoIt = function (p) {',
  4308. ' var w = 0;',
  4309. ' var a = [];',
  4310. ' p = function (b) {',
  4311. ' };',
  4312. ' a = function () {',
  4313. ' var Result = [];',
  4314. ' return Result;',
  4315. ' }();',
  4316. ' w = function () {',
  4317. ' var Result = [];',
  4318. ' return Result;',
  4319. ' }()[3];',
  4320. '};',
  4321. '']),
  4322. LinesToStr([
  4323. '']));
  4324. end;
  4325. procedure TTestModule.TestAnonymousProc_With;
  4326. begin
  4327. StartProgram(false);
  4328. Add([
  4329. 'type',
  4330. ' TProc = reference to procedure(w: word);',
  4331. ' TObject = class',
  4332. ' b: boolean;',
  4333. ' end;',
  4334. 'var',
  4335. ' p: TProc;',
  4336. ' bird: TObject;',
  4337. 'begin',
  4338. ' with bird do',
  4339. ' p:=procedure(w: word)',
  4340. ' begin',
  4341. ' b:=w>2;',
  4342. ' end;',
  4343. '']);
  4344. ConvertProgram;
  4345. CheckSource('TestAnonymousProc_With',
  4346. LinesToStr([ // statements
  4347. 'rtl.createClass($mod, "TObject", null, function () {',
  4348. ' this.$init = function () {',
  4349. ' this.b = false;',
  4350. ' };',
  4351. ' this.$final = function () {',
  4352. ' };',
  4353. '});',
  4354. 'this.p = null;',
  4355. 'this.bird = null;',
  4356. '']),
  4357. LinesToStr([
  4358. 'var $with1 = $mod.bird;',
  4359. '$mod.p = function (w) {',
  4360. ' $with1.b = w > 2;',
  4361. '};',
  4362. '']));
  4363. end;
  4364. procedure TTestModule.TestAnonymousProc_ExceptOn;
  4365. begin
  4366. StartProgram(false);
  4367. Add([
  4368. 'type',
  4369. ' TProc = reference to procedure;',
  4370. ' TObject = class',
  4371. ' b: boolean;',
  4372. ' end;',
  4373. 'procedure DoIt;',
  4374. 'var',
  4375. ' p: TProc;',
  4376. 'begin',
  4377. ' try',
  4378. ' except',
  4379. ' on E: TObject do',
  4380. ' p:=procedure',
  4381. ' begin',
  4382. ' E.b:=true;',
  4383. ' end;',
  4384. ' end;',
  4385. 'end;',
  4386. 'begin']);
  4387. ConvertProgram;
  4388. CheckSource('TestAnonymousProc_ExceptOn',
  4389. LinesToStr([ // statements
  4390. 'rtl.createClass($mod, "TObject", null, function () {',
  4391. ' this.$init = function () {',
  4392. ' this.b = false;',
  4393. ' };',
  4394. ' this.$final = function () {',
  4395. ' };',
  4396. '});',
  4397. 'this.DoIt = function () {',
  4398. ' var p = null;',
  4399. ' try {} catch ($e) {',
  4400. ' if ($mod.TObject.isPrototypeOf($e)) {',
  4401. ' var E = $e;',
  4402. ' p = function () {',
  4403. ' E.b = true;',
  4404. ' };',
  4405. ' } else throw $e',
  4406. ' };',
  4407. '};',
  4408. '']),
  4409. LinesToStr([
  4410. '']));
  4411. end;
  4412. procedure TTestModule.TestAnonymousProc_Nested;
  4413. begin
  4414. StartProgram(false);
  4415. Add([
  4416. 'type',
  4417. ' TProc = reference to procedure;',
  4418. ' TObject = class',
  4419. ' i: byte;',
  4420. ' procedure DoIt;',
  4421. ' end;',
  4422. 'procedure TObject.DoIt;',
  4423. 'var',
  4424. ' p: TProc;',
  4425. ' procedure Sub;',
  4426. ' begin',
  4427. ' p:=procedure',
  4428. ' begin',
  4429. ' i:=3;',
  4430. ' Self.i:=4;',
  4431. ' p:=procedure',
  4432. ' procedure SubSub;',
  4433. ' begin',
  4434. ' i:=13;',
  4435. ' Self.i:=14;',
  4436. ' end;',
  4437. ' begin',
  4438. ' i:=13;',
  4439. ' Self.i:=14;',
  4440. ' end;',
  4441. ' end;',
  4442. ' end;',
  4443. 'begin',
  4444. 'end;',
  4445. 'begin']);
  4446. ConvertProgram;
  4447. CheckSource('TestAnonymousProc_Nested',
  4448. LinesToStr([ // statements
  4449. 'rtl.createClass($mod, "TObject", null, function () {',
  4450. ' this.$init = function () {',
  4451. ' this.i = 0;',
  4452. ' };',
  4453. ' this.$final = function () {',
  4454. ' };',
  4455. ' this.DoIt = function () {',
  4456. ' var $Self = this;',
  4457. ' var p = null;',
  4458. ' function Sub() {',
  4459. ' p = function () {',
  4460. ' $Self.i = 3;',
  4461. ' $Self.i = 4;',
  4462. ' p = function () {',
  4463. ' function SubSub() {',
  4464. ' $Self.i = 13;',
  4465. ' $Self.i = 14;',
  4466. ' };',
  4467. ' $Self.i = 13;',
  4468. ' $Self.i = 14;',
  4469. ' };',
  4470. ' };',
  4471. ' };',
  4472. ' };',
  4473. '});',
  4474. '']),
  4475. LinesToStr([
  4476. '']));
  4477. end;
  4478. procedure TTestModule.TestAnonymousProc_NestedAssignResult;
  4479. begin
  4480. StartProgram(false);
  4481. Add([
  4482. 'type',
  4483. ' TProc = reference to procedure;',
  4484. 'function DoIt: TProc;',
  4485. ' function Sub: TProc;',
  4486. ' begin',
  4487. ' Result:=procedure',
  4488. ' begin',
  4489. ' Sub:=procedure',
  4490. ' procedure SubSub;',
  4491. ' begin',
  4492. ' Result:=nil;',
  4493. ' Sub:=nil;',
  4494. ' DoIt:=nil;',
  4495. ' end;',
  4496. ' begin',
  4497. ' Result:=nil;',
  4498. ' Sub:=nil;',
  4499. ' DoIt:=nil;',
  4500. ' end;',
  4501. ' end;',
  4502. ' end;',
  4503. 'begin',
  4504. 'end;',
  4505. 'begin']);
  4506. ConvertProgram;
  4507. CheckSource('TestAnonymousProc_NestedAssignResult',
  4508. LinesToStr([ // statements
  4509. 'this.DoIt = function () {',
  4510. ' var Result = null;',
  4511. ' function Sub() {',
  4512. ' var Result$1 = null;',
  4513. ' Result$1 = function () {',
  4514. ' Result$1 = function () {',
  4515. ' function SubSub() {',
  4516. ' Result$1 = null;',
  4517. ' Result$1 = null;',
  4518. ' Result = null;',
  4519. ' };',
  4520. ' Result$1 = null;',
  4521. ' Result$1 = null;',
  4522. ' Result = null;',
  4523. ' };',
  4524. ' };',
  4525. ' return Result$1;',
  4526. ' };',
  4527. ' return Result;',
  4528. '};',
  4529. '']),
  4530. LinesToStr([
  4531. '']));
  4532. end;
  4533. procedure TTestModule.TestAnonymousProc_Class;
  4534. begin
  4535. StartProgram(false);
  4536. Add([
  4537. 'type',
  4538. ' TProc = reference to procedure;',
  4539. ' TObject = class',
  4540. ' Size: word;',
  4541. ' function GetIt: TProc;',
  4542. ' end;',
  4543. 'function TObject.GetIt: TProc;',
  4544. 'begin',
  4545. ' Result:=procedure',
  4546. ' begin',
  4547. ' Size:=Size;',
  4548. ' end;',
  4549. 'end;',
  4550. 'begin']);
  4551. ConvertProgram;
  4552. CheckSource('TestAnonymousProc_Class',
  4553. LinesToStr([ // statements
  4554. 'rtl.createClass($mod, "TObject", null, function () {',
  4555. ' this.$init = function () {',
  4556. ' this.Size = 0;',
  4557. ' };',
  4558. ' this.$final = function () {',
  4559. ' };',
  4560. ' this.GetIt = function () {',
  4561. ' var $Self = this;',
  4562. ' var Result = null;',
  4563. ' Result = function () {',
  4564. ' $Self.Size = $Self.Size;',
  4565. ' };',
  4566. ' return Result;',
  4567. ' };',
  4568. '});',
  4569. '']),
  4570. LinesToStr([
  4571. '']));
  4572. end;
  4573. procedure TTestModule.TestEnum_Name;
  4574. begin
  4575. StartProgram(false);
  4576. Add('type TMyEnum = (Red, Green, Blue);');
  4577. Add('var e: TMyEnum;');
  4578. Add('var f: TMyEnum = Blue;');
  4579. Add('begin');
  4580. Add(' e:=green;');
  4581. Add(' e:=default(TMyEnum);');
  4582. ConvertProgram;
  4583. CheckSource('TestEnumName',
  4584. LinesToStr([ // statements
  4585. 'this.TMyEnum = {',
  4586. ' "0":"Red",',
  4587. ' Red:0,',
  4588. ' "1":"Green",',
  4589. ' Green:1,',
  4590. ' "2":"Blue",',
  4591. ' Blue:2',
  4592. ' };',
  4593. 'this.e = 0;',
  4594. 'this.f = $mod.TMyEnum.Blue;'
  4595. ]),
  4596. LinesToStr([
  4597. '$mod.e=$mod.TMyEnum.Green;',
  4598. '$mod.e=$mod.TMyEnum.Red;'
  4599. ]));
  4600. end;
  4601. procedure TTestModule.TestEnum_Number;
  4602. begin
  4603. Converter.Options:=Converter.Options+[coEnumNumbers];
  4604. StartProgram(false);
  4605. Add('type TMyEnum = (Red, Green);');
  4606. Add('var');
  4607. Add(' e: TMyEnum;');
  4608. Add(' f: TMyEnum = Green;');
  4609. Add(' i: longint;');
  4610. Add('begin');
  4611. Add(' e:=green;');
  4612. Add(' i:=longint(e);');
  4613. ConvertProgram;
  4614. CheckSource('TestEnumNumber',
  4615. LinesToStr([ // statements
  4616. 'this.TMyEnum = {',
  4617. ' "0":"Red",',
  4618. ' Red:0,',
  4619. ' "1":"Green",',
  4620. ' Green:1',
  4621. ' };',
  4622. 'this.e = 0;',
  4623. 'this.f = 1;',
  4624. 'this.i = 0;'
  4625. ]),
  4626. LinesToStr([
  4627. '$mod.e=1;',
  4628. '$mod.i=$mod.e;'
  4629. ]));
  4630. end;
  4631. procedure TTestModule.TestEnum_ConstFail;
  4632. begin
  4633. StartProgram(false);
  4634. Add([
  4635. 'type TMyEnum = (Red = 100, Green = 101);',
  4636. 'var',
  4637. ' e: TMyEnum;',
  4638. ' f: TMyEnum = Green;',
  4639. 'begin',
  4640. ' e:=green;']);
  4641. SetExpectedPasResolverError('not yet implemented: Red:TPasEnumValue [20180126202434] enum const',3002);
  4642. ConvertProgram;
  4643. end;
  4644. procedure TTestModule.TestEnum_Functions;
  4645. begin
  4646. StartProgram(false);
  4647. Add([
  4648. 'type TMyEnum = (Red, Green);',
  4649. 'procedure DoIt(var e: TMyEnum; var i: word);',
  4650. 'var',
  4651. ' v: longint;',
  4652. ' s: string;',
  4653. 'begin',
  4654. ' val(s,e,v);',
  4655. ' val(s,e,i);',
  4656. 'end;',
  4657. 'var',
  4658. ' e: TMyEnum;',
  4659. ' i: longint;',
  4660. ' s: string;',
  4661. ' b: boolean;',
  4662. 'begin',
  4663. ' i:=ord(red);',
  4664. ' i:=ord(green);',
  4665. ' i:=ord(e);',
  4666. ' i:=ord(b);',
  4667. ' e:=low(tmyenum);',
  4668. ' e:=low(e);',
  4669. ' b:=low(boolean);',
  4670. ' e:=high(tmyenum);',
  4671. ' e:=high(e);',
  4672. ' b:=high(boolean);',
  4673. ' e:=pred(green);',
  4674. ' e:=pred(e);',
  4675. ' b:=pred(b);',
  4676. ' e:=succ(red);',
  4677. ' e:=succ(e);',
  4678. ' b:=succ(b);',
  4679. ' e:=tmyenum(1);',
  4680. ' e:=tmyenum(i);',
  4681. ' s:=str(e);',
  4682. ' str(e,s);',
  4683. ' str(red,s);',
  4684. ' s:=str(e:3);',
  4685. ' writestr(s,e:3,red);',
  4686. ' val(s,e,i);',
  4687. ' e:=TMyEnum(i);',
  4688. ' i:=longint(e);']);
  4689. ConvertProgram;
  4690. CheckSource('TestEnum_Functions',
  4691. LinesToStr([ // statements
  4692. 'this.TMyEnum = {',
  4693. ' "0":"Red",',
  4694. ' Red:0,',
  4695. ' "1":"Green",',
  4696. ' Green:1',
  4697. ' };',
  4698. 'this.DoIt = function (e, i) {',
  4699. ' var v = 0;',
  4700. ' var s = "";',
  4701. ' e.set(rtl.valEnum(s, $mod.TMyEnum, function (w) {',
  4702. ' v = w;',
  4703. ' }));',
  4704. ' e.set(rtl.valEnum(s, $mod.TMyEnum, i.set));',
  4705. '};',
  4706. 'this.e = 0;',
  4707. 'this.i = 0;',
  4708. 'this.s = "";',
  4709. 'this.b = false;',
  4710. '']),
  4711. LinesToStr([
  4712. '$mod.i=$mod.TMyEnum.Red;',
  4713. '$mod.i=$mod.TMyEnum.Green;',
  4714. '$mod.i=$mod.e;',
  4715. '$mod.i=$mod.b+0;',
  4716. '$mod.e=$mod.TMyEnum.Red;',
  4717. '$mod.e=$mod.TMyEnum.Red;',
  4718. '$mod.b=false;',
  4719. '$mod.e=$mod.TMyEnum.Green;',
  4720. '$mod.e=$mod.TMyEnum.Green;',
  4721. '$mod.b=true;',
  4722. '$mod.e=$mod.TMyEnum.Green-1;',
  4723. '$mod.e=$mod.e-1;',
  4724. '$mod.b=false;',
  4725. '$mod.e=$mod.TMyEnum.Red+1;',
  4726. '$mod.e=$mod.e+1;',
  4727. '$mod.b=true;',
  4728. '$mod.e=1;',
  4729. '$mod.e=$mod.i;',
  4730. '$mod.s = $mod.TMyEnum[$mod.e];',
  4731. '$mod.s = $mod.TMyEnum[$mod.e];',
  4732. '$mod.s = $mod.TMyEnum[$mod.TMyEnum.Red];',
  4733. '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3);',
  4734. '$mod.s = rtl.spaceLeft($mod.TMyEnum[$mod.e], 3)+$mod.TMyEnum[$mod.TMyEnum.Red];',
  4735. '$mod.e = rtl.valEnum($mod.s, $mod.TMyEnum, function (v) {',
  4736. ' $mod.i = v;',
  4737. '});',
  4738. '$mod.e=$mod.i;',
  4739. '$mod.i=$mod.e;',
  4740. '']));
  4741. end;
  4742. procedure TTestModule.TestEnum_AsParams;
  4743. begin
  4744. StartProgram(false);
  4745. Add('type TEnum = (Red,Blue);');
  4746. Add('procedure DoIt(vG: TEnum; const vH: TEnum; var vI: TEnum);');
  4747. Add('var vJ: TEnum;');
  4748. Add('begin');
  4749. Add(' vg:=vg;');
  4750. Add(' vj:=vh;');
  4751. Add(' vi:=vi;');
  4752. Add(' doit(vg,vg,vg);');
  4753. Add(' doit(vh,vh,vj);');
  4754. Add(' doit(vi,vi,vi);');
  4755. Add(' doit(vj,vj,vj);');
  4756. Add('end;');
  4757. Add('var i: TEnum;');
  4758. Add('begin');
  4759. Add(' doit(i,i,i);');
  4760. ConvertProgram;
  4761. CheckSource('TestEnum_AsParams',
  4762. LinesToStr([ // statements
  4763. 'this.TEnum = {',
  4764. ' "0": "Red",',
  4765. ' Red: 0,',
  4766. ' "1": "Blue",',
  4767. ' Blue: 1',
  4768. '};',
  4769. 'this.DoIt = function (vG,vH,vI) {',
  4770. ' var vJ = 0;',
  4771. ' vG = vG;',
  4772. ' vJ = vH;',
  4773. ' vI.set(vI.get());',
  4774. ' $mod.DoIt(vG, vG, {',
  4775. ' get: function () {',
  4776. ' return vG;',
  4777. ' },',
  4778. ' set: function (v) {',
  4779. ' vG = v;',
  4780. ' }',
  4781. ' });',
  4782. ' $mod.DoIt(vH, vH, {',
  4783. ' get: function () {',
  4784. ' return vJ;',
  4785. ' },',
  4786. ' set: function (v) {',
  4787. ' vJ = v;',
  4788. ' }',
  4789. ' });',
  4790. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  4791. ' $mod.DoIt(vJ, vJ, {',
  4792. ' get: function () {',
  4793. ' return vJ;',
  4794. ' },',
  4795. ' set: function (v) {',
  4796. ' vJ = v;',
  4797. ' }',
  4798. ' });',
  4799. '};',
  4800. 'this.i = 0;'
  4801. ]),
  4802. LinesToStr([
  4803. '$mod.DoIt($mod.i,$mod.i,{',
  4804. ' p: $mod,',
  4805. ' get: function () {',
  4806. ' return this.p.i;',
  4807. ' },',
  4808. ' set: function (v) {',
  4809. ' this.p.i = v;',
  4810. ' }',
  4811. '});'
  4812. ]));
  4813. end;
  4814. procedure TTestModule.TestEnumRange_Array;
  4815. begin
  4816. StartProgram(false);
  4817. Add([
  4818. 'type',
  4819. ' TEnum = (Red, Green, Blue);',
  4820. ' TEnumRg = green..blue;',
  4821. ' TArr = array[TEnumRg] of byte;',
  4822. ' TArr2 = array[green..blue] of byte;',
  4823. 'var',
  4824. ' a: TArr;',
  4825. ' b: TArr = (3,4);',
  4826. ' c: TArr2 = (5,6);',
  4827. 'begin',
  4828. ' a[green] := b[blue];',
  4829. ' c[green] := c[blue];',
  4830. '']);
  4831. ConvertProgram;
  4832. CheckSource('TestEnumRange_Array',
  4833. LinesToStr([ // statements
  4834. 'this.TEnum = {',
  4835. ' "0": "Red",',
  4836. ' Red: 0,',
  4837. ' "1": "Green",',
  4838. ' Green: 1,',
  4839. ' "2": "Blue",',
  4840. ' Blue: 2',
  4841. '};',
  4842. 'this.a = rtl.arraySetLength(null, 0, 2);',
  4843. 'this.b = [3, 4];',
  4844. 'this.c = [5, 6];',
  4845. '']),
  4846. LinesToStr([
  4847. ' $mod.a[$mod.TEnum.Green - 1] = $mod.b[$mod.TEnum.Blue - 1];',
  4848. ' $mod.c[$mod.TEnum.Green - 1] = $mod.c[$mod.TEnum.Blue - 1];',
  4849. '']));
  4850. end;
  4851. procedure TTestModule.TestEnum_ForIn;
  4852. begin
  4853. StartProgram(false);
  4854. Add([
  4855. 'type',
  4856. ' TEnum = (Red, Green, Blue);',
  4857. ' TEnumRg = green..blue;',
  4858. ' TArr = array[TEnum] of byte;',
  4859. ' TArrRg = array[TEnumRg] of byte;',
  4860. 'var',
  4861. ' e: TEnum;',
  4862. ' a1: TArr = (3,4,5);',
  4863. ' a2: TArrRg = (11,12);',
  4864. ' b: byte;',
  4865. 'begin',
  4866. ' for e in TEnum do ;',
  4867. ' for e in TEnumRg do ;',
  4868. ' for e in TArr do ;',
  4869. ' for e in TArrRg do ;',
  4870. ' for b in a1 do ;',
  4871. ' for b in a2 do ;',
  4872. '']);
  4873. ConvertProgram;
  4874. CheckSource('TestEnum_ForIn',
  4875. LinesToStr([ // statements
  4876. 'this.TEnum = {',
  4877. ' "0": "Red",',
  4878. ' Red: 0,',
  4879. ' "1": "Green",',
  4880. ' Green: 1,',
  4881. ' "2": "Blue",',
  4882. ' Blue: 2',
  4883. '};',
  4884. 'this.e = 0;',
  4885. 'this.a1 = [3, 4, 5];',
  4886. 'this.a2 = [11, 12];',
  4887. 'this.b = 0;',
  4888. '']),
  4889. LinesToStr([
  4890. ' for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  4891. ' for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  4892. ' for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  4893. ' for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  4894. ' for (var $in1 = $mod.a1, $l2 = 0, $end3 = rtl.length($in1) - 1; $l2 <= $end3; $l2++) $mod.b = $in1[$l2];',
  4895. ' for (var $in4 = $mod.a2, $l5 = 0, $end6 = rtl.length($in4) - 1; $l5 <= $end6; $l5++) $mod.b = $in4[$l5];',
  4896. '']));
  4897. end;
  4898. procedure TTestModule.TestEnum_ScopedNumber;
  4899. begin
  4900. Converter.Options:=Converter.Options+[coEnumNumbers];
  4901. StartProgram(false);
  4902. Add([
  4903. 'type',
  4904. ' TEnum = (Red, Green);',
  4905. 'var',
  4906. ' e: TEnum;',
  4907. 'begin',
  4908. ' e:=TEnum.Green;',
  4909. '']);
  4910. ConvertProgram;
  4911. CheckSource('TestEnum_ScopedNumber',
  4912. LinesToStr([ // statements
  4913. 'this.TEnum = {',
  4914. ' "0": "Red",',
  4915. ' Red: 0,',
  4916. ' "1": "Green",',
  4917. ' Green: 1',
  4918. '};',
  4919. 'this.e = 0;',
  4920. '']),
  4921. LinesToStr([
  4922. '$mod.e = 1;']));
  4923. end;
  4924. procedure TTestModule.TestEnum_InFunction;
  4925. begin
  4926. StartProgram(false);
  4927. Add([
  4928. 'const TEnum = 3;',
  4929. 'procedure DoIt;',
  4930. 'type',
  4931. ' TEnum = (Red, Green, Blue);',
  4932. ' procedure Sub;',
  4933. ' type',
  4934. ' TEnumSub = (Left, Right);',
  4935. ' var',
  4936. ' es: TEnumSub;',
  4937. ' begin',
  4938. ' es:=Left;',
  4939. ' end;',
  4940. 'var',
  4941. ' e, e2: TEnum;',
  4942. 'begin',
  4943. ' if e in [red,blue] then e2:=e;',
  4944. 'end;',
  4945. 'begin']);
  4946. ConvertProgram;
  4947. CheckSource('TestEnum_InFunction',
  4948. LinesToStr([ // statements
  4949. 'this.TEnum = 3;',
  4950. 'var TEnum$1 = {',
  4951. ' "0":"Red",',
  4952. ' Red:0,',
  4953. ' "1":"Green",',
  4954. ' Green:1,',
  4955. ' "2":"Blue",',
  4956. ' Blue:2',
  4957. ' };',
  4958. 'var TEnumSub = {',
  4959. ' "0": "Left",',
  4960. ' Left: 0,',
  4961. ' "1": "Right",',
  4962. ' Right: 1',
  4963. '};',
  4964. 'this.DoIt = function () {',
  4965. ' function Sub() {',
  4966. ' var es = 0;',
  4967. ' es = TEnumSub.Left;',
  4968. ' };',
  4969. ' var e = 0;',
  4970. ' var e2 = 0;',
  4971. ' if (e in rtl.createSet(TEnum$1.Red, TEnum$1.Blue)) e2 = e;',
  4972. '};',
  4973. '']),
  4974. LinesToStr([
  4975. '']));
  4976. end;
  4977. procedure TTestModule.TestSet_Enum;
  4978. begin
  4979. StartProgram(false);
  4980. Add([
  4981. 'type',
  4982. ' TColor = (Red, Green, Blue);',
  4983. ' TColors = set of TColor;',
  4984. 'var',
  4985. ' c: TColor;',
  4986. ' s: TColors;',
  4987. ' t: TColors = [];',
  4988. ' u: TColors = [Red];',
  4989. 'begin',
  4990. ' s:=[];',
  4991. ' s:=[Green];',
  4992. ' s:=[Green,Blue];',
  4993. ' s:=[Red..Blue];',
  4994. ' s:=[Red,Green..Blue];',
  4995. ' s:=[Red,c];',
  4996. ' s:=t;',
  4997. ' s:=default(TColors);',
  4998. '']);
  4999. ConvertProgram;
  5000. CheckSource('TestSet',
  5001. LinesToStr([ // statements
  5002. 'this.TColor = {',
  5003. ' "0":"Red",',
  5004. ' Red:0,',
  5005. ' "1":"Green",',
  5006. ' Green:1,',
  5007. ' "2":"Blue",',
  5008. ' Blue:2',
  5009. ' };',
  5010. 'this.c = 0;',
  5011. 'this.s = {};',
  5012. 'this.t = {};',
  5013. 'this.u = rtl.createSet($mod.TColor.Red);'
  5014. ]),
  5015. LinesToStr([
  5016. '$mod.s={};',
  5017. '$mod.s=rtl.createSet($mod.TColor.Green);',
  5018. '$mod.s=rtl.createSet($mod.TColor.Green,$mod.TColor.Blue);',
  5019. '$mod.s=rtl.createSet(null,$mod.TColor.Red,$mod.TColor.Blue);',
  5020. '$mod.s=rtl.createSet($mod.TColor.Red,null,$mod.TColor.Green,$mod.TColor.Blue);',
  5021. '$mod.s=rtl.createSet($mod.TColor.Red,$mod.c);',
  5022. '$mod.s=rtl.refSet($mod.t);',
  5023. '$mod.s={};',
  5024. '']));
  5025. end;
  5026. procedure TTestModule.TestSet_Operators;
  5027. begin
  5028. StartProgram(false);
  5029. Add('type');
  5030. Add(' TColor = (Red, Green, Blue);');
  5031. Add(' TColors = set of tcolor;');
  5032. Add('var');
  5033. Add(' vC: TColor;');
  5034. Add(' vS: TColors;');
  5035. Add(' vT: TColors;');
  5036. Add(' vU: TColors;');
  5037. Add(' B: boolean;');
  5038. Add('begin');
  5039. Add(' include(vs,green);');
  5040. Add(' exclude(vs,vc);');
  5041. Add(' vs:=vt+vu;');
  5042. Add(' vs:=vt+[red];');
  5043. Add(' vs:=[red]+vt;');
  5044. Add(' vs:=[red]+[green];');
  5045. Add(' vs:=vt-vu;');
  5046. Add(' vs:=vt-[red];');
  5047. Add(' vs:=[red]-vt;');
  5048. Add(' vs:=[red]-[green];');
  5049. Add(' vs:=vt*vu;');
  5050. Add(' vs:=vt*[red];');
  5051. Add(' vs:=[red]*vt;');
  5052. Add(' vs:=[red]*[green];');
  5053. Add(' vs:=vt><vu;');
  5054. Add(' vs:=vt><[red];');
  5055. Add(' vs:=[red]><vt;');
  5056. Add(' vs:=[red]><[green];');
  5057. Add(' b:=vt=vu;');
  5058. Add(' b:=vt=[red];');
  5059. Add(' b:=[red]=vt;');
  5060. Add(' b:=[red]=[green];');
  5061. Add(' b:=vt<>vu;');
  5062. Add(' b:=vt<>[red];');
  5063. Add(' b:=[red]<>vt;');
  5064. Add(' b:=[red]<>[green];');
  5065. Add(' b:=vt<=vu;');
  5066. Add(' b:=vt<=[red];');
  5067. Add(' b:=[red]<=vt;');
  5068. Add(' b:=[red]<=[green];');
  5069. Add(' b:=vt>=vu;');
  5070. Add(' b:=vt>=[red];');
  5071. Add(' b:=[red]>=vt;');
  5072. Add(' b:=[red]>=[green];');
  5073. ConvertProgram;
  5074. CheckSource('TestSet_Operators',
  5075. LinesToStr([ // statements
  5076. 'this.TColor = {',
  5077. ' "0":"Red",',
  5078. ' Red:0,',
  5079. ' "1":"Green",',
  5080. ' Green:1,',
  5081. ' "2":"Blue",',
  5082. ' Blue:2',
  5083. ' };',
  5084. 'this.vC = 0;',
  5085. 'this.vS = {};',
  5086. 'this.vT = {};',
  5087. 'this.vU = {};',
  5088. 'this.B = false;'
  5089. ]),
  5090. LinesToStr([
  5091. '$mod.vS = rtl.includeSet($mod.vS,$mod.TColor.Green);',
  5092. '$mod.vS = rtl.excludeSet($mod.vS,$mod.vC);',
  5093. '$mod.vS = rtl.unionSet($mod.vT, $mod.vU);',
  5094. '$mod.vS = rtl.unionSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5095. '$mod.vS = rtl.unionSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5096. '$mod.vS = rtl.unionSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5097. '$mod.vS = rtl.diffSet($mod.vT, $mod.vU);',
  5098. '$mod.vS = rtl.diffSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5099. '$mod.vS = rtl.diffSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5100. '$mod.vS = rtl.diffSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5101. '$mod.vS = rtl.intersectSet($mod.vT, $mod.vU);',
  5102. '$mod.vS = rtl.intersectSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5103. '$mod.vS = rtl.intersectSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5104. '$mod.vS = rtl.intersectSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5105. '$mod.vS = rtl.symDiffSet($mod.vT, $mod.vU);',
  5106. '$mod.vS = rtl.symDiffSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5107. '$mod.vS = rtl.symDiffSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5108. '$mod.vS = rtl.symDiffSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5109. '$mod.B = rtl.eqSet($mod.vT, $mod.vU);',
  5110. '$mod.B = rtl.eqSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5111. '$mod.B = rtl.eqSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5112. '$mod.B = rtl.eqSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5113. '$mod.B = rtl.neSet($mod.vT, $mod.vU);',
  5114. '$mod.B = rtl.neSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5115. '$mod.B = rtl.neSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5116. '$mod.B = rtl.neSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5117. '$mod.B = rtl.leSet($mod.vT, $mod.vU);',
  5118. '$mod.B = rtl.leSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5119. '$mod.B = rtl.leSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5120. '$mod.B = rtl.leSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5121. '$mod.B = rtl.geSet($mod.vT, $mod.vU);',
  5122. '$mod.B = rtl.geSet($mod.vT, rtl.createSet($mod.TColor.Red));',
  5123. '$mod.B = rtl.geSet(rtl.createSet($mod.TColor.Red), $mod.vT);',
  5124. '$mod.B = rtl.geSet(rtl.createSet($mod.TColor.Red), rtl.createSet($mod.TColor.Green));',
  5125. '']));
  5126. end;
  5127. procedure TTestModule.TestSet_Operator_In;
  5128. begin
  5129. StartProgram(false);
  5130. Add('type');
  5131. Add(' TColor = (Red, Green, Blue);');
  5132. Add(' TColors = set of tcolor;');
  5133. Add('var');
  5134. Add(' vC: tcolor;');
  5135. Add(' vT: tcolors;');
  5136. Add(' B: boolean;');
  5137. Add('begin');
  5138. Add(' b:=red in vt;');
  5139. Add(' b:=vc in vt;');
  5140. Add(' b:=green in [red..blue];');
  5141. Add(' b:=vc in [red..blue];');
  5142. Add(' ');
  5143. Add(' if red in vt then ;');
  5144. Add(' while vC in vt do ;');
  5145. Add(' repeat');
  5146. Add(' until vC in vt;');
  5147. ConvertProgram;
  5148. CheckSource('TestSet_Operator_In',
  5149. LinesToStr([ // statements
  5150. 'this.TColor = {',
  5151. ' "0":"Red",',
  5152. ' Red:0,',
  5153. ' "1":"Green",',
  5154. ' Green:1,',
  5155. ' "2":"Blue",',
  5156. ' Blue:2',
  5157. ' };',
  5158. 'this.vC = 0;',
  5159. 'this.vT = {};',
  5160. 'this.B = false;'
  5161. ]),
  5162. LinesToStr([
  5163. '$mod.B = $mod.TColor.Red in $mod.vT;',
  5164. '$mod.B = $mod.vC in $mod.vT;',
  5165. '$mod.B = $mod.TColor.Green in rtl.createSet(null, $mod.TColor.Red, $mod.TColor.Blue);',
  5166. '$mod.B = $mod.vC in rtl.createSet(null, $mod.TColor.Red, $mod.TColor.Blue);',
  5167. 'if ($mod.TColor.Red in $mod.vT) ;',
  5168. 'while ($mod.vC in $mod.vT) {',
  5169. '};',
  5170. 'do {',
  5171. '} while (!($mod.vC in $mod.vT));',
  5172. '']));
  5173. end;
  5174. procedure TTestModule.TestSet_Functions;
  5175. begin
  5176. StartProgram(false);
  5177. Add('type');
  5178. Add(' TMyEnum = (Red, Green);');
  5179. Add(' TMyEnums = set of TMyEnum;');
  5180. Add('var');
  5181. Add(' e: TMyEnum;');
  5182. Add(' s: TMyEnums;');
  5183. Add('begin');
  5184. Add(' e:=Low(TMyEnums);');
  5185. Add(' e:=Low(s);');
  5186. Add(' e:=High(TMyEnums);');
  5187. Add(' e:=High(s);');
  5188. ConvertProgram;
  5189. CheckSource('TestSetFunctions',
  5190. LinesToStr([ // statements
  5191. 'this.TMyEnum = {',
  5192. ' "0":"Red",',
  5193. ' Red:0,',
  5194. ' "1":"Green",',
  5195. ' Green:1',
  5196. ' };',
  5197. 'this.e = 0;',
  5198. 'this.s = {};'
  5199. ]),
  5200. LinesToStr([
  5201. '$mod.e=$mod.TMyEnum.Red;',
  5202. '$mod.e=$mod.TMyEnum.Red;',
  5203. '$mod.e=$mod.TMyEnum.Green;',
  5204. '$mod.e=$mod.TMyEnum.Green;',
  5205. '']));
  5206. end;
  5207. procedure TTestModule.TestSet_PassAsArgClone;
  5208. begin
  5209. StartProgram(false);
  5210. Add('type');
  5211. Add(' TMyEnum = (Red, Green);');
  5212. Add(' TMyEnums = set of TMyEnum;');
  5213. Add('procedure DoDefault(s: tmyenums); begin end;');
  5214. Add('procedure DoConst(const s: tmyenums); begin end;');
  5215. Add('var');
  5216. Add(' aSet: tmyenums;');
  5217. Add('begin');
  5218. Add(' dodefault(aset);');
  5219. Add(' doconst(aset);');
  5220. ConvertProgram;
  5221. CheckSource('TestSetFunctions',
  5222. LinesToStr([ // statements
  5223. 'this.TMyEnum = {',
  5224. ' "0":"Red",',
  5225. ' Red:0,',
  5226. ' "1":"Green",',
  5227. ' Green:1',
  5228. ' };',
  5229. 'this.DoDefault = function (s) {',
  5230. '};',
  5231. 'this.DoConst = function (s) {',
  5232. '};',
  5233. 'this.aSet = {};'
  5234. ]),
  5235. LinesToStr([
  5236. '$mod.DoDefault(rtl.refSet($mod.aSet));',
  5237. '$mod.DoConst($mod.aSet);',
  5238. '']));
  5239. end;
  5240. procedure TTestModule.TestSet_AsParams;
  5241. begin
  5242. StartProgram(false);
  5243. Add([
  5244. 'type TEnum = (Red,Blue);',
  5245. 'type TEnums = set of TEnum;',
  5246. 'function DoIt(vG: TEnums; const vH: TEnums; var vI: TEnums): TEnums;',
  5247. 'var vJ: TEnums;',
  5248. 'begin',
  5249. ' Include(vg,red);',
  5250. ' Include(result,blue);',
  5251. ' vg:=vg;',
  5252. ' vj:=vh;',
  5253. ' vi:=vi;',
  5254. ' doit(vg,vg,vg);',
  5255. ' doit(vh,vh,vj);',
  5256. ' doit(vi,vi,vi);',
  5257. ' doit(vj,vj,vj);',
  5258. 'end;',
  5259. 'var i: TEnums;',
  5260. 'begin',
  5261. ' doit(i,i,i);']);
  5262. ConvertProgram;
  5263. CheckSource('TestSet_AsParams',
  5264. LinesToStr([ // statements
  5265. 'this.TEnum = {',
  5266. ' "0": "Red",',
  5267. ' Red: 0,',
  5268. ' "1": "Blue",',
  5269. ' Blue: 1',
  5270. '};',
  5271. 'this.DoIt = function (vG,vH,vI) {',
  5272. ' var Result = {};',
  5273. ' var vJ = {};',
  5274. ' vG = rtl.includeSet(vG, $mod.TEnum.Red);',
  5275. ' Result = rtl.includeSet(Result, $mod.TEnum.Blue);',
  5276. ' vG = rtl.refSet(vG);',
  5277. ' vJ = rtl.refSet(vH);',
  5278. ' vI.set(rtl.refSet(vI.get()));',
  5279. ' $mod.DoIt(rtl.refSet(vG), vG, {',
  5280. ' get: function () {',
  5281. ' return vG;',
  5282. ' },',
  5283. ' set: function (v) {',
  5284. ' vG = v;',
  5285. ' }',
  5286. ' });',
  5287. ' $mod.DoIt(rtl.refSet(vH), vH, {',
  5288. ' get: function () {',
  5289. ' return vJ;',
  5290. ' },',
  5291. ' set: function (v) {',
  5292. ' vJ = v;',
  5293. ' }',
  5294. ' });',
  5295. ' $mod.DoIt(rtl.refSet(vI.get()), vI.get(), vI);',
  5296. ' $mod.DoIt(rtl.refSet(vJ), vJ, {',
  5297. ' get: function () {',
  5298. ' return vJ;',
  5299. ' },',
  5300. ' set: function (v) {',
  5301. ' vJ = v;',
  5302. ' }',
  5303. ' });',
  5304. ' return Result;',
  5305. '};',
  5306. 'this.i = {};'
  5307. ]),
  5308. LinesToStr([
  5309. '$mod.DoIt(rtl.refSet($mod.i),$mod.i,{',
  5310. ' p: $mod,',
  5311. ' get: function () {',
  5312. ' return this.p.i;',
  5313. ' },',
  5314. ' set: function (v) {',
  5315. ' this.p.i = v;',
  5316. ' }',
  5317. '});'
  5318. ]));
  5319. end;
  5320. procedure TTestModule.TestSet_Property;
  5321. begin
  5322. StartProgram(false);
  5323. Add('type');
  5324. Add(' TEnum = (Red,Blue);');
  5325. Add(' TEnums = set of TEnum;');
  5326. Add(' TObject = class');
  5327. Add(' function GetColors: TEnums; external name ''GetColors'';');
  5328. Add(' procedure SetColors(const Value: TEnums); external name ''SetColors'';');
  5329. Add(' property Colors: TEnums read GetColors write SetColors;');
  5330. Add(' end;');
  5331. Add('procedure DoIt(i: TEnums; const j: TEnums; var k: TEnums; out l: TEnums);');
  5332. Add('begin end;');
  5333. Add('var Obj: TObject;');
  5334. Add('begin');
  5335. Add(' Include(Obj.Colors,Red);');
  5336. Add(' Exclude(Obj.Colors,Red);');
  5337. //Add(' DoIt(Obj.Colors,Obj.Colors,Obj.Colors,Obj.Colors);');
  5338. ConvertProgram;
  5339. CheckSource('TestSet_Property',
  5340. LinesToStr([ // statements
  5341. 'this.TEnum = {',
  5342. ' "0": "Red",',
  5343. ' Red: 0,',
  5344. ' "1": "Blue",',
  5345. ' Blue: 1',
  5346. '};',
  5347. 'rtl.createClass($mod, "TObject", null, function () {',
  5348. ' this.$init = function () {',
  5349. ' };',
  5350. ' this.$final = function () {',
  5351. ' };',
  5352. '});',
  5353. 'this.DoIt = function (i, j, k, l) {',
  5354. '};',
  5355. 'this.Obj = null;',
  5356. '']),
  5357. LinesToStr([
  5358. '$mod.Obj.SetColors(rtl.includeSet($mod.Obj.GetColors(), $mod.TEnum.Red));',
  5359. '$mod.Obj.SetColors(rtl.excludeSet($mod.Obj.GetColors(), $mod.TEnum.Red));',
  5360. '']));
  5361. end;
  5362. procedure TTestModule.TestSet_EnumConst;
  5363. begin
  5364. StartProgram(false);
  5365. Add([
  5366. 'type',
  5367. ' TEnum = (Red,Blue);',
  5368. ' TEnums = set of TEnum;',
  5369. 'const',
  5370. ' Orange = red;',
  5371. 'var',
  5372. ' Enum: tenum;',
  5373. ' Enums: tenums;',
  5374. 'begin',
  5375. ' Include(enums,orange);',
  5376. ' Exclude(enums,orange);',
  5377. ' if orange in enums then;',
  5378. ' if orange in [orange,red] then;']);
  5379. ConvertProgram;
  5380. CheckSource('TestSet_EnumConst',
  5381. LinesToStr([ // statements
  5382. 'this.TEnum = {',
  5383. ' "0": "Red",',
  5384. ' Red: 0,',
  5385. ' "1": "Blue",',
  5386. ' Blue: 1',
  5387. '};',
  5388. 'this.Orange = $mod.TEnum.Red;',
  5389. 'this.Enum = 0;',
  5390. 'this.Enums = {};',
  5391. '']),
  5392. LinesToStr([
  5393. '$mod.Enums = rtl.includeSet($mod.Enums, $mod.TEnum.Red);',
  5394. '$mod.Enums = rtl.excludeSet($mod.Enums, $mod.TEnum.Red);',
  5395. 'if ($mod.TEnum.Red in $mod.Enums) ;',
  5396. 'if ($mod.TEnum.Red in rtl.createSet($mod.TEnum.Red, $mod.TEnum.Red)) ;',
  5397. '']));
  5398. end;
  5399. procedure TTestModule.TestSet_IntConst;
  5400. begin
  5401. StartProgram(false);
  5402. Add([
  5403. 'type',
  5404. ' TEnums = set of Byte;',
  5405. 'const',
  5406. ' Orange = 0;',
  5407. 'var',
  5408. ' Enum: byte;',
  5409. ' Enums: tenums;',
  5410. 'begin',
  5411. ' Enums:=[];',
  5412. ' Enums:=[0];',
  5413. ' Enums:=[1..2];',
  5414. //' Include(enums,orange);',
  5415. //' Exclude(enums,orange);',
  5416. ' if orange in enums then;',
  5417. ' if orange in [orange,1] then;']);
  5418. ConvertProgram;
  5419. CheckSource('TestSet_IntConst',
  5420. LinesToStr([ // statements
  5421. 'this.Orange = 0;',
  5422. 'this.Enum = 0;',
  5423. 'this.Enums = {};',
  5424. '']),
  5425. LinesToStr([
  5426. '$mod.Enums = {};',
  5427. '$mod.Enums = rtl.createSet(0);',
  5428. '$mod.Enums = rtl.createSet(null, 1, 2);',
  5429. 'if (0 in $mod.Enums) ;',
  5430. 'if (0 in rtl.createSet(0, 1)) ;',
  5431. '']));
  5432. end;
  5433. procedure TTestModule.TestSet_AnonymousEnumType;
  5434. begin
  5435. StartProgram(false);
  5436. Add('type');
  5437. Add(' TFlags = set of (red, green);');
  5438. Add('const');
  5439. Add(' favorite = red;');
  5440. Add('var');
  5441. Add(' f: TFlags;');
  5442. Add(' i: longint;');
  5443. Add('begin');
  5444. Add(' Include(f,red);');
  5445. Add(' Include(f,favorite);');
  5446. Add(' i:=ord(red);');
  5447. Add(' i:=ord(favorite);');
  5448. Add(' i:=ord(low(TFlags));');
  5449. Add(' i:=ord(low(f));');
  5450. Add(' i:=ord(low(favorite));');
  5451. Add(' i:=ord(high(TFlags));');
  5452. Add(' i:=ord(high(f));');
  5453. Add(' i:=ord(high(favorite));');
  5454. Add(' f:=[green,favorite];');
  5455. ConvertProgram;
  5456. CheckSource('TestSet_AnonymousEnumType',
  5457. LinesToStr([ // statements
  5458. 'this.TFlags$a = {',
  5459. ' "0": "red",',
  5460. ' red: 0,',
  5461. ' "1": "green",',
  5462. ' green: 1',
  5463. '};',
  5464. 'this.favorite = $mod.TFlags$a.red;',
  5465. 'this.f = {};',
  5466. 'this.i = 0;',
  5467. '']),
  5468. LinesToStr([
  5469. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  5470. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  5471. '$mod.i = $mod.TFlags$a.red;',
  5472. '$mod.i = $mod.TFlags$a.red;',
  5473. '$mod.i = $mod.TFlags$a.red;',
  5474. '$mod.i = $mod.TFlags$a.red;',
  5475. '$mod.i = $mod.TFlags$a.red;',
  5476. '$mod.i = $mod.TFlags$a.green;',
  5477. '$mod.i = $mod.TFlags$a.green;',
  5478. '$mod.i = $mod.TFlags$a.green;',
  5479. '$mod.f = rtl.createSet($mod.TFlags$a.green, $mod.TFlags$a.red);',
  5480. '']));
  5481. end;
  5482. procedure TTestModule.TestSet_AnonymousEnumTypeChar;
  5483. begin
  5484. exit;
  5485. StartProgram(false);
  5486. Add([
  5487. 'type',
  5488. ' TAtoZ = ''A''..''Z'';',
  5489. ' TSetOfAZ = set of TAtoZ;',
  5490. 'var',
  5491. ' c: char;',
  5492. ' a: TAtoZ;',
  5493. ' s: TSetOfAZ = [''P'',''A''];',
  5494. ' i: longint;',
  5495. 'begin',
  5496. ' Include(s,''S'');',
  5497. ' Include(s,c);',
  5498. ' Include(s,a);',
  5499. ' c:=low(TAtoZ);',
  5500. ' i:=ord(low(TAtoZ));',
  5501. ' a:=high(TAtoZ);',
  5502. ' a:=high(TSetOfAtoZ);',
  5503. ' s:=[a,c,''M''];',
  5504. '']);
  5505. ConvertProgram;
  5506. CheckSource('TestSet_AnonymousEnumTypeChar',
  5507. LinesToStr([ // statements
  5508. '']),
  5509. LinesToStr([
  5510. '']));
  5511. end;
  5512. procedure TTestModule.TestSet_ConstEnum;
  5513. begin
  5514. StartProgram(false);
  5515. Add([
  5516. 'type',
  5517. ' TEnum = (red,blue,green);',
  5518. ' TEnums = set of TEnum;',
  5519. 'const',
  5520. ' teAny = [low(TEnum)..high(TEnum)];',
  5521. ' teRedBlue = [low(TEnum)..pred(high(TEnum))];',
  5522. 'var',
  5523. ' e: TEnum;',
  5524. ' s: TEnums;',
  5525. 'begin',
  5526. ' if blue in teAny then;',
  5527. ' if blue in teAny+[e] then;',
  5528. ' if blue in teAny+teRedBlue then;',
  5529. ' if e in [red,blue] then;',
  5530. ' s:=teAny;',
  5531. ' s:=teAny+[e];',
  5532. ' s:=[e]+teAny;',
  5533. ' s:=teAny+teRedBlue;',
  5534. ' s:=teAny+teRedBlue+[e];',
  5535. '']);
  5536. ConvertProgram;
  5537. CheckSource('TestSet_ConstEnum',
  5538. LinesToStr([ // statements
  5539. 'this.TEnum = {',
  5540. ' "0": "red",',
  5541. ' red: 0,',
  5542. ' "1": "blue",',
  5543. ' blue: 1,',
  5544. ' "2": "green",',
  5545. ' green: 2',
  5546. '};',
  5547. 'this.teAny = rtl.createSet(null, $mod.TEnum.red, $mod.TEnum.green);',
  5548. 'this.teRedBlue = rtl.createSet(null, $mod.TEnum.red, $mod.TEnum.green - 1);',
  5549. 'this.e = 0;',
  5550. 'this.s = {};',
  5551. '']),
  5552. LinesToStr([
  5553. 'if ($mod.TEnum.blue in $mod.teAny) ;',
  5554. 'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, rtl.createSet($mod.e))) ;',
  5555. 'if ($mod.TEnum.blue in rtl.unionSet($mod.teAny, $mod.teRedBlue)) ;',
  5556. 'if ($mod.e in rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)) ;',
  5557. '$mod.s = rtl.refSet($mod.teAny);',
  5558. '$mod.s = rtl.unionSet($mod.teAny, rtl.createSet($mod.e));',
  5559. '$mod.s = rtl.unionSet(rtl.createSet($mod.e), $mod.teAny);',
  5560. '$mod.s = rtl.unionSet($mod.teAny, $mod.teRedBlue);',
  5561. '$mod.s = rtl.unionSet(rtl.unionSet($mod.teAny, $mod.teRedBlue), rtl.createSet($mod.e));',
  5562. '']));
  5563. end;
  5564. procedure TTestModule.TestSet_ConstChar;
  5565. begin
  5566. StartProgram(false);
  5567. Add([
  5568. 'const',
  5569. ' LowChars = [''a''..''z''];',
  5570. ' Chars = LowChars+[''A''..''Z''];',
  5571. ' sc = [''А'', ''Я''];',
  5572. 'var',
  5573. ' c: char;',
  5574. ' s: string;',
  5575. 'begin',
  5576. ' if c in lowchars then ;',
  5577. ' if ''a'' in lowchars then ;',
  5578. ' if s[1] in lowchars then ;',
  5579. ' if c in chars then ;',
  5580. ' if c in [''a''..''z'',''_''] then ;',
  5581. ' if ''b'' in [''a''..''z'',''_''] then ;',
  5582. ' if ''Я'' in sc then ;',
  5583. '']);
  5584. ConvertProgram;
  5585. CheckSource('TestSet_ConstChar',
  5586. LinesToStr([ // statements
  5587. 'this.LowChars = rtl.createSet(null, 97, 122);',
  5588. 'this.Chars = rtl.unionSet($mod.LowChars, rtl.createSet(null, 65, 90));',
  5589. 'this.sc = rtl.createSet(1040, 1071);',
  5590. 'this.c = "";',
  5591. 'this.s = "";',
  5592. '']),
  5593. LinesToStr([
  5594. 'if ($mod.c.charCodeAt() in $mod.LowChars) ;',
  5595. 'if (97 in $mod.LowChars) ;',
  5596. 'if ($mod.s.charCodeAt(0) in $mod.LowChars) ;',
  5597. 'if ($mod.c.charCodeAt() in $mod.Chars) ;',
  5598. 'if ($mod.c.charCodeAt() in rtl.createSet(null, 97, 122, 95)) ;',
  5599. 'if (98 in rtl.createSet(null, 97, 122, 95)) ;',
  5600. 'if (1071 in $mod.sc) ;',
  5601. '']));
  5602. end;
  5603. procedure TTestModule.TestSet_ConstInt;
  5604. begin
  5605. StartProgram(false);
  5606. Add([
  5607. 'const',
  5608. ' Months = [1..12];',
  5609. ' Mirror = [-12..-1]+Months;',
  5610. 'var',
  5611. ' i: smallint;',
  5612. 'begin',
  5613. ' if 3 in Months then;',
  5614. ' if i in Months+[i] then;',
  5615. ' if i in Months+Mirror then;',
  5616. ' if i in [4..6,8] then;',
  5617. '']);
  5618. ConvertProgram;
  5619. CheckSource('TestSet_ConstInt',
  5620. LinesToStr([ // statements
  5621. 'this.Months = rtl.createSet(null, 1, 12);',
  5622. 'this.Mirror = rtl.unionSet(rtl.createSet(null, -12, -1), $mod.Months);',
  5623. 'this.i = 0;',
  5624. '']),
  5625. LinesToStr([
  5626. 'if (3 in $mod.Months) ;',
  5627. 'if ($mod.i in rtl.unionSet($mod.Months, rtl.createSet($mod.i))) ;',
  5628. 'if ($mod.i in rtl.unionSet($mod.Months, $mod.Mirror)) ;',
  5629. 'if ($mod.i in rtl.createSet(null, 4, 6, 8)) ;',
  5630. '']));
  5631. end;
  5632. procedure TTestModule.TestSet_InFunction;
  5633. begin
  5634. StartProgram(false);
  5635. Add([
  5636. 'const',
  5637. ' TEnum = 3;',
  5638. ' TSetOfEnum = 4;',
  5639. ' TSetOfAno = 5;',
  5640. 'procedure DoIt;',
  5641. 'type',
  5642. ' TEnum = (red, blue);',
  5643. ' TSetOfEnum = set of TEnum;',
  5644. ' TSetOfAno = set of (up,down);',
  5645. 'var',
  5646. ' e: TEnum;',
  5647. ' se: TSetOfEnum;',
  5648. ' sa: TSetOfAno;',
  5649. 'begin',
  5650. ' se:=[e];',
  5651. ' sa:=[up];',
  5652. 'end;',
  5653. 'begin',
  5654. '']);
  5655. ConvertProgram;
  5656. CheckSource('TestSet_InFunction',
  5657. LinesToStr([ // statements
  5658. 'this.TEnum = 3;',
  5659. 'this.TSetOfEnum = 4;',
  5660. 'this.TSetOfAno = 5;',
  5661. 'var TEnum$1 = {',
  5662. ' "0": "red",',
  5663. ' red: 0,',
  5664. ' "1": "blue",',
  5665. ' blue: 1',
  5666. '};',
  5667. 'var TSetOfAno$a = {',
  5668. ' "0": "up",',
  5669. ' up: 0,',
  5670. ' "1": "down",',
  5671. ' down: 1',
  5672. '};',
  5673. 'this.DoIt = function () {',
  5674. ' var e = 0;',
  5675. ' var se = {};',
  5676. ' var sa = {};',
  5677. ' se = rtl.createSet(e);',
  5678. ' sa = rtl.createSet(TSetOfAno$a.up);',
  5679. '};',
  5680. '']),
  5681. LinesToStr([
  5682. '']));
  5683. end;
  5684. procedure TTestModule.TestSet_ForIn;
  5685. begin
  5686. StartProgram(false);
  5687. Add([
  5688. 'type',
  5689. ' TEnum = (Red, Green, Blue);',
  5690. ' TEnumRg = green..blue;',
  5691. ' TSetOfEnum = set of TEnum;',
  5692. ' TSetOfEnumRg = set of TEnumRg;',
  5693. 'var',
  5694. ' e, e2: TEnum;',
  5695. ' er: TEnum;',
  5696. ' s: TSetOfEnum;',
  5697. 'begin',
  5698. ' for e in TSetOfEnum do ;',
  5699. ' for e in TSetOfEnumRg do ;',
  5700. ' for e in [] do e2:=e;',
  5701. ' for e in [red..green] do e2:=e;',
  5702. ' for e in [green,blue] do e2:=e;',
  5703. ' for e in [red,blue] do e2:=e;',
  5704. ' for e in s do e2:=e;',
  5705. ' for er in TSetOfEnumRg do ;',
  5706. '']);
  5707. ConvertProgram;
  5708. CheckSource('TestSet_ForIn',
  5709. LinesToStr([ // statements
  5710. 'this.TEnum = {',
  5711. ' "0":"Red",',
  5712. ' Red:0,',
  5713. ' "1":"Green",',
  5714. ' Green:1,',
  5715. ' "2":"Blue",',
  5716. ' Blue:2',
  5717. ' };',
  5718. 'this.e = 0;',
  5719. 'this.e2 = 0;',
  5720. 'this.er = 0;',
  5721. 'this.s = {};',
  5722. '']),
  5723. LinesToStr([
  5724. 'for ($mod.e = 0; $mod.e <= 2; $mod.e++) ;',
  5725. 'for ($mod.e = 1; $mod.e <= 2; $mod.e++) ;',
  5726. 'for ($mod.e = 0; $mod.e <= 1; $mod.e++) $mod.e2 = $mod.e;',
  5727. 'for ($mod.e = 1; $mod.e <= 2; $mod.e++) $mod.e2 = $mod.e;',
  5728. 'for ($mod.e in rtl.createSet($mod.TEnum.Red, $mod.TEnum.Blue)) $mod.e2 = $mod.e;',
  5729. 'for (var $l1 in $mod.s){',
  5730. ' $mod.e = +$l1;',
  5731. ' $mod.e2 = $mod.e;',
  5732. '};',
  5733. 'for ($mod.er = 1; $mod.er <= 2; $mod.er++) ;',
  5734. '']));
  5735. end;
  5736. procedure TTestModule.TestNestBegin;
  5737. begin
  5738. StartProgram(false);
  5739. Add('begin');
  5740. Add(' begin');
  5741. Add(' begin');
  5742. Add(' end;');
  5743. Add(' begin');
  5744. Add(' if true then ;');
  5745. Add(' end;');
  5746. Add(' end;');
  5747. ConvertProgram;
  5748. CheckSource('TestNestBegin',
  5749. '',
  5750. 'if (true) ;');
  5751. end;
  5752. procedure TTestModule.TestUnitImplVars;
  5753. begin
  5754. StartUnit(false);
  5755. Add('interface');
  5756. Add('implementation');
  5757. Add('var');
  5758. Add(' V1:longint;');
  5759. Add(' V2:longint = 3;');
  5760. Add(' V3:string = ''abc'';');
  5761. ConvertUnit;
  5762. CheckSource('TestUnitImplVars',
  5763. LinesToStr([ // statements
  5764. 'var $impl = $mod.$impl;',
  5765. '']),
  5766. '', // this.$init
  5767. LinesToStr([ // implementation
  5768. '$impl.V1 = 0;',
  5769. '$impl.V2 = 3;',
  5770. '$impl.V3 = "abc";',
  5771. '']) );
  5772. end;
  5773. procedure TTestModule.TestUnitImplConsts;
  5774. begin
  5775. StartUnit(false);
  5776. Add('interface');
  5777. Add('implementation');
  5778. Add('const');
  5779. Add(' v1 = 3;');
  5780. Add(' v2:longint = 4;');
  5781. Add(' v3:string = ''abc'';');
  5782. ConvertUnit;
  5783. CheckSource('TestUnitImplConsts',
  5784. LinesToStr([ // statements
  5785. 'var $impl = $mod.$impl;',
  5786. '']),
  5787. '', // this.$init
  5788. LinesToStr([ // implementation
  5789. '$impl.v1 = 3;',
  5790. '$impl.v2 = 4;',
  5791. '$impl.v3 = "abc";',
  5792. '']) );
  5793. end;
  5794. procedure TTestModule.TestUnitImplRecord;
  5795. begin
  5796. StartUnit(false);
  5797. Add('interface');
  5798. Add('implementation');
  5799. Add('type');
  5800. Add(' TMyRecord = record');
  5801. Add(' i: longint;');
  5802. Add(' end;');
  5803. Add('var aRec: TMyRecord;');
  5804. Add('initialization');
  5805. Add(' arec.i:=3;');
  5806. ConvertUnit;
  5807. CheckSource('TestUnitImplRecord',
  5808. LinesToStr([ // statements
  5809. 'var $impl = $mod.$impl;',
  5810. '']),
  5811. // this.$init
  5812. '$impl.aRec.i = 3;',
  5813. LinesToStr([ // implementation
  5814. 'rtl.recNewT($impl, "TMyRecord", function () {',
  5815. ' this.i = 0;',
  5816. ' this.$eq = function (b) {',
  5817. ' return this.i === b.i;',
  5818. ' };',
  5819. ' this.$assign = function (s) {',
  5820. ' this.i = s.i;',
  5821. ' return this;',
  5822. ' };',
  5823. '});',
  5824. '$impl.aRec = $impl.TMyRecord.$new();',
  5825. '']) );
  5826. end;
  5827. procedure TTestModule.TestRenameJSNameConflict;
  5828. begin
  5829. StartProgram(false);
  5830. Add('var apply: longint;');
  5831. Add('var bind: longint;');
  5832. Add('var call: longint;');
  5833. Add('begin');
  5834. ConvertProgram;
  5835. CheckSource('TestRenameJSNameConflict',
  5836. LinesToStr([ // statements
  5837. 'this.Apply = 0;',
  5838. 'this.Bind = 0;',
  5839. 'this.Call = 0;'
  5840. ]),
  5841. LinesToStr([ // this.$main
  5842. ''
  5843. ]));
  5844. end;
  5845. procedure TTestModule.TestLocalConst;
  5846. begin
  5847. StartProgram(false);
  5848. Add('procedure DoIt;');
  5849. Add('const');
  5850. Add(' cA: longint = 1;');
  5851. Add(' cB = 2;');
  5852. Add(' procedure Sub;');
  5853. Add(' const');
  5854. Add(' csA = 3;');
  5855. Add(' cB: double = 4;');
  5856. Add(' begin');
  5857. Add(' cb:=cb+csa;');
  5858. Add(' ca:=ca+csa+5;');
  5859. Add(' end;');
  5860. Add('begin');
  5861. Add(' ca:=ca+cb+6;');
  5862. Add('end;');
  5863. Add('begin');
  5864. ConvertProgram;
  5865. CheckSource('TestLocalConst',
  5866. LinesToStr([
  5867. 'var cA = 1;',
  5868. 'var cB = 2;',
  5869. 'var csA = 3;',
  5870. 'var cB$1 = 4;',
  5871. 'this.DoIt = function () {',
  5872. ' function Sub() {',
  5873. ' cB$1 = cB$1 + 3;',
  5874. ' cA = cA + 3 + 5;',
  5875. ' };',
  5876. ' cA = cA + 2 + 6;',
  5877. '};'
  5878. ]),
  5879. LinesToStr([
  5880. ]));
  5881. end;
  5882. procedure TTestModule.TestVarExternal;
  5883. begin
  5884. StartProgram(false);
  5885. Add('var');
  5886. Add(' NaN: double; external name ''Global.NaN'';');
  5887. Add(' d: double;');
  5888. Add('begin');
  5889. Add(' d:=NaN;');
  5890. ConvertProgram;
  5891. CheckSource('TestVarExternal',
  5892. LinesToStr([
  5893. 'this.d = 0.0;'
  5894. ]),
  5895. LinesToStr([
  5896. '$mod.d = Global.NaN;'
  5897. ]));
  5898. end;
  5899. procedure TTestModule.TestVarExternalOtherUnit;
  5900. begin
  5901. AddModuleWithIntfImplSrc('unit2.pas',
  5902. LinesToStr([
  5903. 'var NaN: double; external name ''Global.NaN'';',
  5904. 'var iV: longint;'
  5905. ]),
  5906. '');
  5907. StartUnit(true);
  5908. Add('interface');
  5909. Add('uses unit2;');
  5910. Add('implementation');
  5911. Add('var');
  5912. Add(' d: double;');
  5913. Add(' i: longint; external name ''$i'';');
  5914. Add('begin');
  5915. Add(' d:=nan;');
  5916. Add(' d:=uNit2.nan;');
  5917. Add(' d:=test1.d;');
  5918. Add(' i:=iv;');
  5919. Add(' i:=uNit2.iv;');
  5920. Add(' i:=test1.i;');
  5921. ConvertUnit;
  5922. CheckSource('TestVarExternalOtherUnit',
  5923. LinesToStr([
  5924. 'var $impl = $mod.$impl;',
  5925. '']),
  5926. LinesToStr([ // this.$init
  5927. '$impl.d = Global.NaN;',
  5928. '$impl.d = Global.NaN;',
  5929. '$impl.d = $impl.d;',
  5930. '$i = pas.unit2.iV;',
  5931. '$i = pas.unit2.iV;',
  5932. '$i = $i;',
  5933. '']),
  5934. LinesToStr([ // implementation
  5935. '$impl.d = 0.0;',
  5936. '']) );
  5937. end;
  5938. procedure TTestModule.TestVarAbsoluteFail;
  5939. begin
  5940. StartProgram(false);
  5941. Add([
  5942. 'var',
  5943. ' a: longint;',
  5944. ' b: longword absolute a;',
  5945. 'begin']);
  5946. SetExpectedPasResolverError('Invalid variable modifier "absolute"',nInvalidVariableModifier);
  5947. ConvertProgram;
  5948. end;
  5949. procedure TTestModule.TestConstExternal;
  5950. begin
  5951. StartProgram(false);
  5952. Add([
  5953. 'const',
  5954. ' PI: double; external name ''Global.PI'';',
  5955. ' Tau = 2*pi;',
  5956. 'var d: double;',
  5957. 'begin',
  5958. ' d:=pi;',
  5959. ' d:=tau+pi;']);
  5960. ConvertProgram;
  5961. CheckSource('TestConstExternal',
  5962. LinesToStr([
  5963. 'this.Tau = 2*Global.PI;',
  5964. 'this.d = 0.0;'
  5965. ]),
  5966. LinesToStr([
  5967. '$mod.d = Global.PI;',
  5968. '$mod.d = $mod.Tau + Global.PI;'
  5969. ]));
  5970. end;
  5971. procedure TTestModule.TestDouble;
  5972. begin
  5973. StartProgram(false);
  5974. Add([
  5975. 'type',
  5976. ' TDateTime = double;',
  5977. 'const',
  5978. ' a = TDateTime(2.7);',
  5979. ' b = a + TDateTime(1.7);',
  5980. ' c = 0.9 + 0.1;',
  5981. ' f0_1 = 0.1;',
  5982. ' f0_3 = 0.3;',
  5983. ' fn0_1 = -0.1;',
  5984. ' fn0_3 = -0.3;',
  5985. ' fn0_003 = -0.003;',
  5986. ' fn0_123456789 = -0.123456789;',
  5987. ' fn300_0 = -300.0;',
  5988. ' fn123456_0 = -123456.0;',
  5989. ' fn1234567_8 = -1234567.8;',
  5990. ' fn12345678_9 = -12345678.9;',
  5991. ' f1_0En12 = 1E-12;',
  5992. ' fn1_0En12 = -1E-12;',
  5993. ' maxdouble = 1.7e+308;',
  5994. ' mindouble = -1.7e+308;',
  5995. ' MinSafeIntDouble = -$1fffffffffffff;',
  5996. ' MinSafeIntDouble2 = -$20000000000000-1;',
  5997. ' MaxSafeIntDouble = $1fffffffffffff;',
  5998. ' DZeroResolution = 1E-12;',
  5999. ' Minus1 = -1E-12;',
  6000. ' EPS = 1E-9;',
  6001. ' DELTA = 0.001;',
  6002. ' Big = 129.789E+100;',
  6003. ' Test0_15 = 0.15;',
  6004. ' Test999 = 2.9999999999999;',
  6005. ' Test111999 = 211199999999999000.0;',
  6006. ' TestMinus111999 = -211199999999999000.0;',
  6007. 'var',
  6008. ' d: double = b;',
  6009. 'begin',
  6010. ' d:=1.0;',
  6011. ' d:=1.0/3.0;',
  6012. ' d:=1/3;',
  6013. ' d:=5.0E-324;',
  6014. ' d:=1.7E308;',
  6015. ' d:=001.00E00;',
  6016. ' d:=002.00E001;',
  6017. ' d:=003.000E000;',
  6018. ' d:=-004.00E-00;',
  6019. ' d:=-005.00E-001;',
  6020. ' d:=10**3;',
  6021. ' d:=10 mod 3;',
  6022. ' d:=10 div 3;',
  6023. ' d:=c;',
  6024. ' d:=f0_1;',
  6025. ' d:=f0_3;',
  6026. ' d:=fn0_1;',
  6027. ' d:=fn0_3;',
  6028. ' d:=fn0_003;',
  6029. ' d:=fn0_123456789;',
  6030. ' d:=fn300_0;',
  6031. ' d:=fn123456_0;',
  6032. ' d:=fn1234567_8;',
  6033. ' d:=fn12345678_9;',
  6034. ' d:=f1_0En12;',
  6035. ' d:=fn1_0En12;',
  6036. ' d:=maxdouble;',
  6037. ' d:=mindouble;',
  6038. ' d:=MinSafeIntDouble;',
  6039. ' d:=double(MinSafeIntDouble);',
  6040. ' d:=MinSafeIntDouble2;',
  6041. ' d:=double(MinSafeIntDouble2);',
  6042. ' d:=MaxSafeIntDouble;',
  6043. ' d:=default(double);',
  6044. '']);
  6045. ConvertProgram;
  6046. CheckSource('TestDouble',
  6047. LinesToStr([
  6048. 'this.a = 2.7;',
  6049. 'this.b = 2.7 + 1.7;',
  6050. 'this.c = 0.9 + 0.1;',
  6051. 'this.f0_1 = 0.1;',
  6052. 'this.f0_3 = 0.3;',
  6053. 'this.fn0_1 = -0.1;',
  6054. 'this.fn0_3 = -0.3;',
  6055. 'this.fn0_003 = -0.003;',
  6056. 'this.fn0_123456789 = -0.123456789;',
  6057. 'this.fn300_0 = -300.0;',
  6058. 'this.fn123456_0 = -123456.0;',
  6059. 'this.fn1234567_8 = -1234567.8;',
  6060. 'this.fn12345678_9 = -12345678.9;',
  6061. 'this.f1_0En12 = 1E-12;',
  6062. 'this.fn1_0En12 = -1E-12;',
  6063. 'this.maxdouble = 1.7e+308;',
  6064. 'this.mindouble = -1.7e+308;',
  6065. 'this.MinSafeIntDouble = -0x1fffffffffffff;',
  6066. 'this.MinSafeIntDouble2 = -0x20000000000000 - 1;',
  6067. 'this.MaxSafeIntDouble = 0x1fffffffffffff;',
  6068. 'this.DZeroResolution = 1E-12;',
  6069. 'this.Minus1 = -1E-12;',
  6070. 'this.EPS = 1E-9;',
  6071. 'this.DELTA = 0.001;',
  6072. 'this.Big = 129.789E+100;',
  6073. 'this.Test0_15 = 0.15;',
  6074. 'this.Test999 = 2.9999999999999;',
  6075. 'this.Test111999 = 211199999999999000.0;',
  6076. 'this.TestMinus111999 = -211199999999999000.0;',
  6077. 'this.d = 4.4;'
  6078. ]),
  6079. LinesToStr([
  6080. '$mod.d = 1.0;',
  6081. '$mod.d = 1.0 / 3.0;',
  6082. '$mod.d = 1 / 3;',
  6083. '$mod.d = 5.0E-324;',
  6084. '$mod.d = 1.7E308;',
  6085. '$mod.d = 1.00E0;',
  6086. '$mod.d = 2.00E1;',
  6087. '$mod.d = 3.000E0;',
  6088. '$mod.d = -4.00E-0;',
  6089. '$mod.d = -5.00E-1;',
  6090. '$mod.d = Math.pow(10, 3);',
  6091. '$mod.d = 10 % 3;',
  6092. '$mod.d = Math.floor(10 / 3);',
  6093. '$mod.d = 1;',
  6094. '$mod.d = 0.1;',
  6095. '$mod.d = 0.3;',
  6096. '$mod.d = -0.1;',
  6097. '$mod.d = -0.3;',
  6098. '$mod.d = -0.003;',
  6099. '$mod.d = -0.123456789;',
  6100. '$mod.d = -300;',
  6101. '$mod.d = -123456;',
  6102. '$mod.d = -1234567.8;',
  6103. '$mod.d = -1.23456789E7;',
  6104. '$mod.d = 1E-12;',
  6105. '$mod.d = -1E-12;',
  6106. '$mod.d = 1.7E308;',
  6107. '$mod.d = -1.7E308;',
  6108. '$mod.d = -9007199254740991;',
  6109. '$mod.d = -9007199254740991;',
  6110. '$mod.d = -9.007199254740992E15;',
  6111. '$mod.d = -9.007199254740992E15;',
  6112. '$mod.d = 9007199254740991;',
  6113. '$mod.d = 0.0;',
  6114. '']));
  6115. end;
  6116. procedure TTestModule.TestInteger;
  6117. begin
  6118. StartProgram(false);
  6119. Add([
  6120. 'const',
  6121. ' MinInt = low(NativeInt);',
  6122. ' MaxInt = high(NativeInt);',
  6123. 'type',
  6124. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  6125. 'const',
  6126. ' a = low(TMyInt)+High(TMyInt);',
  6127. 'var',
  6128. ' i: TMyInt;',
  6129. 'begin',
  6130. ' i:=-MinInt;',
  6131. ' i:=default(TMyInt);',
  6132. ' i:=low(i)+high(i);',
  6133. '']);
  6134. ConvertProgram;
  6135. CheckSource('TestIntegerRange',
  6136. LinesToStr([
  6137. 'this.MinInt = -9007199254740991;',
  6138. 'this.MaxInt = 9007199254740991;',
  6139. 'this.a = -9007199254740991 + 9007199254740991;',
  6140. 'this.i = 0;',
  6141. '']),
  6142. LinesToStr([
  6143. '$mod.i = - -9007199254740991;',
  6144. '$mod.i = -9007199254740991;',
  6145. '$mod.i = -9007199254740991 + 9007199254740991;',
  6146. '']));
  6147. end;
  6148. procedure TTestModule.TestIntegerRange;
  6149. begin
  6150. StartProgram(false);
  6151. Add([
  6152. 'const',
  6153. ' MinInt = -1;',
  6154. ' MaxInt = +1;',
  6155. 'type',
  6156. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  6157. ' TInt2 = 1..3;',
  6158. 'const',
  6159. ' a = low(TMyInt)+High(TMyInt);',
  6160. ' b = low(TInt2)+High(TInt2);',
  6161. ' s1 = [1];',
  6162. ' s2 = [1,2];',
  6163. ' s3 = [1..3];',
  6164. ' s4 = [low(shortint)..high(shortint)];',
  6165. ' s5 = [succ(low(shortint))..pred(high(shortint))];',
  6166. ' s6 = 1 in s2;',
  6167. 'var',
  6168. ' i: TMyInt;',
  6169. ' i2: TInt2;',
  6170. 'begin',
  6171. ' i:=i2;',
  6172. ' i:=default(TMyInt);',
  6173. ' if i=i2 then ;']);
  6174. ConvertProgram;
  6175. CheckSource('TestIntegerRange',
  6176. LinesToStr([
  6177. 'this.MinInt = -1;',
  6178. 'this.MaxInt = +1;',
  6179. 'this.a = -1 + 1;',
  6180. 'this.b = 1 + 3;',
  6181. 'this.s1 = rtl.createSet(1);',
  6182. 'this.s2 = rtl.createSet(1, 2);',
  6183. 'this.s3 = rtl.createSet(null, 1, 3);',
  6184. 'this.s4 = rtl.createSet(null, -128, 127);',
  6185. 'this.s5 = rtl.createSet(null, -128 + 1, 127 - 1);',
  6186. 'this.s6 = 1 in $mod.s2;',
  6187. 'this.i = 0;',
  6188. 'this.i2 = 0;',
  6189. '']),
  6190. LinesToStr([
  6191. '$mod.i = $mod.i2;',
  6192. '$mod.i = -1;',
  6193. 'if ($mod.i === $mod.i2) ;',
  6194. '']));
  6195. end;
  6196. procedure TTestModule.TestIntegerTypecasts;
  6197. begin
  6198. StartProgram(false);
  6199. Add([
  6200. 'var',
  6201. ' i: nativeint;',
  6202. ' b: byte;',
  6203. ' sh: shortint;',
  6204. ' w: word;',
  6205. ' sm: smallint;',
  6206. ' lw: longword;',
  6207. ' li: longint;',
  6208. 'begin',
  6209. ' b:=byte(i);',
  6210. ' sh:=shortint(i);',
  6211. ' w:=word(i);',
  6212. ' sm:=smallint(i);',
  6213. ' lw:=longword(i);',
  6214. ' li:=longint(i);',
  6215. '']);
  6216. ConvertProgram;
  6217. CheckSource('TestIntegerTypecasts',
  6218. LinesToStr([
  6219. 'this.i = 0;',
  6220. 'this.b = 0;',
  6221. 'this.sh = 0;',
  6222. 'this.w = 0;',
  6223. 'this.sm = 0;',
  6224. 'this.lw = 0;',
  6225. 'this.li = 0;',
  6226. '']),
  6227. LinesToStr([
  6228. '$mod.b = $mod.i & 255;',
  6229. '$mod.sh = (($mod.i & 255) << 24) >> 24;',
  6230. '$mod.w = $mod.i & 65535;',
  6231. '$mod.sm = (($mod.i & 65535) << 16) >> 16;',
  6232. '$mod.lw = $mod.i >>> 0;',
  6233. '$mod.li = $mod.i & 0xFFFFFFFF;',
  6234. '']));
  6235. end;
  6236. procedure TTestModule.TestInteger_BitwiseShrNativeInt;
  6237. begin
  6238. StartProgram(false);
  6239. Add([
  6240. 'var',
  6241. ' i,j: nativeint;',
  6242. 'begin',
  6243. ' i:=i shr 0;',
  6244. ' i:=i shr 1;',
  6245. ' i:=i shr 3;',
  6246. ' i:=i shr 54;',
  6247. ' i:=j shr i;',
  6248. '']);
  6249. ConvertProgram;
  6250. CheckResolverUnexpectedHints;
  6251. CheckSource('TestInteger_BitwiseShrNativeInt',
  6252. LinesToStr([
  6253. 'this.i = 0;',
  6254. 'this.j = 0;',
  6255. '']),
  6256. LinesToStr([
  6257. '$mod.i = $mod.i;',
  6258. '$mod.i = Math.floor($mod.i / 2);',
  6259. '$mod.i = Math.floor($mod.i / 8);',
  6260. '$mod.i = 0;',
  6261. '$mod.i = rtl.shr($mod.j, $mod.i);',
  6262. '']));
  6263. end;
  6264. procedure TTestModule.TestInteger_BitwiseShlNativeInt;
  6265. begin
  6266. StartProgram(false);
  6267. Add([
  6268. 'var',
  6269. ' i: nativeint;',
  6270. 'begin',
  6271. ' i:=i shl 0;',
  6272. ' i:=i shl 54;',
  6273. ' i:=123456789012 shl 1;',
  6274. ' i:=i shl 1;',
  6275. '']);
  6276. ConvertProgram;
  6277. CheckResolverUnexpectedHints;
  6278. CheckSource('TestInteger_BitwiseShrNativeInt',
  6279. LinesToStr([
  6280. 'this.i = 0;',
  6281. '']),
  6282. LinesToStr([
  6283. '$mod.i = $mod.i;',
  6284. '$mod.i = 0;',
  6285. '$mod.i = 246913578024;',
  6286. '$mod.i = rtl.shl($mod.i, 1);',
  6287. '']));
  6288. end;
  6289. procedure TTestModule.TestCurrency;
  6290. begin
  6291. StartProgram(false);
  6292. Add([
  6293. 'type',
  6294. ' TCoin = currency;',
  6295. 'const',
  6296. ' a = TCoin(2.7);',
  6297. ' b = a + TCoin(1.7);',
  6298. ' MinSafeIntCurrency: TCoin = -92233720368.5477;',
  6299. ' MaxSafeIntCurrency: TCoin = 92233720368.5477;',
  6300. 'var',
  6301. ' c: TCoin = b;',
  6302. ' i: nativeint;',
  6303. ' d: double;',
  6304. ' j: jsvalue;',
  6305. 'function DoIt(c: currency): currency; begin end;',
  6306. 'function GetIt(d: double): double; begin end;',
  6307. 'procedure Write(v: jsvalue); begin end;',
  6308. 'begin',
  6309. ' c:=1.0;',
  6310. ' c:=0.1;',
  6311. ' c:=1.0/3.0;',
  6312. ' c:=1/3;',
  6313. ' c:=a;',
  6314. ' d:=c;',
  6315. ' c:=d;',
  6316. ' c:=currency(c);',
  6317. ' c:=currency(d);',
  6318. ' d:=double(c);',
  6319. ' c:=i;',
  6320. ' c:=currency(i);',
  6321. //' i:=c;', not allowed
  6322. ' i:=nativeint(c);',
  6323. ' c:=c+a;',
  6324. ' c:=-c-a;',
  6325. ' c:=d+c;',
  6326. ' c:=c+d;',
  6327. ' c:=d-c;',
  6328. ' c:=c-d;',
  6329. ' c:=c*a;',
  6330. ' c:=a*c;',
  6331. ' c:=d*c;',
  6332. ' c:=c*d;',
  6333. ' c:=c/a;',
  6334. ' c:=a/c;',
  6335. ' c:=d/c;',
  6336. ' c:=c/d;',
  6337. ' c:=c**a;',
  6338. ' c:=a**c;',
  6339. ' c:=d**c;',
  6340. ' c:=c**d;',
  6341. ' if c=c then ;',
  6342. ' if c=a then ;',
  6343. ' if a=c then ;',
  6344. ' if d=c then ;',
  6345. ' if c=d then ;',
  6346. ' c:=DoIt(c);',
  6347. ' c:=DoIt(i);',
  6348. ' c:=DoIt(d);',
  6349. ' c:=GetIt(c);',
  6350. ' j:=c;',
  6351. ' Write(c);',
  6352. ' c:=default(currency);',
  6353. ' j:=str(c);',
  6354. ' j:=str(c:0:3);',
  6355. '']);
  6356. ConvertProgram;
  6357. CheckSource('TestCurrency',
  6358. LinesToStr([
  6359. 'this.a = 27000;',
  6360. 'this.b = $mod.a + 17000;',
  6361. 'this.MinSafeIntCurrency = -92233720368.5477;',
  6362. 'this.MaxSafeIntCurrency = 92233720368.5477;',
  6363. 'this.c = $mod.b;',
  6364. 'this.i = 0;',
  6365. 'this.d = 0.0;',
  6366. 'this.j = undefined;',
  6367. 'this.DoIt = function (c) {',
  6368. ' var Result = 0;',
  6369. ' return Result;',
  6370. '};',
  6371. 'this.GetIt = function (d) {',
  6372. ' var Result = 0.0;',
  6373. ' return Result;',
  6374. '};',
  6375. 'this.Write = function (v) {',
  6376. '};',
  6377. '']),
  6378. LinesToStr([
  6379. '$mod.c = 10000;',
  6380. '$mod.c = 1000;',
  6381. '$mod.c = Math.floor((1.0 / 3.0) * 10000);',
  6382. '$mod.c = Math.floor((1 / 3) * 10000);',
  6383. '$mod.c = $mod.a;',
  6384. '$mod.d = $mod.c / 10000;',
  6385. '$mod.c = Math.floor($mod.d * 10000);',
  6386. '$mod.c = $mod.c;',
  6387. '$mod.c = $mod.d * 10000;',
  6388. '$mod.d = $mod.c / 10000;',
  6389. '$mod.c = $mod.i * 10000;',
  6390. '$mod.c = $mod.i * 10000;',
  6391. '$mod.i = Math.floor($mod.c / 10000);',
  6392. '$mod.c = $mod.c + $mod.a;',
  6393. '$mod.c = -$mod.c - $mod.a;',
  6394. '$mod.c = ($mod.d * 10000) + $mod.c;',
  6395. '$mod.c = $mod.c + ($mod.d * 10000);',
  6396. '$mod.c = ($mod.d * 10000) - $mod.c;',
  6397. '$mod.c = $mod.c - ($mod.d * 10000);',
  6398. '$mod.c = ($mod.c * $mod.a) / 10000;',
  6399. '$mod.c = ($mod.a * $mod.c) / 10000;',
  6400. '$mod.c = $mod.d * $mod.c;',
  6401. '$mod.c = $mod.c * $mod.d;',
  6402. '$mod.c = Math.floor(($mod.c / $mod.a) * 10000);',
  6403. '$mod.c = Math.floor(($mod.a / $mod.c) * 10000);',
  6404. '$mod.c = Math.floor($mod.d / $mod.c);',
  6405. '$mod.c = Math.floor($mod.c / $mod.d);',
  6406. '$mod.c = Math.floor(Math.pow($mod.c / 10000, $mod.a / 10000) * 10000);',
  6407. '$mod.c = Math.floor(Math.pow($mod.a / 10000, $mod.c / 10000) * 10000);',
  6408. '$mod.c = Math.floor(Math.pow($mod.d, $mod.c / 10000) * 10000);',
  6409. '$mod.c = Math.floor(Math.pow($mod.c / 10000, $mod.d) * 10000);',
  6410. 'if ($mod.c === $mod.c) ;',
  6411. 'if ($mod.c === $mod.a) ;',
  6412. 'if ($mod.a === $mod.c) ;',
  6413. 'if (($mod.d * 10000) === $mod.c) ;',
  6414. 'if ($mod.c === ($mod.d * 10000)) ;',
  6415. '$mod.c = $mod.DoIt($mod.c);',
  6416. '$mod.c = $mod.DoIt($mod.i * 10000);',
  6417. '$mod.c = $mod.DoIt($mod.d * 10000);',
  6418. '$mod.c = Math.floor($mod.GetIt($mod.c / 10000) * 10000);',
  6419. '$mod.j = $mod.c / 10000;',
  6420. '$mod.Write($mod.c / 10000);',
  6421. '$mod.c = 0;',
  6422. '$mod.j = rtl.floatToStr($mod.c / 10000);',
  6423. '$mod.j = rtl.floatToStr($mod.c / 10000, 0, 3);',
  6424. '']));
  6425. end;
  6426. procedure TTestModule.TestForBoolDo;
  6427. begin
  6428. StartProgram(false);
  6429. Add([
  6430. 'var b: boolean;',
  6431. 'begin',
  6432. ' for b:=false to true do ;',
  6433. ' for b:=b downto false do ;',
  6434. ' for b in boolean do ;',
  6435. '']);
  6436. ConvertProgram;
  6437. CheckSource('TestForBoolDo',
  6438. LinesToStr([ // statements
  6439. 'this.b = false;']),
  6440. LinesToStr([ // this.$main
  6441. 'for (var $l1 = 0; $l1 <= 1; $l1++) $mod.b = $l1 !== 0;',
  6442. 'for (var $l2 = +$mod.b; $l2 >= 0; $l2--) $mod.b = $l2 !== 0;',
  6443. 'for (var $l3 = 0; $l3 <= 1; $l3++) $mod.b = $l3 !== 0;',
  6444. '']));
  6445. end;
  6446. procedure TTestModule.TestForIntDo;
  6447. begin
  6448. StartProgram(false);
  6449. Add([
  6450. 'var i: longint;',
  6451. 'begin',
  6452. ' for i:=3 to 5 do ;',
  6453. ' for i:=i downto 2 do ;',
  6454. ' for i in byte do ;',
  6455. '']);
  6456. ConvertProgram;
  6457. CheckSource('TestForIntDo',
  6458. LinesToStr([ // statements
  6459. 'this.i = 0;']),
  6460. LinesToStr([ // this.$main
  6461. 'for ($mod.i = 3; $mod.i <= 5; $mod.i++) ;',
  6462. 'for (var $l1 = $mod.i; $l1 >= 2; $l1--) $mod.i = $l1;',
  6463. 'for (var $l2 = 0; $l2 <= 255; $l2++) $mod.i = $l2;',
  6464. '']));
  6465. end;
  6466. procedure TTestModule.TestForIntInDo;
  6467. begin
  6468. StartProgram(false);
  6469. Add([
  6470. 'type',
  6471. ' TSetOfInt = set of byte;',
  6472. ' TIntRg = 3..7;',
  6473. ' TSetOfIntRg = set of TIntRg;',
  6474. 'var',
  6475. ' i,i2: longint;',
  6476. ' a1: array of byte;',
  6477. ' a2: array[1..3] of byte;',
  6478. ' soi: TSetOfInt;',
  6479. ' soir: TSetOfIntRg;',
  6480. ' ir: TIntRg;',
  6481. 'begin',
  6482. ' for i in byte do ;',
  6483. ' for i in a1 do ;',
  6484. ' for i in a2 do ;',
  6485. ' for i in [11..13] do ;',
  6486. ' for i in TSetOfInt do ;',
  6487. ' for i in TIntRg do ;',
  6488. ' for i in soi do i2:=i;',
  6489. ' for i in TSetOfIntRg do ;',
  6490. ' for i in soir do ;',
  6491. ' for ir in TIntRg do ;',
  6492. ' for ir in TSetOfIntRg do ;',
  6493. ' for ir in soir do ;',
  6494. '']);
  6495. ConvertProgram;
  6496. CheckSource('TestForIntInDo',
  6497. LinesToStr([ // statements
  6498. 'this.i = 0;',
  6499. 'this.i2 = 0;',
  6500. 'this.a1 = [];',
  6501. 'this.a2 = rtl.arraySetLength(null, 0, 3);',
  6502. 'this.soi = {};',
  6503. 'this.soir = {};',
  6504. 'this.ir = 0;',
  6505. '']),
  6506. LinesToStr([ // this.$main
  6507. 'for (var $l1 = 0; $l1 <= 255; $l1++) $mod.i = $l1;',
  6508. 'for (var $in2 = $mod.a1, $l3 = 0, $end4 = rtl.length($in2) - 1; $l3 <= $end4; $l3++) $mod.i = $in2[$l3];',
  6509. 'for (var $in5 = $mod.a2, $l6 = 0, $end7 = rtl.length($in5) - 1; $l6 <= $end7; $l6++) $mod.i = $in5[$l6];',
  6510. 'for (var $l8 = 11; $l8 <= 13; $l8++) $mod.i = $l8;',
  6511. 'for (var $l9 = 0; $l9 <= 255; $l9++) $mod.i = $l9;',
  6512. 'for (var $l10 = 3; $l10 <= 7; $l10++) $mod.i = $l10;',
  6513. 'for (var $l11 in $mod.soi) {',
  6514. ' $mod.i = +$l11;',
  6515. ' $mod.i2 = $mod.i;',
  6516. '};',
  6517. 'for (var $l12 = 3; $l12 <= 7; $l12++) $mod.i = $l12;',
  6518. 'for (var $l13 in $mod.soir) $mod.i = +$l13;',
  6519. 'for (var $l14 = 3; $l14 <= 7; $l14++) $mod.ir = $l14;',
  6520. 'for (var $l15 = 3; $l15 <= 7; $l15++) $mod.ir = $l15;',
  6521. 'for (var $l16 in $mod.soir) $mod.ir = +$l16;',
  6522. '']));
  6523. end;
  6524. procedure TTestModule.TestCharConst;
  6525. begin
  6526. StartProgram(false);
  6527. Add([
  6528. 'const',
  6529. ' a = #$00F3;',
  6530. ' c: char = ''1'';',
  6531. 'begin',
  6532. ' c:=#0;',
  6533. ' c:=#1;',
  6534. ' c:=#9;',
  6535. ' c:=#10;',
  6536. ' c:=#13;',
  6537. ' c:=#31;',
  6538. ' c:=#32;',
  6539. ' c:=#$A;',
  6540. ' c:=#$0A;',
  6541. ' c:=#$b;',
  6542. ' c:=#$0b;',
  6543. ' c:=^A;',
  6544. ' c:=''"'';',
  6545. ' c:=default(char);',
  6546. ' c:=#$00E4;', // ä
  6547. ' c:=''ä'';',
  6548. ' c:=#$E4;', // ä
  6549. ' c:=#$D800;', // invalid UTF-16
  6550. ' c:=#$DFFF;', // invalid UTF-16
  6551. ' c:=#$FFFF;', // last UCS-2
  6552. ' c:=high(c);', // last UCS-2
  6553. '']);
  6554. ConvertProgram;
  6555. CheckSource('TestCharConst',
  6556. LinesToStr([
  6557. 'this.a="ó";',
  6558. 'this.c="1";'
  6559. ]),
  6560. LinesToStr([
  6561. '$mod.c="\x00";',
  6562. '$mod.c="\x01";',
  6563. '$mod.c="\t";',
  6564. '$mod.c="\n";',
  6565. '$mod.c="\r";',
  6566. '$mod.c="\x1F";',
  6567. '$mod.c=" ";',
  6568. '$mod.c="\n";',
  6569. '$mod.c="\n";',
  6570. '$mod.c="\x0B";',
  6571. '$mod.c="\x0B";',
  6572. '$mod.c="\x01";',
  6573. '$mod.c=''"'';',
  6574. '$mod.c="\x00";',
  6575. '$mod.c = "ä";',
  6576. '$mod.c = "ä";',
  6577. '$mod.c = "ä";',
  6578. '$mod.c="\uD800";',
  6579. '$mod.c="\uDFFF";',
  6580. '$mod.c="\uFFFF";',
  6581. '$mod.c="\uFFFF";',
  6582. '']));
  6583. end;
  6584. procedure TTestModule.TestChar_Compare;
  6585. begin
  6586. StartProgram(false);
  6587. Add('var');
  6588. Add(' c: char;');
  6589. Add(' b: boolean;');
  6590. Add('begin');
  6591. Add(' b:=c=''1'';');
  6592. Add(' b:=''2''=c;');
  6593. Add(' b:=''3''=''4'';');
  6594. Add(' b:=c<>''5'';');
  6595. Add(' b:=''6''<>c;');
  6596. Add(' b:=c>''7'';');
  6597. Add(' b:=''8''>c;');
  6598. Add(' b:=c>=''9'';');
  6599. Add(' b:=''A''>=c;');
  6600. Add(' b:=c<''B'';');
  6601. Add(' b:=''C''<c;');
  6602. Add(' b:=c<=''D'';');
  6603. Add(' b:=''E''<=c;');
  6604. ConvertProgram;
  6605. CheckSource('TestChar_Compare',
  6606. LinesToStr([
  6607. 'this.c="";',
  6608. 'this.b = false;'
  6609. ]),
  6610. LinesToStr([
  6611. '$mod.b = $mod.c === "1";',
  6612. '$mod.b = "2" === $mod.c;',
  6613. '$mod.b = "3" === "4";',
  6614. '$mod.b = $mod.c !== "5";',
  6615. '$mod.b = "6" !== $mod.c;',
  6616. '$mod.b = $mod.c > "7";',
  6617. '$mod.b = "8" > $mod.c;',
  6618. '$mod.b = $mod.c >= "9";',
  6619. '$mod.b = "A" >= $mod.c;',
  6620. '$mod.b = $mod.c < "B";',
  6621. '$mod.b = "C" < $mod.c;',
  6622. '$mod.b = $mod.c <= "D";',
  6623. '$mod.b = "E" <= $mod.c;',
  6624. '']));
  6625. end;
  6626. procedure TTestModule.TestChar_BuiltInProcs;
  6627. begin
  6628. StartProgram(false);
  6629. Add([
  6630. 'var',
  6631. ' c: char;',
  6632. ' i: longint;',
  6633. ' s: string;',
  6634. 'begin',
  6635. ' i:=ord(c);',
  6636. ' i:=ord(s[i]);',
  6637. ' c:=chr(i);',
  6638. ' c:=pred(c);',
  6639. ' c:=succ(c);',
  6640. ' c:=low(c);',
  6641. ' c:=high(c);',
  6642. ' i:=byte(c);',
  6643. ' i:=word(c);',
  6644. ' i:=longint(c);',
  6645. '']);
  6646. ConvertProgram;
  6647. CheckSource('TestChar_BuiltInProcs',
  6648. LinesToStr([
  6649. 'this.c = "";',
  6650. 'this.i = 0;',
  6651. 'this.s = "";'
  6652. ]),
  6653. LinesToStr([
  6654. '$mod.i = $mod.c.charCodeAt();',
  6655. '$mod.i = $mod.s.charCodeAt($mod.i-1);',
  6656. '$mod.c = String.fromCharCode($mod.i);',
  6657. '$mod.c = String.fromCharCode($mod.c.charCodeAt() - 1);',
  6658. '$mod.c = String.fromCharCode($mod.c.charCodeAt() + 1);',
  6659. '$mod.c = "\x00";',
  6660. '$mod.c = "\uFFFF";',
  6661. '$mod.i = $mod.c.charCodeAt() & 255;',
  6662. '$mod.i = $mod.c.charCodeAt();',
  6663. '$mod.i = $mod.c.charCodeAt() & 0xFFFFFFFF;',
  6664. '']));
  6665. end;
  6666. procedure TTestModule.TestStringConst;
  6667. begin
  6668. StartProgram(false);
  6669. Add([
  6670. '{$H+}',
  6671. 'const',
  6672. ' a = #$00F3#$017C;', // first <256, then >=256
  6673. ' b = string(''a'');',
  6674. ' c = string(''ä'');',
  6675. ' d = UnicodeString(''b'');',
  6676. ' e = UnicodeString(''ö'');',
  6677. 'var',
  6678. ' s: string = ''abc'';',
  6679. 'begin',
  6680. ' s:='''';',
  6681. ' s:=#13#10;',
  6682. ' s:=#9''foo'';',
  6683. ' s:=#$A9;',
  6684. ' s:=''foo''#13''bar'';',
  6685. ' s:=''"'';',
  6686. ' s:=''"''''"'';',
  6687. ' s:=#$20AC;', // euro
  6688. ' s:=#$10437;', // outside BMP
  6689. ' s:=default(string);',
  6690. ' s:=concat(s);',
  6691. ' s:=concat(s,''a'',s)',
  6692. '']);
  6693. ConvertProgram;
  6694. CheckSource('TestStringConst',
  6695. LinesToStr([
  6696. 'this.a = "óż";',
  6697. 'this.b = "a";',
  6698. 'this.c = "ä";',
  6699. 'this.d = "b";',
  6700. 'this.e = "ö";',
  6701. 'this.s="abc";',
  6702. '']),
  6703. LinesToStr([
  6704. '$mod.s="";',
  6705. '$mod.s="\r\n";',
  6706. '$mod.s="\tfoo";',
  6707. '$mod.s="©";',
  6708. '$mod.s="foo\rbar";',
  6709. '$mod.s=''"'';',
  6710. '$mod.s=''"\''"'';',
  6711. '$mod.s="€";',
  6712. '$mod.s="'#$F0#$90#$90#$B7'";',
  6713. '$mod.s="";',
  6714. '$mod.s = $mod.s;',
  6715. '$mod.s = $mod.s.concat("a", $mod.s);',
  6716. '']));
  6717. end;
  6718. procedure TTestModule.TestStringConstSurrogate;
  6719. begin
  6720. StartProgram(false);
  6721. Add([
  6722. 'var',
  6723. ' s: string;',
  6724. 'begin',
  6725. ' s:=''😊'';', // 1F60A
  6726. '']);
  6727. ConvertProgram;
  6728. CheckSource('TestStringConstSurrogate',
  6729. LinesToStr([
  6730. 'this.s="";'
  6731. ]),
  6732. LinesToStr([
  6733. '$mod.s="😊";'
  6734. ]));
  6735. end;
  6736. procedure TTestModule.TestString_Length;
  6737. begin
  6738. StartProgram(false);
  6739. Add('const c = ''foo'';');
  6740. Add('var');
  6741. Add(' s: string;');
  6742. Add(' i: longint;');
  6743. Add('begin');
  6744. Add(' i:=length(s);');
  6745. Add(' i:=length(s+s);');
  6746. Add(' i:=length(''abc'');');
  6747. Add(' i:=length(c);');
  6748. ConvertProgram;
  6749. CheckSource('TestString_Length',
  6750. LinesToStr([
  6751. 'this.c = "foo";',
  6752. 'this.s = "";',
  6753. 'this.i = 0;',
  6754. '']),
  6755. LinesToStr([
  6756. '$mod.i = $mod.s.length;',
  6757. '$mod.i = ($mod.s+$mod.s).length;',
  6758. '$mod.i = "abc".length;',
  6759. '$mod.i = $mod.c.length;',
  6760. '']));
  6761. end;
  6762. procedure TTestModule.TestString_Compare;
  6763. begin
  6764. StartProgram(false);
  6765. Add('var');
  6766. Add(' s, t: string;');
  6767. Add(' b: boolean;');
  6768. Add('begin');
  6769. Add(' b:=s=t;');
  6770. Add(' b:=s<>t;');
  6771. Add(' b:=s>t;');
  6772. Add(' b:=s>=t;');
  6773. Add(' b:=s<t;');
  6774. Add(' b:=s<=t;');
  6775. ConvertProgram;
  6776. CheckSource('TestString_Compare',
  6777. LinesToStr([ // statements
  6778. 'this.s = "";',
  6779. 'this.t = "";',
  6780. 'this.b =false;'
  6781. ]),
  6782. LinesToStr([ // this.$main
  6783. '$mod.b = $mod.s === $mod.t;',
  6784. '$mod.b = $mod.s !== $mod.t;',
  6785. '$mod.b = $mod.s > $mod.t;',
  6786. '$mod.b = $mod.s >= $mod.t;',
  6787. '$mod.b = $mod.s < $mod.t;',
  6788. '$mod.b = $mod.s <= $mod.t;',
  6789. '']));
  6790. end;
  6791. procedure TTestModule.TestString_SetLength;
  6792. begin
  6793. StartProgram(false);
  6794. Add([
  6795. 'procedure DoIt(var s: string);',
  6796. 'begin',
  6797. ' SetLength(s,2);',
  6798. 'end;',
  6799. 'var s: string;',
  6800. 'begin',
  6801. ' SetLength(s,3);',
  6802. '']);
  6803. ConvertProgram;
  6804. CheckSource('TestString_SetLength',
  6805. LinesToStr([ // statements
  6806. 'this.DoIt = function (s) {',
  6807. ' s.set(rtl.strSetLength(s.get(), 2));',
  6808. '};',
  6809. 'this.s = "";',
  6810. '']),
  6811. LinesToStr([ // this.$main
  6812. '$mod.s = rtl.strSetLength($mod.s, 3);'
  6813. ]));
  6814. end;
  6815. procedure TTestModule.TestString_CharAt;
  6816. begin
  6817. StartProgram(false);
  6818. Add([
  6819. 'var',
  6820. ' s: string;',
  6821. ' c: char;',
  6822. ' b: boolean;',
  6823. 'begin',
  6824. ' b:= s[1] = c;',
  6825. ' b:= c = s[1];',
  6826. ' b:= c <> s[1];',
  6827. ' b:= c > s[1];',
  6828. ' b:= c >= s[1];',
  6829. ' b:= c < s[2];',
  6830. ' b:= c <= s[1];',
  6831. ' s[1] := c;',
  6832. ' s[2+3] := c;']);
  6833. ConvertProgram;
  6834. CheckSource('TestString_CharAt',
  6835. LinesToStr([ // statements
  6836. 'this.s = "";',
  6837. 'this.c = "";',
  6838. 'this.b = false;'
  6839. ]),
  6840. LinesToStr([ // this.$main
  6841. '$mod.b = $mod.s.charAt(0) === $mod.c;',
  6842. '$mod.b = $mod.c === $mod.s.charAt(0);',
  6843. '$mod.b = $mod.c !== $mod.s.charAt(0);',
  6844. '$mod.b = $mod.c > $mod.s.charAt(0);',
  6845. '$mod.b = $mod.c >= $mod.s.charAt(0);',
  6846. '$mod.b = $mod.c < $mod.s.charAt(1);',
  6847. '$mod.b = $mod.c <= $mod.s.charAt(0);',
  6848. '$mod.s = rtl.setCharAt($mod.s, 0, $mod.c);',
  6849. '$mod.s = rtl.setCharAt($mod.s, (2 + 3) - 1, $mod.c);',
  6850. '']));
  6851. end;
  6852. procedure TTestModule.TestStringHMinusFail;
  6853. begin
  6854. StartProgram(false);
  6855. Add([
  6856. '{$H-}',
  6857. 'var s: string;',
  6858. 'begin']);
  6859. ConvertProgram;
  6860. CheckHint(mtWarning,nWarnIllegalCompilerDirectiveX,'Warning: test1.pp(3,6) : Illegal compiler directive "H-"');
  6861. end;
  6862. procedure TTestModule.TestStr;
  6863. begin
  6864. StartProgram(false);
  6865. Add('var');
  6866. Add(' b: boolean;');
  6867. Add(' i: longint;');
  6868. Add(' d: double;');
  6869. Add(' s: string;');
  6870. Add('begin');
  6871. Add(' str(b,s);');
  6872. Add(' str(i,s);');
  6873. Add(' str(d,s);');
  6874. Add(' str(i:3,s);');
  6875. Add(' str(d:3:2,s);');
  6876. Add(' Str(12.456:12:1,s);');
  6877. Add(' Str(12.456:12,s);');
  6878. Add(' s:=str(b);');
  6879. Add(' s:=str(i);');
  6880. Add(' s:=str(d);');
  6881. Add(' s:=str(i,i);');
  6882. Add(' s:=str(i:3);');
  6883. Add(' s:=str(d:3:2);');
  6884. Add(' s:=str(i:4,i);');
  6885. Add(' s:=str(i,i:5);');
  6886. Add(' s:=str(i:4,i:5);');
  6887. Add(' s:=str(s,s);');
  6888. Add(' s:=str(s,''foo'');');
  6889. ConvertProgram;
  6890. CheckSource('TestStr',
  6891. LinesToStr([ // statements
  6892. 'this.b = false;',
  6893. 'this.i = 0;',
  6894. 'this.d = 0.0;',
  6895. 'this.s = "";',
  6896. '']),
  6897. LinesToStr([ // this.$main
  6898. '$mod.s = ""+$mod.b;',
  6899. '$mod.s = ""+$mod.i;',
  6900. '$mod.s = rtl.floatToStr($mod.d);',
  6901. '$mod.s = rtl.spaceLeft(""+$mod.i,3);',
  6902. '$mod.s = rtl.floatToStr($mod.d,3,2);',
  6903. '$mod.s = rtl.floatToStr(12.456,12,1);',
  6904. '$mod.s = rtl.floatToStr(12.456,12);',
  6905. '$mod.s = ""+$mod.b;',
  6906. '$mod.s = ""+$mod.i;',
  6907. '$mod.s = rtl.floatToStr($mod.d);',
  6908. '$mod.s = ""+$mod.i+$mod.i;',
  6909. '$mod.s = rtl.spaceLeft(""+$mod.i,3);',
  6910. '$mod.s = rtl.floatToStr($mod.d,3,2);',
  6911. '$mod.s = rtl.spaceLeft("" + $mod.i, 4) + $mod.i;',
  6912. '$mod.s = "" + $mod.i + rtl.spaceLeft("" + $mod.i, 5);',
  6913. '$mod.s = rtl.spaceLeft("" + $mod.i, 4) + rtl.spaceLeft("" + $mod.i, 5);',
  6914. '$mod.s = $mod.s + $mod.s;',
  6915. '$mod.s = $mod.s + "foo";',
  6916. '']));
  6917. end;
  6918. procedure TTestModule.TestBaseType_AnsiStringFail;
  6919. begin
  6920. StartProgram(false);
  6921. Add('var s: AnsiString');
  6922. SetExpectedPasResolverError('identifier not found "AnsiString"',PasResolveEval.nIdentifierNotFound);
  6923. ConvertProgram;
  6924. end;
  6925. procedure TTestModule.TestBaseType_WideStringFail;
  6926. begin
  6927. StartProgram(false);
  6928. Add('var s: WideString');
  6929. SetExpectedPasResolverError('identifier not found "WideString"',PasResolveEval.nIdentifierNotFound);
  6930. ConvertProgram;
  6931. end;
  6932. procedure TTestModule.TestBaseType_ShortStringFail;
  6933. begin
  6934. StartProgram(false);
  6935. Add('var s: ShortString');
  6936. SetExpectedPasResolverError('identifier not found "ShortString"',PasResolveEval.nIdentifierNotFound);
  6937. ConvertProgram;
  6938. end;
  6939. procedure TTestModule.TestBaseType_RawByteStringFail;
  6940. begin
  6941. StartProgram(false);
  6942. Add('var s: RawByteString');
  6943. SetExpectedPasResolverError('identifier not found "RawByteString"',PasResolveEval.nIdentifierNotFound);
  6944. ConvertProgram;
  6945. end;
  6946. procedure TTestModule.TestTypeShortstring_Fail;
  6947. begin
  6948. StartProgram(false);
  6949. Add('type t = string[12];');
  6950. Add('var s: t;');
  6951. Add('begin');
  6952. SetExpectedPasResolverError('illegal qualifier "["',nIllegalQualifier);
  6953. ConvertProgram;
  6954. end;
  6955. procedure TTestModule.TestCharSet_Custom;
  6956. begin
  6957. StartProgram(false);
  6958. Add([
  6959. 'type',
  6960. ' TCharRg = ''a''..''z'';',
  6961. ' TSetOfCharRg = set of TCharRg;',
  6962. ' TCharRg2 = ''m''..''p'';',
  6963. 'const',
  6964. ' crg: TCharRg = ''b'';',
  6965. 'var',
  6966. ' c: char;',
  6967. ' crg2: TCharRg2;',
  6968. ' s: TSetOfCharRg;',
  6969. 'begin',
  6970. ' c:=crg;',
  6971. ' crg:=c;',
  6972. ' crg2:=crg;',
  6973. ' if c=crg then ;',
  6974. ' if crg=c then ;',
  6975. ' if crg=crg2 then ;',
  6976. ' if c in s then ;',
  6977. ' if crg2 in s then ;',
  6978. ' c:=default(TCharRg);',
  6979. '']);
  6980. ConvertProgram;
  6981. CheckSource('TestCharSet_Custom',
  6982. LinesToStr([ // statements
  6983. 'this.crg = "b";',
  6984. 'this.c = "";',
  6985. 'this.crg2 = "m";',
  6986. 'this.s = {};',
  6987. '']),
  6988. LinesToStr([ // this.$main
  6989. '$mod.c = $mod.crg;',
  6990. '$mod.crg = $mod.c;',
  6991. '$mod.crg2 = $mod.crg;',
  6992. 'if ($mod.c === $mod.crg) ;',
  6993. 'if ($mod.crg === $mod.c) ;',
  6994. 'if ($mod.crg === $mod.crg2) ;',
  6995. 'if ($mod.c.charCodeAt() in $mod.s) ;',
  6996. 'if ($mod.crg2.charCodeAt() in $mod.s) ;',
  6997. '$mod.c = "a";',
  6998. '']));
  6999. end;
  7000. procedure TTestModule.TestForCharDo;
  7001. begin
  7002. StartProgram(false);
  7003. Add([
  7004. 'var c: char;',
  7005. 'begin',
  7006. ' for c:=''a'' to ''c'' do ;',
  7007. ' for c:=c downto ''a'' do ;',
  7008. ' for c:=''Б'' to ''Я'' do ;',
  7009. '']);
  7010. ConvertProgram;
  7011. CheckSource('TestForCharDo',
  7012. LinesToStr([ // statements
  7013. 'this.c = "";']),
  7014. LinesToStr([ // this.$main
  7015. 'for (var $l1 = 97; $l1 <= 99; $l1++) $mod.c = String.fromCharCode($l1);',
  7016. 'for (var $l2 = $mod.c.charCodeAt(); $l2 >= 97; $l2--) $mod.c = String.fromCharCode($l2);',
  7017. 'for (var $l3 = 1041; $l3 <= 1071; $l3++) $mod.c = String.fromCharCode($l3);',
  7018. '']));
  7019. end;
  7020. procedure TTestModule.TestForCharInDo;
  7021. begin
  7022. StartProgram(false);
  7023. Add([
  7024. 'type',
  7025. ' TSetOfChar = set of char;',
  7026. ' TCharRg = ''a''..''z'';',
  7027. ' TSetOfCharRg = set of TCharRg;',
  7028. 'const Foo = ''foo'';',
  7029. 'var',
  7030. ' c,c2: char;',
  7031. ' s: string;',
  7032. ' a1: array of char;',
  7033. ' a2: array[1..3] of char;',
  7034. ' soc: TSetOfChar;',
  7035. ' socr: TSetOfCharRg;',
  7036. ' cr: TCharRg;',
  7037. 'begin',
  7038. ' for c in foo do ;',
  7039. ' for c in s do ;',
  7040. ' for c in char do ;',
  7041. ' for c in a1 do ;',
  7042. ' for c in a2 do ;',
  7043. ' for c in [''1''..''3''] do ;',
  7044. ' for c in TSetOfChar do ;',
  7045. ' for c in TCharRg do ;',
  7046. ' for c in soc do c2:=c;',
  7047. ' for c in TSetOfCharRg do ;',
  7048. ' for c in socr do ;',
  7049. ' for cr in TCharRg do ;',
  7050. ' for cr in TSetOfCharRg do ;',
  7051. ' for cr in socr do ;',
  7052. '']);
  7053. ConvertProgram;
  7054. CheckSource('TestForCharInDo',
  7055. LinesToStr([ // statements
  7056. 'this.Foo = "foo";',
  7057. 'this.c = "";',
  7058. 'this.c2 = "";',
  7059. 'this.s = "";',
  7060. 'this.a1 = [];',
  7061. 'this.a2 = rtl.arraySetLength(null, "", 3);',
  7062. 'this.soc = {};',
  7063. 'this.socr = {};',
  7064. 'this.cr = "a";',
  7065. '']),
  7066. LinesToStr([ // this.$main
  7067. 'for (var $in1 = $mod.Foo, $l2 = 0, $end3 = $in1.length - 1; $l2 <= $end3; $l2++) $mod.c = $in1.charAt($l2);',
  7068. 'for (var $in4 = $mod.s, $l5 = 0, $end6 = $in4.length - 1; $l5 <= $end6; $l5++) $mod.c = $in4.charAt($l5);',
  7069. 'for (var $l7 = 0; $l7 <= 65535; $l7++) $mod.c = String.fromCharCode($l7);',
  7070. 'for (var $in8 = $mod.a1, $l9 = 0, $end10 = rtl.length($in8) - 1; $l9 <= $end10; $l9++) $mod.c = $in8[$l9];',
  7071. 'for (var $in11 = $mod.a2, $l12 = 0, $end13 = rtl.length($in11) - 1; $l12 <= $end13; $l12++) $mod.c = $in11[$l12];',
  7072. 'for (var $l14 = 49; $l14 <= 51; $l14++) $mod.c = String.fromCharCode($l14);',
  7073. 'for (var $l15 = 0; $l15 <= 65535; $l15++) $mod.c = String.fromCharCode($l15);',
  7074. 'for (var $l16 = 97; $l16 <= 122; $l16++) $mod.c = String.fromCharCode($l16);',
  7075. 'for (var $l17 in $mod.soc) {',
  7076. ' $mod.c = String.fromCharCode($l17);',
  7077. ' $mod.c2 = $mod.c;',
  7078. '};',
  7079. 'for (var $l18 = 97; $l18 <= 122; $l18++) $mod.c = String.fromCharCode($l18);',
  7080. 'for (var $l19 in $mod.socr) $mod.c = String.fromCharCode($l19);',
  7081. 'for (var $l20 = 97; $l20 <= 122; $l20++) $mod.cr = String.fromCharCode($l20);',
  7082. 'for (var $l21 = 97; $l21 <= 122; $l21++) $mod.cr = String.fromCharCode($l21);',
  7083. 'for (var $l22 in $mod.socr) $mod.cr = String.fromCharCode($l22);',
  7084. '']));
  7085. end;
  7086. procedure TTestModule.TestProcTwoArgs;
  7087. begin
  7088. StartProgram(false);
  7089. Add('procedure Test(a,b: longint);');
  7090. Add('begin');
  7091. Add('end;');
  7092. Add('begin');
  7093. ConvertProgram;
  7094. CheckSource('TestProcTwoArgs',
  7095. LinesToStr([ // statements
  7096. 'this.Test = function (a,b) {',
  7097. '};'
  7098. ]),
  7099. LinesToStr([ // this.$main
  7100. ''
  7101. ]));
  7102. end;
  7103. procedure TTestModule.TestProc_DefaultValue;
  7104. begin
  7105. StartProgram(false);
  7106. Add('procedure p1(i: longint = 1);');
  7107. Add('begin');
  7108. Add('end;');
  7109. Add('procedure p2(i: longint = 1; c: char = ''a'');');
  7110. Add('begin');
  7111. Add('end;');
  7112. Add('procedure p3(d: double = 1.0; b: boolean = false; s: string = ''abc'');');
  7113. Add('begin');
  7114. Add('end;');
  7115. Add('begin');
  7116. Add(' p1;');
  7117. Add(' p1();');
  7118. Add(' p1(11);');
  7119. Add(' p2;');
  7120. Add(' p2();');
  7121. Add(' p2(12);');
  7122. Add(' p2(13,''b'');');
  7123. Add(' p3();');
  7124. ConvertProgram;
  7125. CheckSource('TestProc_DefaultValue',
  7126. LinesToStr([ // statements
  7127. 'this.p1 = function (i) {',
  7128. '};',
  7129. 'this.p2 = function (i,c) {',
  7130. '};',
  7131. 'this.p3 = function (d,b,s) {',
  7132. '};'
  7133. ]),
  7134. LinesToStr([ // this.$main
  7135. ' $mod.p1(1);',
  7136. ' $mod.p1(1);',
  7137. ' $mod.p1(11);',
  7138. ' $mod.p2(1,"a");',
  7139. ' $mod.p2(1,"a");',
  7140. ' $mod.p2(12,"a");',
  7141. ' $mod.p2(13,"b");',
  7142. ' $mod.p3(1.0,false,"abc");'
  7143. ]));
  7144. end;
  7145. procedure TTestModule.TestFunctionInt;
  7146. begin
  7147. StartProgram(false);
  7148. Add('function MyTest(Bar: longint): longint;');
  7149. Add('begin');
  7150. Add(' Result:=2*bar');
  7151. Add('end;');
  7152. Add('begin');
  7153. ConvertProgram;
  7154. CheckSource('TestFunctionInt',
  7155. LinesToStr([ // statements
  7156. 'this.MyTest = function (Bar) {',
  7157. ' var Result = 0;',
  7158. ' Result = 2*Bar;',
  7159. ' return Result;',
  7160. '};'
  7161. ]),
  7162. LinesToStr([ // this.$main
  7163. ''
  7164. ]));
  7165. end;
  7166. procedure TTestModule.TestFunctionString;
  7167. begin
  7168. StartProgram(false);
  7169. Add('function Test(Bar: string): string;');
  7170. Add('begin');
  7171. Add(' Result:=bar+BAR');
  7172. Add('end;');
  7173. Add('begin');
  7174. ConvertProgram;
  7175. CheckSource('TestFunctionString',
  7176. LinesToStr([ // statements
  7177. 'this.Test = function (Bar) {',
  7178. ' var Result = "";',
  7179. ' Result = Bar+Bar;',
  7180. ' return Result;',
  7181. '};'
  7182. ]),
  7183. LinesToStr([ // this.$main
  7184. ''
  7185. ]));
  7186. end;
  7187. procedure TTestModule.TestIfThen;
  7188. begin
  7189. StartProgram(false);
  7190. Add([
  7191. 'var b: boolean;',
  7192. 'begin',
  7193. ' if b then ;',
  7194. ' if b then else ;']);
  7195. ConvertProgram;
  7196. CheckSource('TestIfThen',
  7197. LinesToStr([ // statements
  7198. 'this.b = false;',
  7199. '']),
  7200. LinesToStr([ // this.$main
  7201. 'if ($mod.b) ;',
  7202. 'if ($mod.b) ;',
  7203. '']));
  7204. end;
  7205. procedure TTestModule.TestForLoop;
  7206. begin
  7207. StartProgram(false);
  7208. Add('var');
  7209. Add(' vI, vJ, vN: longint;');
  7210. Add('begin');
  7211. Add(' VJ:=0;');
  7212. Add(' VN:=3;');
  7213. Add(' for VI:=1 to VN do');
  7214. Add(' begin');
  7215. Add(' VJ:=VJ+VI;');
  7216. Add(' end;');
  7217. ConvertProgram;
  7218. CheckSource('TestForLoop',
  7219. LinesToStr([ // statements
  7220. 'this.vI = 0;',
  7221. 'this.vJ = 0;',
  7222. 'this.vN = 0;'
  7223. ]),
  7224. LinesToStr([ // this.$main
  7225. ' $mod.vJ = 0;',
  7226. ' $mod.vN = 3;',
  7227. ' for (var $l1 = 1, $end2 = $mod.vN; $l1 <= $end2; $l1++) {',
  7228. ' $mod.vI = $l1;',
  7229. ' $mod.vJ = $mod.vJ + $mod.vI;',
  7230. ' };',
  7231. '']));
  7232. end;
  7233. procedure TTestModule.TestForLoopInsideFunction;
  7234. begin
  7235. StartProgram(false);
  7236. Add('function SumNumbers(Count: longint): longint;');
  7237. Add('var');
  7238. Add(' vI, vJ: longint;');
  7239. Add('begin');
  7240. Add(' vj:=0;');
  7241. Add(' for vi:=1 to count do');
  7242. Add(' begin');
  7243. Add(' vj:=vj+vi;');
  7244. Add(' end;');
  7245. Add('end;');
  7246. Add('begin');
  7247. Add(' sumnumbers(3);');
  7248. ConvertProgram;
  7249. CheckSource('TestForLoopInsideFunction',
  7250. LinesToStr([ // statements
  7251. 'this.SumNumbers = function (Count) {',
  7252. ' var Result = 0;',
  7253. ' var vI = 0;',
  7254. ' var vJ = 0;',
  7255. ' vJ = 0;',
  7256. ' for (var $l1 = 1, $end2 = Count; $l1 <= $end2; $l1++) {',
  7257. ' vI = $l1;',
  7258. ' vJ = vJ + vI;',
  7259. ' };',
  7260. ' return Result;',
  7261. '};'
  7262. ]),
  7263. LinesToStr([ // $mod.$main
  7264. ' $mod.SumNumbers(3);'
  7265. ]));
  7266. end;
  7267. procedure TTestModule.TestForLoop_ReadVarAfter;
  7268. begin
  7269. StartProgram(false);
  7270. Add('var');
  7271. Add(' vI: longint;');
  7272. Add('begin');
  7273. Add(' for vi:=1 to 2 do ;');
  7274. Add(' if vi=3 then ;');
  7275. ConvertProgram;
  7276. CheckSource('TestForLoop',
  7277. LinesToStr([ // statements
  7278. 'this.vI = 0;'
  7279. ]),
  7280. LinesToStr([ // this.$main
  7281. ' for ($mod.vI = 1; $mod.vI <= 2; $mod.vI++) ;',
  7282. ' if ($mod.vI===3) ;'
  7283. ]));
  7284. end;
  7285. procedure TTestModule.TestForLoop_Nested;
  7286. begin
  7287. StartProgram(false);
  7288. Add('function SumNumbers(Count: longint): longint;');
  7289. Add('var');
  7290. Add(' vI, vJ, vK: longint;');
  7291. Add('begin');
  7292. Add(' VK:=0;');
  7293. Add(' for VI:=1 to count do');
  7294. Add(' begin');
  7295. Add(' for vj:=1 to vi do');
  7296. Add(' begin');
  7297. Add(' vk:=VK+VI;');
  7298. Add(' end;');
  7299. Add(' end;');
  7300. Add('end;');
  7301. Add('begin');
  7302. Add(' sumnumbers(3);');
  7303. ConvertProgram;
  7304. CheckSource('TestForLoopInFunction',
  7305. LinesToStr([ // statements
  7306. 'this.SumNumbers = function (Count) {',
  7307. ' var Result = 0;',
  7308. ' var vI = 0;',
  7309. ' var vJ = 0;',
  7310. ' var vK = 0;',
  7311. ' vK = 0;',
  7312. ' for (var $l1 = 1, $end2 = Count; $l1 <= $end2; $l1++) {',
  7313. ' vI = $l1;',
  7314. ' for (var $l3 = 1, $end4 = vI; $l3 <= $end4; $l3++) {',
  7315. ' vJ = $l3;',
  7316. ' vK = vK + vI;',
  7317. ' };',
  7318. ' };',
  7319. ' return Result;',
  7320. '};'
  7321. ]),
  7322. LinesToStr([ // $mod.$main
  7323. ' $mod.SumNumbers(3);'
  7324. ]));
  7325. end;
  7326. procedure TTestModule.TestRepeatUntil;
  7327. begin
  7328. StartProgram(false);
  7329. Add('var');
  7330. Add(' vI, vJ, vN: longint;');
  7331. Add('begin');
  7332. Add(' vn:=3;');
  7333. Add(' vj:=0;');
  7334. Add(' VI:=0;');
  7335. Add(' repeat');
  7336. Add(' VI:=vi+1;');
  7337. Add(' vj:=VJ+vI;');
  7338. Add(' until vi>=vn');
  7339. ConvertProgram;
  7340. CheckSource('TestRepeatUntil',
  7341. LinesToStr([ // statements
  7342. 'this.vI = 0;',
  7343. 'this.vJ = 0;',
  7344. 'this.vN = 0;'
  7345. ]),
  7346. LinesToStr([ // $mod.$main
  7347. ' $mod.vN = 3;',
  7348. ' $mod.vJ = 0;',
  7349. ' $mod.vI = 0;',
  7350. ' do{',
  7351. ' $mod.vI = $mod.vI + 1;',
  7352. ' $mod.vJ = $mod.vJ + $mod.vI;',
  7353. ' }while(!($mod.vI>=$mod.vN));'
  7354. ]));
  7355. end;
  7356. procedure TTestModule.TestAsmBlock;
  7357. begin
  7358. StartProgram(false);
  7359. Add([
  7360. 'var',
  7361. ' vI: longint;',
  7362. 'begin',
  7363. ' vi:=1;',
  7364. ' asm',
  7365. ' if (vI===1) {',
  7366. ' vI=2;',
  7367. //' console.log(''end;'');', ToDo
  7368. ' }',
  7369. ' if (vI===2){ vI=3; }',
  7370. ' end;',
  7371. ' VI:=4;']);
  7372. ConvertProgram;
  7373. CheckSource('TestAsmBlock',
  7374. LinesToStr([ // statements
  7375. 'this.vI = 0;'
  7376. ]),
  7377. LinesToStr([ // $mod.$main
  7378. '$mod.vI = 1;',
  7379. 'if (vI===1) {',
  7380. ' vI=2;',
  7381. '}',
  7382. 'if (vI===2){ vI=3; }',
  7383. ';',
  7384. '$mod.vI = 4;'
  7385. ]));
  7386. end;
  7387. procedure TTestModule.TestAsmPas_Impl;
  7388. begin
  7389. StartUnit(false);
  7390. Add('interface');
  7391. Add('const cIntf: longint = 1;');
  7392. Add('var vIntf: longint;');
  7393. Add('implementation');
  7394. Add('const cImpl: longint = 2;');
  7395. Add('var vImpl: longint;');
  7396. Add('procedure DoIt;');
  7397. Add('const cLoc: longint = 3;');
  7398. Add('var vLoc: longint;');
  7399. Add('begin;');
  7400. Add(' asm');
  7401. //Add(' pas(vIntf)=pas(cIntf);');
  7402. //Add(' pas(vImpl)=pas(cImpl);');
  7403. //Add(' pas(vLoc)=pas(cLoc);');
  7404. Add(' end;');
  7405. Add('end;');
  7406. ConvertUnit;
  7407. CheckSource('TestAsmPas_Impl',
  7408. LinesToStr([
  7409. 'var $impl = $mod.$impl;',
  7410. 'this.cIntf = 1;',
  7411. 'this.vIntf = 0;',
  7412. '']),
  7413. '', // this.$init
  7414. LinesToStr([ // implementation
  7415. '$impl.cImpl = 2;',
  7416. '$impl.vImpl = 0;',
  7417. 'var cLoc = 3;',
  7418. '$impl.DoIt = function () {',
  7419. ' var vLoc = 0;',
  7420. '};',
  7421. '']) );
  7422. end;
  7423. procedure TTestModule.TestTryFinally;
  7424. begin
  7425. StartProgram(false);
  7426. Add('var i: longint;');
  7427. Add('begin');
  7428. Add(' try');
  7429. Add(' i:=0; i:=2 div i;');
  7430. Add(' finally');
  7431. Add(' i:=3');
  7432. Add(' end;');
  7433. ConvertProgram;
  7434. CheckSource('TestTryFinally',
  7435. LinesToStr([ // statements
  7436. 'this.i = 0;'
  7437. ]),
  7438. LinesToStr([ // $mod.$main
  7439. 'try {',
  7440. ' $mod.i = 0;',
  7441. ' $mod.i = Math.floor(2 / $mod.i);',
  7442. '} finally {',
  7443. ' $mod.i = 3;',
  7444. '};'
  7445. ]));
  7446. end;
  7447. procedure TTestModule.TestTryExcept;
  7448. begin
  7449. StartProgram(false);
  7450. Add('type');
  7451. Add(' TObject = class end;');
  7452. Add(' Exception = class Msg: string; end;');
  7453. Add(' EInvalidCast = class(Exception) end;');
  7454. Add('var vI: longint;');
  7455. Add('begin');
  7456. Add(' try');
  7457. Add(' vi:=1;');
  7458. Add(' except');
  7459. Add(' vi:=2');
  7460. Add(' end;');
  7461. Add(' try');
  7462. Add(' vi:=3;');
  7463. Add(' except');
  7464. Add(' raise;');
  7465. Add(' end;');
  7466. Add(' try');
  7467. Add(' VI:=4;');
  7468. Add(' except');
  7469. Add(' on einvalidcast do');
  7470. Add(' raise;');
  7471. Add(' on E: exception do');
  7472. Add(' if e.msg='''' then');
  7473. Add(' raise e;');
  7474. Add(' else');
  7475. Add(' vi:=5');
  7476. Add(' end;');
  7477. Add(' try');
  7478. Add(' VI:=6;');
  7479. Add(' except');
  7480. Add(' on einvalidcast do ;');
  7481. Add(' end;');
  7482. ConvertProgram;
  7483. CheckSource('TestTryExcept',
  7484. LinesToStr([ // statements
  7485. 'rtl.createClass($mod, "TObject", null, function () {',
  7486. ' this.$init = function () {',
  7487. ' };',
  7488. ' this.$final = function () {',
  7489. ' };',
  7490. '});',
  7491. 'rtl.createClass($mod, "Exception", $mod.TObject, function () {',
  7492. ' this.$init = function () {',
  7493. ' $mod.TObject.$init.call(this);',
  7494. ' this.Msg = "";',
  7495. ' };',
  7496. '});',
  7497. 'rtl.createClass($mod, "EInvalidCast", $mod.Exception, function () {',
  7498. '});',
  7499. 'this.vI = 0;'
  7500. ]),
  7501. LinesToStr([ // $mod.$main
  7502. 'try {',
  7503. ' $mod.vI = 1;',
  7504. '} catch ($e) {',
  7505. ' $mod.vI = 2;',
  7506. '};',
  7507. 'try {',
  7508. ' $mod.vI = 3;',
  7509. '} catch ($e) {',
  7510. ' throw $e;',
  7511. '};',
  7512. 'try {',
  7513. ' $mod.vI = 4;',
  7514. '} catch ($e) {',
  7515. ' if ($mod.EInvalidCast.isPrototypeOf($e)){',
  7516. ' throw $e',
  7517. ' } else if ($mod.Exception.isPrototypeOf($e)) {',
  7518. ' var E = $e;',
  7519. ' if (E.Msg === "") throw E;',
  7520. ' } else {',
  7521. ' $mod.vI = 5;',
  7522. ' }',
  7523. '};',
  7524. 'try {',
  7525. ' $mod.vI = 6;',
  7526. '} catch ($e) {',
  7527. ' if ($mod.EInvalidCast.isPrototypeOf($e)){' ,
  7528. ' } else throw $e',
  7529. '};',
  7530. '']));
  7531. end;
  7532. procedure TTestModule.TestTryExcept_ReservedWords;
  7533. begin
  7534. StartProgram(false);
  7535. Add([
  7536. 'type',
  7537. ' TObject = class end;',
  7538. ' Exception = class',
  7539. ' Symbol: string;',
  7540. ' end;',
  7541. 'var &try: longint;',
  7542. 'begin',
  7543. ' try',
  7544. ' &try:=4;',
  7545. ' except',
  7546. ' on Error: exception do',
  7547. ' if errOR.symBol='''' then',
  7548. ' raise ERRor;',
  7549. ' end;',
  7550. '']);
  7551. ConvertProgram;
  7552. CheckSource('TestTryExcept_ReservedWords',
  7553. LinesToStr([ // statements
  7554. 'rtl.createClass($mod, "TObject", null, function () {',
  7555. ' this.$init = function () {',
  7556. ' };',
  7557. ' this.$final = function () {',
  7558. ' };',
  7559. '});',
  7560. 'rtl.createClass($mod, "Exception", $mod.TObject, function () {',
  7561. ' this.$init = function () {',
  7562. ' $mod.TObject.$init.call(this);',
  7563. ' this.Symbol = "";',
  7564. ' };',
  7565. '});',
  7566. 'this.Try = 0;',
  7567. '']),
  7568. LinesToStr([ // $mod.$main
  7569. 'try {',
  7570. ' $mod.Try = 4;',
  7571. '} catch ($e) {',
  7572. ' if ($mod.Exception.isPrototypeOf($e)) {',
  7573. ' var error = $e;',
  7574. ' if (error.Symbol === "") throw error;',
  7575. ' } else throw $e',
  7576. '};',
  7577. '']));
  7578. end;
  7579. procedure TTestModule.TestIfThenRaiseElse;
  7580. begin
  7581. StartProgram(false);
  7582. Add([
  7583. 'type',
  7584. ' TObject = class',
  7585. ' constructor Create;',
  7586. ' end;',
  7587. 'constructor TObject.Create;',
  7588. 'begin',
  7589. 'end;',
  7590. 'var b: boolean;',
  7591. 'begin',
  7592. ' if b then',
  7593. ' raise TObject.Create',
  7594. ' else',
  7595. ' b:=false;',
  7596. '']);
  7597. ConvertProgram;
  7598. CheckSource('TestIfThenRaiseElse',
  7599. LinesToStr([ // statements
  7600. 'rtl.createClass($mod, "TObject", null, function () {',
  7601. ' this.$init = function () {',
  7602. ' };',
  7603. ' this.$final = function () {',
  7604. ' };',
  7605. ' this.Create = function () {',
  7606. ' return this;',
  7607. ' };',
  7608. '});',
  7609. 'this.b = false;',
  7610. '']),
  7611. LinesToStr([ // $mod.$main
  7612. 'if ($mod.b) {',
  7613. ' throw $mod.TObject.$create("Create")}',
  7614. ' else $mod.b = false;',
  7615. '']));
  7616. end;
  7617. procedure TTestModule.TestCaseOf;
  7618. begin
  7619. StartProgram(false);
  7620. Add([
  7621. 'const e: longint; external name ''$e'';',
  7622. 'var vI: longint;',
  7623. 'begin',
  7624. ' case vi of',
  7625. ' 1: ;',
  7626. ' 2: vi:=3;',
  7627. ' e: ;',
  7628. ' else',
  7629. ' VI:=4',
  7630. ' end;']);
  7631. ConvertProgram;
  7632. CheckSource('TestCaseOf',
  7633. LinesToStr([ // statements
  7634. 'this.vI = 0;'
  7635. ]),
  7636. LinesToStr([ // $mod.$main
  7637. 'var $tmp1 = $mod.vI;',
  7638. 'if ($tmp1 === 1) {}',
  7639. 'else if ($tmp1 === 2) {',
  7640. ' $mod.vI = 3}',
  7641. ' else if ($tmp1 === $e) {}',
  7642. 'else {',
  7643. ' $mod.vI = 4;',
  7644. '};'
  7645. ]));
  7646. end;
  7647. procedure TTestModule.TestCaseOf_UseSwitch;
  7648. begin
  7649. StartProgram(false);
  7650. Converter.UseSwitchStatement:=true;
  7651. Add('var Vi: longint;');
  7652. Add('begin');
  7653. Add(' case vi of');
  7654. Add(' 1: ;');
  7655. Add(' 2: VI:=3;');
  7656. Add(' else');
  7657. Add(' vi:=4');
  7658. Add(' end;');
  7659. ConvertProgram;
  7660. CheckSource('TestCaseOf_UseSwitch',
  7661. LinesToStr([ // statements
  7662. 'this.Vi = 0;'
  7663. ]),
  7664. LinesToStr([ // $mod.$main
  7665. 'switch ($mod.Vi) {',
  7666. 'case 1:',
  7667. ' break;',
  7668. 'case 2:',
  7669. ' $mod.Vi = 3;',
  7670. ' break;',
  7671. 'default:',
  7672. ' $mod.Vi = 4;',
  7673. '};'
  7674. ]));
  7675. end;
  7676. procedure TTestModule.TestCaseOfNoElse;
  7677. begin
  7678. StartProgram(false);
  7679. Add('var Vi: longint;');
  7680. Add('begin');
  7681. Add(' case vi of');
  7682. Add(' 1: begin vi:=2; VI:=3; end;');
  7683. Add(' end;');
  7684. ConvertProgram;
  7685. CheckSource('TestCaseOfNoElse',
  7686. LinesToStr([ // statements
  7687. 'this.Vi = 0;'
  7688. ]),
  7689. LinesToStr([ // $mod.$main
  7690. 'var $tmp1 = $mod.Vi;',
  7691. 'if ($tmp1 === 1) {',
  7692. ' $mod.Vi = 2;',
  7693. ' $mod.Vi = 3;',
  7694. '};'
  7695. ]));
  7696. end;
  7697. procedure TTestModule.TestCaseOfNoElse_UseSwitch;
  7698. begin
  7699. StartProgram(false);
  7700. Converter.UseSwitchStatement:=true;
  7701. Add('var vI: longint;');
  7702. Add('begin');
  7703. Add(' case vi of');
  7704. Add(' 1: begin VI:=2; vi:=3; end;');
  7705. Add(' end;');
  7706. ConvertProgram;
  7707. CheckSource('TestCaseOfNoElse_UseSwitch',
  7708. LinesToStr([ // statements
  7709. 'this.vI = 0;'
  7710. ]),
  7711. LinesToStr([ // $mod.$main
  7712. 'switch ($mod.vI) {',
  7713. 'case 1:',
  7714. ' $mod.vI = 2;',
  7715. ' $mod.vI = 3;',
  7716. ' break;',
  7717. '};'
  7718. ]));
  7719. end;
  7720. procedure TTestModule.TestCaseOfRange;
  7721. begin
  7722. StartProgram(false);
  7723. Add('var vI: longint;');
  7724. Add('begin');
  7725. Add(' case vi of');
  7726. Add(' 1..3: vi:=14;');
  7727. Add(' 4,5: vi:=16;');
  7728. Add(' 6..7,9..10: ;');
  7729. Add(' else ;');
  7730. Add(' end;');
  7731. ConvertProgram;
  7732. CheckSource('TestCaseOfRange',
  7733. LinesToStr([ // statements
  7734. 'this.vI = 0;'
  7735. ]),
  7736. LinesToStr([ // $mod.$main
  7737. 'var $tmp1 = $mod.vI;',
  7738. 'if (($tmp1 >= 1) && ($tmp1 <= 3)){',
  7739. ' $mod.vI = 14',
  7740. '} else if (($tmp1 === 4) || ($tmp1 === 5)){',
  7741. ' $mod.vI = 16',
  7742. '} else if ((($tmp1 >= 6) && ($tmp1 <= 7)) || (($tmp1 >= 9) && ($tmp1 <= 10))) ;'
  7743. ]));
  7744. end;
  7745. procedure TTestModule.TestCaseOfString;
  7746. begin
  7747. StartProgram(false);
  7748. Add([
  7749. 'var s,h: string;',
  7750. 'begin',
  7751. ' case s of',
  7752. ' ''foo'': s:=h;',
  7753. ' ''a''..''z'': h:=s;',
  7754. ' ''ў'', ''ё'': ;',
  7755. ' ''Б''..''Я'': ;',
  7756. ' end;',
  7757. '']);
  7758. ConvertProgram;
  7759. CheckSource('TestCaseOfString',
  7760. LinesToStr([ // statements
  7761. 'this.s = "";',
  7762. 'this.h = "";',
  7763. '']),
  7764. LinesToStr([ // $mod.$main
  7765. 'var $tmp1 = $mod.s;',
  7766. 'if ($tmp1 === "foo") {',
  7767. ' $mod.s = $mod.h}',
  7768. ' else if (($tmp1.length === 1) && ($tmp1 >= "a") && ($tmp1 <= "z")) {',
  7769. ' $mod.h = $mod.s}',
  7770. ' else if (($tmp1 === "ў") || ($tmp1 === "ё")) {}',
  7771. ' else if (($tmp1.length === 1) && ($tmp1 >= "Б") && ($tmp1 <= "Я")) ;',
  7772. '']));
  7773. end;
  7774. procedure TTestModule.TestCaseOfChar;
  7775. begin
  7776. StartProgram(false);
  7777. Add([
  7778. 'var s,h: char;',
  7779. 'begin',
  7780. ' case s of',
  7781. ' ''a''..''z'': h:=s;',
  7782. ' ''ä'': ;',
  7783. ' ''ў'', ''ё'': ;',
  7784. ' ''Б''..''Я'': ;',
  7785. ' end;',
  7786. '']);
  7787. ConvertProgram;
  7788. CheckSource('TestCaseOfString',
  7789. LinesToStr([ // statements
  7790. 'this.s = "";',
  7791. 'this.h = "";',
  7792. '']),
  7793. LinesToStr([ // $mod.$main
  7794. 'var $tmp1 = $mod.s;',
  7795. 'if (($tmp1 >= "a") && ($tmp1 <= "z")) {',
  7796. ' $mod.h = $mod.s}',
  7797. ' else if ($tmp1 === "ä") {}',
  7798. ' else if (($tmp1 === "ў") || ($tmp1 === "ё")) {}',
  7799. ' else if (($tmp1 >= "Б") && ($tmp1 <= "Я")) ;',
  7800. '']));
  7801. end;
  7802. procedure TTestModule.TestCaseOfExternalClassConst;
  7803. begin
  7804. StartProgram(false);
  7805. Add([
  7806. '{$modeswitch externalclass}',
  7807. 'type',
  7808. ' TBird = class external name ''Bird''',
  7809. ' const e: longint;',
  7810. ' end;',
  7811. 'var vI: longint;',
  7812. 'begin',
  7813. ' case vi of',
  7814. ' 1: vi:=3;',
  7815. ' TBird.e: ;',
  7816. ' end;']);
  7817. ConvertProgram;
  7818. CheckSource('TestCaseOfExternalClassConst',
  7819. LinesToStr([ // statements
  7820. 'this.vI = 0;'
  7821. ]),
  7822. LinesToStr([ // $mod.$main
  7823. 'var $tmp1 = $mod.vI;',
  7824. 'if ($tmp1 === 1) {',
  7825. ' $mod.vI = 3}',
  7826. ' else if ($tmp1 === Bird.e) ;'
  7827. ]));
  7828. end;
  7829. procedure TTestModule.TestDebugger;
  7830. begin
  7831. StartProgram(false);
  7832. Add([
  7833. 'procedure DoIt;',
  7834. 'begin',
  7835. ' deBugger;',
  7836. ' DeBugger();',
  7837. 'end;',
  7838. 'begin',
  7839. ' Debugger;']);
  7840. ConvertProgram;
  7841. CheckSource('TestDebugger',
  7842. LinesToStr([ // statements
  7843. 'this.DoIt = function () {',
  7844. ' debugger;',
  7845. ' debugger;',
  7846. '};',
  7847. '']),
  7848. LinesToStr([ // $mod.$main
  7849. 'debugger;',
  7850. '']));
  7851. end;
  7852. procedure TTestModule.TestArray_Dynamic;
  7853. begin
  7854. StartProgram(false);
  7855. Add(['type',
  7856. ' TArrayInt = array of longint;',
  7857. 'var',
  7858. ' Arr: TArrayInt;',
  7859. ' i: longint;',
  7860. ' b: boolean;',
  7861. 'begin',
  7862. ' SetLength(arr,3);',
  7863. ' arr[0]:=4;',
  7864. ' arr[1]:=length(arr)+arr[0];',
  7865. ' arr[i]:=5;',
  7866. ' arr[arr[i]]:=arr[6];',
  7867. ' i:=low(arr);',
  7868. ' i:=high(arr);',
  7869. ' b:=Assigned(arr);',
  7870. ' Arr:=default(TArrayInt);']);
  7871. ConvertProgram;
  7872. CheckSource('TestArray_Dynamic',
  7873. LinesToStr([ // statements
  7874. 'this.Arr = [];',
  7875. 'this.i = 0;',
  7876. 'this.b = false;'
  7877. ]),
  7878. LinesToStr([ // $mod.$main
  7879. '$mod.Arr = rtl.arraySetLength($mod.Arr,0,3);',
  7880. '$mod.Arr[0] = 4;',
  7881. '$mod.Arr[1] = rtl.length($mod.Arr) + $mod.Arr[0];',
  7882. '$mod.Arr[$mod.i] = 5;',
  7883. '$mod.Arr[$mod.Arr[$mod.i]] = $mod.Arr[6];',
  7884. '$mod.i = 0;',
  7885. '$mod.i = rtl.length($mod.Arr) - 1;',
  7886. '$mod.b = rtl.length($mod.Arr) > 0;',
  7887. '$mod.Arr = [];',
  7888. '']));
  7889. end;
  7890. procedure TTestModule.TestArray_Dynamic_Nil;
  7891. begin
  7892. StartProgram(false);
  7893. Add('type');
  7894. Add(' TArrayInt = array of longint;');
  7895. Add('var');
  7896. Add(' Arr: TArrayInt;');
  7897. Add('procedure DoIt(const i: TArrayInt; j: TArrayInt); begin end;');
  7898. Add('begin');
  7899. Add(' arr:=nil;');
  7900. Add(' if arr=nil then;');
  7901. Add(' if nil=arr then;');
  7902. Add(' if arr<>nil then;');
  7903. Add(' if nil<>arr then;');
  7904. Add(' DoIt(nil,nil);');
  7905. ConvertProgram;
  7906. CheckSource('TestArray_Dynamic',
  7907. LinesToStr([ // statements
  7908. 'this.Arr = [];',
  7909. 'this.DoIt = function(i,j){',
  7910. '};'
  7911. ]),
  7912. LinesToStr([ // $mod.$main
  7913. '$mod.Arr = [];',
  7914. 'if (rtl.length($mod.Arr) === 0) ;',
  7915. 'if (rtl.length($mod.Arr) === 0) ;',
  7916. 'if (rtl.length($mod.Arr) > 0) ;',
  7917. 'if (rtl.length($mod.Arr) > 0) ;',
  7918. '$mod.DoIt([],[]);',
  7919. '']));
  7920. end;
  7921. procedure TTestModule.TestArray_DynMultiDimensional;
  7922. begin
  7923. StartProgram(false);
  7924. Add('type');
  7925. Add(' TArrayInt = array of longint;');
  7926. Add(' TArrayArrayInt = array of TArrayInt;');
  7927. Add('var');
  7928. Add(' Arr: TArrayInt;');
  7929. Add(' Arr2: TArrayArrayInt;');
  7930. Add(' i: longint;');
  7931. Add('begin');
  7932. Add(' arr2:=nil;');
  7933. Add(' if arr2=nil then;');
  7934. Add(' if nil=arr2 then;');
  7935. Add(' i:=low(arr2);');
  7936. Add(' i:=low(arr2[1]);');
  7937. Add(' i:=high(arr2);');
  7938. Add(' i:=high(arr2[2]);');
  7939. Add(' arr2[3]:=arr;');
  7940. Add(' arr2[4][5]:=i;');
  7941. Add(' i:=arr2[6][7];');
  7942. Add(' arr2[8,9]:=i;');
  7943. Add(' i:=arr2[10,11];');
  7944. Add(' SetLength(arr2,14);');
  7945. Add(' SetLength(arr2[15],16);');
  7946. ConvertProgram;
  7947. CheckSource('TestArray_Dynamic',
  7948. LinesToStr([ // statements
  7949. 'this.Arr = [];',
  7950. 'this.Arr2 = [];',
  7951. 'this.i = 0;'
  7952. ]),
  7953. LinesToStr([ // $mod.$main
  7954. '$mod.Arr2 = [];',
  7955. 'if (rtl.length($mod.Arr2) === 0) ;',
  7956. 'if (rtl.length($mod.Arr2) === 0) ;',
  7957. '$mod.i = 0;',
  7958. '$mod.i = 0;',
  7959. '$mod.i = rtl.length($mod.Arr2) - 1;',
  7960. '$mod.i = rtl.length($mod.Arr2[2]) - 1;',
  7961. '$mod.Arr2[3] = $mod.Arr;',
  7962. '$mod.Arr2[4][5] = $mod.i;',
  7963. '$mod.i = $mod.Arr2[6][7];',
  7964. '$mod.Arr2[8][9] = $mod.i;',
  7965. '$mod.i = $mod.Arr2[10][11];',
  7966. '$mod.Arr2 = rtl.arraySetLength($mod.Arr2, [], 14);',
  7967. '$mod.Arr2[15] = rtl.arraySetLength($mod.Arr2[15], 0, 16);',
  7968. '']));
  7969. end;
  7970. procedure TTestModule.TestArray_StaticInt;
  7971. begin
  7972. StartProgram(false);
  7973. Add('type');
  7974. Add(' TArrayInt = array[2..4] of longint;');
  7975. Add('var');
  7976. Add(' Arr: TArrayInt;');
  7977. Add(' Arr2: TArrayInt = (5,6,7);');
  7978. Add(' i: longint;');
  7979. Add(' b: boolean;');
  7980. Add('begin');
  7981. Add(' arr[2]:=4;');
  7982. Add(' arr[3]:=arr[2]+arr[3];');
  7983. Add(' arr[i]:=5;');
  7984. Add(' arr[arr[i]]:=arr[high(arr)];');
  7985. Add(' i:=low(arr);');
  7986. Add(' i:=high(arr);');
  7987. Add(' b:=arr[2]=arr[3];');
  7988. Add(' arr:=default(TArrayInt);');
  7989. ConvertProgram;
  7990. CheckSource('TestArray_StaticInt',
  7991. LinesToStr([ // statements
  7992. 'this.Arr = rtl.arraySetLength(null,0,3);',
  7993. 'this.Arr2 = [5, 6, 7];',
  7994. 'this.i = 0;',
  7995. 'this.b = false;'
  7996. ]),
  7997. LinesToStr([ // $mod.$main
  7998. '$mod.Arr[0] = 4;',
  7999. '$mod.Arr[1] = $mod.Arr[0] + $mod.Arr[1];',
  8000. '$mod.Arr[$mod.i-2] = 5;',
  8001. '$mod.Arr[$mod.Arr[$mod.i-2]-2] = $mod.Arr[2];',
  8002. '$mod.i = 2;',
  8003. '$mod.i = 4;',
  8004. '$mod.b = $mod.Arr[0] === $mod.Arr[1];',
  8005. '$mod.Arr = rtl.arraySetLength(null,0,3).slice(0);',
  8006. '']));
  8007. end;
  8008. procedure TTestModule.TestArray_StaticBool;
  8009. begin
  8010. StartProgram(false);
  8011. Add('type');
  8012. Add(' TBools = array[boolean] of boolean;');
  8013. Add(' TBool2 = array[true..true] of boolean;');
  8014. Add('var');
  8015. Add(' Arr: TBools;');
  8016. Add(' Arr2: TBool2;');
  8017. Add(' Arr3: TBools = (true,false);');
  8018. Add(' b: boolean;');
  8019. Add('begin');
  8020. Add(' b:=low(arr);');
  8021. Add(' b:=high(arr);');
  8022. Add(' arr[true]:=false;');
  8023. Add(' arr[false]:=arr[b] or arr[true];');
  8024. Add(' arr[b]:=true;');
  8025. Add(' arr[arr[b]]:=arr[high(arr)];');
  8026. Add(' b:=arr[false]=arr[true];');
  8027. Add(' b:=low(arr2);');
  8028. Add(' b:=high(arr2);');
  8029. Add(' arr2[true]:=true;');
  8030. Add(' arr2[true]:=arr2[true] and arr2[b];');
  8031. Add(' arr2[b]:=false;');
  8032. ConvertProgram;
  8033. CheckSource('TestArray_StaticBool',
  8034. LinesToStr([ // statements
  8035. 'this.Arr = rtl.arraySetLength(null,false,2);',
  8036. 'this.Arr2 = rtl.arraySetLength(null,false,1);',
  8037. 'this.Arr3 = [true, false];',
  8038. 'this.b = false;'
  8039. ]),
  8040. LinesToStr([ // $mod.$main
  8041. '$mod.b = false;',
  8042. '$mod.b = true;',
  8043. '$mod.Arr[1] = false;',
  8044. '$mod.Arr[0] = $mod.Arr[+$mod.b] || $mod.Arr[1];',
  8045. '$mod.Arr[+$mod.b] = true;',
  8046. '$mod.Arr[+$mod.Arr[+$mod.b]] = $mod.Arr[1];',
  8047. '$mod.b = $mod.Arr[0] === $mod.Arr[1];',
  8048. '$mod.b = true;',
  8049. '$mod.b = true;',
  8050. '$mod.Arr2[0] = true;',
  8051. '$mod.Arr2[0] = $mod.Arr2[0] && $mod.Arr2[1-$mod.b];',
  8052. '$mod.Arr2[1-$mod.b] = false;',
  8053. '']));
  8054. end;
  8055. procedure TTestModule.TestArray_StaticChar;
  8056. begin
  8057. StartProgram(false);
  8058. Add([
  8059. 'type',
  8060. ' TChars = array[char] of char;',
  8061. ' TChars2 = array[''a''..''z''] of char;',
  8062. 'var',
  8063. ' Arr: TChars;',
  8064. ' Arr2: TChars2;',
  8065. ' Arr3: array[2..4] of char = (''p'',''a'',''s'');',
  8066. ' Arr4: array[11..13] of char = ''pas'';',
  8067. ' Arr5: array[21..22] of char = ''äö'';',
  8068. ' Arr6: array[31..32] of char = ''ä''+''ö'';',
  8069. ' c: char;',
  8070. ' b: boolean;',
  8071. 'begin',
  8072. ' c:=low(arr);',
  8073. ' c:=high(arr);',
  8074. ' arr[''B'']:=''a'';',
  8075. ' arr[''D'']:=arr[c];',
  8076. ' arr[c]:=arr[''d''];',
  8077. ' arr[arr[c]]:=arr[high(arr)];',
  8078. ' b:=arr[low(arr)]=arr[''e''];',
  8079. ' c:=low(arr2);',
  8080. ' c:=high(arr2);',
  8081. ' arr2[''b'']:=''f'';',
  8082. ' arr2[''a'']:=arr2[c];',
  8083. ' arr2[c]:=arr2[''g''];']);
  8084. ConvertProgram;
  8085. CheckSource('TestArray_StaticChar',
  8086. LinesToStr([ // statements
  8087. 'this.Arr = rtl.arraySetLength(null, "", 65536);',
  8088. 'this.Arr2 = rtl.arraySetLength(null, "", 26);',
  8089. 'this.Arr3 = ["p", "a", "s"];',
  8090. 'this.Arr4 = ["p", "a", "s"];',
  8091. 'this.Arr5 = ["ä", "ö"];',
  8092. 'this.Arr6 = ["ä", "ö"];',
  8093. 'this.c = "";',
  8094. 'this.b = false;',
  8095. '']),
  8096. LinesToStr([ // $mod.$main
  8097. '$mod.c = "\x00";',
  8098. '$mod.c = "\uFFFF";',
  8099. '$mod.Arr[66] = "a";',
  8100. '$mod.Arr[68] = $mod.Arr[$mod.c.charCodeAt()];',
  8101. '$mod.Arr[$mod.c.charCodeAt()] = $mod.Arr[100];',
  8102. '$mod.Arr[$mod.Arr[$mod.c.charCodeAt()].charCodeAt()] = $mod.Arr[65535];',
  8103. '$mod.b = $mod.Arr[0] === $mod.Arr[101];',
  8104. '$mod.c = "a";',
  8105. '$mod.c = "z";',
  8106. '$mod.Arr2[1] = "f";',
  8107. '$mod.Arr2[0] = $mod.Arr2[$mod.c.charCodeAt() - 97];',
  8108. '$mod.Arr2[$mod.c.charCodeAt() - 97] = $mod.Arr2[6];',
  8109. '']));
  8110. end;
  8111. procedure TTestModule.TestArray_StaticMultiDim;
  8112. begin
  8113. StartProgram(false);
  8114. Add([
  8115. 'type',
  8116. ' TArrayInt = array[1..3] of longint;',
  8117. ' TArrayArrayInt = array[5..6] of TArrayInt;',
  8118. 'var',
  8119. ' Arr: TArrayInt;',
  8120. ' Arr2: TArrayArrayInt;',
  8121. ' Arr3: array[boolean] of TArrayInt = ((11,12,13),(21,22,23));',
  8122. ' i: longint;',
  8123. 'begin',
  8124. ' i:=low(arr);',
  8125. ' i:=low(arr2);',
  8126. ' i:=low(arr2[5]);',
  8127. ' i:=high(arr);',
  8128. ' i:=high(arr2);',
  8129. ' i:=high(arr2[6]);',
  8130. ' arr2[5]:=arr;',
  8131. ' arr2[6][2]:=i;',
  8132. ' i:=arr2[6][3];',
  8133. ' arr2[6,3]:=i;',
  8134. ' i:=arr2[5,2];',
  8135. ' arr2:=arr2;',// clone multi dim static array
  8136. //' arr3:=arr3;',// clone anonymous multi dim static array
  8137. '']);
  8138. ConvertProgram;
  8139. CheckSource('TestArray_StaticMultiDim',
  8140. LinesToStr([ // statements
  8141. 'this.TArrayArrayInt$clone = function (a) {',
  8142. ' var r = [];',
  8143. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  8144. ' return r;',
  8145. '};',
  8146. 'this.Arr = rtl.arraySetLength(null, 0, 3);',
  8147. 'this.Arr2 = rtl.arraySetLength(null, 0, 2, 3);',
  8148. 'this.Arr3 = [[11, 12, 13], [21, 22, 23]];',
  8149. 'this.i = 0;'
  8150. ]),
  8151. LinesToStr([ // $mod.$main
  8152. '$mod.i = 1;',
  8153. '$mod.i = 5;',
  8154. '$mod.i = 1;',
  8155. '$mod.i = 3;',
  8156. '$mod.i = 6;',
  8157. '$mod.i = 3;',
  8158. '$mod.Arr2[0] = $mod.Arr.slice(0);',
  8159. '$mod.Arr2[1][1] = $mod.i;',
  8160. '$mod.i = $mod.Arr2[1][2];',
  8161. '$mod.Arr2[1][2] = $mod.i;',
  8162. '$mod.i = $mod.Arr2[0][1];',
  8163. '$mod.Arr2 = $mod.TArrayArrayInt$clone($mod.Arr2);',
  8164. '']));
  8165. end;
  8166. procedure TTestModule.TestArray_StaticInFunction;
  8167. begin
  8168. StartProgram(false);
  8169. Add([
  8170. 'const TArrayInt = 3;',
  8171. 'const TArrayArrayInt = 4;',
  8172. 'procedure DoIt;',
  8173. 'type',
  8174. ' TArrayInt = array[1..3] of longint;',
  8175. ' TArrayArrayInt = array[5..6] of TArrayInt;',
  8176. 'var',
  8177. ' Arr: TArrayInt;',
  8178. ' Arr2: TArrayArrayInt;',
  8179. ' Arr3: array[boolean] of TArrayInt = ((11,12,13),(21,22,23));',
  8180. ' i: longint;',
  8181. 'begin',
  8182. ' arr2[5]:=arr;',
  8183. ' arr2:=arr2;',// clone multi dim static array
  8184. 'end;',
  8185. 'begin',
  8186. '']);
  8187. ConvertProgram;
  8188. CheckSource('TestArray_StaticInFunction',
  8189. LinesToStr([ // statements
  8190. 'this.TArrayInt = 3;',
  8191. 'this.TArrayArrayInt = 4;',
  8192. 'var TArrayArrayInt$1$clone = function (a) {',
  8193. ' var r = [];',
  8194. ' for (var i = 0; i < 2; i++) r.push(a[i].slice(0));',
  8195. ' return r;',
  8196. '};',
  8197. 'this.DoIt = function () {',
  8198. ' var Arr = rtl.arraySetLength(null, 0, 3);',
  8199. ' var Arr2 = rtl.arraySetLength(null, 0, 2, 3);',
  8200. ' var Arr3 = [[11, 12, 13], [21, 22, 23]];',
  8201. ' var i = 0;',
  8202. ' Arr2[0] = Arr.slice(0);',
  8203. ' Arr2 = TArrayArrayInt$1$clone(Arr2);',
  8204. '};',
  8205. '']),
  8206. LinesToStr([ // $mod.$main
  8207. '']));
  8208. end;
  8209. procedure TTestModule.TestArrayOfRecord;
  8210. begin
  8211. StartProgram(false);
  8212. Add([
  8213. 'type',
  8214. ' TRec = record',
  8215. ' Int: longint;',
  8216. ' end;',
  8217. ' TArrayRec = array of TRec;',
  8218. 'procedure DoIt(vd: TRec; const vc: TRec; var vv: TRec);',
  8219. 'begin',
  8220. 'end;',
  8221. 'var',
  8222. ' Arr: TArrayRec;',
  8223. ' r: TRec;',
  8224. ' i: longint;',
  8225. 'begin',
  8226. ' SetLength(arr,3);',
  8227. ' arr[0].int:=4;',
  8228. ' arr[1].int:=length(arr)+arr[2].int;',
  8229. ' arr[arr[i].int].int:=arr[5].int;',
  8230. ' arr[7]:=r;',
  8231. ' r:=arr[8];',
  8232. ' i:=low(arr);',
  8233. ' i:=high(arr);',
  8234. ' DoIt(Arr[9],Arr[10],Arr[11]);']);
  8235. ConvertProgram;
  8236. CheckSource('TestArrayOfRecord',
  8237. LinesToStr([ // statements
  8238. 'rtl.recNewT($mod, "TRec", function () {',
  8239. ' this.Int = 0;',
  8240. ' this.$eq = function (b) {',
  8241. ' return this.Int === b.Int;',
  8242. ' };',
  8243. ' this.$assign = function (s) {',
  8244. ' this.Int = s.Int;',
  8245. ' return this;',
  8246. ' };',
  8247. '});',
  8248. 'this.DoIt = function (vd, vc, vv) {',
  8249. '};',
  8250. 'this.Arr = [];',
  8251. 'this.r = $mod.TRec.$new();',
  8252. 'this.i = 0;'
  8253. ]),
  8254. LinesToStr([ // $mod.$main
  8255. '$mod.Arr = rtl.arraySetLength($mod.Arr,$mod.TRec,3);',
  8256. '$mod.Arr[0].Int = 4;',
  8257. '$mod.Arr[1].Int = rtl.length($mod.Arr)+$mod.Arr[2].Int;',
  8258. '$mod.Arr[$mod.Arr[$mod.i].Int].Int = $mod.Arr[5].Int;',
  8259. '$mod.Arr[7].$assign($mod.r);',
  8260. '$mod.r.$assign($mod.Arr[8]);',
  8261. '$mod.i = 0;',
  8262. '$mod.i = rtl.length($mod.Arr)-1;',
  8263. '$mod.DoIt($mod.TRec.$clone($mod.Arr[9]), $mod.Arr[10], $mod.Arr[11]);',
  8264. '']));
  8265. end;
  8266. procedure TTestModule.TestArray_StaticRecord;
  8267. begin
  8268. StartProgram(false);
  8269. Add([
  8270. 'type',
  8271. ' TRec = record',
  8272. ' Int: longint;',
  8273. ' end;',
  8274. ' TArrayRec = array[1..2] of TRec;',
  8275. 'var',
  8276. ' Arr: TArrayRec;',
  8277. 'begin',
  8278. ' arr[1].int:=length(arr)+low(arr)+high(arr);',
  8279. '']);
  8280. ConvertProgram;
  8281. CheckSource('TestArray_StaticRecord',
  8282. LinesToStr([ // statements
  8283. 'rtl.recNewT($mod, "TRec", function () {',
  8284. ' this.Int = 0;',
  8285. ' this.$eq = function (b) {',
  8286. ' return this.Int === b.Int;',
  8287. ' };',
  8288. ' this.$assign = function (s) {',
  8289. ' this.Int = s.Int;',
  8290. ' return this;',
  8291. ' };',
  8292. '});',
  8293. 'this.TArrayRec$clone = function (a) {',
  8294. ' var r = [];',
  8295. ' for (var i = 0; i < 2; i++) r.push($mod.TRec.$clone(a[i]));',
  8296. ' return r;',
  8297. '};',
  8298. 'this.Arr = rtl.arraySetLength(null, $mod.TRec, 2);',
  8299. '']),
  8300. LinesToStr([ // $mod.$main
  8301. '$mod.Arr[0].Int = 2 + 1 + 2;']));
  8302. end;
  8303. procedure TTestModule.TestArrayOfSet;
  8304. begin
  8305. StartProgram(false);
  8306. Add([
  8307. 'type',
  8308. ' TFlag = (big,small);',
  8309. ' TSetOfFlag = set of tflag;',
  8310. ' TArrayFlag = array of TSetOfFlag;',
  8311. 'procedure DoIt(const a: Tarrayflag);',
  8312. 'begin',
  8313. 'end;',
  8314. 'var',
  8315. ' f: TFlag;',
  8316. ' s: TSetOfFlag;',
  8317. ' Arr: TArrayFlag;',
  8318. ' i: longint;',
  8319. 'begin',
  8320. ' SetLength(arr,3);',
  8321. ' arr[0]:=s;',
  8322. ' arr[1]:=[big];',
  8323. ' arr[2]:=[big]+s;',
  8324. ' arr[3]:=s+[big];',
  8325. ' arr[4]:=arr[5];',
  8326. ' s:=arr[6];',
  8327. ' i:=low(arr);',
  8328. ' i:=high(arr);',
  8329. ' DoIt(arr);',
  8330. ' DoIt([s]);',
  8331. ' DoIt([[],s]);',
  8332. ' DoIt([s,[]]);',
  8333. '']);
  8334. ConvertProgram;
  8335. CheckSource('TestArrayOfSet',
  8336. LinesToStr([ // statements
  8337. 'this.TFlag = {',
  8338. ' "0": "big",',
  8339. ' big: 0,',
  8340. ' "1": "small",',
  8341. ' small: 1',
  8342. '};',
  8343. 'this.DoIt = function (a) {',
  8344. '};',
  8345. 'this.f = 0;',
  8346. 'this.s = {};',
  8347. 'this.Arr = [];',
  8348. 'this.i = 0;',
  8349. '']),
  8350. LinesToStr([ // $mod.$main
  8351. '$mod.Arr = rtl.arraySetLength($mod.Arr, {}, 3);',
  8352. '$mod.Arr[0] = rtl.refSet($mod.s);',
  8353. '$mod.Arr[1] = rtl.createSet($mod.TFlag.big);',
  8354. '$mod.Arr[2] = rtl.unionSet(rtl.createSet($mod.TFlag.big), $mod.s);',
  8355. '$mod.Arr[3] = rtl.unionSet($mod.s, rtl.createSet($mod.TFlag.big));',
  8356. '$mod.Arr[4] = rtl.refSet($mod.Arr[5]);',
  8357. '$mod.s = rtl.refSet($mod.Arr[6]);',
  8358. '$mod.i = 0;',
  8359. '$mod.i = rtl.length($mod.Arr) - 1;',
  8360. '$mod.DoIt($mod.Arr);',
  8361. '$mod.DoIt([rtl.refSet($mod.s)]);',
  8362. '$mod.DoIt([{}, rtl.refSet($mod.s)]);',
  8363. '$mod.DoIt([rtl.refSet($mod.s), {}]);',
  8364. '']));
  8365. end;
  8366. procedure TTestModule.TestArray_DynAsParam;
  8367. begin
  8368. StartProgram(false);
  8369. Add([
  8370. 'type integer = longint;',
  8371. 'type TArrInt = array of integer;',
  8372. 'procedure DoIt(vG: TArrInt; const vH: TArrInt; var vI: TArrInt);',
  8373. 'var vJ: TArrInt;',
  8374. 'begin',
  8375. ' vg:=vg;',
  8376. ' vj:=vh;',
  8377. ' vi:=vi;',
  8378. ' doit(vg,vg,vg);',
  8379. ' doit(vh,vh,vj);',
  8380. ' doit(vi,vi,vi);',
  8381. ' doit(vj,vj,vj);',
  8382. 'end;',
  8383. 'var i: TArrInt;',
  8384. 'begin',
  8385. ' doit(i,i,i);']);
  8386. ConvertProgram;
  8387. CheckSource('TestArray_DynAsParams',
  8388. LinesToStr([ // statements
  8389. 'this.DoIt = function (vG,vH,vI) {',
  8390. ' var vJ = [];',
  8391. ' vG = vG;',
  8392. ' vJ = vH;',
  8393. ' vI.set(vI.get());',
  8394. ' $mod.DoIt(vG, vG, {',
  8395. ' get: function () {',
  8396. ' return vG;',
  8397. ' },',
  8398. ' set: function (v) {',
  8399. ' vG = v;',
  8400. ' }',
  8401. ' });',
  8402. ' $mod.DoIt(vH, vH, {',
  8403. ' get: function () {',
  8404. ' return vJ;',
  8405. ' },',
  8406. ' set: function (v) {',
  8407. ' vJ = v;',
  8408. ' }',
  8409. ' });',
  8410. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  8411. ' $mod.DoIt(vJ, vJ, {',
  8412. ' get: function () {',
  8413. ' return vJ;',
  8414. ' },',
  8415. ' set: function (v) {',
  8416. ' vJ = v;',
  8417. ' }',
  8418. ' });',
  8419. '};',
  8420. 'this.i = [];'
  8421. ]),
  8422. LinesToStr([
  8423. '$mod.DoIt($mod.i,$mod.i,{',
  8424. ' p: $mod,',
  8425. ' get: function () {',
  8426. ' return this.p.i;',
  8427. ' },',
  8428. ' set: function (v) {',
  8429. ' this.p.i = v;',
  8430. ' }',
  8431. '});'
  8432. ]));
  8433. end;
  8434. procedure TTestModule.TestArray_StaticAsParam;
  8435. begin
  8436. StartProgram(false);
  8437. Add([
  8438. 'type integer = longint;',
  8439. 'type TArrInt = array[1..2] 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_StaticAsParams',
  8456. LinesToStr([ // statements
  8457. 'this.DoIt = function (vG,vH,vI) {',
  8458. ' var vJ = rtl.arraySetLength(null, 0, 2);',
  8459. ' vG = vG.slice(0);',
  8460. ' vJ = vH.slice(0);',
  8461. ' vI.set(vI.get().slice(0));',
  8462. ' $mod.DoIt(vG.slice(0), vG, {',
  8463. ' get: function () {',
  8464. ' return vG;',
  8465. ' },',
  8466. ' set: function (v) {',
  8467. ' vG = v;',
  8468. ' }',
  8469. ' });',
  8470. ' $mod.DoIt(vH.slice(0), vH, {',
  8471. ' get: function () {',
  8472. ' return vJ;',
  8473. ' },',
  8474. ' set: function (v) {',
  8475. ' vJ = v;',
  8476. ' }',
  8477. ' });',
  8478. ' $mod.DoIt(vI.get().slice(0), vI.get(), vI);',
  8479. ' $mod.DoIt(vJ.slice(0), vJ, {',
  8480. ' get: function () {',
  8481. ' return vJ;',
  8482. ' },',
  8483. ' set: function (v) {',
  8484. ' vJ = v;',
  8485. ' }',
  8486. ' });',
  8487. '};',
  8488. 'this.i = rtl.arraySetLength(null, 0, 2);'
  8489. ]),
  8490. LinesToStr([
  8491. '$mod.DoIt($mod.i.slice(0),$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.TestArrayElement_AsParams;
  8503. begin
  8504. StartProgram(false);
  8505. Add('type integer = longint;');
  8506. Add('type TArrayInt = array of integer;');
  8507. Add('procedure DoIt(vG: Integer; const vH: Integer; var vI: Integer);');
  8508. Add('var vJ: tarrayint;');
  8509. Add('begin');
  8510. Add(' vi:=vi;');
  8511. Add(' doit(vi,vi,vi);');
  8512. Add(' doit(vj[1+1],vj[1+2],vj[1+3]);');
  8513. Add('end;');
  8514. Add('var a: TArrayInt;');
  8515. Add('begin');
  8516. Add(' doit(a[1+4],a[1+5],a[1+6]);');
  8517. ConvertProgram;
  8518. CheckSource('TestArrayElement_AsParams',
  8519. LinesToStr([ // statements
  8520. 'this.DoIt = function (vG,vH,vI) {',
  8521. ' var vJ = [];',
  8522. ' vI.set(vI.get());',
  8523. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  8524. ' $mod.DoIt(vJ[1+1], vJ[1+2], {',
  8525. ' a:1+3,',
  8526. ' p:vJ,',
  8527. ' get: function () {',
  8528. ' return this.p[this.a];',
  8529. ' },',
  8530. ' set: function (v) {',
  8531. ' this.p[this.a] = v;',
  8532. ' }',
  8533. ' });',
  8534. '};',
  8535. 'this.a = [];'
  8536. ]),
  8537. LinesToStr([
  8538. '$mod.DoIt($mod.a[1+4],$mod.a[1+5],{',
  8539. ' a: 1+6,',
  8540. ' p: $mod.a,',
  8541. ' get: function () {',
  8542. ' return this.p[this.a];',
  8543. ' },',
  8544. ' set: function (v) {',
  8545. ' this.p[this.a] = v;',
  8546. ' }',
  8547. '});'
  8548. ]));
  8549. end;
  8550. procedure TTestModule.TestArrayElementFromFuncResult_AsParams;
  8551. begin
  8552. StartProgram(false);
  8553. Add('type Integer = longint;');
  8554. Add('type TArrayInt = array of integer;');
  8555. Add('function GetArr(vB: integer = 0): tarrayint;');
  8556. Add('begin');
  8557. Add('end;');
  8558. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  8559. Add('begin');
  8560. Add('end;');
  8561. Add('begin');
  8562. Add(' doit(getarr[1+1],getarr[1+2],getarr[1+3]);');
  8563. Add(' doit(getarr()[2+1],getarr()[2+2],getarr()[2+3]);');
  8564. Add(' doit(getarr(7)[3+1],getarr(8)[3+2],getarr(9)[3+3]);');
  8565. ConvertProgram;
  8566. CheckSource('TestArrayElementFromFuncResult_AsParams',
  8567. LinesToStr([ // statements
  8568. 'this.GetArr = function (vB) {',
  8569. ' var Result = [];',
  8570. ' return Result;',
  8571. '};',
  8572. 'this.DoIt = function (vG,vH,vI) {',
  8573. '};'
  8574. ]),
  8575. LinesToStr([
  8576. '$mod.DoIt($mod.GetArr(0)[1+1],$mod.GetArr(0)[1+2],{',
  8577. ' a: 1+3,',
  8578. ' p: $mod.GetArr(0),',
  8579. ' get: function () {',
  8580. ' return this.p[this.a];',
  8581. ' },',
  8582. ' set: function (v) {',
  8583. ' this.p[this.a] = v;',
  8584. ' }',
  8585. '});',
  8586. '$mod.DoIt($mod.GetArr(0)[2+1],$mod.GetArr(0)[2+2],{',
  8587. ' a: 2+3,',
  8588. ' p: $mod.GetArr(0),',
  8589. ' get: function () {',
  8590. ' return this.p[this.a];',
  8591. ' },',
  8592. ' set: function (v) {',
  8593. ' this.p[this.a] = v;',
  8594. ' }',
  8595. '});',
  8596. '$mod.DoIt($mod.GetArr(7)[3+1],$mod.GetArr(8)[3+2],{',
  8597. ' a: 3+3,',
  8598. ' p: $mod.GetArr(9),',
  8599. ' get: function () {',
  8600. ' return this.p[this.a];',
  8601. ' },',
  8602. ' set: function (v) {',
  8603. ' this.p[this.a] = v;',
  8604. ' }',
  8605. '});',
  8606. '']));
  8607. end;
  8608. procedure TTestModule.TestArrayEnumTypeRange;
  8609. begin
  8610. StartProgram(false);
  8611. Add([
  8612. 'type',
  8613. ' TEnum = (red,blue);',
  8614. ' TEnumArray = array[TEnum] of longint;',
  8615. 'var',
  8616. ' e: TEnum;',
  8617. ' i: longint;',
  8618. ' a: TEnumArray;',
  8619. ' numbers: TEnumArray = (1,2);',
  8620. ' names: array[TEnum] of string = (''red'',''blue'');',
  8621. 'begin',
  8622. ' e:=low(a);',
  8623. ' e:=high(a);',
  8624. ' i:=a[red];',
  8625. ' a[e]:=a[e];']);
  8626. ConvertProgram;
  8627. CheckSource('TestArrayEnumTypeRange',
  8628. LinesToStr([ // statements
  8629. ' this.TEnum = {',
  8630. ' "0": "red",',
  8631. ' red: 0,',
  8632. ' "1": "blue",',
  8633. ' blue: 1',
  8634. '};',
  8635. 'this.e = 0;',
  8636. 'this.i = 0;',
  8637. 'this.a = rtl.arraySetLength(null,0,2);',
  8638. 'this.numbers = [1, 2];',
  8639. 'this.names = ["red", "blue"];',
  8640. '']),
  8641. LinesToStr([ // $mod.$main
  8642. '$mod.e = $mod.TEnum.red;',
  8643. '$mod.e = $mod.TEnum.blue;',
  8644. '$mod.i = $mod.a[$mod.TEnum.red];',
  8645. '$mod.a[$mod.e] = $mod.a[$mod.e];',
  8646. '']));
  8647. end;
  8648. procedure TTestModule.TestArray_SetLengthOutArg;
  8649. begin
  8650. StartProgram(false);
  8651. Add([
  8652. 'type TArrInt = array of longint;',
  8653. 'procedure DoIt(out a: TArrInt);',
  8654. 'begin',
  8655. ' SetLength(a,2);',
  8656. 'end;',
  8657. 'begin',
  8658. '']);
  8659. ConvertProgram;
  8660. CheckSource('TestArray_SetLengthOutArg',
  8661. LinesToStr([ // statements
  8662. 'this.DoIt = function (a) {',
  8663. ' a.set(rtl.arraySetLength(a.get(), 0, 2));',
  8664. '};',
  8665. '']),
  8666. LinesToStr([
  8667. '']));
  8668. end;
  8669. procedure TTestModule.TestArray_SetLengthProperty;
  8670. begin
  8671. StartProgram(false);
  8672. Add('type');
  8673. Add(' TArrInt = array of longint;');
  8674. Add(' TObject = class');
  8675. Add(' function GetColors: TArrInt; external name ''GetColors'';');
  8676. Add(' procedure SetColors(const Value: TArrInt); external name ''SetColors'';');
  8677. Add(' property Colors: TArrInt read GetColors write SetColors;');
  8678. Add(' end;');
  8679. Add('var Obj: TObject;');
  8680. Add('begin');
  8681. Add(' SetLength(Obj.Colors,2);');
  8682. ConvertProgram;
  8683. CheckSource('TestArray_SetLengthProperty',
  8684. LinesToStr([ // statements
  8685. 'rtl.createClass($mod, "TObject", null, function () {',
  8686. ' this.$init = function () {',
  8687. ' };',
  8688. ' this.$final = function () {',
  8689. ' };',
  8690. '});',
  8691. 'this.Obj = null;',
  8692. '']),
  8693. LinesToStr([
  8694. '$mod.Obj.SetColors(rtl.arraySetLength($mod.Obj.GetColors(), 0, 2));',
  8695. '']));
  8696. end;
  8697. procedure TTestModule.TestArray_SetLengthMultiDim;
  8698. begin
  8699. StartProgram(false);
  8700. Add([
  8701. 'type',
  8702. ' TArrArrInt = array of array of longint;',
  8703. 'var',
  8704. ' a: TArrArrInt;',
  8705. 'begin',
  8706. ' SetLength(a,2);',
  8707. ' SetLength(a,3,4);',
  8708. '']);
  8709. ConvertProgram;
  8710. CheckSource('TestArray_SetLengthMultiDim',
  8711. LinesToStr([ // statements
  8712. 'this.a = [];']),
  8713. LinesToStr([
  8714. '$mod.a = rtl.arraySetLength($mod.a, [], 2);',
  8715. '$mod.a = rtl.arraySetLength($mod.a, 0, 3, 4);',
  8716. '']));
  8717. end;
  8718. procedure TTestModule.TestArray_OpenArrayOfString;
  8719. begin
  8720. StartProgram(false);
  8721. Add('procedure DoIt(const a: array of String);');
  8722. Add('var');
  8723. Add(' i: longint;');
  8724. Add(' s: string;');
  8725. Add('begin');
  8726. Add(' for i:=low(a) to high(a) do s:=a[length(a)-i-1];');
  8727. Add('end;');
  8728. Add('var s: string;');
  8729. Add('begin');
  8730. Add(' DoIt([]);');
  8731. Add(' DoIt([s,''foo'','''',s+s]);');
  8732. ConvertProgram;
  8733. CheckSource('TestArray_OpenArrayOfString',
  8734. LinesToStr([ // statements
  8735. 'this.DoIt = function (a) {',
  8736. ' var i = 0;',
  8737. ' var s = "";',
  8738. ' for (var $l1 = 0, $end2 = rtl.length(a) - 1; $l1 <= $end2; $l1++) {',
  8739. ' i = $l1;',
  8740. ' s = a[rtl.length(a) - i - 1];',
  8741. ' };',
  8742. '};',
  8743. 'this.s = "";',
  8744. '']),
  8745. LinesToStr([
  8746. '$mod.DoIt([]);',
  8747. '$mod.DoIt([$mod.s, "foo", "", $mod.s + $mod.s]);',
  8748. '']));
  8749. end;
  8750. procedure TTestModule.TestArray_Concat;
  8751. begin
  8752. StartProgram(false);
  8753. Add([
  8754. 'type',
  8755. ' integer = longint;',
  8756. ' TFlag = (big,small);',
  8757. ' TFlags = set of TFlag;',
  8758. ' TRec = record',
  8759. ' i: integer;',
  8760. ' end;',
  8761. ' TArrInt = array of integer;',
  8762. ' TArrRec = array of TRec;',
  8763. ' TArrFlag = array of TFlag;',
  8764. ' TArrSet = array of TFlags;',
  8765. ' TArrJSValue = array of jsvalue;',
  8766. 'var',
  8767. ' ArrInt: tarrint;',
  8768. ' ArrRec: tarrrec;',
  8769. ' ArrFlag: tarrflag;',
  8770. ' ArrSet: tarrset;',
  8771. ' ArrJSValue: tarrjsvalue;',
  8772. 'begin',
  8773. ' arrint:=concat(arrint);',
  8774. ' arrint:=concat(arrint,arrint);',
  8775. ' arrint:=concat(arrint,arrint,arrint);',
  8776. ' arrrec:=concat(arrrec);',
  8777. ' arrrec:=concat(arrrec,arrrec);',
  8778. ' arrrec:=concat(arrrec,arrrec,arrrec);',
  8779. ' arrset:=concat(arrset);',
  8780. ' arrset:=concat(arrset,arrset);',
  8781. ' arrset:=concat(arrset,arrset,arrset);',
  8782. ' arrjsvalue:=concat(arrjsvalue);',
  8783. ' arrjsvalue:=concat(arrjsvalue,arrjsvalue);',
  8784. ' arrjsvalue:=concat(arrjsvalue,arrjsvalue,arrjsvalue);',
  8785. ' arrint:=concat([1],arrint);',
  8786. ' arrflag:=concat([big]);',
  8787. ' arrflag:=concat([big],arrflag);',
  8788. ' arrflag:=concat(arrflag,[small]);',
  8789. '']);
  8790. ConvertProgram;
  8791. CheckSource('TestArray_Concat',
  8792. LinesToStr([ // statements
  8793. 'this.TFlag = {',
  8794. ' "0": "big",',
  8795. ' big: 0,',
  8796. ' "1": "small",',
  8797. ' small: 1',
  8798. '};',
  8799. 'rtl.recNewT($mod, "TRec", function () {',
  8800. ' this.i = 0;',
  8801. ' this.$eq = function (b) {',
  8802. ' return this.i === b.i;',
  8803. ' };',
  8804. ' this.$assign = function (s) {',
  8805. ' this.i = s.i;',
  8806. ' return this;',
  8807. ' };',
  8808. '});',
  8809. 'this.ArrInt = [];',
  8810. 'this.ArrRec = [];',
  8811. 'this.ArrFlag = [];',
  8812. 'this.ArrSet = [];',
  8813. 'this.ArrJSValue = [];',
  8814. '']),
  8815. LinesToStr([ // $mod.$main
  8816. '$mod.ArrInt = $mod.ArrInt;',
  8817. '$mod.ArrInt = rtl.arrayConcatN($mod.ArrInt, $mod.ArrInt);',
  8818. '$mod.ArrInt = rtl.arrayConcatN($mod.ArrInt, $mod.ArrInt, $mod.ArrInt);',
  8819. '$mod.ArrRec = $mod.ArrRec;',
  8820. '$mod.ArrRec = rtl.arrayConcat($mod.TRec, $mod.ArrRec, $mod.ArrRec);',
  8821. '$mod.ArrRec = rtl.arrayConcat($mod.TRec, $mod.ArrRec, $mod.ArrRec, $mod.ArrRec);',
  8822. '$mod.ArrSet = $mod.ArrSet;',
  8823. '$mod.ArrSet = rtl.arrayConcat("refSet", $mod.ArrSet, $mod.ArrSet);',
  8824. '$mod.ArrSet = rtl.arrayConcat("refSet", $mod.ArrSet, $mod.ArrSet, $mod.ArrSet);',
  8825. '$mod.ArrJSValue = $mod.ArrJSValue;',
  8826. '$mod.ArrJSValue = rtl.arrayConcatN($mod.ArrJSValue, $mod.ArrJSValue);',
  8827. '$mod.ArrJSValue = rtl.arrayConcatN($mod.ArrJSValue, $mod.ArrJSValue, $mod.ArrJSValue);',
  8828. '$mod.ArrInt = rtl.arrayConcatN([1], $mod.ArrInt);',
  8829. '$mod.ArrFlag = [$mod.TFlag.big];',
  8830. '$mod.ArrFlag = rtl.arrayConcatN([$mod.TFlag.big], $mod.ArrFlag);',
  8831. '$mod.ArrFlag = rtl.arrayConcatN($mod.ArrFlag, [$mod.TFlag.small]);',
  8832. '']));
  8833. end;
  8834. procedure TTestModule.TestArray_Copy;
  8835. begin
  8836. StartProgram(false);
  8837. Add([
  8838. 'type',
  8839. ' integer = longint;',
  8840. ' TFlag = (big,small);',
  8841. ' TFlags = set of TFlag;',
  8842. ' TRec = record',
  8843. ' i: integer;',
  8844. ' end;',
  8845. ' TArrInt = array of integer;',
  8846. ' TArrRec = array of TRec;',
  8847. ' TArrSet = array of TFlags;',
  8848. ' TArrJSValue = array of jsvalue;',
  8849. 'var',
  8850. ' ArrInt: tarrint;',
  8851. ' ArrRec: tarrrec;',
  8852. ' ArrSet: tarrset;',
  8853. ' ArrJSValue: tarrjsvalue;',
  8854. 'begin',
  8855. ' arrint:=copy(arrint);',
  8856. ' arrint:=copy(arrint,2);',
  8857. ' arrint:=copy(arrint,3,4);',
  8858. ' arrint:=copy([1,1],1,2);',
  8859. ' arrrec:=copy(arrrec);',
  8860. ' arrrec:=copy(arrrec,5);',
  8861. ' arrrec:=copy(arrrec,6,7);',
  8862. ' arrset:=copy(arrset);',
  8863. ' arrset:=copy(arrset,8);',
  8864. ' arrset:=copy(arrset,9,10);',
  8865. ' arrjsvalue:=copy(arrjsvalue);',
  8866. ' arrjsvalue:=copy(arrjsvalue,11);',
  8867. ' arrjsvalue:=copy(arrjsvalue,12,13);',
  8868. ' ']);
  8869. ConvertProgram;
  8870. CheckSource('TestArray_Copy',
  8871. LinesToStr([ // statements
  8872. 'this.TFlag = {',
  8873. ' "0": "big",',
  8874. ' big: 0,',
  8875. ' "1": "small",',
  8876. ' small: 1',
  8877. '};',
  8878. 'rtl.recNewT($mod, "TRec", function () {',
  8879. ' this.i = 0;',
  8880. ' this.$eq = function (b) {',
  8881. ' return this.i === b.i;',
  8882. ' };',
  8883. ' this.$assign = function (s) {',
  8884. ' this.i = s.i;',
  8885. ' return this;',
  8886. ' };',
  8887. '});',
  8888. 'this.ArrInt = [];',
  8889. 'this.ArrRec = [];',
  8890. 'this.ArrSet = [];',
  8891. 'this.ArrJSValue = [];',
  8892. '']),
  8893. LinesToStr([ // $mod.$main
  8894. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 0);',
  8895. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 2);',
  8896. '$mod.ArrInt = rtl.arrayCopy(0, $mod.ArrInt, 3, 4);',
  8897. '$mod.ArrInt = rtl.arrayCopy(0, [1, 1], 1, 2);',
  8898. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 0);',
  8899. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 5);',
  8900. '$mod.ArrRec = rtl.arrayCopy($mod.TRec, $mod.ArrRec, 6, 7);',
  8901. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 0);',
  8902. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 8);',
  8903. '$mod.ArrSet = rtl.arrayCopy("refSet", $mod.ArrSet, 9, 10);',
  8904. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 0);',
  8905. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 11);',
  8906. '$mod.ArrJSValue = rtl.arrayCopy(0, $mod.ArrJSValue, 12, 13);',
  8907. '']));
  8908. end;
  8909. procedure TTestModule.TestArray_InsertDelete;
  8910. begin
  8911. StartProgram(false);
  8912. Add([
  8913. 'type',
  8914. ' integer = longint;',
  8915. ' TFlag = (big,small);',
  8916. ' TFlags = set of TFlag;',
  8917. ' TRec = record',
  8918. ' i: integer;',
  8919. ' end;',
  8920. ' TArrInt = array of integer;',
  8921. ' TArrRec = array of TRec;',
  8922. ' TArrSet = array of TFlags;',
  8923. ' TArrJSValue = array of jsvalue;',
  8924. ' TArrArrInt = array of TArrInt;',
  8925. 'var',
  8926. ' ArrInt: tarrint;',
  8927. ' ArrRec: tarrrec;',
  8928. ' ArrSet: tarrset;',
  8929. ' ArrJSValue: tarrjsvalue;',
  8930. ' ArrArrInt: TArrArrInt;',
  8931. 'begin',
  8932. ' Insert(1,arrint,2);',
  8933. ' Insert(arrint[3],arrint,4);',
  8934. ' Insert(arrrec[5],arrrec,6);',
  8935. ' Insert(arrset[7],arrset,7);',
  8936. ' Insert(arrjsvalue[8],arrjsvalue,9);',
  8937. ' Insert(10,arrjsvalue,11);',
  8938. ' Insert([23],arrarrint,22);',
  8939. ' Delete(arrint,12,13);',
  8940. ' Delete(arrrec,14,15);',
  8941. ' Delete(arrset,17,18);',
  8942. ' Delete(arrjsvalue,19,10);']);
  8943. ConvertProgram;
  8944. CheckSource('TestArray_InsertDelete',
  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. 'this.ArrArrInt = [];',
  8967. '']),
  8968. LinesToStr([ // $mod.$main
  8969. '$mod.ArrInt.splice(2, 0, 1);',
  8970. '$mod.ArrInt.splice(4, 0, $mod.ArrInt[3]);',
  8971. '$mod.ArrRec.splice(6, 0, $mod.ArrRec[5]);',
  8972. '$mod.ArrSet.splice(7, 0, $mod.ArrSet[7]);',
  8973. '$mod.ArrJSValue.splice(9, 0, $mod.ArrJSValue[8]);',
  8974. '$mod.ArrJSValue.splice(11, 0, 10);',
  8975. '$mod.ArrArrInt.splice(22, 0, [23]);',
  8976. '$mod.ArrInt.splice(12, 13);',
  8977. '$mod.ArrRec.splice(14, 15);',
  8978. '$mod.ArrSet.splice(17, 18);',
  8979. '$mod.ArrJSValue.splice(19, 10);',
  8980. '']));
  8981. end;
  8982. procedure TTestModule.TestArray_DynArrayConstObjFPC;
  8983. begin
  8984. StartProgram(false);
  8985. Add([
  8986. '{$modeswitch arrayoperators}',
  8987. 'type',
  8988. ' integer = longint;',
  8989. ' TArrInt = array of integer;',
  8990. ' TArrStr = array of string;',
  8991. 'const',
  8992. ' Ints: TArrInt = (1,2,3);',
  8993. ' Aliases: TarrStr = (''foo'',''b'');',
  8994. ' OneInt: TArrInt = (7);',
  8995. ' OneStr: array of integer = (7);',
  8996. ' Chars: array of char = ''aoc'';',
  8997. ' Names: array of string = (''a'',''foo'');',
  8998. ' NameCount = low(Names)+high(Names)+length(Names);',
  8999. 'var i: integer;',
  9000. 'begin',
  9001. ' Ints:=[];',
  9002. ' Ints:=[1,1];',
  9003. ' Ints:=[1]+[2];',
  9004. ' Ints:=[2];',
  9005. ' Ints:=[]+ints;',
  9006. ' Ints:=Ints+[];',
  9007. ' Ints:=Ints+OneInt;',
  9008. ' Ints:=Ints+[1,1];',
  9009. ' Ints:=[i,i]+Ints;',
  9010. ' Ints:=[1]+[i]+[3];',
  9011. '']);
  9012. ConvertProgram;
  9013. CheckSource('TestArray_DynArrayConstObjFPC',
  9014. LinesToStr([ // statements
  9015. 'this.Ints = [1, 2, 3];',
  9016. 'this.Aliases = ["foo", "b"];',
  9017. 'this.OneInt = [7];',
  9018. 'this.OneStr = [7];',
  9019. 'this.Chars = ["a", "o", "c"];',
  9020. 'this.Names = ["a", "foo"];',
  9021. 'this.NameCount = 0 + (rtl.length($mod.Names) - 1) + rtl.length($mod.Names);',
  9022. 'this.i = 0;',
  9023. '']),
  9024. LinesToStr([ // $mod.$main
  9025. '$mod.Ints = [];',
  9026. '$mod.Ints = [1, 1];',
  9027. '$mod.Ints = rtl.arrayConcatN([1], [2]);',
  9028. '$mod.Ints = [2];',
  9029. '$mod.Ints = rtl.arrayConcatN([], $mod.Ints);',
  9030. '$mod.Ints = rtl.arrayConcatN($mod.Ints, []);',
  9031. '$mod.Ints = rtl.arrayConcatN($mod.Ints, $mod.OneInt);',
  9032. '$mod.Ints = rtl.arrayConcatN($mod.Ints, [1, 1]);',
  9033. '$mod.Ints = rtl.arrayConcatN([$mod.i, $mod.i], $mod.Ints);',
  9034. '$mod.Ints = rtl.arrayConcatN(rtl.arrayConcatN([1], [$mod.i]), [3]);',
  9035. '']));
  9036. end;
  9037. procedure TTestModule.TestArray_DynArrayConstDelphi;
  9038. begin
  9039. StartProgram(false);
  9040. // Note: const c = [1,1]; defines a set!
  9041. Add([
  9042. '{$mode delphi}',
  9043. 'type',
  9044. ' integer = longint;',
  9045. ' TArrInt = array of integer;',
  9046. ' TArrStr = array of string;',
  9047. 'const',
  9048. ' Ints: TArrInt = [1,1,2];',
  9049. ' Aliases: TarrStr = [''foo'',''b''];',
  9050. ' OneInt: TArrInt = [7];',
  9051. ' OneStr: array of integer = [7]+[8];',
  9052. ' Chars: array of char = ''aoc'';',
  9053. ' Names: array of string = [''a'',''a''];',
  9054. ' NameCount = low(Names)+high(Names)+length(Names);',
  9055. 'begin',
  9056. '']);
  9057. ConvertProgram;
  9058. CheckSource('TestArray_DynArrayConstDelphi',
  9059. LinesToStr([ // statements
  9060. 'this.Ints = [1, 1, 2];',
  9061. 'this.Aliases = ["foo", "b"];',
  9062. 'this.OneInt = [7];',
  9063. 'this.OneStr = rtl.arrayConcatN([7],[8]);',
  9064. 'this.Chars = ["a", "o", "c"];',
  9065. 'this.Names = ["a", "a"];',
  9066. 'this.NameCount = 0 + (rtl.length($mod.Names) - 1) + rtl.length($mod.Names);',
  9067. '']),
  9068. LinesToStr([ // $mod.$main
  9069. '']));
  9070. end;
  9071. procedure TTestModule.TestArray_ArrayLitAsParam;
  9072. begin
  9073. StartProgram(false);
  9074. Add([
  9075. '{$modeswitch arrayoperators}',
  9076. 'type',
  9077. ' integer = longint;',
  9078. ' TArrInt = array of integer;',
  9079. ' TArrSet = array of (red,green,blue);',
  9080. 'procedure DoOpenInt(a: array of integer); forward;',
  9081. 'procedure DoInt(a: TArrInt);',
  9082. 'begin',
  9083. ' DoInt(a+[1]);',
  9084. ' DoInt([1]+a);',
  9085. ' DoOpenInt(a);',
  9086. ' DoOpenInt(a+[1]);',
  9087. ' DoOpenInt([1]+a);',
  9088. 'end;',
  9089. 'procedure DoOpenInt(a: array of integer);',
  9090. 'begin',
  9091. ' DoOpenInt(a+[1]);',
  9092. ' DoOpenInt([1]+a);',
  9093. ' DoInt(a);',
  9094. ' DoInt(a+[1]);',
  9095. ' DoInt([1]+a);',
  9096. 'end;',
  9097. 'procedure DoSet(a: TArrSet);',
  9098. 'begin',
  9099. ' DoSet(a+[red]);',
  9100. ' DoSet([blue]+a);',
  9101. 'end;',
  9102. 'var',
  9103. ' i: TArrInt;',
  9104. ' s: TArrSet;',
  9105. 'begin',
  9106. ' DoInt([1]);',
  9107. ' DoInt([1]+[2]);',
  9108. ' DoInt(i+[1]);',
  9109. ' DoInt([1]+i);',
  9110. ' DoOpenInt([1]);',
  9111. ' DoOpenInt([1]+[2]);',
  9112. ' DoOpenInt(i+[1]);',
  9113. ' DoOpenInt([1]+i);',
  9114. ' DoSet([red]);',
  9115. ' DoSet([blue]+[green]);',
  9116. ' DoSet(s+[blue]);',
  9117. ' DoSet([red]+s);',
  9118. '']);
  9119. ConvertProgram;
  9120. CheckSource('TestArray_ArrayLitAsParam',
  9121. LinesToStr([ // statements
  9122. 'this.TArrSet$a = {',
  9123. ' "0": "red",',
  9124. ' red: 0,',
  9125. ' "1": "green",',
  9126. ' green: 1,',
  9127. ' "2": "blue",',
  9128. ' blue: 2',
  9129. '};',
  9130. 'this.DoInt = function (a) {',
  9131. ' $mod.DoInt(rtl.arrayConcatN(a, [1]));',
  9132. ' $mod.DoInt(rtl.arrayConcatN([1], a));',
  9133. ' $mod.DoOpenInt(a);',
  9134. ' $mod.DoOpenInt(rtl.arrayConcatN(a, [1]));',
  9135. ' $mod.DoOpenInt(rtl.arrayConcatN([1], a));',
  9136. '};',
  9137. 'this.DoOpenInt = function (a) {',
  9138. ' $mod.DoOpenInt(rtl.arrayConcatN(a, [1]));',
  9139. ' $mod.DoOpenInt(rtl.arrayConcatN([1], a));',
  9140. ' $mod.DoInt(a);',
  9141. ' $mod.DoInt(rtl.arrayConcatN(a, [1]));',
  9142. ' $mod.DoInt(rtl.arrayConcatN([1], a));',
  9143. '};',
  9144. 'this.DoSet = function (a) {',
  9145. ' $mod.DoSet(rtl.arrayConcatN(a, [$mod.TArrSet$a.red]));',
  9146. ' $mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.blue], a));',
  9147. '};',
  9148. 'this.i = [];',
  9149. 'this.s = [];',
  9150. '']),
  9151. LinesToStr([ // $mod.$main
  9152. '$mod.DoInt([1]);',
  9153. '$mod.DoInt(rtl.arrayConcatN([1], [2]));',
  9154. '$mod.DoInt(rtl.arrayConcatN($mod.i, [1]));',
  9155. '$mod.DoInt(rtl.arrayConcatN([1], $mod.i));',
  9156. '$mod.DoOpenInt([1]);',
  9157. '$mod.DoOpenInt(rtl.arrayConcatN([1], [2]));',
  9158. '$mod.DoOpenInt(rtl.arrayConcatN($mod.i, [1]));',
  9159. '$mod.DoOpenInt(rtl.arrayConcatN([1], $mod.i));',
  9160. '$mod.DoSet([$mod.TArrSet$a.red]);',
  9161. '$mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.blue], [$mod.TArrSet$a.green]));',
  9162. '$mod.DoSet(rtl.arrayConcatN($mod.s, [$mod.TArrSet$a.blue]));',
  9163. '$mod.DoSet(rtl.arrayConcatN([$mod.TArrSet$a.red], $mod.s));',
  9164. '']));
  9165. end;
  9166. procedure TTestModule.TestArray_ArrayLitMultiDimAsParam;
  9167. begin
  9168. StartProgram(false);
  9169. Add([
  9170. '{$modeswitch arrayoperators}',
  9171. 'type',
  9172. ' integer = longint;',
  9173. ' TArrInt = array of integer;',
  9174. ' TArrArrInt = array of TArrInt;',
  9175. 'procedure DoInt(a: TArrArrInt);',
  9176. 'begin',
  9177. ' DoInt(a+[[1]]);',
  9178. ' DoInt([[1]]+a);',
  9179. ' DoInt(a);',
  9180. 'end;',
  9181. 'var',
  9182. ' i: TArrInt;',
  9183. ' a: TArrArrInt;',
  9184. 'begin',
  9185. ' a:=[[1]];',
  9186. ' a:=[i];',
  9187. ' a:=a+[i];',
  9188. ' a:=[i]+a;',
  9189. ' a:=[[1]+i];',
  9190. ' a:=[[1]+[2]];',
  9191. ' a:=[i+[2]];',
  9192. ' DoInt([[1]]);',
  9193. ' DoInt([[1]+[2],[3,4],[5]]);',
  9194. ' DoInt([i+[1]]+a);',
  9195. ' DoInt([i]+a);',
  9196. '']);
  9197. ConvertProgram;
  9198. CheckSource('TestArray_ArrayLitMultiDimAsParam',
  9199. LinesToStr([ // statements
  9200. 'this.DoInt = function (a) {',
  9201. ' $mod.DoInt(rtl.arrayConcatN(a, [[1]]));',
  9202. ' $mod.DoInt(rtl.arrayConcatN([[1]], a));',
  9203. ' $mod.DoInt(a);',
  9204. '};',
  9205. 'this.i = [];',
  9206. 'this.a = [];',
  9207. '']),
  9208. LinesToStr([ // $mod.$main
  9209. '$mod.a = [[1]];',
  9210. '$mod.a = [$mod.i];',
  9211. '$mod.a = rtl.arrayConcatN($mod.a, [$mod.i]);',
  9212. '$mod.a = rtl.arrayConcatN([$mod.i], $mod.a);',
  9213. '$mod.a = [rtl.arrayConcatN([1], $mod.i)];',
  9214. '$mod.a = [rtl.arrayConcatN([1], [2])];',
  9215. '$mod.a = [rtl.arrayConcatN($mod.i, [2])];',
  9216. '$mod.DoInt([[1]]);',
  9217. '$mod.DoInt([rtl.arrayConcatN([1], [2]), [3, 4], [5]]);',
  9218. '$mod.DoInt(rtl.arrayConcatN([rtl.arrayConcatN($mod.i, [1])], $mod.a));',
  9219. '$mod.DoInt(rtl.arrayConcatN([$mod.i], $mod.a));',
  9220. '']));
  9221. end;
  9222. procedure TTestModule.TestArray_ArrayLitStaticAsParam;
  9223. begin
  9224. StartProgram(false);
  9225. Add([
  9226. '{$modeswitch arrayoperators}',
  9227. 'type',
  9228. ' integer = longint;',
  9229. ' TArrInt = array[1..2] of integer;',
  9230. ' TArrArrInt = array of TArrInt;',
  9231. 'procedure DoInt(a: TArrArrInt);',
  9232. 'begin',
  9233. ' DoInt(a+[[1,2]]);',
  9234. ' DoInt([[1,2]]+a);',
  9235. ' DoInt(a);',
  9236. 'end;',
  9237. 'var',
  9238. ' i: TArrInt;',
  9239. ' a: TArrArrInt;',
  9240. 'begin',
  9241. ' a:=[[1,1]];',
  9242. ' a:=[i];',
  9243. ' a:=a+[i];',
  9244. ' a:=[i]+a;',
  9245. ' DoInt([[1,1]]);',
  9246. ' DoInt([[1,2],[3,4]]);',
  9247. '']);
  9248. ConvertProgram;
  9249. CheckSource('TestArray_ArrayLitStaticAsParam',
  9250. LinesToStr([ // statements
  9251. 'this.DoInt = function (a) {',
  9252. ' $mod.DoInt(rtl.arrayConcatN(a, [[1, 2]]));',
  9253. ' $mod.DoInt(rtl.arrayConcatN([[1, 2]], a));',
  9254. ' $mod.DoInt(a);',
  9255. '};',
  9256. 'this.i = rtl.arraySetLength(null, 0, 2);',
  9257. 'this.a = [];',
  9258. '']),
  9259. LinesToStr([ // $mod.$main
  9260. '$mod.a = [[1, 1]];',
  9261. '$mod.a = [$mod.i.slice(0)];',
  9262. '$mod.a = rtl.arrayConcatN($mod.a, [$mod.i.slice(0)]);',
  9263. '$mod.a = rtl.arrayConcatN([$mod.i.slice(0)], $mod.a);',
  9264. '$mod.DoInt([[1, 1]]);',
  9265. '$mod.DoInt([[1, 2], [3, 4]]);',
  9266. '']));
  9267. end;
  9268. procedure TTestModule.TestArray_ForInArrOfString;
  9269. begin
  9270. StartProgram(false);
  9271. Add([
  9272. 'type',
  9273. 'type',
  9274. ' TMonthNameArray = array [1..12] of string;',
  9275. ' TMonthNames = TMonthNameArray;',
  9276. ' TObject = class',
  9277. ' private',
  9278. ' function GetLongMonthNames: TMonthNames; virtual; abstract;',
  9279. ' public',
  9280. ' Property LongMonthNames : TMonthNames Read GetLongMonthNames;',
  9281. ' end;',
  9282. 'var f: TObject;',
  9283. ' Month: string;',
  9284. 'begin',
  9285. ' for Month in f.LongMonthNames do ;',
  9286. '']);
  9287. ConvertProgram;
  9288. CheckSource('TestArray_ForInArrOfString',
  9289. LinesToStr([ // statements
  9290. 'rtl.createClass($mod, "TObject", null, function () {',
  9291. ' this.$init = function () {',
  9292. ' };',
  9293. ' this.$final = function () {',
  9294. ' };',
  9295. '});',
  9296. 'this.f = null;',
  9297. 'this.Month = "";',
  9298. '']),
  9299. LinesToStr([ // $mod.$main
  9300. 'for (var $in1 = $mod.f.GetLongMonthNames(), $l2 = 0, $end3 = rtl.length($in1) - 1; $l2 <= $end3; $l2++) $mod.Month = $in1[$l2];',
  9301. '']));
  9302. end;
  9303. procedure TTestModule.TestExternalClass_TypeCastArrayToExternalClass;
  9304. begin
  9305. StartProgram(false);
  9306. Add([
  9307. '{$modeswitch externalclass}',
  9308. 'type',
  9309. ' TJSObject = class external name ''Object''',
  9310. ' end;',
  9311. ' TJSArray = class external name ''Array''',
  9312. ' class function isArray(Value: JSValue) : boolean;',
  9313. ' function concat() : TJSArray; varargs;',
  9314. ' end;',
  9315. 'var',
  9316. ' aObj: TJSArray;',
  9317. ' a: array of longint;',
  9318. ' o: TJSObject;',
  9319. 'begin',
  9320. ' if TJSArray.isArray(65) then ;',
  9321. ' aObj:=TJSArray(a).concat(a);',
  9322. ' o:=TJSObject(a);']);
  9323. ConvertProgram;
  9324. CheckSource('TestExternalClass_TypeCastArrayToExternalClass',
  9325. LinesToStr([ // statements
  9326. 'this.aObj = null;',
  9327. 'this.a = [];',
  9328. 'this.o = null;',
  9329. '']),
  9330. LinesToStr([ // $mod.$main
  9331. 'if (Array.isArray(65)) ;',
  9332. '$mod.aObj = $mod.a.concat($mod.a);',
  9333. '$mod.o = $mod.a;',
  9334. '']));
  9335. end;
  9336. procedure TTestModule.TestExternalClass_TypeCastArrayFromExternalClass;
  9337. begin
  9338. StartProgram(false);
  9339. Add([
  9340. '{$modeswitch externalclass}',
  9341. 'type',
  9342. ' TArrStr = array of string;',
  9343. ' TJSArray = class external name ''Array''',
  9344. ' end;',
  9345. ' TJSObject = class external name ''Object''',
  9346. ' end;',
  9347. 'var',
  9348. ' aObj: TJSArray;',
  9349. ' a: TArrStr;',
  9350. ' jo: TJSObject;',
  9351. 'begin',
  9352. ' a:=TArrStr(aObj);',
  9353. ' TArrStr(aObj)[1]:=TArrStr(aObj)[2];',
  9354. ' a:=TarrStr(jo);',
  9355. '']);
  9356. ConvertProgram;
  9357. CheckSource('TestExternalClass_TypeCastArrayFromExternalClass',
  9358. LinesToStr([ // statements
  9359. 'this.aObj = null;',
  9360. 'this.a = [];',
  9361. 'this.jo = null;',
  9362. '']),
  9363. LinesToStr([ // $mod.$main
  9364. '$mod.a = $mod.aObj;',
  9365. '$mod.aObj[1] = $mod.aObj[2];',
  9366. '$mod.a = $mod.jo;',
  9367. '']));
  9368. end;
  9369. procedure TTestModule.TestArrayOfConst_TVarRec;
  9370. begin
  9371. StartProgram(true,[supTVarRec]);
  9372. Add([
  9373. 'procedure Say(args: array of const);',
  9374. 'var',
  9375. ' i: longint;',
  9376. ' v: TVarRec;',
  9377. 'begin',
  9378. ' for i:=low(args) to high(args) do begin',
  9379. ' v:=args[i];',
  9380. ' case v.vtype of',
  9381. ' vtInteger: if length(args)=args[i].vInteger then ;',
  9382. ' end;',
  9383. ' end;',
  9384. ' for v in args do ;',
  9385. ' args:=nil;',
  9386. ' SetLength(args,2);',
  9387. 'end;',
  9388. 'begin']);
  9389. ConvertProgram;
  9390. CheckSource('TestArrayOfConst_TVarRec',
  9391. LinesToStr([ // statements
  9392. 'this.Say = function (args) {',
  9393. ' var i = 0;',
  9394. ' var v = pas.system.TVarRec.$new();',
  9395. ' for (var $l1 = 0, $end2 = rtl.length(args) - 1; $l1 <= $end2; $l1++) {',
  9396. ' i = $l1;',
  9397. ' v.$assign(args[i]);',
  9398. ' var $tmp3 = v.VType;',
  9399. ' if ($tmp3 === 0) if (rtl.length(args) === args[i].VJSValue) ;',
  9400. ' };',
  9401. ' for (var $in4 = args, $l5 = 0, $end6 = rtl.length($in4) - 1; $l5 <= $end6; $l5++) v = $in4[$l5];',
  9402. ' args = [];',
  9403. ' args = rtl.arraySetLength(args, pas.system.TVarRec, 2);',
  9404. '};',
  9405. '']),
  9406. LinesToStr([ // $mod.$main
  9407. ]));
  9408. end;
  9409. procedure TTestModule.TestArrayOfConst_PassBaseTypes;
  9410. begin
  9411. StartProgram(true,[supTVarRec]);
  9412. Add([
  9413. 'procedure Say(args: array of const);',
  9414. 'begin',
  9415. ' Say(args);',
  9416. 'end;',
  9417. 'var',
  9418. ' p: Pointer;',
  9419. ' j: jsvalue;',
  9420. ' c: currency;',
  9421. 'begin',
  9422. ' Say([]);',
  9423. ' Say([1]);',
  9424. ' Say([''c'',''foo'',nil,true,1.3,p,j,c]);',
  9425. '']);
  9426. ConvertProgram;
  9427. CheckSource('TestArrayOfConst_PassBaseTypes',
  9428. LinesToStr([ // statements
  9429. 'this.Say = function (args) {',
  9430. ' $mod.Say(args);',
  9431. '};',
  9432. 'this.p = null;',
  9433. 'this.j = undefined;',
  9434. 'this.c = 0;',
  9435. '']),
  9436. LinesToStr([ // $mod.$main
  9437. '$mod.Say([]);',
  9438. '$mod.Say(pas.system.VarRecs(0, 1));',
  9439. '$mod.Say(pas.system.VarRecs(',
  9440. ' 9,',
  9441. ' "c",',
  9442. ' 18,',
  9443. ' "foo",',
  9444. ' 5,',
  9445. ' null,',
  9446. ' 1,',
  9447. ' true,',
  9448. ' 3,',
  9449. ' 1.3,',
  9450. ' 5,',
  9451. ' $mod.p,',
  9452. ' 20,',
  9453. ' $mod.j,',
  9454. ' 12,',
  9455. ' $mod.c',
  9456. ' ));',
  9457. '']));
  9458. end;
  9459. procedure TTestModule.TestArrayOfConst_PassObj;
  9460. begin
  9461. StartProgram(true,[supTVarRec]);
  9462. Add([
  9463. '{$interfaces corba}',
  9464. 'type',
  9465. ' TObject = class',
  9466. ' end;',
  9467. ' TClass = class of TObject;',
  9468. ' IUnknown = interface',
  9469. ' end;',
  9470. 'procedure Say(args: array of const);',
  9471. 'begin',
  9472. 'end;',
  9473. 'var',
  9474. ' o: TObject;',
  9475. ' c: TClass;',
  9476. ' i: IUnknown;',
  9477. 'begin',
  9478. ' Say([o,c,TObject]);',
  9479. ' Say([nil,i]);',
  9480. '']);
  9481. ConvertProgram;
  9482. CheckSource('TestArrayOfConst_PassObj',
  9483. LinesToStr([ // statements
  9484. 'rtl.createClass($mod, "TObject", null, function () {',
  9485. ' this.$init = function () {',
  9486. ' };',
  9487. ' this.$final = function () {',
  9488. ' };',
  9489. '});',
  9490. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  9491. 'this.Say = function (args) {',
  9492. '};',
  9493. 'this.o = null;',
  9494. 'this.c = null;',
  9495. 'this.i = null;',
  9496. '']),
  9497. LinesToStr([ // $mod.$main
  9498. '$mod.Say(pas.system.VarRecs(',
  9499. ' 7,',
  9500. ' $mod.o,',
  9501. ' 8,',
  9502. ' $mod.c,',
  9503. ' 8,',
  9504. ' $mod.TObject',
  9505. '));',
  9506. '$mod.Say(pas.system.VarRecs(5, null, 14, $mod.i));',
  9507. '']));
  9508. end;
  9509. procedure TTestModule.TestRecord_Empty;
  9510. begin
  9511. StartProgram(false);
  9512. Add([
  9513. 'type',
  9514. ' TRecA = record',
  9515. ' end;',
  9516. 'var a,b: TRecA;',
  9517. 'begin',
  9518. ' if a=b then ;']);
  9519. ConvertProgram;
  9520. CheckSource('TestRecord_Empty',
  9521. LinesToStr([ // statements
  9522. 'rtl.recNewT($mod, "TRecA", function () {',
  9523. ' this.$eq = function (b) {',
  9524. ' return true;',
  9525. ' };',
  9526. ' this.$assign = function (s) {',
  9527. ' return this;',
  9528. ' };',
  9529. '});',
  9530. 'this.a = $mod.TRecA.$new();',
  9531. 'this.b = $mod.TRecA.$new();',
  9532. '']),
  9533. LinesToStr([ // $mod.$main
  9534. 'if ($mod.a.$eq($mod.b)) ;'
  9535. ]));
  9536. end;
  9537. procedure TTestModule.TestRecord_Var;
  9538. begin
  9539. StartProgram(false);
  9540. Add('type');
  9541. Add(' TRecA = record');
  9542. Add(' Bold: longint;');
  9543. Add(' end;');
  9544. Add('var Rec: TRecA;');
  9545. Add('begin');
  9546. Add(' rec.bold:=123');
  9547. ConvertProgram;
  9548. CheckSource('TestRecord_Var',
  9549. LinesToStr([ // statements
  9550. 'rtl.recNewT($mod, "TRecA", function () {',
  9551. ' this.Bold = 0;',
  9552. ' this.$eq = function (b) {',
  9553. ' return this.Bold === b.Bold;',
  9554. ' };',
  9555. ' this.$assign = function (s) {',
  9556. ' this.Bold = s.Bold;',
  9557. ' return this;',
  9558. ' };',
  9559. '});',
  9560. 'this.Rec = $mod.TRecA.$new();',
  9561. '']),
  9562. LinesToStr([ // $mod.$main
  9563. '$mod.Rec.Bold = 123;'
  9564. ]));
  9565. end;
  9566. procedure TTestModule.TestRecord_VarExternal;
  9567. begin
  9568. StartProgram(false);
  9569. Add([
  9570. '{$modeswitch externalclass}',
  9571. 'type',
  9572. ' TRecA = record',
  9573. ' i: byte;',
  9574. ' length_: longint external name ''length'';',
  9575. ' end;',
  9576. 'var Rec: TRecA;',
  9577. 'begin',
  9578. ' rec.length_ := rec.length_',
  9579. '']);
  9580. ConvertProgram;
  9581. CheckSource('TestRecord_VarExternal',
  9582. LinesToStr([ // statements
  9583. 'rtl.recNewT($mod, "TRecA", function () {',
  9584. ' this.i = 0;',
  9585. ' this.$eq = function (b) {',
  9586. ' return (this.i === b.i) && (this.length === b.length);',
  9587. ' };',
  9588. ' this.$assign = function (s) {',
  9589. ' this.i = s.i;',
  9590. ' this.length = s.length;',
  9591. ' return this;',
  9592. ' };',
  9593. '});',
  9594. 'this.Rec = $mod.TRecA.$new();',
  9595. '']),
  9596. LinesToStr([ // $mod.$main
  9597. '$mod.Rec.length = $mod.Rec.length;'
  9598. ]));
  9599. end;
  9600. procedure TTestModule.TestRecord_WithDo;
  9601. begin
  9602. StartProgram(false);
  9603. Add('type');
  9604. Add(' TRec = record');
  9605. Add(' vI: longint;');
  9606. Add(' end;');
  9607. Add('var');
  9608. Add(' Int: longint;');
  9609. Add(' r: TRec;');
  9610. Add('begin');
  9611. Add(' with r do');
  9612. Add(' int:=vi;');
  9613. Add(' with r do begin');
  9614. Add(' int:=vi;');
  9615. Add(' vi:=int;');
  9616. Add(' end;');
  9617. ConvertProgram;
  9618. CheckSource('TestWithRecordDo',
  9619. LinesToStr([ // statements
  9620. 'rtl.recNewT($mod, "TRec", function () {',
  9621. ' this.vI = 0;',
  9622. ' this.$eq = function (b) {',
  9623. ' return this.vI === b.vI;',
  9624. ' };',
  9625. ' this.$assign = function (s) {',
  9626. ' this.vI = s.vI;',
  9627. ' return this;',
  9628. ' };',
  9629. '});',
  9630. 'this.Int = 0;',
  9631. 'this.r = $mod.TRec.$new();',
  9632. '']),
  9633. LinesToStr([ // $mod.$main
  9634. 'var $with1 = $mod.r;',
  9635. '$mod.Int = $with1.vI;',
  9636. 'var $with2 = $mod.r;',
  9637. '$mod.Int = $with2.vI;',
  9638. '$with2.vI = $mod.Int;'
  9639. ]));
  9640. end;
  9641. procedure TTestModule.TestRecord_Assign;
  9642. begin
  9643. StartProgram(false);
  9644. Add('type');
  9645. Add(' TEnum = (red,green);');
  9646. Add(' TEnums = set of TEnum;');
  9647. Add(' TSmallRec = record');
  9648. Add(' N: longint;');
  9649. Add(' end;');
  9650. Add(' TBigRec = record');
  9651. Add(' Int: longint;');
  9652. Add(' D: double;');
  9653. Add(' Arr: array of longint;');
  9654. Add(' Arr2: array[1..2] of longint;');
  9655. Add(' Small: TSmallRec;');
  9656. Add(' Enums: TEnums;');
  9657. Add(' end;');
  9658. Add('var');
  9659. Add(' r, s: TBigRec;');
  9660. Add('begin');
  9661. Add(' r:=s;');
  9662. Add(' r:=default(TBigRec);');
  9663. Add(' r:=default(s);');
  9664. ConvertProgram;
  9665. CheckSource('TestRecord_Assign',
  9666. LinesToStr([ // statements
  9667. 'this.TEnum = {',
  9668. ' "0": "red",',
  9669. ' red: 0,',
  9670. ' "1": "green",',
  9671. ' green: 1',
  9672. '};',
  9673. 'rtl.recNewT($mod, "TSmallRec", function () {',
  9674. ' this.N = 0;',
  9675. ' this.$eq = function (b) {',
  9676. ' return this.N === b.N;',
  9677. ' };',
  9678. ' this.$assign = function (s) {',
  9679. ' this.N = s.N;',
  9680. ' return this;',
  9681. ' };',
  9682. '});',
  9683. 'rtl.recNewT($mod, "TBigRec", function () {',
  9684. ' this.Int = 0;',
  9685. ' this.D = 0.0;',
  9686. ' this.Arr = [];',
  9687. ' this.$new = function () {',
  9688. ' var r = Object.create(this);',
  9689. ' r.Arr2 = rtl.arraySetLength(null, 0, 2);',
  9690. ' r.Small = $mod.TSmallRec.$new();',
  9691. ' r.Enums = {};',
  9692. ' return r;',
  9693. ' };',
  9694. ' this.$eq = function (b) {',
  9695. ' 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);',
  9696. ' };',
  9697. ' this.$assign = function (s) {',
  9698. ' this.Int = s.Int;',
  9699. ' this.D = s.D;',
  9700. ' this.Arr = s.Arr;',
  9701. ' this.Arr2 = s.Arr2.slice(0);',
  9702. ' this.Small.$assign(s.Small);',
  9703. ' this.Enums = rtl.refSet(s.Enums);',
  9704. ' return this;',
  9705. ' };',
  9706. '});',
  9707. 'this.r = $mod.TBigRec.$new();',
  9708. 'this.s = $mod.TBigRec.$new();',
  9709. '']),
  9710. LinesToStr([ // $mod.$main
  9711. '$mod.r.$assign($mod.s);',
  9712. '$mod.r.$assign($mod.TBigRec.$new());',
  9713. '$mod.r.$assign($mod.TBigRec.$new());',
  9714. '']));
  9715. end;
  9716. procedure TTestModule.TestRecord_AsParams;
  9717. begin
  9718. StartProgram(false);
  9719. Add([
  9720. 'type',
  9721. ' integer = longint;',
  9722. ' TRecord = record',
  9723. ' i: integer;',
  9724. ' end;',
  9725. 'procedure DoIt(vD: TRecord; const vC: TRecord; var vV: TRecord; var U);',
  9726. 'var vL: TRecord;',
  9727. 'begin',
  9728. ' vd:=vd;',
  9729. ' vd.i:=vd.i;',
  9730. ' vl:=vc;',
  9731. ' vv:=vv;',
  9732. ' vv.i:=vv.i;',
  9733. ' U:=vl;',
  9734. ' U:=vd;',
  9735. ' U:=vc;',
  9736. ' U:=vv;',
  9737. ' vl:=TRecord(U);',
  9738. ' vd:=TRecord(U);',
  9739. ' vv:=TRecord(U);',
  9740. ' doit(vd,vd,vd,vd);',
  9741. ' doit(vc,vc,vl,vl);',
  9742. ' doit(vv,vv,vv,vv);',
  9743. ' doit(vl,vl,vl,vl);',
  9744. ' TRecord(U).i:=3;',
  9745. 'end;',
  9746. 'var i: TRecord;',
  9747. 'begin',
  9748. ' doit(i,i,i,i);',
  9749. '']);
  9750. ConvertProgram;
  9751. CheckSource('TestRecord_AsParams',
  9752. LinesToStr([ // statements
  9753. 'rtl.recNewT($mod, "TRecord", function () {',
  9754. ' this.i = 0;',
  9755. ' this.$eq = function (b) {',
  9756. ' return this.i === b.i;',
  9757. ' };',
  9758. ' this.$assign = function (s) {',
  9759. ' this.i = s.i;',
  9760. ' return this;',
  9761. ' };',
  9762. '});',
  9763. 'this.DoIt = function (vD, vC, vV, U) {',
  9764. ' var vL = $mod.TRecord.$new();',
  9765. ' vD.$assign(vD);',
  9766. ' vD.i = vD.i;',
  9767. ' vL.$assign(vC);',
  9768. ' vV.$assign(vV);',
  9769. ' vV.i = vV.i;',
  9770. ' U.$assign(vL);',
  9771. ' U.$assign(vD);',
  9772. ' U.$assign(vC);',
  9773. ' U.$assign(vV);',
  9774. ' vL.$assign(U);',
  9775. ' vD.$assign(U);',
  9776. ' vV.$assign(U);',
  9777. ' $mod.DoIt($mod.TRecord.$clone(vD), vD, vD, vD);',
  9778. ' $mod.DoIt($mod.TRecord.$clone(vC), vC, vL, vL);',
  9779. ' $mod.DoIt($mod.TRecord.$clone(vV), vV, vV, vV);',
  9780. ' $mod.DoIt($mod.TRecord.$clone(vL), vL, vL, vL);',
  9781. ' U.i = 3;',
  9782. '};',
  9783. 'this.i = $mod.TRecord.$new();'
  9784. ]),
  9785. LinesToStr([
  9786. '$mod.DoIt($mod.TRecord.$clone($mod.i), $mod.i, $mod.i, $mod.i);',
  9787. '']));
  9788. end;
  9789. procedure TTestModule.TestRecordElement_AsParams;
  9790. begin
  9791. StartProgram(false);
  9792. Add('type');
  9793. Add(' integer = longint;');
  9794. Add(' TRecord = record');
  9795. Add(' i: integer;');
  9796. Add(' end;');
  9797. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  9798. Add('var vJ: TRecord;');
  9799. Add('begin');
  9800. Add(' doit(vj.i,vj.i,vj.i);');
  9801. Add('end;');
  9802. Add('var r: TRecord;');
  9803. Add('begin');
  9804. Add(' doit(r.i,r.i,r.i);');
  9805. ConvertProgram;
  9806. CheckSource('TestRecordElement_AsParams',
  9807. LinesToStr([ // statements
  9808. 'rtl.recNewT($mod, "TRecord", function () {',
  9809. ' this.i = 0;',
  9810. ' this.$eq = function (b) {',
  9811. ' return this.i === b.i;',
  9812. ' };',
  9813. ' this.$assign = function (s) {',
  9814. ' this.i = s.i;',
  9815. ' return this;',
  9816. ' };',
  9817. '});',
  9818. 'this.DoIt = function (vG,vH,vI) {',
  9819. ' var vJ = $mod.TRecord.$new();',
  9820. ' $mod.DoIt(vJ.i, vJ.i, {',
  9821. ' p: vJ,',
  9822. ' get: function () {',
  9823. ' return this.p.i;',
  9824. ' },',
  9825. ' set: function (v) {',
  9826. ' this.p.i = v;',
  9827. ' }',
  9828. ' });',
  9829. '};',
  9830. 'this.r = $mod.TRecord.$new();'
  9831. ]),
  9832. LinesToStr([
  9833. '$mod.DoIt($mod.r.i,$mod.r.i,{',
  9834. ' p: $mod.r,',
  9835. ' get: function () {',
  9836. ' return this.p.i;',
  9837. ' },',
  9838. ' set: function (v) {',
  9839. ' this.p.i = v;',
  9840. ' }',
  9841. '});'
  9842. ]));
  9843. end;
  9844. procedure TTestModule.TestRecordElementFromFuncResult_AsParams;
  9845. begin
  9846. StartProgram(false);
  9847. Add('type');
  9848. Add(' integer = longint;');
  9849. Add(' TRecord = record');
  9850. Add(' i: integer;');
  9851. Add(' end;');
  9852. Add('function GetRec(vB: integer = 0): TRecord;');
  9853. Add('begin');
  9854. Add('end;');
  9855. Add('procedure DoIt(vG: integer; const vH: integer);');
  9856. Add('begin');
  9857. Add('end;');
  9858. Add('begin');
  9859. Add(' doit(getrec.i,getrec.i);');
  9860. Add(' doit(getrec().i,getrec().i);');
  9861. Add(' doit(getrec(1).i,getrec(2).i);');
  9862. ConvertProgram;
  9863. CheckSource('TestRecordElementFromFuncResult_AsParams',
  9864. LinesToStr([ // statements
  9865. 'rtl.recNewT($mod, "TRecord", function () {',
  9866. ' this.i = 0;',
  9867. ' this.$eq = function (b) {',
  9868. ' return this.i === b.i;',
  9869. ' };',
  9870. ' this.$assign = function (s) {',
  9871. ' this.i = s.i;',
  9872. ' return this;',
  9873. ' };',
  9874. '});',
  9875. 'this.GetRec = function (vB) {',
  9876. ' var Result = $mod.TRecord.$new();',
  9877. ' return Result;',
  9878. '};',
  9879. 'this.DoIt = function (vG, vH) {',
  9880. '};',
  9881. '']),
  9882. LinesToStr([
  9883. '$mod.DoIt($mod.GetRec(0).i,$mod.GetRec(0).i);',
  9884. '$mod.DoIt($mod.GetRec(0).i,$mod.GetRec(0).i);',
  9885. '$mod.DoIt($mod.GetRec(1).i,$mod.GetRec(2).i);',
  9886. '']));
  9887. end;
  9888. procedure TTestModule.TestRecordElementFromWith_AsParams;
  9889. begin
  9890. StartProgram(false);
  9891. Add('type');
  9892. Add(' integer = longint;');
  9893. Add(' TRecord = record');
  9894. Add(' i: integer;');
  9895. Add(' end;');
  9896. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  9897. Add('begin');
  9898. Add('end;');
  9899. Add('var r: trecord;');
  9900. Add('begin');
  9901. Add(' with r do ');
  9902. Add(' doit(i,i,i);');
  9903. ConvertProgram;
  9904. CheckSource('TestRecordElementFromWith_AsParams',
  9905. LinesToStr([ // statements
  9906. 'rtl.recNewT($mod, "TRecord", function () {',
  9907. ' this.i = 0;',
  9908. ' this.$eq = function (b) {',
  9909. ' return this.i === b.i;',
  9910. ' };',
  9911. ' this.$assign = function (s) {',
  9912. ' this.i = s.i;',
  9913. ' return this;',
  9914. ' };',
  9915. '});',
  9916. 'this.DoIt = function (vG,vH,vI) {',
  9917. '};',
  9918. 'this.r = $mod.TRecord.$new();'
  9919. ]),
  9920. LinesToStr([
  9921. 'var $with1 = $mod.r;',
  9922. '$mod.DoIt($with1.i,$with1.i,{',
  9923. ' p: $with1,',
  9924. ' get: function () {',
  9925. ' return this.p.i;',
  9926. ' },',
  9927. ' set: function (v) {',
  9928. ' this.p.i = v;',
  9929. ' }',
  9930. '});',
  9931. '']));
  9932. end;
  9933. procedure TTestModule.TestRecord_Equal;
  9934. begin
  9935. StartProgram(false);
  9936. Add('type');
  9937. Add(' integer = longint;');
  9938. Add(' TFlag = (red,blue);');
  9939. Add(' TFlags = set of TFlag;');
  9940. Add(' TProc = procedure;');
  9941. Add(' TRecord = record');
  9942. Add(' i: integer;');
  9943. Add(' Event: TProc;');
  9944. Add(' f: TFlags;');
  9945. Add(' end;');
  9946. Add(' TNested = record');
  9947. Add(' r: TRecord;');
  9948. Add(' end;');
  9949. Add('var');
  9950. Add(' b: boolean;');
  9951. Add(' r,s: trecord;');
  9952. Add('begin');
  9953. Add(' b:=r=s;');
  9954. Add(' b:=r<>s;');
  9955. ConvertProgram;
  9956. CheckSource('TestRecord_Equal',
  9957. LinesToStr([ // statements
  9958. 'this.TFlag = {',
  9959. ' "0": "red",',
  9960. ' red: 0,',
  9961. ' "1": "blue",',
  9962. ' blue: 1',
  9963. '};',
  9964. 'rtl.recNewT($mod, "TRecord", function () {',
  9965. ' this.i = 0;',
  9966. ' this.Event = null;',
  9967. ' this.$new = function () {',
  9968. ' var r = Object.create(this);',
  9969. ' r.f = {};',
  9970. ' return r;',
  9971. ' };',
  9972. ' this.$eq = function (b) {',
  9973. ' return (this.i === b.i) && rtl.eqCallback(this.Event, b.Event) && rtl.eqSet(this.f, b.f);',
  9974. ' };',
  9975. ' this.$assign = function (s) {',
  9976. ' this.i = s.i;',
  9977. ' this.Event = s.Event;',
  9978. ' this.f = rtl.refSet(s.f);',
  9979. ' return this;',
  9980. ' };',
  9981. '});',
  9982. 'rtl.recNewT($mod, "TNested", function () {',
  9983. ' this.$new = function () {',
  9984. ' var r = Object.create(this);',
  9985. ' r.r = $mod.TRecord.$new();',
  9986. ' return r;',
  9987. ' };',
  9988. ' this.$eq = function (b) {',
  9989. ' return this.r.$eq(b.r);',
  9990. ' };',
  9991. ' this.$assign = function (s) {',
  9992. ' this.r.$assign(s.r);',
  9993. ' return this;',
  9994. ' };',
  9995. '});',
  9996. 'this.b = false;',
  9997. 'this.r = $mod.TRecord.$new();',
  9998. 'this.s = $mod.TRecord.$new();',
  9999. '']),
  10000. LinesToStr([
  10001. '$mod.b = $mod.r.$eq($mod.s);',
  10002. '$mod.b = !$mod.r.$eq($mod.s);',
  10003. '']));
  10004. end;
  10005. procedure TTestModule.TestRecord_JSValue;
  10006. begin
  10007. StartProgram(false);
  10008. Add([
  10009. 'type',
  10010. ' TRecord = record',
  10011. ' i: longint;',
  10012. ' end;',
  10013. 'procedure Fly(d: jsvalue; const c: jsvalue);',
  10014. 'begin',
  10015. 'end;',
  10016. 'var',
  10017. ' Jv: jsvalue;',
  10018. ' Rec: trecord;',
  10019. 'begin',
  10020. ' rec:=trecord(jv);',
  10021. ' jv:=rec;',
  10022. ' Fly(rec,rec);',
  10023. ' Fly(@rec,@rec);',
  10024. '']);
  10025. ConvertProgram;
  10026. CheckSource('TestRecord_JSValue',
  10027. LinesToStr([ // statements
  10028. 'rtl.recNewT($mod, "TRecord", function () {',
  10029. ' this.i = 0;',
  10030. ' this.$eq = function (b) {',
  10031. ' return this.i === b.i;',
  10032. ' };',
  10033. ' this.$assign = function (s) {',
  10034. ' this.i = s.i;',
  10035. ' return this;',
  10036. ' };',
  10037. '});',
  10038. 'this.Fly = function (d, c) {',
  10039. '};',
  10040. 'this.Jv = undefined;',
  10041. 'this.Rec = $mod.TRecord.$new();',
  10042. '']),
  10043. LinesToStr([
  10044. '$mod.Rec.$assign(rtl.getObject($mod.Jv));',
  10045. '$mod.Jv = $mod.Rec;',
  10046. '$mod.Fly($mod.TRecord.$clone($mod.Rec), $mod.Rec);',
  10047. '$mod.Fly($mod.Rec, $mod.Rec);',
  10048. '']));
  10049. end;
  10050. procedure TTestModule.TestRecord_VariantFail;
  10051. begin
  10052. StartProgram(false);
  10053. Add([
  10054. 'type',
  10055. ' TRec = record',
  10056. ' case word of',
  10057. ' 0: (b0, b1: Byte);',
  10058. ' 1: (i: word);',
  10059. ' end;',
  10060. 'begin']);
  10061. SetExpectedPasResolverError('variant record is not supported',
  10062. nXIsNotSupported);
  10063. ConvertProgram;
  10064. end;
  10065. procedure TTestModule.TestRecord_FieldArray;
  10066. begin
  10067. StartProgram(false);
  10068. Add([
  10069. 'type',
  10070. ' TArrInt = array[3..4] of longint;',
  10071. ' TArrArrInt = array[3..4] of longint;',
  10072. ' TRec = record',
  10073. ' a: array of longint;',
  10074. ' s: array[1..2] of longint;',
  10075. ' m: array[1..2,3..4] of longint;',
  10076. ' o: TArrArrInt;',
  10077. ' end;',
  10078. 'begin']);
  10079. ConvertProgram;
  10080. CheckSource('TestRecord_FieldArray',
  10081. LinesToStr([ // statements
  10082. 'rtl.recNewT($mod, "TRec", function () {',
  10083. ' this.a = [];',
  10084. ' this.$new = function () {',
  10085. ' var r = Object.create(this);',
  10086. ' r.s = rtl.arraySetLength(null, 0, 2);',
  10087. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  10088. ' r.o = rtl.arraySetLength(null, 0, 2);',
  10089. ' return r;',
  10090. ' };',
  10091. ' this.$eq = function (b) {',
  10092. ' return (this.a === b.a) && rtl.arrayEq(this.s, b.s) && rtl.arrayEq(this.m, b.m) && rtl.arrayEq(this.o, b.o);',
  10093. ' };',
  10094. ' this.$assign = function (s) {',
  10095. ' this.a = s.a;',
  10096. ' this.s = s.s.slice(0);',
  10097. ' this.m = s.m.slice(0);',
  10098. ' this.o = s.o.slice(0);',
  10099. ' return this;',
  10100. ' };',
  10101. '});',
  10102. '']),
  10103. LinesToStr([ // $mod.$main
  10104. '']));
  10105. end;
  10106. procedure TTestModule.TestRecord_Const;
  10107. begin
  10108. StartProgram(false);
  10109. Add([
  10110. 'type',
  10111. ' TArrInt = array[3..4] of longint;',
  10112. ' TPoint = record x,y: longint; end;',
  10113. ' TRec = record',
  10114. ' i: longint;',
  10115. ' a: array of longint;',
  10116. ' s: array[1..2] of longint;',
  10117. ' m: array[1..2,3..4] of longint;',
  10118. ' p: TPoint;',
  10119. ' end;',
  10120. ' TPoints = array of TPoint;',
  10121. 'const',
  10122. ' r: TRec = (',
  10123. ' i:1;',
  10124. ' a:(2,3);',
  10125. ' s:(4,5);',
  10126. ' m:( (11,12), (13,14) );',
  10127. ' p: (x:21; y:22)',
  10128. ' );',
  10129. ' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
  10130. 'begin']);
  10131. ConvertProgram;
  10132. CheckSource('TestRecord_Const',
  10133. LinesToStr([ // statements
  10134. 'rtl.recNewT($mod, "TPoint", function () {',
  10135. ' this.x = 0;',
  10136. ' this.y = 0;',
  10137. ' this.$eq = function (b) {',
  10138. ' return (this.x === b.x) && (this.y === b.y);',
  10139. ' };',
  10140. ' this.$assign = function (s) {',
  10141. ' this.x = s.x;',
  10142. ' this.y = s.y;',
  10143. ' return this;',
  10144. ' };',
  10145. '});',
  10146. 'rtl.recNewT($mod, "TRec", function () {',
  10147. ' this.i = 0;',
  10148. ' this.a = [];',
  10149. ' this.$new = function () {',
  10150. ' var r = Object.create(this);',
  10151. ' r.s = rtl.arraySetLength(null, 0, 2);',
  10152. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  10153. ' r.p = $mod.TPoint.$new();',
  10154. ' return r;',
  10155. ' };',
  10156. ' this.$eq = function (b) {',
  10157. ' 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);',
  10158. ' };',
  10159. ' this.$assign = function (s) {',
  10160. ' this.i = s.i;',
  10161. ' this.a = s.a;',
  10162. ' this.s = s.s.slice(0);',
  10163. ' this.m = s.m.slice(0);',
  10164. ' this.p.$assign(s.p);',
  10165. ' return this;',
  10166. ' };',
  10167. '});',
  10168. 'this.r = $mod.TRec.$clone({',
  10169. ' i: 1,',
  10170. ' a: [2, 3],',
  10171. ' s: [4, 5],',
  10172. ' m: [[11, 12], [13, 14]],',
  10173. ' p: $mod.TPoint.$clone({',
  10174. ' x: 21,',
  10175. ' y: 22',
  10176. ' })',
  10177. '});',
  10178. 'this.p = [$mod.TPoint.$clone({',
  10179. ' x: 1,',
  10180. ' y: 2',
  10181. '}), $mod.TPoint.$clone({',
  10182. ' x: 3,',
  10183. ' y: 4',
  10184. '})];',
  10185. '']),
  10186. LinesToStr([ // $mod.$main
  10187. '']));
  10188. end;
  10189. procedure TTestModule.TestRecord_TypecastFail;
  10190. begin
  10191. StartProgram(false);
  10192. Add([
  10193. 'type',
  10194. ' TPoint = record x,y: longint; end;',
  10195. ' TRec = record l: longint end;',
  10196. 'var p: TPoint;',
  10197. 'begin',
  10198. ' if TRec(p).l=2 then ;']);
  10199. SetExpectedPasResolverError('Illegal type conversion: "TPoint" to "record TRec"',
  10200. nIllegalTypeConversionTo);
  10201. ConvertProgram;
  10202. end;
  10203. procedure TTestModule.TestRecord_InFunction;
  10204. begin
  10205. StartProgram(false);
  10206. Add([
  10207. 'var TPoint: longint = 3;',
  10208. 'procedure DoIt;',
  10209. 'type',
  10210. ' TPoint = record x,y: longint; end;',
  10211. ' TPoints = array of TPoint;',
  10212. 'var',
  10213. ' r: TPoint;',
  10214. ' p: TPoints;',
  10215. 'begin',
  10216. ' SetLength(p,2);',
  10217. 'end;',
  10218. 'begin']);
  10219. ConvertProgram;
  10220. CheckSource('TestRecord_InFunction',
  10221. LinesToStr([ // statements
  10222. 'this.TPoint = 3;',
  10223. 'var TPoint$1 = rtl.recNewT(null, "", function () {',
  10224. ' this.x = 0;',
  10225. ' this.y = 0;',
  10226. ' this.$eq = function (b) {',
  10227. ' return (this.x === b.x) && (this.y === b.y);',
  10228. ' };',
  10229. ' this.$assign = function (s) {',
  10230. ' this.x = s.x;',
  10231. ' this.y = s.y;',
  10232. ' return this;',
  10233. ' };',
  10234. '});',
  10235. 'this.DoIt = function () {',
  10236. ' var r = TPoint$1.$new();',
  10237. ' var p = [];',
  10238. ' p = rtl.arraySetLength(p, TPoint$1, 2);',
  10239. '};',
  10240. '']),
  10241. LinesToStr([ // $mod.$main
  10242. '']));
  10243. end;
  10244. procedure TTestModule.TestRecord_AnonymousFail;
  10245. begin
  10246. StartProgram(false);
  10247. Add([
  10248. 'var',
  10249. ' r: record x: word end;',
  10250. 'begin']);
  10251. SetExpectedPasResolverError('not yet implemented: :TPasRecordType [20190408224556] anonymous record type',
  10252. nNotYetImplemented);
  10253. ConvertProgram;
  10254. end;
  10255. procedure TTestModule.TestAdvRecord_Function;
  10256. begin
  10257. StartProgram(false);
  10258. Parser.Options:=Parser.Options+[po_cassignments];
  10259. Add([
  10260. '{$modeswitch AdvancedRecords}',
  10261. 'type',
  10262. ' TPoint = record',
  10263. ' x,y: word;',
  10264. ' function Add(const apt: TPoint): TPoint;',
  10265. ' end;',
  10266. 'function TPoint.Add(const apt: TPoint): TPoint;',
  10267. 'begin',
  10268. ' Result:=Self;',
  10269. ' Result.x+=apt.x;',
  10270. ' Result.y:=Result.y+apt.y;',
  10271. ' Self:=apt;',
  10272. 'end;',
  10273. 'var p,q: TPoint;',
  10274. 'begin',
  10275. ' p.add(q);',
  10276. ' p:=default(TPoint);',
  10277. ' p:=q;',
  10278. '']);
  10279. ConvertProgram;
  10280. CheckSource('TestAdvRecord_Function',
  10281. LinesToStr([ // statements
  10282. 'rtl.recNewT($mod, "TPoint", function () {',
  10283. ' this.x = 0;',
  10284. ' this.y = 0;',
  10285. ' this.$eq = function (b) {',
  10286. ' return (this.x === b.x) && (this.y === b.y);',
  10287. ' };',
  10288. ' this.$assign = function (s) {',
  10289. ' this.x = s.x;',
  10290. ' this.y = s.y;',
  10291. ' return this;',
  10292. ' };',
  10293. ' this.Add = function (apt) {',
  10294. ' var Result = $mod.TPoint.$new();',
  10295. ' Result.$assign(this);',
  10296. ' Result.x += apt.x;',
  10297. ' Result.y = Result.y + apt.y;',
  10298. ' this.$assign(apt);',
  10299. ' return Result;',
  10300. ' };',
  10301. '});',
  10302. 'this.p = $mod.TPoint.$new();',
  10303. 'this.q = $mod.TPoint.$new();',
  10304. '']),
  10305. LinesToStr([ // $mod.$main
  10306. '$mod.p.Add($mod.q);',
  10307. '$mod.p.$assign($mod.TPoint.$new());',
  10308. '$mod.p.$assign($mod.q);',
  10309. '']));
  10310. end;
  10311. procedure TTestModule.TestAdvRecord_Property;
  10312. begin
  10313. StartProgram(false);
  10314. Add([
  10315. '{$modeswitch AdvancedRecords}',
  10316. 'type',
  10317. ' TPoint = record',
  10318. ' x,y: word;',
  10319. ' strict private',
  10320. ' function GetSize: longword;',
  10321. ' procedure SetSize(Value: longword);',
  10322. ' public',
  10323. ' property Size: longword read GetSize write SetSize;',
  10324. ' property Left: word read x write y;',
  10325. ' end;',
  10326. 'procedure SetSize(Value: longword); begin end;',// check auto rename
  10327. 'function TPoint.GetSize: longword;',
  10328. 'begin',
  10329. ' x:=y;',
  10330. ' Size:=Size;',
  10331. ' Left:=Left;',
  10332. 'end;',
  10333. 'procedure TPoint.SetSize(Value: longword);',
  10334. 'begin',
  10335. 'end;',
  10336. 'var p,q: TPoint;',
  10337. 'begin',
  10338. ' p.Size:=q.Size;',
  10339. ' p.Left:=q.Left;',
  10340. '']);
  10341. ConvertProgram;
  10342. CheckSource('TestAdvRecord_Property',
  10343. LinesToStr([ // statements
  10344. 'rtl.recNewT($mod, "TPoint", function () {',
  10345. ' this.x = 0;',
  10346. ' this.y = 0;',
  10347. ' this.$eq = function (b) {',
  10348. ' return (this.x === b.x) && (this.y === b.y);',
  10349. ' };',
  10350. ' this.$assign = function (s) {',
  10351. ' this.x = s.x;',
  10352. ' this.y = s.y;',
  10353. ' return this;',
  10354. ' };',
  10355. ' this.GetSize = function () {',
  10356. ' var Result = 0;',
  10357. ' this.x = this.y;',
  10358. ' this.SetSize(this.GetSize());',
  10359. ' this.y = this.x;',
  10360. ' return Result;',
  10361. ' };',
  10362. ' this.SetSize = function (Value) {',
  10363. ' };',
  10364. '});',
  10365. 'this.SetSize = function (Value) {',
  10366. '};',
  10367. 'this.p = $mod.TPoint.$new();',
  10368. 'this.q = $mod.TPoint.$new();',
  10369. '']),
  10370. LinesToStr([ // $mod.$main
  10371. '$mod.p.SetSize($mod.q.GetSize());',
  10372. '$mod.p.y = $mod.q.x;',
  10373. '']));
  10374. end;
  10375. procedure TTestModule.TestAdvRecord_PropertyDefault;
  10376. begin
  10377. StartProgram(false);
  10378. Add([
  10379. '{$modeswitch AdvancedRecords}',
  10380. 'type',
  10381. ' TPoint = record',
  10382. ' strict private',
  10383. ' function GetItems(Index: word): word;',
  10384. ' procedure SetItems(Index: word; Value: word);',
  10385. ' public',
  10386. ' property Items[Index: word]: word read GetItems write SetItems; default;',
  10387. ' end;',
  10388. 'function TPoint.GetItems(Index: word): word;',
  10389. 'begin',
  10390. ' Items[index]:=Items[index];',
  10391. ' self.Items[index]:=self.Items[index];',
  10392. 'end;',
  10393. 'procedure TPoint.SetItems(Index: word; Value: word);',
  10394. 'begin',
  10395. 'end;',
  10396. 'var p: TPoint;',
  10397. 'begin',
  10398. ' p[1]:=p[2];',
  10399. ' p.Items[3]:=p.Items[4];',
  10400. '']);
  10401. ConvertProgram;
  10402. CheckSource('TestAdvRecord_PropertyDefault',
  10403. LinesToStr([ // statements
  10404. 'rtl.recNewT($mod, "TPoint", function () {',
  10405. ' this.$eq = function (b) {',
  10406. ' return true;',
  10407. ' };',
  10408. ' this.$assign = function (s) {',
  10409. ' return this;',
  10410. ' };',
  10411. ' this.GetItems = function (Index) {',
  10412. ' var Result = 0;',
  10413. ' this.SetItems(Index, this.GetItems(Index));',
  10414. ' this.SetItems(Index, this.GetItems(Index));',
  10415. ' return Result;',
  10416. ' };',
  10417. ' this.SetItems = function (Index, Value) {',
  10418. ' };',
  10419. '});',
  10420. 'this.p = $mod.TPoint.$new();',
  10421. '']),
  10422. LinesToStr([ // $mod.$main
  10423. '$mod.p.SetItems(1, $mod.p.GetItems(2));',
  10424. '$mod.p.SetItems(3, $mod.p.GetItems(4));',
  10425. '']));
  10426. end;
  10427. procedure TTestModule.TestAdvRecord_Property_ClassMethod;
  10428. begin
  10429. StartProgram(false);
  10430. Add([
  10431. '{$modeswitch AdvancedRecords}',
  10432. 'type',
  10433. ' TRec = record',
  10434. ' class var Fx: longint;',
  10435. ' class var Fy: longint;',
  10436. ' class function GetInt: longint; static;',
  10437. ' class procedure SetInt(Value: longint); static;',
  10438. ' class procedure DoIt; static;',
  10439. ' class property IntA: longint read Fx write Fy;',
  10440. ' class property IntB: longint read GetInt write SetInt;',
  10441. ' end;',
  10442. 'class function trec.getint: longint;',
  10443. 'begin',
  10444. ' result:=fx;',
  10445. 'end;',
  10446. 'class procedure trec.setint(value: longint);',
  10447. 'begin',
  10448. 'end;',
  10449. 'class procedure trec.doit;',
  10450. 'begin',
  10451. ' IntA:=IntA+1;',
  10452. ' IntB:=IntB+1;',
  10453. 'end;',
  10454. 'var r: trec;',
  10455. 'begin',
  10456. ' trec.inta:=trec.inta+1;',
  10457. ' if trec.intb=2 then;',
  10458. ' trec.intb:=trec.intb+2;',
  10459. ' trec.setint(trec.inta);',
  10460. ' r.inta:=r.inta+1;',
  10461. ' if r.intb=2 then;',
  10462. ' r.intb:=r.intb+2;',
  10463. ' r.setint(r.inta);']);
  10464. ConvertProgram;
  10465. CheckSource('TestAdvRecord_Property_ClassMethod',
  10466. LinesToStr([ // statements
  10467. 'rtl.recNewT($mod, "TRec", function () {',
  10468. ' this.Fx = 0;',
  10469. ' this.Fy = 0;',
  10470. ' this.$eq = function (b) {',
  10471. ' return true;',
  10472. ' };',
  10473. ' this.$assign = function (s) {',
  10474. ' return this;',
  10475. ' };',
  10476. ' this.GetInt = function () {',
  10477. ' var Result = 0;',
  10478. ' Result = this.Fx;',
  10479. ' return Result;',
  10480. ' };',
  10481. ' this.SetInt = function (Value) {',
  10482. ' };',
  10483. ' this.DoIt = function () {',
  10484. ' $mod.TRec.Fy = this.Fx + 1;',
  10485. ' this.SetInt(this.GetInt() + 1);',
  10486. ' };',
  10487. '}, true);',
  10488. 'this.r = $mod.TRec.$new();',
  10489. '']),
  10490. LinesToStr([ // $mod.$main
  10491. '$mod.TRec.Fy = $mod.TRec.Fx + 1;',
  10492. 'if ($mod.TRec.GetInt() === 2) ;',
  10493. '$mod.TRec.SetInt($mod.TRec.GetInt() + 2);',
  10494. '$mod.TRec.SetInt($mod.TRec.Fx);',
  10495. '$mod.TRec.Fy = $mod.r.Fx + 1;',
  10496. 'if ($mod.r.GetInt() === 2) ;',
  10497. '$mod.r.SetInt($mod.r.GetInt() + 2);',
  10498. '$mod.r.SetInt($mod.r.Fx);',
  10499. '']));
  10500. end;
  10501. procedure TTestModule.TestAdvRecord_Const;
  10502. begin
  10503. StartProgram(false);
  10504. Add([
  10505. '{$modeswitch AdvancedRecords}',
  10506. 'type',
  10507. ' TArrInt = array[3..4] of longint;',
  10508. ' TPoint = record',
  10509. ' x,y: longint;',
  10510. ' class var Count: nativeint;',
  10511. ' end;',
  10512. ' TRec = record',
  10513. ' i: longint;',
  10514. ' a: array of longint;',
  10515. ' s: array[1..2] of longint;',
  10516. ' m: array[1..2,3..4] of longint;',
  10517. ' p: TPoint;',
  10518. ' end;',
  10519. ' TPoints = array of TPoint;',
  10520. 'const',
  10521. ' r: TRec = (',
  10522. ' i:1;',
  10523. ' a:(2,3);',
  10524. ' s:(4,5);',
  10525. ' m:( (11,12), (13,14) );',
  10526. ' p: (x:21)',
  10527. ' );',
  10528. ' p: TPoints = ( (x:1;y:2), (x:3;y:4) );',
  10529. 'begin']);
  10530. ConvertProgram;
  10531. CheckSource('TestAdvRecord_Const',
  10532. LinesToStr([ // statements
  10533. 'rtl.recNewT($mod, "TPoint", function () {',
  10534. ' this.x = 0;',
  10535. ' this.y = 0;',
  10536. ' this.Count = 0;',
  10537. ' this.$eq = function (b) {',
  10538. ' return (this.x === b.x) && (this.y === b.y);',
  10539. ' };',
  10540. ' this.$assign = function (s) {',
  10541. ' this.x = s.x;',
  10542. ' this.y = s.y;',
  10543. ' return this;',
  10544. ' };',
  10545. '}, true);',
  10546. 'rtl.recNewT($mod, "TRec", function () {',
  10547. ' this.i = 0;',
  10548. ' this.a = [];',
  10549. ' this.$new = function () {',
  10550. ' var r = Object.create(this);',
  10551. ' r.s = rtl.arraySetLength(null, 0, 2);',
  10552. ' r.m = rtl.arraySetLength(null, 0, 2, 2);',
  10553. ' r.p = $mod.TPoint.$new();',
  10554. ' return r;',
  10555. ' };',
  10556. ' this.$eq = function (b) {',
  10557. ' 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);',
  10558. ' };',
  10559. ' this.$assign = function (s) {',
  10560. ' this.i = s.i;',
  10561. ' this.a = s.a;',
  10562. ' this.s = s.s.slice(0);',
  10563. ' this.m = s.m.slice(0);',
  10564. ' this.p.$assign(s.p);',
  10565. ' return this;',
  10566. ' };',
  10567. '});',
  10568. 'this.r = $mod.TRec.$clone({',
  10569. ' i: 1,',
  10570. ' a: [2, 3],',
  10571. ' s: [4, 5],',
  10572. ' m: [[11, 12], [13, 14]],',
  10573. ' p: $mod.TPoint.$clone({',
  10574. ' x: 21,',
  10575. ' y: 0',
  10576. ' })',
  10577. '});',
  10578. 'this.p = [$mod.TPoint.$clone({',
  10579. ' x: 1,',
  10580. ' y: 2',
  10581. '}), $mod.TPoint.$clone({',
  10582. ' x: 3,',
  10583. ' y: 4',
  10584. '})];',
  10585. '']),
  10586. LinesToStr([ // $mod.$main
  10587. '']));
  10588. end;
  10589. procedure TTestModule.TestAdvRecord_ExternalField;
  10590. begin
  10591. StartProgram(false);
  10592. Add([
  10593. '{$modeswitch AdvancedRecords}',
  10594. '{$modeswitch externalclass}',
  10595. 'type',
  10596. ' TCar = record',
  10597. ' public',
  10598. ' Intern: longint external name ''$Intern'';',
  10599. ' Intern2: longint external name ''$Intern2'';',
  10600. ' Bracket: longint external name ''["A B"]'';',
  10601. ' procedure DoIt;',
  10602. ' end;',
  10603. 'implementation',
  10604. 'procedure tcar.doit;',
  10605. 'begin',
  10606. ' Intern:=Intern+1;',
  10607. ' Intern2:=Intern2+2;',
  10608. ' Bracket:=Bracket+3;',
  10609. 'end;',
  10610. 'var Rec: TCar = (intern: 11; intern2: 12; bracket: 13);',
  10611. 'begin',
  10612. ' Rec.intern:=Rec.intern+1;',
  10613. ' Rec.intern2:=Rec.intern2+2;',
  10614. ' Rec.Bracket:=Rec.Bracket+3;',
  10615. ' with Rec do begin',
  10616. ' intern:=intern+1;',
  10617. ' intern2:=intern2+2;',
  10618. ' Bracket:=Bracket+3;',
  10619. ' end;']);
  10620. ConvertProgram;
  10621. CheckSource('TestAdvRecord_ExternalField',
  10622. LinesToStr([ // statements
  10623. 'rtl.recNewT($mod, "TCar", function () {',
  10624. ' this.$eq = function (b) {',
  10625. ' return (this.$Intern === b.$Intern) && (this.$Intern2 === b.$Intern2) && (this["A B"] === b["A B"]);',
  10626. ' };',
  10627. ' this.$assign = function (s) {',
  10628. ' this.$Intern = s.$Intern;',
  10629. ' this.$Intern2 = s.$Intern2;',
  10630. ' this["A B"] = s["A B"];',
  10631. ' return this;',
  10632. ' };',
  10633. ' this.DoIt = function () {',
  10634. ' this.$Intern = this.$Intern + 1;',
  10635. ' this.$Intern2 = this.$Intern2 + 2;',
  10636. ' this["A B"] = this["A B"] + 3;',
  10637. ' };',
  10638. '});',
  10639. 'this.Rec = $mod.TCar.$clone({',
  10640. ' $Intern: 11,',
  10641. ' $Intern2: 12,',
  10642. ' "A B": 13',
  10643. '});',
  10644. '']),
  10645. LinesToStr([ // $mod.$main
  10646. '$mod.Rec.$Intern = $mod.Rec.$Intern + 1;',
  10647. '$mod.Rec.$Intern2 = $mod.Rec.$Intern2 + 2;',
  10648. '$mod.Rec["A B"] = $mod.Rec["A B"] + 3;',
  10649. 'var $with1 = $mod.Rec;',
  10650. '$with1.$Intern = $with1.$Intern + 1;',
  10651. '$with1.$Intern2 = $with1.$Intern2 + 2;',
  10652. '$with1["A B"] = $with1["A B"] + 3;',
  10653. '']));
  10654. end;
  10655. procedure TTestModule.TestAdvRecord_SubRecord;
  10656. begin
  10657. StartProgram(false);
  10658. Add([
  10659. '{$modeswitch AdvancedRecords}',
  10660. 'type',
  10661. ' TRec = record',
  10662. ' type',
  10663. ' TPoint = record',
  10664. ' x,y: longint;',
  10665. ' class var Count: nativeint;',
  10666. ' procedure DoIt;',
  10667. ' class procedure DoThat; static;',
  10668. ' end;',
  10669. ' var',
  10670. ' i: longint;',
  10671. ' p: TPoint;',
  10672. ' procedure DoSome;',
  10673. ' end;',
  10674. 'const',
  10675. ' r: TRec = (',
  10676. ' i:1;',
  10677. ' p: (x:21;y:22)',
  10678. ' );',
  10679. 'procedure TRec.DoSome;',
  10680. 'begin',
  10681. ' p.x:=p.y+1;',
  10682. ' p.Count:=p.Count+2;',
  10683. 'end;',
  10684. 'procedure TRec.TPoint.DoIt;',
  10685. 'begin',
  10686. ' Count:=Count+3;',
  10687. 'end;',
  10688. 'class procedure TRec.TPoint.DoThat;',
  10689. 'begin',
  10690. ' Count:=Count+4;',
  10691. 'end;',
  10692. 'begin']);
  10693. ConvertProgram;
  10694. CheckSource('TestAdvRecord_SubRecord',
  10695. LinesToStr([ // statements
  10696. 'rtl.recNewT($mod, "TRec", function () {',
  10697. ' rtl.recNewT(this, "TPoint", function () {',
  10698. ' this.x = 0;',
  10699. ' this.y = 0;',
  10700. ' this.Count = 0;',
  10701. ' this.$eq = function (b) {',
  10702. ' return (this.x === b.x) && (this.y === b.y);',
  10703. ' };',
  10704. ' this.$assign = function (s) {',
  10705. ' this.x = s.x;',
  10706. ' this.y = s.y;',
  10707. ' return this;',
  10708. ' };',
  10709. ' this.DoIt = function () {',
  10710. ' $mod.TRec.TPoint.Count = this.Count + 3;',
  10711. ' };',
  10712. ' this.DoThat = function () {',
  10713. ' $mod.TRec.TPoint.Count = this.Count + 4;',
  10714. ' };',
  10715. ' }, true);',
  10716. ' this.i = 0;',
  10717. ' this.$new = function () {',
  10718. ' var r = Object.create(this);',
  10719. ' r.p = this.TPoint.$new();',
  10720. ' return r;',
  10721. ' };',
  10722. ' this.$eq = function (b) {',
  10723. ' return (this.i === b.i) && this.p.$eq(b.p);',
  10724. ' };',
  10725. ' this.$assign = function (s) {',
  10726. ' this.i = s.i;',
  10727. ' this.p.$assign(s.p);',
  10728. ' return this;',
  10729. ' };',
  10730. ' this.DoSome = function () {',
  10731. ' this.p.x = this.p.y + 1;',
  10732. ' this.TPoint.Count = this.p.Count + 2;',
  10733. ' };',
  10734. '}, true);',
  10735. 'this.r = $mod.TRec.$clone({',
  10736. ' i: 1,',
  10737. ' p: $mod.TRec.TPoint.$clone({',
  10738. ' x: 21,',
  10739. ' y: 22',
  10740. ' })',
  10741. '});',
  10742. '']),
  10743. LinesToStr([ // $mod.$main
  10744. '']));
  10745. end;
  10746. procedure TTestModule.TestAdvRecord_SubClass;
  10747. begin
  10748. StartProgram(false);
  10749. Add([
  10750. '{$modeswitch AdvancedRecords}',
  10751. 'type',
  10752. ' TObject = class end;',
  10753. ' TPoint = record',
  10754. ' type',
  10755. ' TBird = class',
  10756. ' procedure DoIt;',
  10757. ' class procedure Glob;',
  10758. ' end;',
  10759. ' procedure DoIt(b: TBird);',
  10760. ' end;',
  10761. 'procedure TPoint.TBird.DoIt;',
  10762. 'begin',
  10763. ' doit;',
  10764. ' self.doit;',
  10765. ' glob;',
  10766. ' self.glob;',
  10767. 'end;',
  10768. 'class procedure TPoint.TBird.Glob;',
  10769. 'begin',
  10770. ' glob;',
  10771. ' self.glob;',
  10772. 'end;',
  10773. 'procedure TPoint.DoIt(b: TBird);',
  10774. 'begin',
  10775. ' b.doit;',
  10776. ' b.glob;',
  10777. ' TBird.glob;',
  10778. 'end;',
  10779. 'begin',
  10780. '']);
  10781. ConvertProgram;
  10782. CheckSource('TestAdvRecord_SubClass',
  10783. LinesToStr([ // statements
  10784. 'rtl.createClass($mod, "TObject", null, function () {',
  10785. ' this.$init = function () {',
  10786. ' };',
  10787. ' this.$final = function () {',
  10788. ' };',
  10789. '});',
  10790. 'rtl.recNewT($mod, "TPoint", function () {',
  10791. ' rtl.createClass(this, "TBird", $mod.TObject, function () {',
  10792. ' this.DoIt = function () {',
  10793. ' this.DoIt();',
  10794. ' this.DoIt();',
  10795. ' this.$class.Glob();',
  10796. ' this.$class.Glob();',
  10797. ' };',
  10798. ' this.Glob = function () {',
  10799. ' this.Glob();',
  10800. ' this.Glob();',
  10801. ' };',
  10802. ' });',
  10803. ' this.$eq = function (b) {',
  10804. ' return true;',
  10805. ' };',
  10806. ' this.$assign = function (s) {',
  10807. ' return this;',
  10808. ' };',
  10809. ' this.DoIt = function (b) {',
  10810. ' b.DoIt();',
  10811. ' b.$class.Glob();',
  10812. ' this.TBird.Glob();',
  10813. ' };',
  10814. '}, true);',
  10815. '']),
  10816. LinesToStr([ // $mod.$main
  10817. '']));
  10818. end;
  10819. procedure TTestModule.TestAdvRecord_SubInterfaceFail;
  10820. begin
  10821. StartProgram(false);
  10822. Add([
  10823. '{$modeswitch AdvancedRecords}',
  10824. 'type',
  10825. ' IUnknown = interface end;',
  10826. ' TPoint = record',
  10827. ' type IBird = interface end;',
  10828. ' end;',
  10829. 'begin',
  10830. '']);
  10831. SetExpectedPasResolverError('not yet implemented: IBird:TPasClassType [20190105143752] interface inside record',
  10832. nNotYetImplemented);
  10833. ParseProgram;
  10834. end;
  10835. procedure TTestModule.TestAdvRecord_Constructor;
  10836. begin
  10837. StartProgram(false);
  10838. Add([
  10839. '{$modeswitch AdvancedRecords}',
  10840. 'type',
  10841. ' TPoint = record',
  10842. ' x,y: longint;',
  10843. ' constructor Create(ax: longint; ay: longint = -1);',
  10844. ' end;',
  10845. 'constructor tpoint.create(ax,ay: longint);',
  10846. 'begin',
  10847. ' x:=ax;',
  10848. ' self.y:=ay;',
  10849. 'end;',
  10850. 'var r: TPoint;',
  10851. 'begin',
  10852. ' r:=TPoint.Create(1,2);',
  10853. ' with TPoint do r:=Create(1,2);',
  10854. ' r.Create(3);',
  10855. ' r:=r.Create(4);',
  10856. '']);
  10857. ConvertProgram;
  10858. CheckSource('TestAdvRecord_Constructor',
  10859. LinesToStr([ // statements
  10860. 'rtl.recNewT($mod, "TPoint", function () {',
  10861. ' this.x = 0;',
  10862. ' this.y = 0;',
  10863. ' this.$eq = function (b) {',
  10864. ' return (this.x === b.x) && (this.y === b.y);',
  10865. ' };',
  10866. ' this.$assign = function (s) {',
  10867. ' this.x = s.x;',
  10868. ' this.y = s.y;',
  10869. ' return this;',
  10870. ' };',
  10871. ' this.Create = function (ax, ay) {',
  10872. ' this.x = ax;',
  10873. ' this.y = ay;',
  10874. ' return this;',
  10875. ' };',
  10876. '}, true);',
  10877. 'this.r = $mod.TPoint.$new();',
  10878. '']),
  10879. LinesToStr([ // $mod.$main
  10880. '$mod.r.$assign($mod.TPoint.$new().Create(1, 2));',
  10881. 'var $with1 = $mod.TPoint;',
  10882. '$mod.r.$assign($with1.$new().Create(1, 2));',
  10883. '$mod.r.Create(3, -1);',
  10884. '$mod.r.$assign($mod.r.Create(4, -1));',
  10885. '']));
  10886. end;
  10887. procedure TTestModule.TestAdvRecord_ClassConstructor_Program;
  10888. begin
  10889. StartProgram(false);
  10890. Add([
  10891. '{$modeswitch AdvancedRecords}',
  10892. 'type',
  10893. ' TPoint = record',
  10894. ' class var x: longint;',
  10895. ' class procedure Fly; static;',
  10896. ' class constructor Init;',
  10897. ' end;',
  10898. 'var count: word;',
  10899. 'class procedure Tpoint.Fly;',
  10900. 'begin',
  10901. 'end;',
  10902. 'class constructor tpoint.init;',
  10903. 'begin',
  10904. ' count:=count+1;',
  10905. ' x:=3;',
  10906. ' tpoint.x:=4;',
  10907. ' fly;',
  10908. ' tpoint.fly;',
  10909. 'end;',
  10910. 'var r: TPoint;',
  10911. 'begin',
  10912. ' r.x:=10;',
  10913. '']);
  10914. ConvertProgram;
  10915. CheckSource('TestAdvRecord_ClassConstructor_Program',
  10916. LinesToStr([ // statements
  10917. 'rtl.recNewT($mod, "TPoint", function () {',
  10918. ' this.x = 0;',
  10919. ' this.$eq = function (b) {',
  10920. ' return true;',
  10921. ' };',
  10922. ' this.$assign = function (s) {',
  10923. ' return this;',
  10924. ' };',
  10925. ' this.Fly = function () {',
  10926. ' };',
  10927. '}, true);',
  10928. 'this.count = 0;',
  10929. 'this.r = $mod.TPoint.$new();',
  10930. '']),
  10931. LinesToStr([ // $mod.$main
  10932. '(function () {',
  10933. ' $mod.count = $mod.count + 1;',
  10934. ' $mod.TPoint.x = 3;',
  10935. ' $mod.TPoint.x = 4;',
  10936. ' $mod.TPoint.Fly();',
  10937. ' $mod.TPoint.Fly();',
  10938. '})();',
  10939. '$mod.TPoint.x = 10;',
  10940. '']));
  10941. end;
  10942. procedure TTestModule.TestAdvRecord_ClassConstructor_Unit;
  10943. begin
  10944. StartUnit(false);
  10945. Add([
  10946. 'interface',
  10947. '{$modeswitch AdvancedRecords}',
  10948. 'type',
  10949. ' TPoint = record',
  10950. ' class var x: longint;',
  10951. ' class procedure Fly; static;',
  10952. ' class constructor Init;',
  10953. ' end;',
  10954. 'implementation',
  10955. 'var count: word;',
  10956. 'class procedure Tpoint.Fly;',
  10957. 'begin',
  10958. 'end;',
  10959. 'class constructor tpoint.init;',
  10960. 'begin',
  10961. ' count:=count+1;',
  10962. ' x:=3;',
  10963. ' tpoint.x:=4;',
  10964. ' fly;',
  10965. ' tpoint.fly;',
  10966. 'end;',
  10967. '']);
  10968. ConvertUnit;
  10969. CheckSource('TestAdvRecord_ClassConstructor_Unit',
  10970. LinesToStr([ // statements
  10971. 'var $impl = $mod.$impl;',
  10972. 'rtl.recNewT($mod, "TPoint", function () {',
  10973. ' this.x = 0;',
  10974. ' this.$eq = function (b) {',
  10975. ' return true;',
  10976. ' };',
  10977. ' this.$assign = function (s) {',
  10978. ' return this;',
  10979. ' };',
  10980. ' this.Fly = function () {',
  10981. ' };',
  10982. '}, true);',
  10983. '']),
  10984. LinesToStr([ // $mod.$init
  10985. '(function () {',
  10986. ' $impl.count = $impl.count + 1;',
  10987. ' $mod.TPoint.x = 3;',
  10988. ' $mod.TPoint.x = 4;',
  10989. ' $mod.TPoint.Fly();',
  10990. ' $mod.TPoint.Fly();',
  10991. '})();',
  10992. '']),
  10993. LinesToStr([ // $mod.$main
  10994. '$impl.count = 0;',
  10995. '']));
  10996. end;
  10997. procedure TTestModule.TestClass_TObjectDefaultConstructor;
  10998. begin
  10999. StartProgram(false);
  11000. Add(['type',
  11001. ' TObject = class',
  11002. ' public',
  11003. ' constructor Create;',
  11004. ' destructor Destroy;',
  11005. ' end;',
  11006. ' TBird = TObject;',
  11007. 'constructor tobject.create;',
  11008. 'begin end;',
  11009. 'destructor tobject.destroy;',
  11010. 'begin end;',
  11011. 'var Obj: tobject;',
  11012. 'begin',
  11013. ' obj:=tobject.create;',
  11014. ' obj:=tobject.create();',
  11015. ' obj:=tbird.create;',
  11016. ' obj:=tbird.create();',
  11017. ' obj:=obj.create();',
  11018. ' obj.destroy;',
  11019. '']);
  11020. ConvertProgram;
  11021. CheckSource('TestClass_TObjectDefaultConstructor',
  11022. LinesToStr([ // statements
  11023. 'rtl.createClass($mod,"TObject",null,function(){',
  11024. ' this.$init = function () {',
  11025. ' };',
  11026. ' this.$final = function () {',
  11027. ' };',
  11028. ' this.Create = function(){',
  11029. ' return this;',
  11030. ' };',
  11031. ' this.Destroy = function(){',
  11032. ' };',
  11033. '});',
  11034. 'this.Obj = null;'
  11035. ]),
  11036. LinesToStr([ // $mod.$main
  11037. '$mod.Obj = $mod.TObject.$create("Create");',
  11038. '$mod.Obj = $mod.TObject.$create("Create");',
  11039. '$mod.Obj = $mod.TObject.$create("Create");',
  11040. '$mod.Obj = $mod.TObject.$create("Create");',
  11041. '$mod.Obj = $mod.Obj.Create();',
  11042. '$mod.Obj.$destroy("Destroy");',
  11043. '']));
  11044. end;
  11045. procedure TTestModule.TestClass_TObjectConstructorWithParams;
  11046. begin
  11047. StartProgram(false);
  11048. Add('type');
  11049. Add(' TObject = class');
  11050. Add(' public');
  11051. Add(' constructor Create(Par: longint);');
  11052. Add(' end;');
  11053. Add('constructor tobject.create(par: longint);');
  11054. Add('begin end;');
  11055. Add('var Obj: tobject;');
  11056. Add('begin');
  11057. Add(' obj:=tobject.create(3);');
  11058. ConvertProgram;
  11059. CheckSource('TestClass_TObjectConstructorWithParams',
  11060. LinesToStr([ // statements
  11061. 'rtl.createClass($mod,"TObject",null,function(){',
  11062. ' this.$init = function () {',
  11063. ' };',
  11064. ' this.$final = function () {',
  11065. ' };',
  11066. ' this.Create = function(Par){',
  11067. ' return this;',
  11068. ' };',
  11069. '});',
  11070. 'this.Obj = null;'
  11071. ]),
  11072. LinesToStr([ // $mod.$main
  11073. '$mod.Obj = $mod.TObject.$create("Create",[3]);'
  11074. ]));
  11075. end;
  11076. procedure TTestModule.TestClass_TObjectConstructorWithDefaultParam;
  11077. begin
  11078. StartProgram(false);
  11079. Add('type');
  11080. Add(' TObject = class');
  11081. Add(' public');
  11082. Add(' constructor Create;');
  11083. Add(' end;');
  11084. Add(' TTest = class(TObject)');
  11085. Add(' public');
  11086. Add(' constructor Create(const Par: longint = 1);');
  11087. Add(' end;');
  11088. Add('constructor tobject.create;');
  11089. Add('begin end;');
  11090. Add('constructor ttest.create(const par: longint);');
  11091. Add('begin end;');
  11092. Add('var t: ttest;');
  11093. Add('begin');
  11094. Add(' t:=ttest.create;');
  11095. Add(' t:=ttest.create(2);');
  11096. ConvertProgram;
  11097. CheckSource('TestClass_TObjectConstructorWithDefaultParam',
  11098. LinesToStr([ // statements
  11099. 'rtl.createClass($mod,"TObject",null,function(){',
  11100. ' this.$init = function () {',
  11101. ' };',
  11102. ' this.$final = function () {',
  11103. ' };',
  11104. ' this.Create = function(){',
  11105. ' return this;',
  11106. ' };',
  11107. '});',
  11108. 'rtl.createClass($mod, "TTest", $mod.TObject, function () {',
  11109. ' this.Create$1 = function (Par) {',
  11110. ' return this;',
  11111. ' };',
  11112. '});',
  11113. 'this.t = null;'
  11114. ]),
  11115. LinesToStr([ // $mod.$main
  11116. '$mod.t = $mod.TTest.$create("Create$1", [1]);',
  11117. '$mod.t = $mod.TTest.$create("Create$1", [2]);'
  11118. ]));
  11119. end;
  11120. procedure TTestModule.TestClass_Var;
  11121. begin
  11122. StartProgram(false);
  11123. Add([
  11124. 'type',
  11125. ' TObject = class',
  11126. ' public',
  11127. ' vI: longint;',
  11128. ' constructor Create(Par: longint);',
  11129. ' end;',
  11130. 'constructor tobject.create(par: longint);',
  11131. 'begin',
  11132. ' vi:=par+3',
  11133. 'end;',
  11134. 'var Obj: tobject;',
  11135. 'begin',
  11136. ' obj:=tobject.create(4);',
  11137. ' obj.vi:=obj.VI+5;']);
  11138. ConvertProgram;
  11139. CheckSource('TestClass_Var',
  11140. LinesToStr([ // statements
  11141. 'rtl.createClass($mod,"TObject",null,function(){',
  11142. ' this.$init = function () {',
  11143. ' this.vI = 0;',
  11144. ' };',
  11145. ' this.$final = function () {',
  11146. ' };',
  11147. ' this.Create = function(Par){',
  11148. ' this.vI = Par+3;',
  11149. ' return this;',
  11150. ' };',
  11151. '});',
  11152. 'this.Obj = null;'
  11153. ]),
  11154. LinesToStr([ // $mod.$main
  11155. '$mod.Obj = $mod.TObject.$create("Create",[4]);',
  11156. '$mod.Obj.vI = $mod.Obj.vI + 5;'
  11157. ]));
  11158. end;
  11159. procedure TTestModule.TestClass_Method;
  11160. begin
  11161. StartProgram(false);
  11162. Add('type');
  11163. Add(' TObject = class');
  11164. Add(' public');
  11165. Add(' vI: longint;');
  11166. Add(' Sub: TObject;');
  11167. Add(' constructor Create;');
  11168. Add(' function GetIt(Par: longint): tobject;');
  11169. Add(' end;');
  11170. Add('constructor tobject.create; begin end;');
  11171. Add('function tobject.getit(par: longint): tobject;');
  11172. Add('begin');
  11173. Add(' Self.vi:=par+3;');
  11174. Add(' Result:=self.sub;');
  11175. Add('end;');
  11176. Add('var Obj: tobject;');
  11177. Add('begin');
  11178. Add(' obj:=tobject.create;');
  11179. Add(' obj.getit(4);');
  11180. Add(' obj.sub.sub:=nil;');
  11181. Add(' obj.sub.getit(5);');
  11182. Add(' obj.sub.getit(6).SUB:=nil;');
  11183. Add(' obj.sub.getit(7).GETIT(8);');
  11184. Add(' obj.sub.getit(9).SuB.getit(10);');
  11185. ConvertProgram;
  11186. CheckSource('TestClass_Method',
  11187. LinesToStr([ // statements
  11188. 'rtl.createClass($mod,"TObject",null,function(){',
  11189. ' this.$init = function () {',
  11190. ' this.vI = 0;',
  11191. ' this.Sub = null;',
  11192. ' };',
  11193. ' this.$final = function () {',
  11194. ' this.Sub = undefined;',
  11195. ' };',
  11196. ' this.Create = function(){',
  11197. ' return this;',
  11198. ' };',
  11199. ' this.GetIt = function(Par){',
  11200. ' var Result = null;',
  11201. ' this.vI = Par + 3;',
  11202. ' Result = this.Sub;',
  11203. ' return Result;',
  11204. ' };',
  11205. '});',
  11206. 'this.Obj = null;'
  11207. ]),
  11208. LinesToStr([ // $mod.$main
  11209. '$mod.Obj = $mod.TObject.$create("Create");',
  11210. '$mod.Obj.GetIt(4);',
  11211. '$mod.Obj.Sub.Sub=null;',
  11212. '$mod.Obj.Sub.GetIt(5);',
  11213. '$mod.Obj.Sub.GetIt(6).Sub=null;',
  11214. '$mod.Obj.Sub.GetIt(7).GetIt(8);',
  11215. '$mod.Obj.Sub.GetIt(9).Sub.GetIt(10);'
  11216. ]));
  11217. end;
  11218. procedure TTestModule.TestClass_Implementation;
  11219. begin
  11220. StartUnit(false);
  11221. Add([
  11222. 'interface',
  11223. 'type',
  11224. ' TObject = class',
  11225. ' constructor Create;',
  11226. ' end;',
  11227. 'implementation',
  11228. 'type',
  11229. ' TIntClass = class',
  11230. ' constructor Create; reintroduce;',
  11231. ' class procedure DoGlob;',
  11232. ' end;',
  11233. 'constructor tintclass.create;',
  11234. 'begin',
  11235. ' inherited;',
  11236. ' inherited create;',
  11237. ' doglob;',
  11238. 'end;',
  11239. 'class procedure tintclass.doglob;',
  11240. 'begin',
  11241. 'end;',
  11242. 'constructor tobject.create;',
  11243. 'var',
  11244. ' iC: tintclass;',
  11245. 'begin',
  11246. ' ic:=tintclass.create;',
  11247. ' tintclass.doglob;',
  11248. ' ic.doglob;',
  11249. 'end;',
  11250. 'initialization',
  11251. ' tintclass.doglob;',
  11252. '']);
  11253. ConvertUnit;
  11254. CheckSource('TestClass_Implementation',
  11255. LinesToStr([ // statements
  11256. 'var $impl = $mod.$impl;',
  11257. 'rtl.createClass($mod, "TObject", null, function () {',
  11258. ' this.$init = function () {',
  11259. ' };',
  11260. ' this.$final = function () {',
  11261. ' };',
  11262. ' this.Create = function () {',
  11263. ' var iC = null;',
  11264. ' iC = $impl.TIntClass.$create("Create$1");',
  11265. ' $impl.TIntClass.DoGlob();',
  11266. ' iC.$class.DoGlob();',
  11267. ' return this;',
  11268. ' };',
  11269. '});',
  11270. '']),
  11271. LinesToStr([ // $mod.$main
  11272. '$impl.TIntClass.DoGlob();',
  11273. '']),
  11274. LinesToStr([
  11275. 'rtl.createClass($impl, "TIntClass", $mod.TObject, function () {',
  11276. ' this.Create$1 = function () {',
  11277. ' $mod.TObject.Create.call(this);',
  11278. ' $mod.TObject.Create.call(this);',
  11279. ' this.$class.DoGlob();',
  11280. ' return this;',
  11281. ' };',
  11282. ' this.DoGlob = function () {',
  11283. ' };',
  11284. '});',
  11285. '']));
  11286. end;
  11287. procedure TTestModule.TestClass_Inheritance;
  11288. begin
  11289. StartProgram(false);
  11290. Add('type');
  11291. Add(' TObject = class');
  11292. Add(' public');
  11293. Add(' constructor Create;');
  11294. Add(' end;');
  11295. Add(' TClassA = class');
  11296. Add(' end;');
  11297. Add(' TClassB = class(TObject)');
  11298. Add(' procedure ProcB;');
  11299. Add(' end;');
  11300. Add('constructor tobject.create; begin end;');
  11301. Add('procedure tclassb.procb; begin end;');
  11302. Add('var');
  11303. Add(' oO: TObject;');
  11304. Add(' oA: TClassA;');
  11305. Add(' oB: TClassB;');
  11306. Add('begin');
  11307. Add(' oO:=tobject.Create;');
  11308. Add(' oA:=tclassa.Create;');
  11309. Add(' ob:=tclassb.Create;');
  11310. Add(' if oo is tclassa then ;');
  11311. Add(' ob:=oo as tclassb;');
  11312. Add(' (oo as tclassb).procb;');
  11313. ConvertProgram;
  11314. CheckSource('TestClass_Inheritance',
  11315. LinesToStr([ // statements
  11316. 'rtl.createClass($mod,"TObject",null,function(){',
  11317. ' this.$init = function () {',
  11318. ' };',
  11319. ' this.$final = function () {',
  11320. ' };',
  11321. ' this.Create = function () {',
  11322. ' return this;',
  11323. ' };',
  11324. '});',
  11325. 'rtl.createClass($mod,"TClassA",$mod.TObject,function(){',
  11326. '});',
  11327. 'rtl.createClass($mod,"TClassB",$mod.TObject,function(){',
  11328. ' this.ProcB = function () {',
  11329. ' };',
  11330. '});',
  11331. 'this.oO = null;',
  11332. 'this.oA = null;',
  11333. 'this.oB = null;'
  11334. ]),
  11335. LinesToStr([ // $mod.$main
  11336. '$mod.oO = $mod.TObject.$create("Create");',
  11337. '$mod.oA = $mod.TClassA.$create("Create");',
  11338. '$mod.oB = $mod.TClassB.$create("Create");',
  11339. 'if ($mod.TClassA.isPrototypeOf($mod.oO));',
  11340. '$mod.oB = rtl.as($mod.oO, $mod.TClassB);',
  11341. 'rtl.as($mod.oO, $mod.TClassB).ProcB();'
  11342. ]));
  11343. end;
  11344. procedure TTestModule.TestClass_TypeAlias;
  11345. begin
  11346. StartProgram(false);
  11347. Add([
  11348. '{$interfaces corba}',
  11349. 'type',
  11350. ' IObject = interface',
  11351. ' end;',
  11352. ' IBird = type IObject;',
  11353. ' TObject = class',
  11354. ' end;',
  11355. ' TBird = type TObject;',
  11356. 'var',
  11357. ' oObj: TObject;',
  11358. ' oBird: TBird;',
  11359. ' IntfObj: IObject;',
  11360. ' IntfBird: IBird;',
  11361. 'begin',
  11362. ' oObj:=oBird;',
  11363. '']);
  11364. ConvertProgram;
  11365. CheckSource('TestClass_TypeAlias',
  11366. LinesToStr([ // statements
  11367. 'rtl.createInterface($mod, "IObject", "{B92D5841-6F2A-306A-8000-000000000000}", [], null);',
  11368. 'rtl.createInterface($mod, "IBird", "{4B0D080B-C0F6-387B-AE88-F10981585074}", [], $mod.IObject);',
  11369. 'rtl.createClass($mod, "TObject", null, function () {',
  11370. ' this.$init = function () {',
  11371. ' };',
  11372. ' this.$final = function () {',
  11373. ' };',
  11374. '});',
  11375. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  11376. '});',
  11377. 'this.oObj = null;',
  11378. 'this.oBird = null;',
  11379. 'this.IntfObj = null;',
  11380. 'this.IntfBird = null;',
  11381. '']),
  11382. LinesToStr([ // $mod.$main
  11383. '$mod.oObj = $mod.oBird;',
  11384. '']));
  11385. end;
  11386. procedure TTestModule.TestClass_AbstractMethod;
  11387. begin
  11388. StartProgram(false);
  11389. Add('type');
  11390. Add(' TObject = class');
  11391. Add(' public');
  11392. Add(' procedure DoIt; virtual; abstract;');
  11393. Add(' end;');
  11394. Add('begin');
  11395. ConvertProgram;
  11396. CheckSource('TestClass_AbstractMethod',
  11397. LinesToStr([ // statements
  11398. 'rtl.createClass($mod,"TObject",null,function(){',
  11399. ' this.$init = function () {',
  11400. ' };',
  11401. ' this.$final = function () {',
  11402. ' };',
  11403. '});'
  11404. ]),
  11405. LinesToStr([ // this.$main
  11406. ''
  11407. ]));
  11408. end;
  11409. procedure TTestModule.TestClass_CallInherited_ProcNoParams;
  11410. begin
  11411. StartProgram(false);
  11412. Add([
  11413. 'type',
  11414. ' TObject = class',
  11415. ' procedure DoAbstract; virtual; abstract;',
  11416. ' procedure DoVirtual; virtual;',
  11417. ' procedure DoIt;',
  11418. ' end;',
  11419. ' TA = class',
  11420. ' procedure doabstract; override;',
  11421. ' procedure dovirtual; override;',
  11422. ' procedure DoSome;',
  11423. ' end;',
  11424. 'procedure tobject.dovirtual;',
  11425. 'begin',
  11426. ' inherited; // call non existing ancestor -> ignore silently',
  11427. 'end;',
  11428. 'procedure tobject.doit;',
  11429. 'begin',
  11430. 'end;',
  11431. 'procedure ta.doabstract;',
  11432. 'begin',
  11433. ' inherited dovirtual; // call TObject.DoVirtual',
  11434. 'end;',
  11435. 'procedure ta.dovirtual;',
  11436. 'begin',
  11437. ' inherited; // call TObject.DoVirtual',
  11438. ' inherited dovirtual; // call TObject.DoVirtual',
  11439. ' inherited dovirtual(); // call TObject.DoVirtual',
  11440. ' doit;',
  11441. ' doit();',
  11442. 'end;',
  11443. 'procedure ta.dosome;',
  11444. 'begin',
  11445. ' inherited; // call non existing ancestor method -> silently ignore',
  11446. 'end;',
  11447. 'begin']);
  11448. ConvertProgram;
  11449. CheckSource('TestClass_CallInherited_ProcNoParams',
  11450. LinesToStr([ // statements
  11451. 'rtl.createClass($mod,"TObject",null,function(){',
  11452. ' this.$init = function () {',
  11453. ' };',
  11454. ' this.$final = function () {',
  11455. ' };',
  11456. ' this.DoVirtual = function () {',
  11457. ' };',
  11458. ' this.DoIt = function () {',
  11459. ' };',
  11460. '});',
  11461. 'rtl.createClass($mod, "TA", $mod.TObject, function () {',
  11462. ' this.DoAbstract = function () {',
  11463. ' $mod.TObject.DoVirtual.call(this);',
  11464. ' };',
  11465. ' this.DoVirtual = function () {',
  11466. ' $mod.TObject.DoVirtual.call(this);',
  11467. ' $mod.TObject.DoVirtual.call(this);',
  11468. ' $mod.TObject.DoVirtual.call(this);',
  11469. ' this.DoIt();',
  11470. ' this.DoIt();',
  11471. ' };',
  11472. ' this.DoSome = function () {',
  11473. ' };',
  11474. '});'
  11475. ]),
  11476. LinesToStr([ // this.$main
  11477. ''
  11478. ]));
  11479. end;
  11480. procedure TTestModule.TestClass_CallInherited_WithParams;
  11481. begin
  11482. StartProgram(false);
  11483. Add([
  11484. 'type',
  11485. ' TObject = class',
  11486. ' procedure DoAbstract(pA: longint; pB: longint = 0); virtual; abstract;',
  11487. ' procedure DoVirtual(pA: longint; pB: longint = 0); virtual;',
  11488. ' procedure DoIt(pA: longint; pB: longint = 0);',
  11489. ' procedure DoIt2(pA: longint = 1; pB: longint = 2);',
  11490. ' function GetIt(pA: longint = 1; pB: longint = 2): longint;',
  11491. ' end;',
  11492. ' TClassA = class',
  11493. ' procedure DoAbstract(pA: longint; pB: longint = 0); override;',
  11494. ' procedure DoVirtual(pA: longint; pB: longint = 0); override;',
  11495. ' function GetIt(pA: longint = 1; pB: longint = 2): longint;',
  11496. ' end;',
  11497. 'procedure tobject.dovirtual(pa: longint; pb: longint = 0);',
  11498. 'begin',
  11499. 'end;',
  11500. 'procedure tobject.doit(pa: longint; pb: longint = 0);',
  11501. 'begin',
  11502. 'end;',
  11503. 'procedure tobject.doit2(pa: longint; pb: longint = 0);',
  11504. 'begin',
  11505. 'end;',
  11506. 'function tobject.getit(pa: longint; pb: longint = 0): longint;',
  11507. 'begin',
  11508. 'end;',
  11509. 'procedure tclassa.doabstract(pa: longint; pb: longint = 0);',
  11510. 'begin',
  11511. ' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)',
  11512. ' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)',
  11513. 'end;',
  11514. 'procedure tclassa.dovirtual(pa: longint; pb: longint = 0);',
  11515. 'begin',
  11516. ' inherited; // call TObject.DoVirtual(pA,pB)',
  11517. ' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)',
  11518. ' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)',
  11519. ' doit(pa,pb);',
  11520. ' doit(pa);',
  11521. ' doit2(pa);',
  11522. ' doit2;',
  11523. 'end;',
  11524. 'function tclassa.getit(pa: longint; pb: longint = 0): longint;',
  11525. 'begin',
  11526. ' pa:=inherited;',
  11527. 'end;',
  11528. 'begin']);
  11529. ConvertProgram;
  11530. CheckSource('TestClass_CallInherited_WithParams',
  11531. LinesToStr([ // statements
  11532. 'rtl.createClass($mod,"TObject",null,function(){',
  11533. ' this.$init = function () {',
  11534. ' };',
  11535. ' this.$final = function () {',
  11536. ' };',
  11537. ' this.DoVirtual = function (pA,pB) {',
  11538. ' };',
  11539. ' this.DoIt = function (pA,pB) {',
  11540. ' };',
  11541. ' this.DoIt2 = function (pA,pB) {',
  11542. ' };',
  11543. ' this.GetIt = function (pA, pB) {',
  11544. ' var Result = 0;',
  11545. ' return Result;',
  11546. ' };',
  11547. '});',
  11548. 'rtl.createClass($mod, "TClassA", $mod.TObject, function () {',
  11549. ' this.DoAbstract = function (pA,pB) {',
  11550. ' $mod.TObject.DoVirtual.call(this,pA,pB);',
  11551. ' $mod.TObject.DoVirtual.call(this,pA,0);',
  11552. ' };',
  11553. ' this.DoVirtual = function (pA,pB) {',
  11554. ' $mod.TObject.DoVirtual.apply(this, arguments);',
  11555. ' $mod.TObject.DoVirtual.call(this,pA,pB);',
  11556. ' $mod.TObject.DoVirtual.call(this,pA,0);',
  11557. ' this.DoIt(pA,pB);',
  11558. ' this.DoIt(pA,0);',
  11559. ' this.DoIt2(pA,2);',
  11560. ' this.DoIt2(1,2);',
  11561. ' };',
  11562. ' this.GetIt$1 = function (pA, pB) {',
  11563. ' var Result = 0;',
  11564. ' pA = $mod.TObject.GetIt.apply(this, arguments);',
  11565. ' return Result;',
  11566. ' };',
  11567. '});'
  11568. ]),
  11569. LinesToStr([ // this.$main
  11570. ''
  11571. ]));
  11572. end;
  11573. procedure TTestModule.TestClasS_CallInheritedConstructor;
  11574. begin
  11575. StartProgram(false);
  11576. Add('type');
  11577. Add(' TObject = class');
  11578. Add(' constructor Create; virtual;');
  11579. Add(' constructor CreateWithB(b: boolean);');
  11580. Add(' end;');
  11581. Add(' TA = class');
  11582. Add(' constructor Create; override;');
  11583. Add(' constructor CreateWithC(c: char);');
  11584. Add(' procedure DoIt;');
  11585. Add(' class function DoSome: TObject;');
  11586. Add(' end;');
  11587. Add('constructor tobject.create;');
  11588. Add('begin');
  11589. Add(' inherited; // call non existing ancestor -> ignore silently');
  11590. Add('end;');
  11591. Add('constructor tobject.createwithb(b: boolean);');
  11592. Add('begin');
  11593. Add(' inherited; // call non existing ancestor -> ignore silently');
  11594. Add(' create; // normal call');
  11595. Add('end;');
  11596. Add('constructor ta.create;');
  11597. Add('begin');
  11598. Add(' inherited; // normal call TObject.Create');
  11599. Add(' inherited create; // normal call TObject.Create');
  11600. Add(' inherited createwithb(false); // normal call TObject.CreateWithB');
  11601. Add('end;');
  11602. Add('constructor ta.createwithc(c: char);');
  11603. Add('begin');
  11604. Add(' inherited create; // call TObject.Create');
  11605. Add(' inherited createwithb(true); // call TObject.CreateWithB');
  11606. Add(' doit;');
  11607. Add(' doit();');
  11608. Add(' dosome;');
  11609. Add('end;');
  11610. Add('procedure ta.doit;');
  11611. Add('begin');
  11612. Add(' create; // normal call');
  11613. Add(' createwithb(false); // normal call');
  11614. Add(' createwithc(''c''); // normal call');
  11615. Add('end;');
  11616. Add('class function ta.dosome: TObject;');
  11617. Add('begin');
  11618. Add(' Result:=create; // constructor');
  11619. Add(' Result:=createwithb(true); // constructor');
  11620. Add(' Result:=createwithc(''c''); // constructor');
  11621. Add('end;');
  11622. Add('begin');
  11623. ConvertProgram;
  11624. CheckSource('TestClass_CallInheritedConstructor',
  11625. LinesToStr([ // statements
  11626. 'rtl.createClass($mod,"TObject",null,function(){',
  11627. ' this.$init = function () {',
  11628. ' };',
  11629. ' this.$final = function () {',
  11630. ' };',
  11631. ' this.Create = function () {',
  11632. ' return this;',
  11633. ' };',
  11634. ' this.CreateWithB = function (b) {',
  11635. ' this.Create();',
  11636. ' return this;',
  11637. ' };',
  11638. '});',
  11639. 'rtl.createClass($mod, "TA", $mod.TObject, function () {',
  11640. ' this.Create = function () {',
  11641. ' $mod.TObject.Create.call(this);',
  11642. ' $mod.TObject.Create.call(this);',
  11643. ' $mod.TObject.CreateWithB.call(this, false);',
  11644. ' return this;',
  11645. ' };',
  11646. ' this.CreateWithC = function (c) {',
  11647. ' $mod.TObject.Create.call(this);',
  11648. ' $mod.TObject.CreateWithB.call(this, true);',
  11649. ' this.DoIt();',
  11650. ' this.DoIt();',
  11651. ' this.$class.DoSome();',
  11652. ' return this;',
  11653. ' };',
  11654. ' this.DoIt = function () {',
  11655. ' this.Create();',
  11656. ' this.CreateWithB(false);',
  11657. ' this.CreateWithC("c");',
  11658. ' };',
  11659. ' this.DoSome = function () {',
  11660. ' var Result = null;',
  11661. ' Result = this.$create("Create");',
  11662. ' Result = this.$create("CreateWithB", [true]);',
  11663. ' Result = this.$create("CreateWithC", ["c"]);',
  11664. ' return Result;',
  11665. ' };',
  11666. '});'
  11667. ]),
  11668. LinesToStr([ // this.$main
  11669. ''
  11670. ]));
  11671. end;
  11672. procedure TTestModule.TestClass_ClassVar_Assign;
  11673. begin
  11674. StartProgram(false);
  11675. Add([
  11676. 'type',
  11677. ' TObject = class',
  11678. ' public',
  11679. ' class var vI: longint;',
  11680. ' class var Sub: TObject;',
  11681. ' constructor Create;',
  11682. ' class function GetIt(var Par: longint): tobject;',
  11683. ' end;',
  11684. 'constructor tobject.create;',
  11685. 'begin',
  11686. ' vi:=vi+1;',
  11687. ' Self.vi:=Self.vi+1;',
  11688. ' inc(vi);',
  11689. 'end;',
  11690. 'class function tobject.getit(var par: longint): tobject;',
  11691. 'begin',
  11692. ' vi:=vi+3;',
  11693. ' Self.vi:=Self.vi+4;',
  11694. ' inc(vi);',
  11695. ' Result:=self.sub;',
  11696. ' GetIt(vi);',
  11697. 'end;',
  11698. 'var Obj: tobject;',
  11699. 'begin',
  11700. ' obj:=tobject.create;',
  11701. ' tobject.vi:=3;',
  11702. ' if tobject.vi=4 then ;',
  11703. ' tobject.sub:=nil;',
  11704. ' obj.sub:=nil;',
  11705. ' obj.sub.sub:=nil;']);
  11706. ConvertProgram;
  11707. CheckSource('TestClass_ClassVar_Assign',
  11708. LinesToStr([ // statements
  11709. 'rtl.createClass($mod,"TObject",null,function(){',
  11710. ' this.vI = 0;',
  11711. ' this.Sub = null;',
  11712. ' this.$init = function () {',
  11713. ' };',
  11714. ' this.$final = function () {',
  11715. ' };',
  11716. ' this.Create = function(){',
  11717. ' $mod.TObject.vI = this.vI+1;',
  11718. ' $mod.TObject.vI = this.vI+1;',
  11719. ' $mod.TObject.vI += 1;',
  11720. ' return this;',
  11721. ' };',
  11722. ' this.GetIt = function(Par){',
  11723. ' var Result = null;',
  11724. ' $mod.TObject.vI = this.vI + 3;',
  11725. ' $mod.TObject.vI = this.vI + 4;',
  11726. ' $mod.TObject.vI += 1;',
  11727. ' Result = this.Sub;',
  11728. ' this.GetIt({',
  11729. ' p: $mod.TObject,',
  11730. ' get: function () {',
  11731. ' return this.p.vI;',
  11732. ' },',
  11733. ' set: function (v) {',
  11734. ' this.p.vI = v;',
  11735. ' }',
  11736. ' });',
  11737. ' return Result;',
  11738. ' };',
  11739. '});',
  11740. 'this.Obj = null;'
  11741. ]),
  11742. LinesToStr([ // $mod.$main
  11743. '$mod.Obj = $mod.TObject.$create("Create");',
  11744. '$mod.TObject.vI = 3;',
  11745. 'if ($mod.TObject.vI === 4);',
  11746. '$mod.TObject.Sub=null;',
  11747. '$mod.TObject.Sub=null;',
  11748. '$mod.TObject.Sub=null;',
  11749. '']));
  11750. end;
  11751. procedure TTestModule.TestClass_CallClassMethod;
  11752. begin
  11753. StartProgram(false);
  11754. Add('type');
  11755. Add(' TObject = class');
  11756. Add(' public');
  11757. Add(' class var vI: longint;');
  11758. Add(' class var Sub: TObject;');
  11759. Add(' constructor Create;');
  11760. Add(' function GetMore(Par: longint): longint;');
  11761. Add(' class function GetIt(Par: longint): tobject;');
  11762. Add(' end;');
  11763. Add('constructor tobject.create;');
  11764. Add('begin');
  11765. Add(' sub:=getit(3);');
  11766. Add(' vi:=getmore(4);');
  11767. Add(' sub:=Self.getit(5);');
  11768. Add(' vi:=Self.getmore(6);');
  11769. Add('end;');
  11770. Add('function tobject.getmore(par: longint): longint;');
  11771. Add('begin');
  11772. Add(' sub:=getit(11);');
  11773. Add(' vi:=getmore(12);');
  11774. Add(' sub:=self.getit(13);');
  11775. Add(' vi:=self.getmore(14);');
  11776. Add('end;');
  11777. Add('class function tobject.getit(par: longint): tobject;');
  11778. Add('begin');
  11779. Add(' sub:=getit(21);');
  11780. Add(' vi:=sub.getmore(22);');
  11781. Add(' sub:=self.getit(23);');
  11782. Add(' vi:=self.sub.getmore(24);');
  11783. Add('end;');
  11784. Add('var Obj: tobject;');
  11785. Add('begin');
  11786. Add(' obj:=tobject.create;');
  11787. Add(' tobject.getit(5);');
  11788. Add(' obj.getit(6);');
  11789. Add(' obj.sub.getit(7);');
  11790. Add(' obj.sub.getit(8).SUB:=nil;');
  11791. Add(' obj.sub.getit(9).GETIT(10);');
  11792. Add(' obj.sub.getit(11).SuB.getit(12);');
  11793. ConvertProgram;
  11794. CheckSource('TestClass_CallClassMethod',
  11795. LinesToStr([ // statements
  11796. 'rtl.createClass($mod,"TObject",null,function(){',
  11797. ' this.vI = 0;',
  11798. ' this.Sub = null;',
  11799. ' this.$init = function () {',
  11800. ' };',
  11801. ' this.$final = function () {',
  11802. ' };',
  11803. ' this.Create = function(){',
  11804. ' $mod.TObject.Sub = this.$class.GetIt(3);',
  11805. ' $mod.TObject.vI = this.GetMore(4);',
  11806. ' $mod.TObject.Sub = this.$class.GetIt(5);',
  11807. ' $mod.TObject.vI = this.GetMore(6);',
  11808. ' return this;',
  11809. ' };',
  11810. ' this.GetMore = function(Par){',
  11811. ' var Result = 0;',
  11812. ' $mod.TObject.Sub = this.$class.GetIt(11);',
  11813. ' $mod.TObject.vI = this.GetMore(12);',
  11814. ' $mod.TObject.Sub = this.$class.GetIt(13);',
  11815. ' $mod.TObject.vI = this.GetMore(14);',
  11816. ' return Result;',
  11817. ' };',
  11818. ' this.GetIt = function(Par){',
  11819. ' var Result = null;',
  11820. ' $mod.TObject.Sub = this.GetIt(21);',
  11821. ' $mod.TObject.vI = this.Sub.GetMore(22);',
  11822. ' $mod.TObject.Sub = this.GetIt(23);',
  11823. ' $mod.TObject.vI = this.Sub.GetMore(24);',
  11824. ' return Result;',
  11825. ' };',
  11826. '});',
  11827. 'this.Obj = null;'
  11828. ]),
  11829. LinesToStr([ // $mod.$main
  11830. '$mod.Obj = $mod.TObject.$create("Create");',
  11831. '$mod.TObject.GetIt(5);',
  11832. '$mod.Obj.$class.GetIt(6);',
  11833. '$mod.Obj.Sub.$class.GetIt(7);',
  11834. '$mod.TObject.Sub=null;',
  11835. '$mod.Obj.Sub.$class.GetIt(9).$class.GetIt(10);',
  11836. '$mod.Obj.Sub.$class.GetIt(11).Sub.$class.GetIt(12);',
  11837. '']));
  11838. end;
  11839. procedure TTestModule.TestClass_Property;
  11840. begin
  11841. StartProgram(false);
  11842. Add('type');
  11843. Add(' TObject = class');
  11844. Add(' Fx: longint;');
  11845. Add(' Fy: longint;');
  11846. Add(' function GetInt: longint;');
  11847. Add(' procedure SetInt(Value: longint);');
  11848. Add(' procedure DoIt;');
  11849. Add(' property IntA: longint read Fx write Fy;');
  11850. Add(' property IntB: longint read GetInt write SetInt;');
  11851. Add(' end;');
  11852. Add('function tobject.getint: longint;');
  11853. Add('begin');
  11854. Add(' result:=fx;');
  11855. Add('end;');
  11856. Add('procedure tobject.setint(value: longint);');
  11857. Add('begin');
  11858. Add(' if value=fy then exit;');
  11859. Add(' fy:=value;');
  11860. Add('end;');
  11861. Add('procedure tobject.doit;');
  11862. Add('begin');
  11863. Add(' IntA:=IntA+1;');
  11864. Add(' Self.IntA:=Self.IntA+1;');
  11865. Add(' IntB:=IntB+1;');
  11866. Add(' Self.IntB:=Self.IntB+1;');
  11867. Add('end;');
  11868. Add('var Obj: tobject;');
  11869. Add('begin');
  11870. Add(' obj.inta:=obj.inta+1;');
  11871. Add(' if obj.intb=2 then;');
  11872. Add(' obj.intb:=obj.intb+2;');
  11873. Add(' obj.setint(obj.inta);');
  11874. ConvertProgram;
  11875. CheckSource('TestClass_Property',
  11876. LinesToStr([ // statements
  11877. 'rtl.createClass($mod, "TObject", null, function () {',
  11878. ' this.$init = function () {',
  11879. ' this.Fx = 0;',
  11880. ' this.Fy = 0;',
  11881. ' };',
  11882. ' this.$final = function () {',
  11883. ' };',
  11884. ' this.GetInt = function () {',
  11885. ' var Result = 0;',
  11886. ' Result = this.Fx;',
  11887. ' return Result;',
  11888. ' };',
  11889. ' this.SetInt = function (Value) {',
  11890. ' if (Value === this.Fy) return;',
  11891. ' this.Fy = Value;',
  11892. ' };',
  11893. ' this.DoIt = function () {',
  11894. ' this.Fy = this.Fx + 1;',
  11895. ' this.Fy = this.Fx + 1;',
  11896. ' this.SetInt(this.GetInt() + 1);',
  11897. ' this.SetInt(this.GetInt() + 1);',
  11898. ' };',
  11899. '});',
  11900. 'this.Obj = null;'
  11901. ]),
  11902. LinesToStr([ // $mod.$main
  11903. '$mod.Obj.Fy = $mod.Obj.Fx + 1;',
  11904. 'if ($mod.Obj.GetInt() === 2);',
  11905. '$mod.Obj.SetInt($mod.Obj.GetInt() + 2);',
  11906. '$mod.Obj.SetInt($mod.Obj.Fx);'
  11907. ]));
  11908. end;
  11909. procedure TTestModule.TestClass_Property_ClassMethod;
  11910. begin
  11911. StartProgram(false);
  11912. Add([
  11913. 'type',
  11914. ' TObject = class',
  11915. ' class var Fx: longint;',
  11916. ' class var Fy: longint;',
  11917. ' class function GetInt: longint;',
  11918. ' class procedure SetInt(Value: longint);',
  11919. ' end;',
  11920. ' TBird = class',
  11921. ' class procedure DoIt;',
  11922. ' class property IntA: longint read Fx write Fy;',
  11923. ' class property IntB: longint read GetInt write SetInt;',
  11924. ' end;',
  11925. 'class function tobject.getint: longint;',
  11926. 'begin',
  11927. ' result:=fx;',
  11928. 'end;',
  11929. 'class procedure tobject.setint(value: longint);',
  11930. 'begin',
  11931. 'end;',
  11932. 'class procedure tbird.doit;',
  11933. 'begin',
  11934. ' FX:=3;',
  11935. ' IntA:=IntA+1;',
  11936. ' Self.IntA:=Self.IntA+1;',
  11937. ' IntB:=IntB+1;',
  11938. ' Self.IntB:=Self.IntB+1;',
  11939. ' with Self do begin',
  11940. ' FX:=11;',
  11941. ' IntA:=IntA+12;',
  11942. ' IntB:=IntB+13;',
  11943. ' end;',
  11944. 'end;',
  11945. 'var Obj: tbird;',
  11946. 'begin',
  11947. ' tbird.fx:=tbird.fx+1;',
  11948. ' tbird.inta:=tbird.inta+1;',
  11949. ' if tbird.intb=2 then;',
  11950. ' tbird.intb:=tbird.intb+2;',
  11951. ' tbird.setint(tbird.inta);',
  11952. ' obj.inta:=obj.inta+1;',
  11953. ' if obj.intb=2 then;',
  11954. ' obj.intb:=obj.intb+2;',
  11955. ' obj.setint(obj.inta);',
  11956. ' with Tbird do begin',
  11957. ' FX:=FY+1;',
  11958. ' inta:=inta+2;',
  11959. ' intb:=intb+3;',
  11960. ' end;',
  11961. ' with Obj do begin',
  11962. ' FX:=FY+1;',
  11963. ' inta:=inta+2;',
  11964. ' intb:=intb+3;',
  11965. ' end;',
  11966. '']);
  11967. ConvertProgram;
  11968. CheckSource('TestClass_Property_ClassMethod',
  11969. LinesToStr([ // statements
  11970. 'rtl.createClass($mod, "TObject", null, function () {',
  11971. ' this.Fx = 0;',
  11972. ' this.Fy = 0;',
  11973. ' this.$init = function () {',
  11974. ' };',
  11975. ' this.$final = function () {',
  11976. ' };',
  11977. ' this.GetInt = function () {',
  11978. ' var Result = 0;',
  11979. ' Result = this.Fx;',
  11980. ' return Result;',
  11981. ' };',
  11982. ' this.SetInt = function (Value) {',
  11983. ' };',
  11984. '});',
  11985. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  11986. ' this.DoIt = function () {',
  11987. ' $mod.TObject.Fx = 3;',
  11988. ' $mod.TObject.Fy = this.Fx + 1;',
  11989. ' $mod.TObject.Fy = this.Fx + 1;',
  11990. ' this.SetInt(this.GetInt() + 1);',
  11991. ' this.SetInt(this.GetInt() + 1);',
  11992. ' $mod.TObject.Fx = 11;',
  11993. ' $mod.TObject.Fy = this.Fx + 12;',
  11994. ' this.SetInt(this.GetInt() + 13);',
  11995. ' };',
  11996. '});',
  11997. 'this.Obj = null;'
  11998. ]),
  11999. LinesToStr([ // $mod.$main
  12000. '$mod.TObject.Fx = $mod.TBird.Fx + 1;',
  12001. '$mod.TObject.Fy = $mod.TBird.Fx + 1;',
  12002. 'if ($mod.TBird.GetInt() === 2);',
  12003. '$mod.TBird.SetInt($mod.TBird.GetInt() + 2);',
  12004. '$mod.TBird.SetInt($mod.TBird.Fx);',
  12005. '$mod.TObject.Fy = $mod.Obj.Fx + 1;',
  12006. 'if ($mod.Obj.$class.GetInt() === 2);',
  12007. '$mod.Obj.$class.SetInt($mod.Obj.$class.GetInt() + 2);',
  12008. '$mod.Obj.$class.SetInt($mod.Obj.Fx);',
  12009. 'var $with1 = $mod.TBird;',
  12010. '$mod.TObject.Fx = $with1.Fy + 1;',
  12011. '$mod.TObject.Fy = $with1.Fx + 2;',
  12012. '$with1.SetInt($with1.GetInt() + 3);',
  12013. 'var $with2 = $mod.Obj;',
  12014. '$mod.TObject.Fx = $with2.Fy + 1;',
  12015. '$mod.TObject.Fy = $with2.Fx + 2;',
  12016. '$with2.$class.SetInt($with2.$class.GetInt() + 3);',
  12017. '']));
  12018. end;
  12019. procedure TTestModule.TestClass_Property_Indexed;
  12020. begin
  12021. StartProgram(false);
  12022. Add('type');
  12023. Add(' TObject = class');
  12024. Add(' FItems: array of longint;');
  12025. Add(' function GetItems(Index: longint): longint;');
  12026. Add(' procedure SetItems(Index: longint; Value: longint);');
  12027. Add(' procedure DoIt;');
  12028. Add(' property Items[Index: longint]: longint read getitems write setitems;');
  12029. Add(' end;');
  12030. Add('function tobject.getitems(index: longint): longint;');
  12031. Add('begin');
  12032. Add(' Result:=fitems[index];');
  12033. Add('end;');
  12034. Add('procedure tobject.setitems(index: longint; value: longint);');
  12035. Add('begin');
  12036. Add(' fitems[index]:=value;');
  12037. Add('end;');
  12038. Add('procedure tobject.doit;');
  12039. Add('begin');
  12040. Add(' items[1]:=2;');
  12041. Add(' items[3]:=items[4];');
  12042. Add(' self.items[5]:=self.items[6];');
  12043. Add(' items[items[7]]:=items[items[8]];');
  12044. Add('end;');
  12045. Add('var Obj: tobject;');
  12046. Add('begin');
  12047. Add(' obj.Items[11]:=obj.Items[12];');
  12048. ConvertProgram;
  12049. CheckSource('TestClass_Property_Indexed',
  12050. LinesToStr([ // statements
  12051. 'rtl.createClass($mod, "TObject", null, function () {',
  12052. ' this.$init = function () {',
  12053. ' this.FItems = [];',
  12054. ' };',
  12055. ' this.$final = function () {',
  12056. ' this.FItems = undefined;',
  12057. ' };',
  12058. ' this.GetItems = function (Index) {',
  12059. ' var Result = 0;',
  12060. ' Result = this.FItems[Index];',
  12061. ' return Result;',
  12062. ' };',
  12063. ' this.SetItems = function (Index, Value) {',
  12064. ' this.FItems[Index] = Value;',
  12065. ' };',
  12066. ' this.DoIt = function () {',
  12067. ' this.SetItems(1, 2);',
  12068. ' this.SetItems(3,this.GetItems(4));',
  12069. ' this.SetItems(5,this.GetItems(6));',
  12070. ' this.SetItems(this.GetItems(7), this.GetItems(this.GetItems(8)));',
  12071. ' };',
  12072. '});',
  12073. 'this.Obj = null;'
  12074. ]),
  12075. LinesToStr([ // $mod.$main
  12076. '$mod.Obj.SetItems(11,$mod.Obj.GetItems(12));'
  12077. ]));
  12078. end;
  12079. procedure TTestModule.TestClass_Property_IndexSpec;
  12080. begin
  12081. StartProgram(false);
  12082. Add([
  12083. 'type',
  12084. ' TEnum = (red, blue);',
  12085. ' TObject = class',
  12086. ' function GetIntBool(Index: longint): boolean; virtual; abstract;',
  12087. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  12088. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  12089. ' procedure SetEnumBool(Index: TEnum; b: boolean); virtual; abstract;',
  12090. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  12091. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  12092. ' property B1: boolean index 1 read GetIntBool write SetIntBool;',
  12093. ' property B2: boolean index TEnum.blue read GetEnumBool write SetEnumBool;',
  12094. ' property B3: boolean index ord(red) read GetIntBool write SetIntBool;',
  12095. ' property I1[A: String]: boolean index ord(blue) read GetStrIntBool write SetStrIntBool;',
  12096. ' end;',
  12097. 'procedure DoIt(b: boolean); begin end;',
  12098. 'var',
  12099. ' o: TObject;',
  12100. 'begin',
  12101. ' o.B1:=o.B1;',
  12102. ' o.B2:=o.B2;',
  12103. ' o.B3:=o.B3;',
  12104. ' o.I1[''a'']:=o.I1[''b''];',
  12105. ' doit(o.b1);',
  12106. ' doit(o.b2);',
  12107. ' doit(o.i1[''c'']);',
  12108. '']);
  12109. ConvertProgram;
  12110. CheckSource('TestClass_Property_IndexSpec',
  12111. LinesToStr([ // statements
  12112. 'this.TEnum = {',
  12113. ' "0": "red",',
  12114. ' red: 0,',
  12115. ' "1": "blue",',
  12116. ' blue: 1',
  12117. '};',
  12118. 'rtl.createClass($mod, "TObject", null, function () {',
  12119. ' this.$init = function () {',
  12120. ' };',
  12121. ' this.$final = function () {',
  12122. ' };',
  12123. '});',
  12124. 'this.DoIt = function (b) {',
  12125. '};',
  12126. 'this.o = null;',
  12127. '']),
  12128. LinesToStr([ // $mod.$main
  12129. '$mod.o.SetIntBool(1, $mod.o.GetIntBool(1));',
  12130. '$mod.o.SetEnumBool($mod.TEnum.blue, $mod.o.GetEnumBool($mod.TEnum.blue));',
  12131. '$mod.o.SetIntBool(0, $mod.o.GetIntBool(0));',
  12132. '$mod.o.SetStrIntBool("a", 1, $mod.o.GetStrIntBool("b", 1));',
  12133. '$mod.DoIt($mod.o.GetIntBool(1));',
  12134. '$mod.DoIt($mod.o.GetEnumBool($mod.TEnum.blue));',
  12135. '$mod.DoIt($mod.o.GetStrIntBool("c", 1));',
  12136. '']));
  12137. end;
  12138. procedure TTestModule.TestClass_PropertyOfTypeArray;
  12139. begin
  12140. StartProgram(false);
  12141. Add('type');
  12142. Add(' TArray = array of longint;');
  12143. Add(' TObject = class');
  12144. Add(' FItems: TArray;');
  12145. Add(' function GetItems: tarray;');
  12146. Add(' procedure SetItems(Value: tarray);');
  12147. Add(' property Items: tarray read getitems write setitems;');
  12148. Add(' end;');
  12149. Add('function tobject.getitems: tarray;');
  12150. Add('begin');
  12151. Add(' Result:=fitems;');
  12152. Add('end;');
  12153. Add('procedure tobject.setitems(value: tarray);');
  12154. Add('begin');
  12155. Add(' fitems:=value;');
  12156. Add(' fitems:=nil;');
  12157. Add(' Items:=nil;');
  12158. Add(' Items:=Items;');
  12159. Add(' Items[1]:=2;');
  12160. Add(' fitems[3]:=Items[4];');
  12161. Add(' Items[5]:=Items[6];');
  12162. Add(' Self.Items[7]:=8;');
  12163. Add(' Self.Items[9]:=Self.Items[10];');
  12164. Add(' Items[Items[11]]:=Items[Items[12]];');
  12165. Add('end;');
  12166. Add('var Obj: tobject;');
  12167. Add('begin');
  12168. Add(' obj.items:=nil;');
  12169. Add(' obj.items:=obj.items;');
  12170. Add(' obj.items[11]:=obj.items[12];');
  12171. ConvertProgram;
  12172. CheckSource('TestClass_PropertyOfTypeArray',
  12173. LinesToStr([ // statements
  12174. 'rtl.createClass($mod, "TObject", null, function () {',
  12175. ' this.$init = function () {',
  12176. ' this.FItems = [];',
  12177. ' };',
  12178. ' this.$final = function () {',
  12179. ' this.FItems = undefined;',
  12180. ' };',
  12181. ' this.GetItems = function () {',
  12182. ' var Result = [];',
  12183. ' Result = this.FItems;',
  12184. ' return Result;',
  12185. ' };',
  12186. ' this.SetItems = function (Value) {',
  12187. ' this.FItems = Value;',
  12188. ' this.FItems = [];',
  12189. ' this.SetItems([]);',
  12190. ' this.SetItems(this.GetItems());',
  12191. ' this.GetItems()[1] = 2;',
  12192. ' this.FItems[3] = this.GetItems()[4];',
  12193. ' this.GetItems()[5] = this.GetItems()[6];',
  12194. ' this.GetItems()[7] = 8;',
  12195. ' this.GetItems()[9] = this.GetItems()[10];',
  12196. ' this.GetItems()[this.GetItems()[11]] = this.GetItems()[this.GetItems()[12]];',
  12197. ' };',
  12198. '});',
  12199. 'this.Obj = null;'
  12200. ]),
  12201. LinesToStr([ // $mod.$main
  12202. '$mod.Obj.SetItems([]);',
  12203. '$mod.Obj.SetItems($mod.Obj.GetItems());',
  12204. '$mod.Obj.GetItems()[11] = $mod.Obj.GetItems()[12];'
  12205. ]));
  12206. end;
  12207. procedure TTestModule.TestClass_PropertyDefault;
  12208. begin
  12209. StartProgram(false);
  12210. Add([
  12211. 'type',
  12212. ' TArray = array of longint;',
  12213. ' TObject = class',
  12214. ' FItems: TArray;',
  12215. ' function GetItems(Index: longint): longint;',
  12216. ' procedure SetItems(Index, Value: longint);',
  12217. ' property Items[Index: longint]: longint read getitems write setitems; default;',
  12218. ' end;',
  12219. 'function tobject.getitems(index: longint): longint;',
  12220. 'begin',
  12221. 'end;',
  12222. 'procedure tobject.setitems(index, value: longint);',
  12223. 'begin',
  12224. ' Self[1]:=2;',
  12225. ' Self[3]:=Self[index];',
  12226. ' Self[index]:=Self[Self[value]];',
  12227. ' Self[Self[4]]:=value;',
  12228. 'end;',
  12229. 'var Obj: tobject;',
  12230. 'begin',
  12231. ' obj[11]:=12;',
  12232. ' obj[13]:=obj[14];',
  12233. ' obj[obj[15]]:=obj[obj[15]];',
  12234. ' TObject(obj)[16]:=TObject(obj)[17];']);
  12235. ConvertProgram;
  12236. CheckSource('TestClass_PropertyDefault',
  12237. LinesToStr([ // statements
  12238. 'rtl.createClass($mod, "TObject", null, function () {',
  12239. ' this.$init = function () {',
  12240. ' this.FItems = [];',
  12241. ' };',
  12242. ' this.$final = function () {',
  12243. ' this.FItems = undefined;',
  12244. ' };',
  12245. ' this.GetItems = function (Index) {',
  12246. ' var Result = 0;',
  12247. ' return Result;',
  12248. ' };',
  12249. ' this.SetItems = function (Index, Value) {',
  12250. ' this.SetItems(1, 2);',
  12251. ' this.SetItems(3, this.GetItems(Index));',
  12252. ' this.SetItems(Index, this.GetItems(this.GetItems(Value)));',
  12253. ' this.SetItems(this.GetItems(4), Value);',
  12254. ' };',
  12255. '});',
  12256. 'this.Obj = null;'
  12257. ]),
  12258. LinesToStr([ // $mod.$main
  12259. '$mod.Obj.SetItems(11, 12);',
  12260. '$mod.Obj.SetItems(13, $mod.Obj.GetItems(14));',
  12261. '$mod.Obj.SetItems($mod.Obj.GetItems(15), $mod.Obj.GetItems($mod.Obj.GetItems(15)));',
  12262. '$mod.Obj.SetItems(16, $mod.Obj.GetItems(17));',
  12263. '']));
  12264. end;
  12265. procedure TTestModule.TestClass_PropertyDefault2;
  12266. begin
  12267. StartProgram(false);
  12268. Add([
  12269. 'type',
  12270. ' TObject = class end;',
  12271. ' TAlphaList = class',
  12272. ' function GetAlphas(Index: boolean): Pointer; virtual; abstract;',
  12273. ' procedure SetAlphas(Index: boolean; Value: Pointer); virtual; abstract;',
  12274. ' property Alphas[Index: boolean]: Pointer read getAlphas write setAlphas; default;',
  12275. ' end;',
  12276. ' TBetaList = class',
  12277. ' function GetBetas(Index: longint): Pointer; virtual; abstract;',
  12278. ' procedure SetBetas(Index: longint; Value: Pointer); virtual; abstract;',
  12279. ' property Betas[Index: longint]: Pointer read getBetas write setBetas; default;',
  12280. ' end;',
  12281. ' TBird = class',
  12282. ' procedure DoIt;',
  12283. ' end;',
  12284. 'procedure TBird.DoIt;',
  12285. 'var',
  12286. ' List: TAlphaList;',
  12287. 'begin',
  12288. ' if TBetaList(List[true])[3]=nil then ;',
  12289. ' TBetaList(List[false])[5]:=nil;',
  12290. 'end;',
  12291. 'var',
  12292. ' List: TAlphaList;',
  12293. 'begin',
  12294. ' if TBetaList(List[true])[3]=nil then ;',
  12295. ' TBetaList(List[false])[5]:=nil;',
  12296. '']);
  12297. ConvertProgram;
  12298. CheckSource('TestClass_PropertyDefault2',
  12299. LinesToStr([ // statements
  12300. 'rtl.createClass($mod, "TObject", null, function () {',
  12301. ' this.$init = function () {',
  12302. ' };',
  12303. ' this.$final = function () {',
  12304. ' };',
  12305. '});',
  12306. 'rtl.createClass($mod, "TAlphaList", $mod.TObject, function () {',
  12307. '});',
  12308. 'rtl.createClass($mod, "TBetaList", $mod.TObject, function () {',
  12309. '});',
  12310. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  12311. ' this.DoIt = function () {',
  12312. ' var List = null;',
  12313. ' if (List.GetAlphas(true).GetBetas(3) === null) ;',
  12314. ' List.GetAlphas(false).SetBetas(5, null);',
  12315. ' };',
  12316. '});',
  12317. 'this.List = null;',
  12318. '']),
  12319. LinesToStr([ // $mod.$main
  12320. 'if ($mod.List.GetAlphas(true).GetBetas(3) === null) ;',
  12321. '$mod.List.GetAlphas(false).SetBetas(5, null);',
  12322. '']));
  12323. end;
  12324. procedure TTestModule.TestClass_PropertyOverride;
  12325. begin
  12326. StartProgram(false);
  12327. Add('type');
  12328. Add(' integer = longint;');
  12329. Add(' TObject = class');
  12330. Add(' FItem: integer;');
  12331. Add(' function GetItem: integer; external name ''GetItem'';');
  12332. Add(' procedure SetItem(Value: integer); external name ''SetItem'';');
  12333. Add(' property Item: integer read getitem write setitem;');
  12334. Add(' end;');
  12335. Add(' TCar = class');
  12336. Add(' FBag: integer;');
  12337. Add(' function GetBag: integer; external name ''GetBag'';');
  12338. Add(' property Item read getbag;');
  12339. Add(' end;');
  12340. Add('var');
  12341. Add(' Obj: tobject;');
  12342. Add(' Car: tcar;');
  12343. Add('begin');
  12344. Add(' Obj.Item:=Obj.Item;');
  12345. Add(' Car.Item:=Car.Item;');
  12346. ConvertProgram;
  12347. CheckSource('TestClass_PropertyOverride',
  12348. LinesToStr([ // statements
  12349. 'rtl.createClass($mod, "TObject", null, function () {',
  12350. ' this.$init = function () {',
  12351. ' this.FItem = 0;',
  12352. ' };',
  12353. ' this.$final = function () {',
  12354. ' };',
  12355. '});',
  12356. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  12357. ' this.$init = function () {',
  12358. ' $mod.TObject.$init.call(this);',
  12359. ' this.FBag = 0;',
  12360. ' };',
  12361. '});',
  12362. 'this.Obj = null;',
  12363. 'this.Car = null;',
  12364. '']),
  12365. LinesToStr([ // $mod.$main
  12366. '$mod.Obj.SetItem($mod.Obj.GetItem());',
  12367. '$mod.Car.SetItem($mod.Car.GetBag());',
  12368. '']));
  12369. end;
  12370. procedure TTestModule.TestClass_PropertyIncVisibility;
  12371. begin
  12372. AddModuleWithIntfImplSrc('unit1.pp',
  12373. LinesToStr([
  12374. 'type',
  12375. ' TNumber = longint;',
  12376. ' TInteger = longint;',
  12377. ' TObject = class',
  12378. ' private',
  12379. ' function GetItems(Index: TNumber): TInteger; virtual; abstract;',
  12380. ' procedure SetItems(Index: TInteger; Value: TNumber); virtual; abstract;',
  12381. ' protected',
  12382. ' property Items[Index: TNumber]: longint read GetItems write SetItems;',
  12383. ' end;']),
  12384. LinesToStr([
  12385. '']));
  12386. StartProgram(true);
  12387. Add([
  12388. 'uses unit1;',
  12389. 'type',
  12390. ' TBird = class',
  12391. ' public',
  12392. ' property Items;',
  12393. ' end;',
  12394. 'procedure DoIt(i: TInteger);',
  12395. 'begin',
  12396. 'end;',
  12397. 'var b: TBird;',
  12398. 'begin',
  12399. ' b.Items[1]:=2;',
  12400. ' b.Items[3]:=b.Items[4];',
  12401. ' DoIt(b.Items[5]);',
  12402. '']);
  12403. ConvertProgram;
  12404. CheckSource('TestClass_PropertyIncVisibility',
  12405. LinesToStr([ // statements
  12406. 'rtl.createClass($mod, "TBird", pas.unit1.TObject, function () {',
  12407. '});',
  12408. 'this.DoIt = function (i) {',
  12409. '};',
  12410. 'this.b = null;'
  12411. ]),
  12412. LinesToStr([ // $mod.$main
  12413. '$mod.b.SetItems(1, 2);',
  12414. '$mod.b.SetItems(3, $mod.b.GetItems(4));',
  12415. '$mod.DoIt($mod.b.GetItems(5));'
  12416. ]));
  12417. end;
  12418. procedure TTestModule.TestClass_Assigned;
  12419. begin
  12420. StartProgram(false);
  12421. Add('type');
  12422. Add(' TObject = class');
  12423. Add(' end;');
  12424. Add('var');
  12425. Add(' Obj: tobject;');
  12426. Add(' b: boolean;');
  12427. Add('begin');
  12428. Add(' if Assigned(obj) then ;');
  12429. Add(' b:=Assigned(obj) or false;');
  12430. ConvertProgram;
  12431. CheckSource('TestClass_Assigned',
  12432. LinesToStr([ // statements
  12433. 'rtl.createClass($mod, "TObject", null, function () {',
  12434. ' this.$init = function () {',
  12435. ' };',
  12436. ' this.$final = function () {',
  12437. ' };',
  12438. '});',
  12439. 'this.Obj = null;',
  12440. 'this.b = false;'
  12441. ]),
  12442. LinesToStr([ // $mod.$main
  12443. 'if ($mod.Obj != null);',
  12444. '$mod.b = ($mod.Obj != null) || false;'
  12445. ]));
  12446. end;
  12447. procedure TTestModule.TestClass_WithClassDoCreate;
  12448. begin
  12449. StartProgram(false);
  12450. Add('type');
  12451. Add(' TObject = class');
  12452. Add(' aBool: boolean;');
  12453. Add(' Arr: array of boolean;');
  12454. Add(' constructor Create;');
  12455. Add(' end;');
  12456. Add('constructor TObject.Create; begin end;');
  12457. Add('var');
  12458. Add(' Obj: tobject;');
  12459. Add(' b: boolean;');
  12460. Add('begin');
  12461. Add(' with tobject.create do begin');
  12462. Add(' b:=abool;');
  12463. Add(' abool:=b;');
  12464. Add(' b:=arr[1];');
  12465. Add(' arr[2]:=b;');
  12466. Add(' end;');
  12467. Add(' with tobject do');
  12468. Add(' obj:=create;');
  12469. Add(' with obj do begin');
  12470. Add(' create;');
  12471. Add(' b:=abool;');
  12472. Add(' abool:=b;');
  12473. Add(' b:=arr[3];');
  12474. Add(' arr[4]:=b;');
  12475. Add(' end;');
  12476. ConvertProgram;
  12477. CheckSource('TestClass_WithClassDoCreate',
  12478. LinesToStr([ // statements
  12479. 'rtl.createClass($mod, "TObject", null, function () {',
  12480. ' this.$init = function () {',
  12481. ' this.aBool = false;',
  12482. ' this.Arr = [];',
  12483. ' };',
  12484. ' this.$final = function () {',
  12485. ' this.Arr = undefined;',
  12486. ' };',
  12487. ' this.Create = function () {',
  12488. ' return this;',
  12489. ' };',
  12490. '});',
  12491. 'this.Obj = null;',
  12492. 'this.b = false;'
  12493. ]),
  12494. LinesToStr([ // $mod.$main
  12495. 'var $with1 = $mod.TObject.$create("Create");',
  12496. '$mod.b = $with1.aBool;',
  12497. '$with1.aBool = $mod.b;',
  12498. '$mod.b = $with1.Arr[1];',
  12499. '$with1.Arr[2] = $mod.b;',
  12500. 'var $with2 = $mod.TObject;',
  12501. '$mod.Obj = $with2.$create("Create");',
  12502. 'var $with3 = $mod.Obj;',
  12503. '$with3.Create();',
  12504. '$mod.b = $with3.aBool;',
  12505. '$with3.aBool = $mod.b;',
  12506. '$mod.b = $with3.Arr[3];',
  12507. '$with3.Arr[4] = $mod.b;',
  12508. '']));
  12509. end;
  12510. procedure TTestModule.TestClass_WithClassInstDoProperty;
  12511. begin
  12512. StartProgram(false);
  12513. Add('type');
  12514. Add(' TObject = class');
  12515. Add(' FInt: longint;');
  12516. Add(' constructor Create;');
  12517. Add(' function GetSize: longint;');
  12518. Add(' procedure SetSize(Value: longint);');
  12519. Add(' property Int: longint read FInt write FInt;');
  12520. Add(' property Size: longint read GetSize write SetSize;');
  12521. Add(' end;');
  12522. Add('constructor TObject.Create; begin end;');
  12523. Add('function TObject.GetSize: longint; begin; end;');
  12524. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  12525. Add('var');
  12526. Add(' Obj: tobject;');
  12527. Add(' i: longint;');
  12528. Add('begin');
  12529. Add(' with TObject.Create do begin');
  12530. Add(' i:=int;');
  12531. Add(' int:=i;');
  12532. Add(' i:=size;');
  12533. Add(' size:=i;');
  12534. Add(' end;');
  12535. Add(' with obj do begin');
  12536. Add(' i:=int;');
  12537. Add(' int:=i;');
  12538. Add(' i:=size;');
  12539. Add(' size:=i;');
  12540. Add(' end;');
  12541. ConvertProgram;
  12542. CheckSource('TestClass_WithClassInstDoProperty',
  12543. LinesToStr([ // statements
  12544. 'rtl.createClass($mod, "TObject", null, function () {',
  12545. ' this.$init = function () {',
  12546. ' this.FInt = 0;',
  12547. ' };',
  12548. ' this.$final = function () {',
  12549. ' };',
  12550. ' this.Create = function () {',
  12551. ' return this;',
  12552. ' };',
  12553. ' this.GetSize = function () {',
  12554. ' var Result = 0;',
  12555. ' return Result;',
  12556. ' };',
  12557. ' this.SetSize = function (Value) {',
  12558. ' };',
  12559. '});',
  12560. 'this.Obj = null;',
  12561. 'this.i = 0;'
  12562. ]),
  12563. LinesToStr([ // $mod.$main
  12564. 'var $with1 = $mod.TObject.$create("Create");',
  12565. '$mod.i = $with1.FInt;',
  12566. '$with1.FInt = $mod.i;',
  12567. '$mod.i = $with1.GetSize();',
  12568. '$with1.SetSize($mod.i);',
  12569. 'var $with2 = $mod.Obj;',
  12570. '$mod.i = $with2.FInt;',
  12571. '$with2.FInt = $mod.i;',
  12572. '$mod.i = $with2.GetSize();',
  12573. '$with2.SetSize($mod.i);',
  12574. '']));
  12575. end;
  12576. procedure TTestModule.TestClass_WithClassInstDoPropertyWithParams;
  12577. begin
  12578. StartProgram(false);
  12579. Add('type');
  12580. Add(' TObject = class');
  12581. Add(' constructor Create;');
  12582. Add(' function GetItems(Index: longint): longint;');
  12583. Add(' procedure SetItems(Index, Value: longint);');
  12584. Add(' property Items[Index: longint]: longint read GetItems write SetItems;');
  12585. Add(' end;');
  12586. Add('constructor TObject.Create; begin end;');
  12587. Add('function tobject.getitems(index: longint): longint; begin; end;');
  12588. Add('procedure tobject.setitems(index, value: longint); begin; end;');
  12589. Add('var');
  12590. Add(' Obj: tobject;');
  12591. Add(' i: longint;');
  12592. Add('begin');
  12593. Add(' with TObject.Create do begin');
  12594. Add(' i:=Items[1];');
  12595. Add(' Items[2]:=i;');
  12596. Add(' end;');
  12597. Add(' with obj do begin');
  12598. Add(' i:=Items[3];');
  12599. Add(' Items[4]:=i;');
  12600. Add(' end;');
  12601. ConvertProgram;
  12602. CheckSource('TestClass_WithClassInstDoPropertyWithParams',
  12603. LinesToStr([ // statements
  12604. 'rtl.createClass($mod, "TObject", null, function () {',
  12605. ' this.$init = function () {',
  12606. ' };',
  12607. ' this.$final = function () {',
  12608. ' };',
  12609. ' this.Create = function () {',
  12610. ' return this;',
  12611. ' };',
  12612. ' this.GetItems = function (Index) {',
  12613. ' var Result = 0;',
  12614. ' return Result;',
  12615. ' };',
  12616. ' this.SetItems = function (Index, Value) {',
  12617. ' };',
  12618. '});',
  12619. 'this.Obj = null;',
  12620. 'this.i = 0;'
  12621. ]),
  12622. LinesToStr([ // $mod.$main
  12623. 'var $with1 = $mod.TObject.$create("Create");',
  12624. '$mod.i = $with1.GetItems(1);',
  12625. '$with1.SetItems(2, $mod.i);',
  12626. 'var $with2 = $mod.Obj;',
  12627. '$mod.i = $with2.GetItems(3);',
  12628. '$with2.SetItems(4, $mod.i);',
  12629. '']));
  12630. end;
  12631. procedure TTestModule.TestClass_WithClassInstDoFunc;
  12632. begin
  12633. StartProgram(false);
  12634. Add('type');
  12635. Add(' TObject = class');
  12636. Add(' constructor Create;');
  12637. Add(' function GetSize: longint;');
  12638. Add(' procedure SetSize(Value: longint);');
  12639. Add(' end;');
  12640. Add('constructor TObject.Create; begin end;');
  12641. Add('function TObject.GetSize: longint; begin; end;');
  12642. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  12643. Add('var');
  12644. Add(' Obj: tobject;');
  12645. Add(' i: longint;');
  12646. Add('begin');
  12647. Add(' with TObject.Create do begin');
  12648. Add(' i:=GetSize;');
  12649. Add(' i:=GetSize();');
  12650. Add(' SetSize(i);');
  12651. Add(' end;');
  12652. Add(' with obj do begin');
  12653. Add(' i:=GetSize;');
  12654. Add(' i:=GetSize();');
  12655. Add(' SetSize(i);');
  12656. Add(' end;');
  12657. ConvertProgram;
  12658. CheckSource('TestClass_WithClassInstDoFunc',
  12659. LinesToStr([ // statements
  12660. 'rtl.createClass($mod, "TObject", null, function () {',
  12661. ' this.$init = function () {',
  12662. ' };',
  12663. ' this.$final = function () {',
  12664. ' };',
  12665. ' this.Create = function () {',
  12666. ' return this;',
  12667. ' };',
  12668. ' this.GetSize = function () {',
  12669. ' var Result = 0;',
  12670. ' return Result;',
  12671. ' };',
  12672. ' this.SetSize = function (Value) {',
  12673. ' };',
  12674. '});',
  12675. 'this.Obj = null;',
  12676. 'this.i = 0;'
  12677. ]),
  12678. LinesToStr([ // $mod.$main
  12679. 'var $with1 = $mod.TObject.$create("Create");',
  12680. '$mod.i = $with1.GetSize();',
  12681. '$mod.i = $with1.GetSize();',
  12682. '$with1.SetSize($mod.i);',
  12683. 'var $with2 = $mod.Obj;',
  12684. '$mod.i = $with2.GetSize();',
  12685. '$mod.i = $with2.GetSize();',
  12686. '$with2.SetSize($mod.i);',
  12687. '']));
  12688. end;
  12689. procedure TTestModule.TestClass_TypeCast;
  12690. begin
  12691. StartProgram(false);
  12692. Add('type');
  12693. Add(' TObject = class');
  12694. Add(' Next: TObject;');
  12695. Add(' constructor Create;');
  12696. Add(' end;');
  12697. Add(' TControl = class(TObject)');
  12698. Add(' Arr: array of TObject;');
  12699. Add(' function GetIt(vI: longint = 0): TObject;');
  12700. Add(' end;');
  12701. Add('constructor tobject.create; begin end;');
  12702. Add('function tcontrol.getit(vi: longint = 0): tobject; begin end;');
  12703. Add('var');
  12704. Add(' Obj: tobject;');
  12705. Add('begin');
  12706. Add(' obj:=tcontrol(obj).next;');
  12707. Add(' tcontrol(obj):=nil;');
  12708. Add(' obj:=tcontrol(obj);');
  12709. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit);');
  12710. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit());');
  12711. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit(1));');
  12712. Add(' tcontrol(obj):=tcontrol(tcontrol(tcontrol(obj).getit).arr[2]);');
  12713. ConvertProgram;
  12714. CheckSource('TestClass_TypeCast',
  12715. LinesToStr([ // statements
  12716. 'rtl.createClass($mod, "TObject", null, function () {',
  12717. ' this.$init = function () {',
  12718. ' this.Next = null;',
  12719. ' };',
  12720. ' this.$final = function () {',
  12721. ' this.Next = undefined;',
  12722. ' };',
  12723. ' this.Create = function () {',
  12724. ' return this;',
  12725. ' };',
  12726. '});',
  12727. 'rtl.createClass($mod, "TControl", $mod.TObject, function () {',
  12728. ' this.$init = function () {',
  12729. ' $mod.TObject.$init.call(this);',
  12730. ' this.Arr = [];',
  12731. ' };',
  12732. ' this.$final = function () {',
  12733. ' this.Arr = undefined;',
  12734. ' $mod.TObject.$final.call(this);',
  12735. ' };',
  12736. ' this.GetIt = function (vI) {',
  12737. ' var Result = null;',
  12738. ' return Result;',
  12739. ' };',
  12740. '});',
  12741. 'this.Obj = null;'
  12742. ]),
  12743. LinesToStr([ // $mod.$main
  12744. '$mod.Obj = $mod.Obj.Next;',
  12745. '$mod.Obj = null;',
  12746. '$mod.Obj = $mod.Obj;',
  12747. '$mod.Obj = $mod.Obj.GetIt(0);',
  12748. '$mod.Obj = $mod.Obj.GetIt(0);',
  12749. '$mod.Obj = $mod.Obj.GetIt(1);',
  12750. '$mod.Obj = $mod.Obj.GetIt(0).Arr[2];',
  12751. '']));
  12752. end;
  12753. procedure TTestModule.TestClass_TypeCastUntypedParam;
  12754. begin
  12755. StartProgram(false);
  12756. Add('type');
  12757. Add(' TObject = class end;');
  12758. Add('procedure ProcA(var A);');
  12759. Add('begin');
  12760. Add(' TObject(A):=nil;');
  12761. Add(' TObject(A):=TObject(A);');
  12762. Add(' if TObject(A)=nil then ;');
  12763. Add(' if nil=TObject(A) then ;');
  12764. Add('end;');
  12765. Add('procedure ProcB(out A);');
  12766. Add('begin');
  12767. Add(' TObject(A):=nil;');
  12768. Add(' TObject(A):=TObject(A);');
  12769. Add(' if TObject(A)=nil then ;');
  12770. Add(' if nil=TObject(A) then ;');
  12771. Add('end;');
  12772. Add('procedure ProcC(const A);');
  12773. Add('begin');
  12774. Add(' if TObject(A)=nil then ;');
  12775. Add(' if nil=TObject(A) then ;');
  12776. Add('end;');
  12777. Add('var o: TObject;');
  12778. Add('begin');
  12779. Add(' ProcA(o);');
  12780. Add(' ProcB(o);');
  12781. Add(' ProcC(o);');
  12782. ConvertProgram;
  12783. CheckSource('TestClass_TypeCastUntypedParam',
  12784. LinesToStr([ // statements
  12785. 'rtl.createClass($mod, "TObject", null, function () {',
  12786. ' this.$init = function () {',
  12787. ' };',
  12788. ' this.$final = function () {',
  12789. ' };',
  12790. '});',
  12791. 'this.ProcA = function (A) {',
  12792. ' A.set(null);',
  12793. ' A.set(A.get());',
  12794. ' if (A.get() === null);',
  12795. ' if (null === A.get());',
  12796. '};',
  12797. 'this.ProcB = function (A) {',
  12798. ' A.set(null);',
  12799. ' A.set(A.get());',
  12800. ' if (A.get() === null);',
  12801. ' if (null === A.get());',
  12802. '};',
  12803. 'this.ProcC = function (A) {',
  12804. ' if (A === null);',
  12805. ' if (null === A);',
  12806. '};',
  12807. 'this.o = null;',
  12808. '']),
  12809. LinesToStr([ // $mod.$main
  12810. '$mod.ProcA({',
  12811. ' p: $mod,',
  12812. ' get: function () {',
  12813. ' return this.p.o;',
  12814. ' },',
  12815. ' set: function (v) {',
  12816. ' this.p.o = v;',
  12817. ' }',
  12818. '});',
  12819. '$mod.ProcB({',
  12820. ' p: $mod,',
  12821. ' get: function () {',
  12822. ' return this.p.o;',
  12823. ' },',
  12824. ' set: function (v) {',
  12825. ' this.p.o = v;',
  12826. ' }',
  12827. '});',
  12828. '$mod.ProcC($mod.o);',
  12829. '']));
  12830. end;
  12831. procedure TTestModule.TestClass_Overloads;
  12832. begin
  12833. StartProgram(false);
  12834. Add('type');
  12835. Add(' TObject = class');
  12836. Add(' procedure DoIt;');
  12837. Add(' procedure DoIt(vI: longint);');
  12838. Add(' end;');
  12839. Add('procedure TObject.DoIt;');
  12840. Add('begin');
  12841. Add(' DoIt;');
  12842. Add(' DoIt(1);');
  12843. Add('end;');
  12844. Add('procedure TObject.DoIt(vI: longint); begin end;');
  12845. Add('begin');
  12846. ConvertProgram;
  12847. CheckSource('TestClass_Overloads',
  12848. LinesToStr([ // statements
  12849. 'rtl.createClass($mod, "TObject", null, function () {',
  12850. ' this.$init = function () {',
  12851. ' };',
  12852. ' this.$final = function () {',
  12853. ' };',
  12854. ' this.DoIt = function () {',
  12855. ' this.DoIt();',
  12856. ' this.DoIt$1(1);',
  12857. ' };',
  12858. ' this.DoIt$1 = function (vI) {',
  12859. ' };',
  12860. '});',
  12861. '']),
  12862. LinesToStr([ // $mod.$main
  12863. '']));
  12864. end;
  12865. procedure TTestModule.TestClass_OverloadsAncestor;
  12866. begin
  12867. StartProgram(false);
  12868. Add('type');
  12869. Add(' TObject = class;');
  12870. Add(' TObject = class');
  12871. Add(' procedure DoIt(vA: longint);');
  12872. Add(' procedure DoIt(vA, vB: longint);');
  12873. Add(' end;');
  12874. Add(' TCar = class;');
  12875. Add(' TCar = class');
  12876. Add(' procedure DoIt(vA: longint);');
  12877. Add(' procedure DoIt(vA, vB: longint);');
  12878. Add(' end;');
  12879. Add('procedure tobject.doit(va: longint);');
  12880. Add('begin');
  12881. Add(' doit(1);');
  12882. Add(' doit(1,2);');
  12883. Add('end;');
  12884. Add('procedure tobject.doit(va, vb: longint); begin end;');
  12885. Add('procedure tcar.doit(va: longint);');
  12886. Add('begin');
  12887. Add(' doit(1);');
  12888. Add(' doit(1,2);');
  12889. Add(' inherited doit(1);');
  12890. Add(' inherited doit(1,2);');
  12891. Add('end;');
  12892. Add('procedure tcar.doit(va, vb: longint); begin end;');
  12893. Add('begin');
  12894. ConvertProgram;
  12895. CheckSource('TestClass_OverloadsAncestor',
  12896. LinesToStr([ // statements
  12897. 'rtl.createClass($mod, "TObject", null, function () {',
  12898. ' this.$init = function () {',
  12899. ' };',
  12900. ' this.$final = function () {',
  12901. ' };',
  12902. ' this.DoIt = function (vA) {',
  12903. ' this.DoIt(1);',
  12904. ' this.DoIt$1(1,2);',
  12905. ' };',
  12906. ' this.DoIt$1 = function (vA, vB) {',
  12907. ' };',
  12908. '});',
  12909. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  12910. ' this.DoIt$2 = function (vA) {',
  12911. ' this.DoIt$2(1);',
  12912. ' this.DoIt$3(1, 2);',
  12913. ' $mod.TObject.DoIt.call(this, 1);',
  12914. ' $mod.TObject.DoIt$1.call(this, 1, 2);',
  12915. ' };',
  12916. ' this.DoIt$3 = function (vA, vB) {',
  12917. ' };',
  12918. '});',
  12919. '']),
  12920. LinesToStr([ // $mod.$main
  12921. '']));
  12922. end;
  12923. procedure TTestModule.TestClass_OverloadConstructor;
  12924. begin
  12925. StartProgram(false);
  12926. Add('type');
  12927. Add(' TObject = class');
  12928. Add(' constructor Create(vA: longint);');
  12929. Add(' constructor Create(vA, vB: longint);');
  12930. Add(' end;');
  12931. Add(' TCar = class');
  12932. Add(' constructor Create(vA: longint);');
  12933. Add(' constructor Create(vA, vB: longint);');
  12934. Add(' end;');
  12935. Add('constructor tobject.create(va: longint);');
  12936. Add('begin');
  12937. Add(' create(1);');
  12938. Add(' create(1,2);');
  12939. Add('end;');
  12940. Add('constructor tobject.create(va, vb: longint); begin end;');
  12941. Add('constructor tcar.create(va: longint);');
  12942. Add('begin');
  12943. Add(' create(1);');
  12944. Add(' create(1,2);');
  12945. Add(' inherited create(1);');
  12946. Add(' inherited create(1,2);');
  12947. Add('end;');
  12948. Add('constructor tcar.create(va, vb: longint); begin end;');
  12949. Add('begin');
  12950. Add(' tobject.create(1);');
  12951. Add(' tobject.create(1,2);');
  12952. Add(' tcar.create(1);');
  12953. Add(' tcar.create(1,2);');
  12954. ConvertProgram;
  12955. CheckSource('TestClass_OverloadConstructor',
  12956. LinesToStr([ // statements
  12957. 'rtl.createClass($mod, "TObject", null, function () {',
  12958. ' this.$init = function () {',
  12959. ' };',
  12960. ' this.$final = function () {',
  12961. ' };',
  12962. ' this.Create = function (vA) {',
  12963. ' this.Create(1);',
  12964. ' this.Create$1(1,2);',
  12965. ' return this;',
  12966. ' };',
  12967. ' this.Create$1 = function (vA, vB) {',
  12968. ' return this;',
  12969. ' };',
  12970. '});',
  12971. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  12972. ' this.Create$2 = function (vA) {',
  12973. ' this.Create$2(1);',
  12974. ' this.Create$3(1, 2);',
  12975. ' $mod.TObject.Create.call(this, 1);',
  12976. ' $mod.TObject.Create$1.call(this, 1, 2);',
  12977. ' return this;',
  12978. ' };',
  12979. ' this.Create$3 = function (vA, vB) {',
  12980. ' return this;',
  12981. ' };',
  12982. '});',
  12983. '']),
  12984. LinesToStr([ // $mod.$main
  12985. '$mod.TObject.$create("Create", [1]);',
  12986. '$mod.TObject.$create("Create$1", [1, 2]);',
  12987. '$mod.TCar.$create("Create$2", [1]);',
  12988. '$mod.TCar.$create("Create$3", [1, 2]);',
  12989. '']));
  12990. end;
  12991. procedure TTestModule.TestClass_OverloadDelphiOverride;
  12992. begin
  12993. StartProgram(false);
  12994. Add([
  12995. '{$mode delphi}',
  12996. 'type',
  12997. ' TObject = class end;',
  12998. ' TBird = class',
  12999. ' function {#a}GetValue: longint; overload; virtual;',
  13000. ' function {#b}GetValue(AValue: longint): longint; overload; virtual;',
  13001. ' end;',
  13002. ' TEagle = class(TBird)',
  13003. ' function {#c}GetValue: longint; overload; override;',
  13004. ' function {#d}GetValue(AValue: longint): longint; overload; override;',
  13005. ' end;',
  13006. 'function TBird.GetValue: longint;',
  13007. 'begin',
  13008. ' if 3={@a}GetValue then ;',
  13009. ' if 4={@b}GetValue(5) then ;',
  13010. 'end;',
  13011. 'function TBird.GetValue(AValue: longint): longint;',
  13012. 'begin',
  13013. 'end;',
  13014. 'function TEagle.GetValue: longint;',
  13015. 'begin',
  13016. ' if 13={@c}GetValue then ;',
  13017. ' if 14={@d}GetValue(15) then ;',
  13018. ' if 15=inherited {@a}GetValue then ;',
  13019. ' if 16=inherited {@b}GetValue(17) then ;',
  13020. 'end;',
  13021. 'function TEagle.GetValue(AValue: longint): longint;',
  13022. 'begin',
  13023. 'end;',
  13024. 'var',
  13025. ' e: TEagle;',
  13026. 'begin',
  13027. ' if 23=e.{@c}GetValue then ;',
  13028. ' if 24=e.{@d}GetValue(25) then ;']);
  13029. ConvertProgram;
  13030. CheckSource('TestClass_OverloadDelphiOverride',
  13031. LinesToStr([ // statements
  13032. 'rtl.createClass($mod, "TObject", null, function () {',
  13033. ' this.$init = function () {',
  13034. ' };',
  13035. ' this.$final = function () {',
  13036. ' };',
  13037. '});',
  13038. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  13039. ' this.GetValue = function () {',
  13040. ' var Result = 0;',
  13041. ' if (3 === this.GetValue()) ;',
  13042. ' if (4 === this.GetValue$1(5)) ;',
  13043. ' return Result;',
  13044. ' };',
  13045. ' this.GetValue$1 = function (AValue) {',
  13046. ' var Result = 0;',
  13047. ' return Result;',
  13048. ' };',
  13049. '});',
  13050. 'rtl.createClass($mod, "TEagle", $mod.TBird, function () {',
  13051. ' this.GetValue = function () {',
  13052. ' var Result = 0;',
  13053. ' if (13 === this.GetValue()) ;',
  13054. ' if (14 === this.GetValue$1(15)) ;',
  13055. ' if (15 === $mod.TBird.GetValue.call(this)) ;',
  13056. ' if (16 === $mod.TBird.GetValue$1.call(this, 17)) ;',
  13057. ' return Result;',
  13058. ' };',
  13059. ' this.GetValue$1 = function (AValue) {',
  13060. ' var Result = 0;',
  13061. ' return Result;',
  13062. ' };',
  13063. '});',
  13064. 'this.e = null;',
  13065. '']),
  13066. LinesToStr([ // $mod.$main
  13067. 'if (23 === $mod.e.GetValue()) ;',
  13068. 'if (24 === $mod.e.GetValue$1(25)) ;',
  13069. '']));
  13070. end;
  13071. procedure TTestModule.TestClass_ReintroducedVar;
  13072. begin
  13073. StartProgram(false);
  13074. Add('type');
  13075. Add(' TObject = class');
  13076. Add(' strict private');
  13077. Add(' Some: longint;');
  13078. Add(' end;');
  13079. Add(' TMobile = class');
  13080. Add(' strict private');
  13081. Add(' Some: string;');
  13082. Add(' end;');
  13083. Add(' TCar = class(tmobile)');
  13084. Add(' procedure Some;');
  13085. Add(' procedure Some(vA: longint);');
  13086. Add(' end;');
  13087. Add('procedure tcar.some;');
  13088. Add('begin');
  13089. Add(' Some;');
  13090. Add(' Some(1);');
  13091. Add('end;');
  13092. Add('procedure tcar.some(va: longint); begin end;');
  13093. Add('begin');
  13094. ConvertProgram;
  13095. CheckSource('TestClass_ReintroducedVar',
  13096. LinesToStr([ // statements
  13097. 'rtl.createClass($mod, "TObject", null, function () {',
  13098. ' this.$init = function () {',
  13099. ' this.Some = 0;',
  13100. ' };',
  13101. ' this.$final = function () {',
  13102. ' };',
  13103. '});',
  13104. 'rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
  13105. ' this.$init = function () {',
  13106. ' $mod.TObject.$init.call(this);',
  13107. ' this.Some$1 = "";',
  13108. ' };',
  13109. '});',
  13110. 'rtl.createClass($mod, "TCar", $mod.TMobile, function () {',
  13111. ' this.Some$2 = function () {',
  13112. ' this.Some$2();',
  13113. ' this.Some$3(1);',
  13114. ' };',
  13115. ' this.Some$3 = function (vA) {',
  13116. ' };',
  13117. '});',
  13118. '']),
  13119. LinesToStr([ // $mod.$main
  13120. '']));
  13121. end;
  13122. procedure TTestModule.TestClass_RaiseDescendant;
  13123. begin
  13124. StartProgram(false);
  13125. Add([
  13126. 'type',
  13127. ' TObject = class',
  13128. ' constructor Create(Msg: string);',
  13129. ' end;',
  13130. ' Exception = class',
  13131. ' end;',
  13132. ' EConvertError = class(Exception)',
  13133. ' end;',
  13134. 'constructor TObject.Create(Msg: string); begin end;',
  13135. 'function AssertConv(Msg: string = ''def''): EConvertError; begin end;',
  13136. 'begin',
  13137. ' raise Exception.Create(''Bar1'');',
  13138. ' raise EConvertError.Create(''Bar2'');',
  13139. ' raise AssertConv(''Bar2'');',
  13140. ' raise AssertConv;',
  13141. '']);
  13142. ConvertProgram;
  13143. CheckSource('TestClass_RaiseDescendant',
  13144. LinesToStr([ // statements
  13145. 'rtl.createClass($mod, "TObject", null, function () {',
  13146. ' this.$init = function () {',
  13147. ' };',
  13148. ' this.$final = function () {',
  13149. ' };',
  13150. ' this.Create = function (Msg) {',
  13151. ' return this;',
  13152. ' };',
  13153. '});',
  13154. 'rtl.createClass($mod, "Exception", $mod.TObject, function () {',
  13155. '});',
  13156. 'rtl.createClass($mod, "EConvertError", $mod.Exception, function () {',
  13157. '});',
  13158. 'this.AssertConv = function (Msg) {',
  13159. ' var Result = null;',
  13160. ' return Result;',
  13161. '};',
  13162. '']),
  13163. LinesToStr([ // $mod.$main
  13164. 'throw $mod.Exception.$create("Create",["Bar1"]);',
  13165. 'throw $mod.EConvertError.$create("Create",["Bar2"]);',
  13166. 'throw $mod.AssertConv("Bar2");',
  13167. 'throw $mod.AssertConv("def");',
  13168. '']));
  13169. end;
  13170. procedure TTestModule.TestClass_ExternalMethod;
  13171. begin
  13172. AddModuleWithIntfImplSrc('unit2.pas',
  13173. LinesToStr([
  13174. 'type',
  13175. ' TObject = class',
  13176. ' public',
  13177. ' procedure Intern; external name ''$DoIntern'';',
  13178. ' end;',
  13179. '']),
  13180. LinesToStr([
  13181. '']));
  13182. StartUnit(true);
  13183. Add('interface');
  13184. Add('uses unit2;');
  13185. Add('type');
  13186. Add(' TCar = class(TObject)');
  13187. Add(' public');
  13188. Add(' procedure Intern2; external name ''$DoIntern2'';');
  13189. Add(' procedure DoIt;');
  13190. Add(' end;');
  13191. Add('implementation');
  13192. Add('procedure tcar.doit;');
  13193. Add('begin');
  13194. Add(' Intern;');
  13195. Add(' Intern();');
  13196. Add(' Intern2;');
  13197. Add(' Intern2();');
  13198. Add('end;');
  13199. Add('var Obj: TCar;');
  13200. Add('begin');
  13201. Add(' obj.intern;');
  13202. Add(' obj.intern();');
  13203. Add(' obj.intern2;');
  13204. Add(' obj.intern2();');
  13205. Add(' obj.doit;');
  13206. Add(' obj.doit();');
  13207. Add(' with obj do begin');
  13208. Add(' Intern;');
  13209. Add(' Intern();');
  13210. Add(' Intern2;');
  13211. Add(' Intern2();');
  13212. Add(' end;');
  13213. ConvertUnit;
  13214. CheckSource('TestClass_ExternalMethod',
  13215. LinesToStr([
  13216. 'var $impl = $mod.$impl;',
  13217. 'rtl.createClass($mod, "TCar", pas.unit2.TObject, function () {',
  13218. ' this.DoIt = function () {',
  13219. ' this.$DoIntern();',
  13220. ' this.$DoIntern();',
  13221. ' this.$DoIntern2();',
  13222. ' this.$DoIntern2();',
  13223. ' };',
  13224. ' });',
  13225. '']),
  13226. LinesToStr([ // this.$init
  13227. '$impl.Obj.$DoIntern();',
  13228. '$impl.Obj.$DoIntern();',
  13229. '$impl.Obj.$DoIntern2();',
  13230. '$impl.Obj.$DoIntern2();',
  13231. '$impl.Obj.DoIt();',
  13232. '$impl.Obj.DoIt();',
  13233. 'var $with1 = $impl.Obj;',
  13234. '$with1.$DoIntern();',
  13235. '$with1.$DoIntern();',
  13236. '$with1.$DoIntern2();',
  13237. '$with1.$DoIntern2();',
  13238. '']),
  13239. LinesToStr([ // implementation
  13240. '$impl.Obj = null;',
  13241. '']) );
  13242. end;
  13243. procedure TTestModule.TestClass_ExternalVirtualNameMismatchFail;
  13244. begin
  13245. StartProgram(false);
  13246. Add('type');
  13247. Add(' TObject = class');
  13248. Add(' procedure DoIt; virtual; external name ''Foo'';');
  13249. Add(' end;');
  13250. Add('begin');
  13251. SetExpectedPasResolverError('Virtual method name must match external',
  13252. nVirtualMethodNameMustMatchExternal);
  13253. ConvertProgram;
  13254. end;
  13255. procedure TTestModule.TestClass_ExternalOverrideFail;
  13256. begin
  13257. StartProgram(false);
  13258. Add('type');
  13259. Add(' TObject = class');
  13260. Add(' procedure DoIt; virtual; external name ''DoIt'';');
  13261. Add(' end;');
  13262. Add(' TCar = class');
  13263. Add(' procedure DoIt; override; external name ''DoIt'';');
  13264. Add(' end;');
  13265. Add('begin');
  13266. SetExpectedPasResolverError('Invalid procedure modifier override,external',
  13267. nInvalidXModifierY);
  13268. ConvertProgram;
  13269. end;
  13270. procedure TTestModule.TestClass_ExternalVar;
  13271. begin
  13272. AddModuleWithIntfImplSrc('unit2.pas',
  13273. LinesToStr([
  13274. '{$modeswitch externalclass}',
  13275. 'type',
  13276. ' TObject = class',
  13277. ' public',
  13278. ' Intern: longint external name ''$Intern'';',
  13279. ' Bracket: longint external name ''["A B"]'';',
  13280. ' end;',
  13281. '']),
  13282. LinesToStr([
  13283. '']));
  13284. StartUnit(true);
  13285. Add([
  13286. 'interface',
  13287. 'uses unit2;',
  13288. '{$modeswitch externalclass}',
  13289. 'type',
  13290. ' TCar = class(tobject)',
  13291. ' public',
  13292. ' Intern2: longint external name ''$Intern2'';',
  13293. ' procedure DoIt;',
  13294. ' end;',
  13295. 'implementation',
  13296. 'procedure tcar.doit;',
  13297. 'begin',
  13298. ' Intern:=Intern+1;',
  13299. ' Intern2:=Intern2+2;',
  13300. ' Bracket:=Bracket+3;',
  13301. 'end;',
  13302. 'var Obj: TCar;',
  13303. 'begin',
  13304. ' obj.intern:=obj.intern+1;',
  13305. ' obj.intern2:=obj.intern2+2;',
  13306. ' obj.Bracket:=obj.Bracket+3;',
  13307. ' with obj do begin',
  13308. ' intern:=intern+1;',
  13309. ' intern2:=intern2+2;',
  13310. ' Bracket:=Bracket+3;',
  13311. ' end;']);
  13312. ConvertUnit;
  13313. CheckSource('TestClass_ExternalVar',
  13314. LinesToStr([
  13315. 'var $impl = $mod.$impl;',
  13316. 'rtl.createClass($mod, "TCar", pas.unit2.TObject, function () {',
  13317. ' this.DoIt = function () {',
  13318. ' this.$Intern = this.$Intern + 1;',
  13319. ' this.$Intern2 = this.$Intern2 + 2;',
  13320. ' this["A B"] = this["A B"] + 3;',
  13321. ' };',
  13322. ' });',
  13323. '']),
  13324. LinesToStr([
  13325. '$impl.Obj.$Intern = $impl.Obj.$Intern + 1;',
  13326. '$impl.Obj.$Intern2 = $impl.Obj.$Intern2 + 2;',
  13327. '$impl.Obj["A B"] = $impl.Obj["A B"] + 3;',
  13328. 'var $with1 = $impl.Obj;',
  13329. '$with1.$Intern = $with1.$Intern + 1;',
  13330. '$with1.$Intern2 = $with1.$Intern2 + 2;',
  13331. '$with1["A B"] = $with1["A B"] + 3;',
  13332. '']),
  13333. LinesToStr([ // implementation
  13334. '$impl.Obj = null;',
  13335. '']));
  13336. end;
  13337. procedure TTestModule.TestClass_Const;
  13338. begin
  13339. StartProgram(false);
  13340. Add('type');
  13341. Add(' integer = longint;');
  13342. Add(' TClass = class of TObject;');
  13343. Add(' TObject = class');
  13344. Add(' public');
  13345. Add(' const cI: integer = 3;');
  13346. Add(' procedure DoIt;');
  13347. Add(' class procedure DoMore;');
  13348. Add(' end;');
  13349. Add('implementation');
  13350. Add('procedure tobject.doit;');
  13351. Add('begin');
  13352. Add(' if cI=4 then;');
  13353. Add(' if 5=cI then;');
  13354. Add(' if Self.cI=6 then;');
  13355. Add(' if 7=Self.cI then;');
  13356. Add(' with Self do begin');
  13357. Add(' if cI=11 then;');
  13358. Add(' if 12=cI then;');
  13359. Add(' end;');
  13360. Add('end;');
  13361. Add('class procedure tobject.domore;');
  13362. Add('begin');
  13363. Add(' if cI=8 then;');
  13364. Add(' if Self.cI=9 then;');
  13365. Add(' if 10=cI then;');
  13366. Add(' if 11=Self.cI then;');
  13367. Add(' with Self do begin');
  13368. Add(' if cI=13 then;');
  13369. Add(' if 14=cI then;');
  13370. Add(' end;');
  13371. Add('end;');
  13372. Add('var');
  13373. Add(' Obj: TObject;');
  13374. Add(' Cla: TClass;');
  13375. Add('begin');
  13376. Add(' if TObject.cI=21 then ;');
  13377. Add(' if Obj.cI=22 then ;');
  13378. Add(' if Cla.cI=23 then ;');
  13379. Add(' with obj do if ci=24 then;');
  13380. Add(' with TObject do if ci=25 then;');
  13381. Add(' with Cla do if ci=26 then;');
  13382. ConvertProgram;
  13383. CheckSource('TestClass_Const',
  13384. LinesToStr([
  13385. 'rtl.createClass($mod, "TObject", null, function () {',
  13386. ' this.cI = 3;',
  13387. ' this.$init = function () {',
  13388. ' };',
  13389. ' this.$final = function () {',
  13390. ' };',
  13391. ' this.DoIt = function () {',
  13392. ' if (this.cI === 4) ;',
  13393. ' if (5 === this.cI) ;',
  13394. ' if (this.cI === 6) ;',
  13395. ' if (7 === this.cI) ;',
  13396. ' if (this.cI === 11) ;',
  13397. ' if (12 === this.cI) ;',
  13398. ' };',
  13399. ' this.DoMore = function () {',
  13400. ' if (this.cI === 8) ;',
  13401. ' if (this.cI === 9) ;',
  13402. ' if (10 === this.cI) ;',
  13403. ' if (11 === this.cI) ;',
  13404. ' if (this.cI === 13) ;',
  13405. ' if (14 === this.cI) ;',
  13406. ' };',
  13407. '});',
  13408. 'this.Obj = null;',
  13409. 'this.Cla = null;',
  13410. '']),
  13411. LinesToStr([
  13412. 'if ($mod.TObject.cI === 21) ;',
  13413. 'if ($mod.Obj.cI === 22) ;',
  13414. 'if ($mod.Cla.cI === 23) ;',
  13415. 'var $with1 = $mod.Obj;',
  13416. 'if ($with1.cI === 24) ;',
  13417. 'var $with2 = $mod.TObject;',
  13418. 'if ($with2.cI === 25) ;',
  13419. 'var $with3 = $mod.Cla;',
  13420. 'if ($with3.cI === 26) ;',
  13421. '']));
  13422. end;
  13423. procedure TTestModule.TestClass_LocalVarSelfFail;
  13424. begin
  13425. StartProgram(false);
  13426. Add([
  13427. 'type',
  13428. ' TObject = class',
  13429. ' constructor Create;',
  13430. ' end;',
  13431. 'constructor tobject.create;',
  13432. 'var self: longint;',
  13433. 'begin',
  13434. 'end',
  13435. 'begin',
  13436. '']);
  13437. SetExpectedPasResolverError('Duplicate identifier "self" at (0)',nDuplicateIdentifier);
  13438. ConvertProgram;
  13439. end;
  13440. procedure TTestModule.TestClass_ArgSelfFail;
  13441. begin
  13442. StartProgram(false);
  13443. Add([
  13444. 'type',
  13445. ' TObject = class',
  13446. ' procedure DoIt(Self: longint);',
  13447. ' end;',
  13448. 'procedure tobject.doit(self: longint);',
  13449. 'begin',
  13450. 'end',
  13451. 'begin',
  13452. '']);
  13453. SetExpectedPasResolverError('Duplicate identifier "Self" at test1.pp(5,24)',nDuplicateIdentifier);
  13454. ConvertProgram;
  13455. end;
  13456. procedure TTestModule.TestClass_NestedProcSelf;
  13457. begin
  13458. StartProgram(false);
  13459. Add([
  13460. 'type',
  13461. ' TObject = class',
  13462. ' Key: longint;',
  13463. ' class var State: longint;',
  13464. ' procedure DoIt;',
  13465. ' function GetSize: longint; virtual; abstract;',
  13466. ' procedure SetSize(Value: longint); virtual; abstract;',
  13467. ' property Size: longint read GetSize write SetSize;',
  13468. ' end;',
  13469. 'procedure tobject.doit;',
  13470. ' procedure Sub;',
  13471. ' begin',
  13472. ' key:=key+2;',
  13473. ' self.key:=self.key+3;',
  13474. ' state:=state+4;',
  13475. ' self.state:=self.state+5;',
  13476. ' tobject.state:=tobject.state+6;',
  13477. ' size:=size+7;',
  13478. ' self.size:=self.size+8;',
  13479. ' end;',
  13480. 'begin',
  13481. ' sub;',
  13482. ' key:=key+12;',
  13483. ' self.key:=self.key+13;',
  13484. ' state:=state+14;',
  13485. ' self.state:=self.state+15;',
  13486. ' tobject.state:=tobject.state+16;',
  13487. ' size:=size+17;',
  13488. ' self.size:=self.size+18;',
  13489. 'end;',
  13490. 'begin',
  13491. '']);
  13492. ConvertProgram;
  13493. CheckSource('TestClass_NestedProcSelf',
  13494. LinesToStr([ // statements
  13495. 'rtl.createClass($mod, "TObject", null, function () {',
  13496. ' this.State = 0;',
  13497. ' this.$init = function () {',
  13498. ' this.Key = 0;',
  13499. ' };',
  13500. ' this.$final = function () {',
  13501. ' };',
  13502. ' this.DoIt = function () {',
  13503. ' var $Self = this;',
  13504. ' function Sub() {',
  13505. ' $Self.Key = $Self.Key + 2;',
  13506. ' $Self.Key = $Self.Key + 3;',
  13507. ' $mod.TObject.State = $Self.State + 4;',
  13508. ' $mod.TObject.State = $Self.State + 5;',
  13509. ' $mod.TObject.State = $mod.TObject.State + 6;',
  13510. ' $Self.SetSize($Self.GetSize() + 7);',
  13511. ' $Self.SetSize($Self.GetSize() + 8);',
  13512. ' };',
  13513. ' Sub();',
  13514. ' $Self.Key = $Self.Key + 12;',
  13515. ' $Self.Key = $Self.Key + 13;',
  13516. ' $mod.TObject.State = $Self.State + 14;',
  13517. ' $mod.TObject.State = $Self.State + 15;',
  13518. ' $mod.TObject.State = $mod.TObject.State + 16;',
  13519. ' $Self.SetSize($Self.GetSize() + 17);',
  13520. ' $Self.SetSize($Self.GetSize() + 18);',
  13521. ' };',
  13522. '});',
  13523. '']),
  13524. LinesToStr([ // $mod.$main
  13525. '']));
  13526. end;
  13527. procedure TTestModule.TestClass_NestedProcSelf2;
  13528. begin
  13529. StartProgram(false);
  13530. Add([
  13531. 'type',
  13532. ' TObject = class',
  13533. ' Key: longint;',
  13534. ' class var State: longint;',
  13535. ' function GetSize: longint; virtual; abstract;',
  13536. ' procedure SetSize(Value: longint); virtual; abstract;',
  13537. ' property Size: longint read GetSize write SetSize;',
  13538. ' end;',
  13539. ' TBird = class',
  13540. ' procedure DoIt;',
  13541. ' end;',
  13542. 'procedure tbird.doit;',
  13543. ' procedure Sub;',
  13544. ' begin',
  13545. ' key:=key+2;',
  13546. ' self.key:=self.key+3;',
  13547. ' state:=state+4;',
  13548. ' self.state:=self.state+5;',
  13549. ' tobject.state:=tobject.state+6;',
  13550. ' size:=size+7;',
  13551. ' self.size:=self.size+8;',
  13552. ' end;',
  13553. 'begin',
  13554. ' sub;',
  13555. ' key:=key+12;',
  13556. ' self.key:=self.key+13;',
  13557. ' state:=state+14;',
  13558. ' self.state:=self.state+15;',
  13559. ' tobject.state:=tobject.state+16;',
  13560. ' size:=size+17;',
  13561. ' self.size:=self.size+18;',
  13562. 'end;',
  13563. 'begin',
  13564. '']);
  13565. ConvertProgram;
  13566. CheckSource('TestClass_NestedProcSelf2',
  13567. LinesToStr([ // statements
  13568. 'rtl.createClass($mod, "TObject", null, function () {',
  13569. ' this.State = 0;',
  13570. ' this.$init = function () {',
  13571. ' this.Key = 0;',
  13572. ' };',
  13573. ' this.$final = function () {',
  13574. ' };',
  13575. '});',
  13576. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  13577. ' this.DoIt = function () {',
  13578. ' var $Self = this;',
  13579. ' function Sub() {',
  13580. ' $Self.Key = $Self.Key + 2;',
  13581. ' $Self.Key = $Self.Key + 3;',
  13582. ' $mod.TObject.State = $Self.State + 4;',
  13583. ' $mod.TObject.State = $Self.State + 5;',
  13584. ' $mod.TObject.State = $mod.TObject.State + 6;',
  13585. ' $Self.SetSize($Self.GetSize() + 7);',
  13586. ' $Self.SetSize($Self.GetSize() + 8);',
  13587. ' };',
  13588. ' Sub();',
  13589. ' $Self.Key = $Self.Key + 12;',
  13590. ' $Self.Key = $Self.Key + 13;',
  13591. ' $mod.TObject.State = $Self.State + 14;',
  13592. ' $mod.TObject.State = $Self.State + 15;',
  13593. ' $mod.TObject.State = $mod.TObject.State + 16;',
  13594. ' $Self.SetSize($Self.GetSize() + 17);',
  13595. ' $Self.SetSize($Self.GetSize() + 18);',
  13596. ' };',
  13597. '});',
  13598. '']),
  13599. LinesToStr([ // $mod.$main
  13600. '']));
  13601. end;
  13602. procedure TTestModule.TestClass_NestedProcClassSelf;
  13603. begin
  13604. StartProgram(false);
  13605. Add([
  13606. 'type',
  13607. ' TObject = class',
  13608. ' class var State: longint;',
  13609. ' class procedure DoIt;',
  13610. ' class function GetSize: longint; virtual; abstract;',
  13611. ' class procedure SetSize(Value: longint); virtual; abstract;',
  13612. ' class property Size: longint read GetSize write SetSize;',
  13613. ' end;',
  13614. 'class procedure tobject.doit;',
  13615. ' procedure Sub;',
  13616. ' begin',
  13617. ' state:=state+2;',
  13618. ' self.state:=self.state+3;',
  13619. ' tobject.state:=tobject.state+4;',
  13620. ' size:=size+5;',
  13621. ' self.size:=self.size+6;',
  13622. ' tobject.size:=tobject.size+7;',
  13623. ' end;',
  13624. 'begin',
  13625. ' sub;',
  13626. ' state:=state+12;',
  13627. ' self.state:=self.state+13;',
  13628. ' tobject.state:=tobject.state+14;',
  13629. ' size:=size+15;',
  13630. ' self.size:=self.size+16;',
  13631. ' tobject.size:=tobject.size+17;',
  13632. 'end;',
  13633. 'begin',
  13634. '']);
  13635. ConvertProgram;
  13636. CheckSource('TestClass_NestedProcClassSelf',
  13637. LinesToStr([ // statements
  13638. 'rtl.createClass($mod, "TObject", null, function () {',
  13639. ' this.State = 0;',
  13640. ' this.$init = function () {',
  13641. ' };',
  13642. ' this.$final = function () {',
  13643. ' };',
  13644. ' this.DoIt = function () {',
  13645. ' var $Self = this;',
  13646. ' function Sub() {',
  13647. ' $mod.TObject.State = $Self.State + 2;',
  13648. ' $mod.TObject.State = $Self.State + 3;',
  13649. ' $mod.TObject.State = $mod.TObject.State + 4;',
  13650. ' $Self.SetSize($Self.GetSize() + 5);',
  13651. ' $Self.SetSize($Self.GetSize() + 6);',
  13652. ' $mod.TObject.SetSize($mod.TObject.GetSize() + 7);',
  13653. ' };',
  13654. ' Sub();',
  13655. ' $mod.TObject.State = $Self.State + 12;',
  13656. ' $mod.TObject.State = $Self.State + 13;',
  13657. ' $mod.TObject.State = $mod.TObject.State + 14;',
  13658. ' $Self.SetSize($Self.GetSize() + 15);',
  13659. ' $Self.SetSize($Self.GetSize() + 16);',
  13660. ' $mod.TObject.SetSize($mod.TObject.GetSize() + 17);',
  13661. ' };',
  13662. '});',
  13663. '']),
  13664. LinesToStr([ // $mod.$main
  13665. '']));
  13666. end;
  13667. procedure TTestModule.TestClass_NestedProcCallInherited;
  13668. begin
  13669. StartProgram(false);
  13670. Add([
  13671. 'type',
  13672. ' TObject = class',
  13673. ' function DoIt(k: boolean): longint; virtual;',
  13674. ' end;',
  13675. ' TBird = class',
  13676. ' function DoIt(k: boolean): longint; override;',
  13677. ' end;',
  13678. 'function tobject.doit(k: boolean): longint;',
  13679. 'begin',
  13680. 'end;',
  13681. 'function tbird.doit(k: boolean): longint;',
  13682. ' procedure Sub;',
  13683. ' begin',
  13684. ' inherited DoIt(true);',
  13685. //' if inherited DoIt(false)=4 then ;',
  13686. ' end;',
  13687. 'begin',
  13688. ' Sub;',
  13689. ' inherited;',
  13690. ' inherited DoIt(true);',
  13691. //' if inherited DoIt(false)=14 then ;',
  13692. 'end;',
  13693. 'begin',
  13694. '']);
  13695. ConvertProgram;
  13696. CheckSource('TestClass_NestedProcCallInherited',
  13697. LinesToStr([ // statements
  13698. 'rtl.createClass($mod, "TObject", null, function () {',
  13699. ' this.$init = function () {',
  13700. ' };',
  13701. ' this.$final = function () {',
  13702. ' };',
  13703. ' this.DoIt = function (k) {',
  13704. ' var Result = 0;',
  13705. ' return Result;',
  13706. ' };',
  13707. '});',
  13708. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  13709. ' this.DoIt = function (k) {',
  13710. ' var $Self = this;',
  13711. ' var Result = 0;',
  13712. ' function Sub() {',
  13713. ' $mod.TObject.DoIt.call($Self, true);',
  13714. ' };',
  13715. ' Sub();',
  13716. ' $mod.TObject.DoIt.apply($Self, arguments);',
  13717. ' $mod.TObject.DoIt.call($Self, true);',
  13718. ' return Result;',
  13719. ' };',
  13720. '});',
  13721. '']),
  13722. LinesToStr([ // $mod.$main
  13723. '']));
  13724. end;
  13725. procedure TTestModule.TestClass_TObjectFree;
  13726. begin
  13727. StartProgram(false);
  13728. Add([
  13729. 'type',
  13730. ' TObject = class',
  13731. ' Obj: tobject;',
  13732. ' procedure Free;',
  13733. ' procedure Release;',
  13734. ' end;',
  13735. 'procedure tobject.free;',
  13736. 'begin',
  13737. 'end;',
  13738. 'procedure tobject.release;',
  13739. 'begin',
  13740. ' free;',
  13741. ' if true then free;',
  13742. 'end;',
  13743. 'function DoIt(o: tobject): tobject;',
  13744. 'var l: tobject;',
  13745. 'begin',
  13746. ' o.free;',
  13747. ' o.free();',
  13748. ' l.free;',
  13749. ' l.free();',
  13750. ' o.obj.free;',
  13751. ' o.obj.free();',
  13752. ' with o do obj.free;',
  13753. ' with o do obj.free();',
  13754. ' result.Free;',
  13755. ' result.Free();',
  13756. 'end;',
  13757. 'var o: tobject;',
  13758. ' a: array of tobject;',
  13759. 'begin',
  13760. ' o.free;',
  13761. ' o.obj.free;',
  13762. ' a[1+2].free;',
  13763. '']);
  13764. ConvertProgram;
  13765. CheckSource('TestClass_TObjectFree',
  13766. LinesToStr([ // statements
  13767. 'rtl.createClass($mod, "TObject", null, function () {',
  13768. ' this.$init = function () {',
  13769. ' this.Obj = null;',
  13770. ' };',
  13771. ' this.$final = function () {',
  13772. ' this.Obj = undefined;',
  13773. ' };',
  13774. ' this.Free = function () {',
  13775. ' };',
  13776. ' this.Release = function () {',
  13777. ' this.Free();',
  13778. ' if (true) this.Free();',
  13779. ' };',
  13780. '});',
  13781. 'this.DoIt = function (o) {',
  13782. ' var Result = null;',
  13783. ' var l = null;',
  13784. ' o = rtl.freeLoc(o);',
  13785. ' o = rtl.freeLoc(o);',
  13786. ' l = rtl.freeLoc(l);',
  13787. ' l = rtl.freeLoc(l);',
  13788. ' rtl.free(o, "Obj");',
  13789. ' rtl.free(o, "Obj");',
  13790. ' rtl.free(o, "Obj");',
  13791. ' rtl.free(o, "Obj");',
  13792. ' Result = rtl.freeLoc(Result);',
  13793. ' Result = rtl.freeLoc(Result);',
  13794. ' return Result;',
  13795. '};',
  13796. 'this.o = null;',
  13797. 'this.a = [];',
  13798. '']),
  13799. LinesToStr([ // $mod.$main
  13800. 'rtl.free($mod, "o");',
  13801. 'rtl.free($mod.o, "Obj");',
  13802. 'rtl.free($mod.a, 1 + 2);',
  13803. '']));
  13804. end;
  13805. procedure TTestModule.TestClass_TObjectFree_VarArg;
  13806. begin
  13807. StartProgram(false);
  13808. Add([
  13809. 'type',
  13810. ' TObject = class',
  13811. ' Obj: tobject;',
  13812. ' procedure Free;',
  13813. ' end;',
  13814. 'procedure tobject.free;',
  13815. 'begin',
  13816. 'end;',
  13817. 'procedure DoIt(var o: tobject);',
  13818. 'begin',
  13819. ' o.free;',
  13820. ' o.free();',
  13821. 'end;',
  13822. 'begin',
  13823. '']);
  13824. ConvertProgram;
  13825. CheckSource('TestClass_TObjectFree_VarArg',
  13826. LinesToStr([ // statements
  13827. 'rtl.createClass($mod, "TObject", null, function () {',
  13828. ' this.$init = function () {',
  13829. ' this.Obj = null;',
  13830. ' };',
  13831. ' this.$final = function () {',
  13832. ' this.Obj = undefined;',
  13833. ' };',
  13834. ' this.Free = function () {',
  13835. ' };',
  13836. '});',
  13837. 'this.DoIt = function (o) {',
  13838. ' o.set(rtl.freeLoc(o.get()));',
  13839. ' o.set(rtl.freeLoc(o.get()));',
  13840. '};',
  13841. '']),
  13842. LinesToStr([ // $mod.$main
  13843. '']));
  13844. end;
  13845. procedure TTestModule.TestClass_TObjectFreeNewInstance;
  13846. begin
  13847. StartProgram(false);
  13848. Add([
  13849. 'type',
  13850. ' TObject = class',
  13851. ' constructor Create;',
  13852. ' procedure Free;',
  13853. ' end;',
  13854. 'constructor TObject.Create; begin end;',
  13855. 'procedure tobject.free; begin end;',
  13856. 'begin',
  13857. ' with tobject.create do free;',
  13858. '']);
  13859. ConvertProgram;
  13860. CheckSource('TestClass_TObjectFreeNewInstance',
  13861. LinesToStr([ // statements
  13862. 'rtl.createClass($mod, "TObject", null, function () {',
  13863. ' this.$init = function () {',
  13864. ' };',
  13865. ' this.$final = function () {',
  13866. ' };',
  13867. ' this.Create = function () {',
  13868. ' return this;',
  13869. ' };',
  13870. ' this.Free = function () {',
  13871. ' };',
  13872. '});',
  13873. '']),
  13874. LinesToStr([ // $mod.$main
  13875. 'var $with1 = $mod.TObject.$create("Create");',
  13876. '$with1=rtl.freeLoc($with1);',
  13877. '']));
  13878. end;
  13879. procedure TTestModule.TestClass_TObjectFreeLowerCase;
  13880. begin
  13881. StartProgram(false);
  13882. Add([
  13883. 'type',
  13884. ' TObject = class',
  13885. ' destructor Destroy;',
  13886. ' procedure Free;',
  13887. ' end;',
  13888. 'destructor TObject.Destroy; begin end;',
  13889. 'procedure tobject.free; begin end;',
  13890. 'var o: tobject;',
  13891. 'begin',
  13892. ' o.free;',
  13893. '']);
  13894. Converter.UseLowerCase:=true;
  13895. ConvertProgram;
  13896. CheckSource('TestClass_TObjectFreeLowerCase',
  13897. LinesToStr([ // statements
  13898. 'rtl.createClass($mod, "tobject", null, function () {',
  13899. ' this.$init = function () {',
  13900. ' };',
  13901. ' this.$final = function () {',
  13902. ' };',
  13903. ' rtl.tObjectDestroy = "destroy";',
  13904. ' this.destroy = function () {',
  13905. ' };',
  13906. ' this.free = function () {',
  13907. ' };',
  13908. '});',
  13909. 'this.o = null;',
  13910. '']),
  13911. LinesToStr([ // $mod.$main
  13912. 'rtl.free($mod, "o");',
  13913. '']));
  13914. end;
  13915. procedure TTestModule.TestClass_TObjectFreeFunctionFail;
  13916. begin
  13917. StartProgram(false);
  13918. Add([
  13919. 'type',
  13920. ' TObject = class',
  13921. ' procedure Free;',
  13922. ' function GetObj: tobject; virtual; abstract;',
  13923. ' end;',
  13924. 'procedure tobject.free;',
  13925. 'begin',
  13926. 'end;',
  13927. 'var o: tobject;',
  13928. 'begin',
  13929. ' o.getobj.free;',
  13930. '']);
  13931. SetExpectedPasResolverError(sFreeNeedsVar,nFreeNeedsVar);
  13932. ConvertProgram;
  13933. end;
  13934. procedure TTestModule.TestClass_TObjectFreePropertyFail;
  13935. begin
  13936. StartProgram(false);
  13937. Add([
  13938. 'type',
  13939. ' TObject = class',
  13940. ' procedure Free;',
  13941. ' FObj: TObject;',
  13942. ' property Obj: tobject read FObj write FObj;',
  13943. ' end;',
  13944. 'procedure tobject.free;',
  13945. 'begin',
  13946. 'end;',
  13947. 'var o: tobject;',
  13948. 'begin',
  13949. ' o.obj.free;',
  13950. '']);
  13951. SetExpectedPasResolverError(sFreeNeedsVar,nFreeNeedsVar);
  13952. ConvertProgram;
  13953. end;
  13954. procedure TTestModule.TestClass_ForIn;
  13955. begin
  13956. StartProgram(false);
  13957. Add([
  13958. 'type',
  13959. ' TObject = class end;',
  13960. ' TItem = TObject;',
  13961. ' TEnumerator = class',
  13962. ' FCurrent: TItem;',
  13963. ' property Current: TItem read FCurrent;',
  13964. ' function MoveNext: boolean;',
  13965. ' end;',
  13966. ' TBird = class',
  13967. ' function GetEnumerator: TEnumerator;',
  13968. ' end;',
  13969. 'function TEnumerator.MoveNext: boolean;',
  13970. 'begin',
  13971. 'end;',
  13972. 'function TBird.GetEnumerator: TEnumerator;',
  13973. 'begin',
  13974. 'end;',
  13975. 'var',
  13976. ' b: TBird;',
  13977. ' i, i2: TItem;',
  13978. 'begin',
  13979. ' for i in b do i2:=i;']);
  13980. ConvertProgram;
  13981. CheckSource('TestClass_ForIn',
  13982. LinesToStr([ // statements
  13983. 'rtl.createClass($mod, "TObject", null, function () {',
  13984. ' this.$init = function () {',
  13985. ' };',
  13986. ' this.$final = function () {',
  13987. ' };',
  13988. '});',
  13989. 'rtl.createClass($mod, "TEnumerator", $mod.TObject, function () {',
  13990. ' this.$init = function () {',
  13991. ' $mod.TObject.$init.call(this);',
  13992. ' this.FCurrent = null;',
  13993. ' };',
  13994. ' this.$final = function () {',
  13995. ' this.FCurrent = undefined;',
  13996. ' $mod.TObject.$final.call(this);',
  13997. ' };',
  13998. ' this.MoveNext = function () {',
  13999. ' var Result = false;',
  14000. ' return Result;',
  14001. ' };',
  14002. '});',
  14003. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  14004. ' this.GetEnumerator = function () {',
  14005. ' var Result = null;',
  14006. ' return Result;',
  14007. ' };',
  14008. '});',
  14009. 'this.b = null;',
  14010. 'this.i = null;',
  14011. 'this.i2 = null;'
  14012. ]),
  14013. LinesToStr([ // $mod.$main
  14014. 'var $in1 = $mod.b.GetEnumerator();',
  14015. 'try {',
  14016. ' while ($in1.MoveNext()){',
  14017. ' $mod.i = $in1.FCurrent;',
  14018. ' $mod.i2 = $mod.i;',
  14019. ' }',
  14020. '} finally {',
  14021. ' $in1 = rtl.freeLoc($in1)',
  14022. '};',
  14023. '']));
  14024. end;
  14025. procedure TTestModule.TestClass_DispatchMessage;
  14026. begin
  14027. StartProgram(false);
  14028. Add([
  14029. 'type',
  14030. ' TObject = class',
  14031. ' {$DispatchField DispInt}',
  14032. ' procedure Dispatch(var Msg); virtual; abstract;',
  14033. ' {$DispatchStrField DispStr}',
  14034. ' procedure DispatchStr(var Msg); virtual; abstract;',
  14035. ' end;',
  14036. ' THopMsg = record',
  14037. ' DispInt: longint;',
  14038. ' end;',
  14039. ' TPutMsg = record',
  14040. ' DispStr: string;',
  14041. ' end;',
  14042. ' TBird = class',
  14043. ' procedure Fly(var Msg); virtual; abstract; message 2;',
  14044. ' procedure Run; overload; virtual; abstract;',
  14045. ' procedure Run(var Msg); overload; message ''Fast'';',
  14046. ' procedure Hop(var Msg: THopMsg); virtual; abstract; message 3;',
  14047. ' procedure Put(var Msg: TPutMsg); virtual; abstract; message ''foo'';',
  14048. ' end;',
  14049. 'procedure TBird.Run(var Msg);',
  14050. 'begin',
  14051. 'end;',
  14052. 'begin',
  14053. '']);
  14054. ConvertProgram;
  14055. CheckSource('TestClass_Message',
  14056. LinesToStr([ // statements
  14057. 'rtl.createClass($mod, "TObject", null, function () {',
  14058. ' this.$init = function () {',
  14059. ' };',
  14060. ' this.$final = function () {',
  14061. ' };',
  14062. '});',
  14063. 'rtl.recNewT($mod, "THopMsg", function () {',
  14064. ' this.DispInt = 0;',
  14065. ' this.$eq = function (b) {',
  14066. ' return this.DispInt === b.DispInt;',
  14067. ' };',
  14068. ' this.$assign = function (s) {',
  14069. ' this.DispInt = s.DispInt;',
  14070. ' return this;',
  14071. ' };',
  14072. '});',
  14073. 'rtl.recNewT($mod, "TPutMsg", function () {',
  14074. ' this.DispStr = "";',
  14075. ' this.$eq = function (b) {',
  14076. ' return this.DispStr === b.DispStr;',
  14077. ' };',
  14078. ' this.$assign = function (s) {',
  14079. ' this.DispStr = s.DispStr;',
  14080. ' return this;',
  14081. ' };',
  14082. '});',
  14083. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  14084. ' this.Run$1 = function (Msg) {',
  14085. ' };',
  14086. ' this.$msgint = {',
  14087. ' "2": "Fly",',
  14088. ' "3": "Hop"',
  14089. ' };',
  14090. ' this.$msgstr = {',
  14091. ' Fast: "Run$1",',
  14092. ' foo: "Put"',
  14093. ' };',
  14094. '});',
  14095. '']),
  14096. LinesToStr([ // $mod.$main
  14097. '']));
  14098. end;
  14099. procedure TTestModule.TestClass_Message_DuplicateIntFail;
  14100. begin
  14101. StartProgram(false);
  14102. Add([
  14103. 'type',
  14104. ' TObject = class',
  14105. ' procedure Fly(var Msg); virtual; abstract; message 3;',
  14106. ' procedure Run(var Msg); virtual; abstract; message 1+2;',
  14107. ' end;',
  14108. 'begin',
  14109. '']);
  14110. SetExpectedPasResolverError('Duplicate message id "3" at test1.pp(5,56)',nDuplicateMessageIdXAtY);
  14111. ConvertProgram;
  14112. end;
  14113. procedure TTestModule.TestClass_DispatchMessage_WrongFieldNameFail;
  14114. begin
  14115. StartProgram(false);
  14116. Add([
  14117. 'type',
  14118. ' TObject = class',
  14119. ' {$dispatchfield Msg}',
  14120. ' procedure Dispatch(var Msg); virtual; abstract;',
  14121. ' end;',
  14122. ' TFlyMsg = record',
  14123. ' FlyId: longint;',
  14124. ' end;',
  14125. ' TBird = class',
  14126. ' procedure Fly(var Msg: TFlyMsg); virtual; abstract; message 3;',
  14127. ' end;',
  14128. 'begin',
  14129. '']);
  14130. ConvertProgram;
  14131. CheckHint(mtWarning,nDispatchRequiresX,'Dispatch requires record field "Msg"');
  14132. end;
  14133. procedure TTestModule.TestClassOf_Create;
  14134. begin
  14135. StartProgram(false);
  14136. Add('type');
  14137. Add(' TObject = class');
  14138. Add(' constructor Create;');
  14139. Add(' end;');
  14140. Add(' TClass = class of TObject;');
  14141. Add('constructor tobject.create; begin end;');
  14142. Add('var');
  14143. Add(' Obj: tobject;');
  14144. Add(' C: tclass;');
  14145. Add('begin');
  14146. Add(' obj:=C.create;');
  14147. Add(' with c do obj:=create;');
  14148. ConvertProgram;
  14149. CheckSource('TestClassOf_Create',
  14150. LinesToStr([ // statements
  14151. 'rtl.createClass($mod, "TObject", null, function () {',
  14152. ' this.$init = function () {',
  14153. ' };',
  14154. ' this.$final = function () {',
  14155. ' };',
  14156. ' this.Create = function () {',
  14157. ' return this;',
  14158. ' };',
  14159. '});',
  14160. 'this.Obj = null;',
  14161. 'this.C = null;'
  14162. ]),
  14163. LinesToStr([ // $mod.$main
  14164. '$mod.Obj = $mod.C.$create("Create");',
  14165. 'var $with1 = $mod.C;',
  14166. '$mod.Obj = $with1.$create("Create");',
  14167. '']));
  14168. end;
  14169. procedure TTestModule.TestClassOf_Call;
  14170. begin
  14171. StartProgram(false);
  14172. Add('type');
  14173. Add(' TObject = class');
  14174. Add(' class procedure DoIt;');
  14175. Add(' end;');
  14176. Add(' TClass = class of TObject;');
  14177. Add('class procedure tobject.doit; begin end;');
  14178. Add('var');
  14179. Add(' C: tclass;');
  14180. Add('begin');
  14181. Add(' c.doit;');
  14182. Add(' with c do doit;');
  14183. ConvertProgram;
  14184. CheckSource('TestClassOf_Call',
  14185. LinesToStr([ // statements
  14186. 'rtl.createClass($mod, "TObject", null, function () {',
  14187. ' this.$init = function () {',
  14188. ' };',
  14189. ' this.$final = function () {',
  14190. ' };',
  14191. ' this.DoIt = function () {',
  14192. ' };',
  14193. '});',
  14194. 'this.C = null;'
  14195. ]),
  14196. LinesToStr([ // $mod.$main
  14197. '$mod.C.DoIt();',
  14198. 'var $with1 = $mod.C;',
  14199. '$with1.DoIt();',
  14200. '']));
  14201. end;
  14202. procedure TTestModule.TestClassOf_Assign;
  14203. begin
  14204. StartProgram(false);
  14205. Add('type');
  14206. Add(' TClass = class of TObject;');
  14207. Add(' TObject = class');
  14208. Add(' ClassType: TClass; ');
  14209. Add(' end;');
  14210. Add('var');
  14211. Add(' Obj: tobject;');
  14212. Add(' C: tclass;');
  14213. Add('begin');
  14214. Add(' c:=nil;');
  14215. Add(' c:=obj.classtype;');
  14216. ConvertProgram;
  14217. CheckSource('TestClassOf_Assign',
  14218. LinesToStr([ // statements
  14219. 'rtl.createClass($mod, "TObject", null, function () {',
  14220. ' this.$init = function () {',
  14221. ' this.ClassType = null;',
  14222. ' };',
  14223. ' this.$final = function () {',
  14224. ' this.ClassType = undefined;',
  14225. ' };',
  14226. '});',
  14227. 'this.Obj = null;',
  14228. 'this.C = null;'
  14229. ]),
  14230. LinesToStr([ // $mod.$main
  14231. '$mod.C = null;',
  14232. '$mod.C = $mod.Obj.ClassType;',
  14233. '']));
  14234. end;
  14235. procedure TTestModule.TestClassOf_Is;
  14236. begin
  14237. StartProgram(false);
  14238. Add('type');
  14239. Add(' TClass = class of TObject;');
  14240. Add(' TObject = class');
  14241. Add(' end;');
  14242. Add(' TCar = class');
  14243. Add(' end;');
  14244. Add(' TCars = class of TCar;');
  14245. Add('var');
  14246. Add(' Obj: tobject;');
  14247. Add(' C: tclass;');
  14248. Add(' Cars: tcars;');
  14249. Add('begin');
  14250. Add(' if c is tcar then ;');
  14251. Add(' if c is tcars then ;');
  14252. ConvertProgram;
  14253. CheckSource('TestClassOf_Is',
  14254. LinesToStr([ // statements
  14255. 'rtl.createClass($mod, "TObject", null, function () {',
  14256. ' this.$init = function () {',
  14257. ' };',
  14258. ' this.$final = function () {',
  14259. ' };',
  14260. '});',
  14261. 'rtl.createClass($mod, "TCar", $mod.TObject, function () {',
  14262. '});',
  14263. 'this.Obj = null;',
  14264. 'this.C = null;',
  14265. 'this.Cars = null;'
  14266. ]),
  14267. LinesToStr([ // $mod.$main
  14268. 'if(rtl.is($mod.C,$mod.TCar));',
  14269. 'if(rtl.is($mod.C,$mod.TCar));',
  14270. '']));
  14271. end;
  14272. procedure TTestModule.TestClassOf_Compare;
  14273. begin
  14274. StartProgram(false);
  14275. Add('type');
  14276. Add(' TClass = class of TObject;');
  14277. Add(' TObject = class');
  14278. Add(' ClassType: TClass; ');
  14279. Add(' end;');
  14280. Add('var');
  14281. Add(' b: boolean;');
  14282. Add(' Obj: tobject;');
  14283. Add(' C: tclass;');
  14284. Add('begin');
  14285. Add(' b:=c=nil;');
  14286. Add(' b:=nil=c;');
  14287. Add(' b:=c=obj.classtype;');
  14288. Add(' b:=obj.classtype=c;');
  14289. Add(' b:=c=TObject;');
  14290. Add(' b:=TObject=c;');
  14291. Add(' b:=c<>nil;');
  14292. Add(' b:=nil<>c;');
  14293. Add(' b:=c<>obj.classtype;');
  14294. Add(' b:=obj.classtype<>c;');
  14295. Add(' b:=c<>TObject;');
  14296. Add(' b:=TObject<>c;');
  14297. ConvertProgram;
  14298. CheckSource('TestClassOf_Compare',
  14299. LinesToStr([ // statements
  14300. 'rtl.createClass($mod, "TObject", null, function () {',
  14301. ' this.$init = function () {',
  14302. ' this.ClassType = null;',
  14303. ' };',
  14304. ' this.$final = function () {',
  14305. ' this.ClassType = undefined;',
  14306. ' };',
  14307. '});',
  14308. 'this.b = false;',
  14309. 'this.Obj = null;',
  14310. 'this.C = null;'
  14311. ]),
  14312. LinesToStr([ // $mod.$main
  14313. '$mod.b = $mod.C === null;',
  14314. '$mod.b = null === $mod.C;',
  14315. '$mod.b = $mod.C === $mod.Obj.ClassType;',
  14316. '$mod.b = $mod.Obj.ClassType === $mod.C;',
  14317. '$mod.b = $mod.C === $mod.TObject;',
  14318. '$mod.b = $mod.TObject === $mod.C;',
  14319. '$mod.b = $mod.C !== null;',
  14320. '$mod.b = null !== $mod.C;',
  14321. '$mod.b = $mod.C !== $mod.Obj.ClassType;',
  14322. '$mod.b = $mod.Obj.ClassType !== $mod.C;',
  14323. '$mod.b = $mod.C !== $mod.TObject;',
  14324. '$mod.b = $mod.TObject !== $mod.C;',
  14325. '']));
  14326. end;
  14327. procedure TTestModule.TestClassOf_ClassVar;
  14328. begin
  14329. StartProgram(false);
  14330. Add('type');
  14331. Add(' TObject = class');
  14332. Add(' class var id: longint;');
  14333. Add(' end;');
  14334. Add(' TClass = class of TObject;');
  14335. Add('var');
  14336. Add(' C: tclass;');
  14337. Add('begin');
  14338. Add(' C.id:=C.id;');
  14339. ConvertProgram;
  14340. CheckSource('TestClassOf_ClassVar',
  14341. LinesToStr([ // statements
  14342. 'rtl.createClass($mod, "TObject", null, function () {',
  14343. ' this.id = 0;',
  14344. ' this.$init = function () {',
  14345. ' };',
  14346. ' this.$final = function () {',
  14347. ' };',
  14348. '});',
  14349. 'this.C = null;'
  14350. ]),
  14351. LinesToStr([ // $mod.$main
  14352. '$mod.TObject.id = $mod.C.id;',
  14353. '']));
  14354. end;
  14355. procedure TTestModule.TestClassOf_ClassMethod;
  14356. begin
  14357. StartProgram(false);
  14358. Add('type');
  14359. Add(' TObject = class');
  14360. Add(' class function DoIt(i: longint = 0): longint;');
  14361. Add(' end;');
  14362. Add(' TClass = class of TObject;');
  14363. Add('class function tobject.doit(i: longint = 0): longint; begin end;');
  14364. Add('var');
  14365. Add(' i: longint;');
  14366. Add(' C: tclass;');
  14367. Add('begin');
  14368. Add(' C.DoIt;');
  14369. Add(' C.DoIt();');
  14370. Add(' i:=C.DoIt;');
  14371. Add(' i:=C.DoIt();');
  14372. ConvertProgram;
  14373. CheckSource('TestClassOf_ClassMethod',
  14374. LinesToStr([ // statements
  14375. 'rtl.createClass($mod, "TObject", null, function () {',
  14376. ' this.$init = function () {',
  14377. ' };',
  14378. ' this.$final = function () {',
  14379. ' };',
  14380. ' this.DoIt = function (i) {',
  14381. ' var Result = 0;',
  14382. ' return Result;',
  14383. ' };',
  14384. '});',
  14385. 'this.i = 0;',
  14386. 'this.C = null;'
  14387. ]),
  14388. LinesToStr([ // $mod.$main
  14389. '$mod.C.DoIt(0);',
  14390. '$mod.C.DoIt(0);',
  14391. '$mod.i = $mod.C.DoIt(0);',
  14392. '$mod.i = $mod.C.DoIt(0);',
  14393. '']));
  14394. end;
  14395. procedure TTestModule.TestClassOf_ClassProperty;
  14396. begin
  14397. StartProgram(false);
  14398. Add([
  14399. 'type',
  14400. ' TObject = class',
  14401. ' class var FA: longint;',
  14402. ' class function GetA: longint;',
  14403. ' class procedure SetA(Value: longint);',
  14404. ' class property pA: longint read fa write fa;',
  14405. ' class property pB: longint read geta write seta;',
  14406. ' end;',
  14407. ' TObjectClass = class of tobject;',
  14408. 'class function tobject.geta: longint; begin end;',
  14409. 'class procedure tobject.seta(value: longint); begin end;',
  14410. 'var',
  14411. ' b: boolean;',
  14412. ' Obj: tobject;',
  14413. ' Cla: tobjectclass;',
  14414. 'begin',
  14415. ' obj.pa:=obj.pa;',
  14416. ' obj.pb:=obj.pb;',
  14417. ' b:=obj.pa=4;',
  14418. ' b:=obj.pb=obj.pb;',
  14419. ' b:=5=obj.pa;',
  14420. ' cla.pa:=6;',
  14421. ' cla.pa:=cla.pa;',
  14422. ' cla.pb:=cla.pb;',
  14423. ' b:=cla.pa=7;',
  14424. ' b:=cla.pb=cla.pb;',
  14425. ' b:=8=cla.pa;',
  14426. ' tobject.pa:=9;',
  14427. ' tobject.pb:=tobject.pb;',
  14428. ' b:=tobject.pa=10;',
  14429. ' b:=11=tobject.pa;',
  14430. '']);
  14431. ConvertProgram;
  14432. CheckSource('TestClassOf_ClassProperty',
  14433. LinesToStr([ // statements
  14434. 'rtl.createClass($mod, "TObject", null, function () {',
  14435. ' this.FA = 0;',
  14436. ' this.$init = function () {',
  14437. ' };',
  14438. ' this.$final = function () {',
  14439. ' };',
  14440. ' this.GetA = function () {',
  14441. ' var Result = 0;',
  14442. ' return Result;',
  14443. ' };',
  14444. ' this.SetA = function (Value) {',
  14445. ' };',
  14446. '});',
  14447. 'this.b = false;',
  14448. 'this.Obj = null;',
  14449. 'this.Cla = null;'
  14450. ]),
  14451. LinesToStr([ // $mod.$main
  14452. '$mod.TObject.FA = $mod.Obj.FA;',
  14453. '$mod.Obj.$class.SetA($mod.Obj.$class.GetA());',
  14454. '$mod.b = $mod.Obj.FA === 4;',
  14455. '$mod.b = $mod.Obj.$class.GetA() === $mod.Obj.$class.GetA();',
  14456. '$mod.b = 5 === $mod.Obj.FA;',
  14457. '$mod.TObject.FA = 6;',
  14458. '$mod.TObject.FA = $mod.Cla.FA;',
  14459. '$mod.Cla.SetA($mod.Cla.GetA());',
  14460. '$mod.b = $mod.Cla.FA === 7;',
  14461. '$mod.b = $mod.Cla.GetA() === $mod.Cla.GetA();',
  14462. '$mod.b = 8 === $mod.Cla.FA;',
  14463. '$mod.TObject.FA = 9;',
  14464. '$mod.TObject.SetA($mod.TObject.GetA());',
  14465. '$mod.b = $mod.TObject.FA === 10;',
  14466. '$mod.b = 11 === $mod.TObject.FA;',
  14467. '']));
  14468. end;
  14469. procedure TTestModule.TestClassOf_ClassMethodSelf;
  14470. begin
  14471. StartProgram(false);
  14472. Add('type');
  14473. Add(' TObject = class');
  14474. Add(' class var GlobalId: longint;');
  14475. Add(' class procedure ProcA;');
  14476. Add(' end;');
  14477. Add('class procedure tobject.proca;');
  14478. Add('var b: boolean;');
  14479. Add('begin');
  14480. Add(' b:=self=nil;');
  14481. Add(' b:=self.globalid=3;');
  14482. Add(' b:=4=self.globalid;');
  14483. Add(' self.globalid:=5;');
  14484. Add(' self.proca;');
  14485. Add('end;');
  14486. Add('begin');
  14487. ConvertProgram;
  14488. CheckSource('TestClassOf_ClassMethodSelf',
  14489. LinesToStr([ // statements
  14490. 'rtl.createClass($mod, "TObject", null, function () {',
  14491. ' this.GlobalId = 0;',
  14492. ' this.$init = function () {',
  14493. ' };',
  14494. ' this.$final = function () {',
  14495. ' };',
  14496. ' this.ProcA = function () {',
  14497. ' var b = false;',
  14498. ' b = this === null;',
  14499. ' b = this.GlobalId === 3;',
  14500. ' b = 4 === this.GlobalId;',
  14501. ' $mod.TObject.GlobalId = 5;',
  14502. ' this.ProcA();',
  14503. ' };',
  14504. '});'
  14505. ]),
  14506. LinesToStr([ // $mod.$main
  14507. '']));
  14508. end;
  14509. procedure TTestModule.TestClassOf_TypeCast;
  14510. begin
  14511. StartProgram(false);
  14512. Add('type');
  14513. Add(' TObject = class');
  14514. Add(' class procedure {#TObject_DoIt}DoIt;');
  14515. Add(' end;');
  14516. Add(' TClass = class of TObject;');
  14517. Add(' TMobile = class');
  14518. Add(' class procedure {#TMobile_DoIt}DoIt;');
  14519. Add(' end;');
  14520. Add(' TMobileClass = class of TMobile;');
  14521. Add(' TCar = class(TMobile)');
  14522. Add(' class procedure {#TCar_DoIt}DoIt;');
  14523. Add(' end;');
  14524. Add(' TCarClass = class of TCar;');
  14525. Add('class procedure TObject.DoIt;');
  14526. Add('begin');
  14527. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  14528. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  14529. Add('end;');
  14530. Add('class procedure TMobile.DoIt;');
  14531. Add('begin');
  14532. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  14533. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  14534. Add(' TCarClass(Self).{@TCar_DoIt}DoIt;');
  14535. Add('end;');
  14536. Add('class procedure TCar.DoIt; begin end;');
  14537. Add('var');
  14538. Add(' ObjC: TClass;');
  14539. Add(' MobileC: TMobileClass;');
  14540. Add(' CarC: TCarClass;');
  14541. Add('begin');
  14542. Add(' ObjC.{@TObject_DoIt}DoIt;');
  14543. Add(' MobileC.{@TMobile_DoIt}DoIt;');
  14544. Add(' CarC.{@TCar_DoIt}DoIt;');
  14545. Add(' TClass(ObjC).{@TObject_DoIt}DoIt;');
  14546. Add(' TMobileClass(ObjC).{@TMobile_DoIt}DoIt;');
  14547. Add(' TCarClass(ObjC).{@TCar_DoIt}DoIt;');
  14548. Add(' TClass(MobileC).{@TObject_DoIt}DoIt;');
  14549. Add(' TMobileClass(MobileC).{@TMobile_DoIt}DoIt;');
  14550. Add(' TCarClass(MobileC).{@TCar_DoIt}DoIt;');
  14551. Add(' TClass(CarC).{@TObject_DoIt}DoIt;');
  14552. Add(' TMobileClass(CarC).{@TMobile_DoIt}DoIt;');
  14553. Add(' TCarClass(CarC).{@TCar_DoIt}DoIt;');
  14554. ConvertProgram;
  14555. CheckSource('TestClassOf_TypeCast',
  14556. LinesToStr([ // statements
  14557. 'rtl.createClass($mod, "TObject", null, function () {',
  14558. ' this.$init = function () {',
  14559. ' };',
  14560. ' this.$final = function () {',
  14561. ' };',
  14562. ' this.DoIt = function () {',
  14563. ' this.DoIt();',
  14564. ' this.DoIt$1();',
  14565. ' };',
  14566. '});',
  14567. 'rtl.createClass($mod, "TMobile", $mod.TObject, function () {',
  14568. ' this.DoIt$1 = function () {',
  14569. ' this.DoIt();',
  14570. ' this.DoIt$1();',
  14571. ' this.DoIt$2();',
  14572. ' };',
  14573. '});',
  14574. 'rtl.createClass($mod, "TCar", $mod.TMobile, function () {',
  14575. ' this.DoIt$2 = function () {',
  14576. ' };',
  14577. '});',
  14578. 'this.ObjC = null;',
  14579. 'this.MobileC = null;',
  14580. 'this.CarC = null;',
  14581. '']),
  14582. LinesToStr([ // $mod.$main
  14583. '$mod.ObjC.DoIt();',
  14584. '$mod.MobileC.DoIt$1();',
  14585. '$mod.CarC.DoIt$2();',
  14586. '$mod.ObjC.DoIt();',
  14587. '$mod.ObjC.DoIt$1();',
  14588. '$mod.ObjC.DoIt$2();',
  14589. '$mod.MobileC.DoIt();',
  14590. '$mod.MobileC.DoIt$1();',
  14591. '$mod.MobileC.DoIt$2();',
  14592. '$mod.CarC.DoIt();',
  14593. '$mod.CarC.DoIt$1();',
  14594. '$mod.CarC.DoIt$2();',
  14595. '']));
  14596. end;
  14597. procedure TTestModule.TestClassOf_ImplicitFunctionCall;
  14598. begin
  14599. StartProgram(false);
  14600. Add('type');
  14601. Add(' TObject = class');
  14602. Add(' function CurNow: longint; ');
  14603. Add(' class function Now: longint; ');
  14604. Add(' end;');
  14605. Add('function TObject.CurNow: longint; begin end;');
  14606. Add('class function TObject.Now: longint; begin end;');
  14607. Add('var');
  14608. Add(' Obj: tobject;');
  14609. Add(' vI: longint;');
  14610. Add('begin');
  14611. Add(' obj.curnow;');
  14612. Add(' vi:=obj.curnow;');
  14613. Add(' tobject.now;');
  14614. Add(' vi:=tobject.now;');
  14615. ConvertProgram;
  14616. CheckSource('TestClassOf_ImplicitFunctionCall',
  14617. LinesToStr([ // statements
  14618. 'rtl.createClass($mod, "TObject", null, function () {',
  14619. ' this.$init = function () {',
  14620. ' };',
  14621. ' this.$final = function () {',
  14622. ' };',
  14623. ' this.CurNow = function () {',
  14624. ' var Result = 0;',
  14625. ' return Result;',
  14626. ' };',
  14627. ' this.Now = function () {',
  14628. ' var Result = 0;',
  14629. ' return Result;',
  14630. ' };',
  14631. '});',
  14632. 'this.Obj = null;',
  14633. 'this.vI = 0;',
  14634. '']),
  14635. LinesToStr([ // $mod.$main
  14636. '$mod.Obj.CurNow();',
  14637. '$mod.vI = $mod.Obj.CurNow();',
  14638. '$mod.TObject.Now();',
  14639. '$mod.vI = $mod.TObject.Now();',
  14640. '']));
  14641. end;
  14642. procedure TTestModule.TestClassOf_Const;
  14643. begin
  14644. StartProgram(false);
  14645. Add([
  14646. 'type',
  14647. ' TObject = class',
  14648. ' end;',
  14649. ' TBird = TObject;',
  14650. ' TBirds = class of TBird;',
  14651. ' TEagles = TBirds;',
  14652. ' THawk = class(TBird);',
  14653. 'const',
  14654. ' Hawk: TEagles = THawk;',
  14655. ' DefaultBirdClasses : Array [1..2] of TEagles = (',
  14656. ' TBird,',
  14657. ' THawk',
  14658. ' );',
  14659. 'begin']);
  14660. ConvertProgram;
  14661. CheckSource('TestClassOf_Const',
  14662. LinesToStr([ // statements
  14663. 'rtl.createClass($mod, "TObject", null, function () {',
  14664. ' this.$init = function () {',
  14665. ' };',
  14666. ' this.$final = function () {',
  14667. ' };',
  14668. '});',
  14669. 'rtl.createClass($mod, "THawk", $mod.TObject, function () {',
  14670. '});',
  14671. 'this.Hawk = $mod.THawk;',
  14672. 'this.DefaultBirdClasses = [$mod.TObject, $mod.THawk];',
  14673. '']),
  14674. LinesToStr([ // $mod.$main
  14675. '']));
  14676. end;
  14677. procedure TTestModule.TestNestedClass_Alias;
  14678. begin
  14679. Converter.Options:=Converter.Options-[coNoTypeInfo];
  14680. StartProgram(false);
  14681. Add([
  14682. 'type',
  14683. ' TObject = class',
  14684. ' type TNested = type longint;',
  14685. ' end;',
  14686. 'type TAlias = type tobject.tnested;',
  14687. 'var i: tobject.tnested = 3;',
  14688. 'var j: TAlias = 4;',
  14689. 'begin',
  14690. ' if typeinfo(TAlias)=nil then ;',
  14691. ' if typeinfo(tobject.tnested)=nil then ;',
  14692. '']);
  14693. ConvertProgram;
  14694. CheckSource('TestNestedClass_Alias',
  14695. LinesToStr([ // statements
  14696. 'rtl.createClass($mod, "TObject", null, function () {',
  14697. ' $mod.$rtti.$inherited("TObject.TNested", rtl.longint, {});',
  14698. ' this.$init = function () {',
  14699. ' };',
  14700. ' this.$final = function () {',
  14701. ' };',
  14702. '});',
  14703. '$mod.$rtti.$inherited("TAlias", $mod.$rtti["TObject.TNested"], {});',
  14704. 'this.i = 3;',
  14705. 'this.j = 4;',
  14706. '']),
  14707. LinesToStr([ // $mod.$main
  14708. 'if ($mod.$rtti["TAlias"] === null) ;',
  14709. 'if ($mod.$rtti["TObject.TNested"] === null) ;',
  14710. '']));
  14711. end;
  14712. procedure TTestModule.TestNestedClass_Record;
  14713. begin
  14714. Converter.Options:=Converter.Options-[coNoTypeInfo];
  14715. StartProgram(false);
  14716. Add([
  14717. 'type',
  14718. ' TObject = class',
  14719. ' type TPoint = record',
  14720. ' x,y: byte;',
  14721. ' end;',
  14722. ' procedure DoIt(t: TPoint);',
  14723. ' end;',
  14724. 'procedure tobject.DoIt(t: TPoint);',
  14725. 'var p: TPoint;',
  14726. 'begin',
  14727. ' t.x:=t.y;',
  14728. ' p:=t;',
  14729. 'end;',
  14730. 'var',
  14731. ' p: tobject.tpoint = (x:2; y:4);',
  14732. ' o: TObject;',
  14733. 'begin',
  14734. ' p:=p;',
  14735. ' o.doit(p);',
  14736. '']);
  14737. ConvertProgram;
  14738. CheckSource('TestNestedClass_Record',
  14739. LinesToStr([ // statements
  14740. 'rtl.createClass($mod, "TObject", null, function () {',
  14741. ' rtl.recNewT(this, "TPoint", function () {',
  14742. ' this.x = 0;',
  14743. ' this.y = 0;',
  14744. ' this.$eq = function (b) {',
  14745. ' return (this.x === b.x) && (this.y === b.y);',
  14746. ' };',
  14747. ' this.$assign = function (s) {',
  14748. ' this.x = s.x;',
  14749. ' this.y = s.y;',
  14750. ' return this;',
  14751. ' };',
  14752. ' var $r = $mod.$rtti.$Record("TObject.TPoint", {});',
  14753. ' $r.addField("x", rtl.byte);',
  14754. ' $r.addField("y", rtl.byte);',
  14755. ' });',
  14756. ' this.$init = function () {',
  14757. ' };',
  14758. ' this.$final = function () {',
  14759. ' };',
  14760. ' this.DoIt = function (t) {',
  14761. ' var p = this.TPoint.$new();',
  14762. ' t.x = t.y;',
  14763. ' p.$assign(t);',
  14764. ' };',
  14765. '});',
  14766. 'this.p = $mod.TObject.TPoint.$clone({',
  14767. ' x: 2,',
  14768. ' y: 4',
  14769. '});',
  14770. 'this.o = null;',
  14771. '']),
  14772. LinesToStr([ // $mod.$main
  14773. '$mod.p.$assign($mod.p);',
  14774. '$mod.o.DoIt($mod.TObject.TPoint.$clone($mod.p));',
  14775. '']));
  14776. end;
  14777. procedure TTestModule.TestNestedClass_Class;
  14778. begin
  14779. Converter.Options:=Converter.Options-[coNoTypeInfo];
  14780. StartProgram(false);
  14781. Add([
  14782. 'type',
  14783. ' TObject = class end;',
  14784. ' TBird = class',
  14785. ' type TLeg = class',
  14786. ' FId: longint;',
  14787. ' constructor Create;',
  14788. ' function Create(i: longint): TLeg;',
  14789. ' end;',
  14790. ' function DoIt(b: TBird): Tleg;',
  14791. ' end;',
  14792. 'constructor tbird.tleg.create;',
  14793. 'begin',
  14794. ' FId:=3;',
  14795. 'end;',
  14796. 'function tbird.tleg.Create(i: longint): TLeg;',
  14797. 'begin',
  14798. ' Create;',
  14799. ' Result:=TLeg.Create;',
  14800. ' Result:=TBird.TLeg.Create;',
  14801. ' Result:=Create(3);',
  14802. ' FId:=i;',
  14803. 'end;',
  14804. 'function tbird.DoIt(b: tbird): tleg;',
  14805. 'begin',
  14806. ' Result.Create;',
  14807. ' Result:=TLeg.Create;',
  14808. ' Result:=TBird.TLeg.Create;',
  14809. ' Result:=Result.Create(3);',
  14810. 'end;',
  14811. 'var',
  14812. ' b: Tbird.tleg;',
  14813. 'begin',
  14814. ' b.Create;',
  14815. ' b:=TBird.TLeg.Create;',
  14816. ' b:=b.Create(3);',
  14817. '']);
  14818. ConvertProgram;
  14819. CheckSource('TestNestedClass_Class',
  14820. LinesToStr([ // statements
  14821. 'rtl.createClass($mod, "TObject", null, function () {',
  14822. ' this.$init = function () {',
  14823. ' };',
  14824. ' this.$final = function () {',
  14825. ' };',
  14826. '});',
  14827. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  14828. ' rtl.createClass(this, "TLeg", $mod.TObject, function () {',
  14829. ' this.$init = function () {',
  14830. ' $mod.TObject.$init.call(this);',
  14831. ' this.FId = 0;',
  14832. ' };',
  14833. ' this.Create = function () {',
  14834. ' this.FId = 3;',
  14835. ' return this;',
  14836. ' };',
  14837. ' this.Create$1 = function (i) {',
  14838. ' var Result = null;',
  14839. ' this.Create();',
  14840. ' Result = $mod.TBird.TLeg.$create("Create");',
  14841. ' Result = $mod.TBird.TLeg.$create("Create");',
  14842. ' Result = this.Create$1(3);',
  14843. ' this.FId = i;',
  14844. ' return Result;',
  14845. ' };',
  14846. ' });',
  14847. ' this.DoIt = function (b) {',
  14848. ' var Result = null;',
  14849. ' Result.Create();',
  14850. ' Result = this.TLeg.$create("Create");',
  14851. ' Result = $mod.TBird.TLeg.$create("Create");',
  14852. ' Result = Result.Create$1(3);',
  14853. ' return Result;',
  14854. ' };',
  14855. '});',
  14856. 'this.b = null;',
  14857. '']),
  14858. LinesToStr([ // $mod.$main
  14859. '$mod.b.Create();',
  14860. '$mod.b = $mod.TBird.TLeg.$create("Create");',
  14861. '$mod.b = $mod.b.Create$1(3);',
  14862. '']));
  14863. end;
  14864. procedure TTestModule.TestExternalClass_Var;
  14865. begin
  14866. StartProgram(false);
  14867. Add([
  14868. '{$modeswitch externalclass}',
  14869. 'type',
  14870. ' TExtA = class external name ''ExtObj''',
  14871. ' Id: longint external name ''$Id'';',
  14872. ' B: longint;',
  14873. ' end;',
  14874. 'var Obj: TExtA;',
  14875. 'begin',
  14876. ' obj.id:=obj.id+1;',
  14877. ' obj.B:=obj.B+1;']);
  14878. ConvertProgram;
  14879. CheckSource('TestExternalClass_Var',
  14880. LinesToStr([ // statements
  14881. 'this.Obj = null;',
  14882. '']),
  14883. LinesToStr([ // $mod.$main
  14884. '$mod.Obj.$Id = $mod.Obj.$Id + 1;',
  14885. '$mod.Obj.B = $mod.Obj.B + 1;',
  14886. '']));
  14887. end;
  14888. procedure TTestModule.TestExternalClass_Const;
  14889. begin
  14890. StartProgram(false);
  14891. Add([
  14892. '{$modeswitch externalclass}',
  14893. 'type',
  14894. ' TExtA = class external name ''ExtObj''',
  14895. ' const Two: longint = 2;',
  14896. ' const Three = 3;',
  14897. ' const Id: longint;',
  14898. ' end;',
  14899. ' TExtB = class external name ''ExtB''',
  14900. ' A: TExtA;',
  14901. ' end;',
  14902. 'var',
  14903. ' A: texta;',
  14904. ' B: textb;',
  14905. ' i: longint;',
  14906. 'begin',
  14907. ' i:=a.two;',
  14908. ' i:=texta.two;',
  14909. ' i:=a.three;',
  14910. ' i:=texta.three;',
  14911. ' i:=a.id;',
  14912. ' i:=texta.id;',
  14913. '']);
  14914. ConvertProgram;
  14915. CheckSource('TestExternalClass_Const',
  14916. LinesToStr([ // statements
  14917. 'this.A = null;',
  14918. 'this.B = null;',
  14919. 'this.i = 0;',
  14920. '']),
  14921. LinesToStr([ // $mod.$main
  14922. '$mod.i = 2;',
  14923. '$mod.i = 2;',
  14924. '$mod.i = 3;',
  14925. '$mod.i = 3;',
  14926. '$mod.i = $mod.A.Id;',
  14927. '$mod.i = ExtObj.Id;',
  14928. '']));
  14929. end;
  14930. procedure TTestModule.TestExternalClass_Dollar;
  14931. begin
  14932. StartProgram(false);
  14933. Add([
  14934. '{$modeswitch externalclass}',
  14935. 'type',
  14936. ' TExtA = class external name ''$''',
  14937. ' Id: longint external name ''$'';',
  14938. ' function Bla(i: longint): longint; external name ''$'';',
  14939. ' end;',
  14940. 'function dollar(k: longint): longint; external name ''$'';',
  14941. 'var Obj: TExtA;',
  14942. 'begin',
  14943. ' dollar(1);',
  14944. ' obj.id:=obj.id+2;',
  14945. ' obj.Bla(3);',
  14946. '']);
  14947. ConvertProgram;
  14948. CheckSource('TestExternalClass_Dollar',
  14949. LinesToStr([ // statements
  14950. 'this.Obj = null;',
  14951. '']),
  14952. LinesToStr([ // $mod.$main
  14953. '$(1);',
  14954. '$mod.Obj.$ = $mod.Obj.$ + 2;',
  14955. '$mod.Obj.$(3);',
  14956. '']));
  14957. end;
  14958. procedure TTestModule.TestExternalClass_DuplicateVarFail;
  14959. begin
  14960. StartProgram(false);
  14961. Add('{$modeswitch externalclass}');
  14962. Add('type');
  14963. Add(' TExtA = class external name ''ExtA''');
  14964. Add(' Id: longint external name ''$Id'';');
  14965. Add(' end;');
  14966. Add(' TExtB = class external ''lib'' name ''ExtB''(TExtA)');
  14967. Add(' Id: longint;');
  14968. Add(' end;');
  14969. Add('begin');
  14970. SetExpectedPasResolverError('Duplicate identifier "Id" at test1.pp(6,5)',nDuplicateIdentifier);
  14971. ConvertProgram;
  14972. end;
  14973. procedure TTestModule.TestExternalClass_Method;
  14974. begin
  14975. StartProgram(false);
  14976. Add('{$modeswitch externalclass}');
  14977. Add('type');
  14978. Add(' TExtA = class external name ''ExtObj''');
  14979. Add(' procedure DoIt(Id: longint = 1); external name ''$Execute'';');
  14980. Add(' procedure DoSome(Id: longint = 1);');
  14981. Add(' end;');
  14982. Add('var Obj: texta;');
  14983. Add('begin');
  14984. Add(' obj.doit;');
  14985. Add(' obj.doit();');
  14986. Add(' obj.doit(2);');
  14987. Add(' with obj do begin');
  14988. Add(' doit;');
  14989. Add(' doit();');
  14990. Add(' doit(3);');
  14991. Add(' end;');
  14992. ConvertProgram;
  14993. CheckSource('TestExternalClass_Method',
  14994. LinesToStr([ // statements
  14995. 'this.Obj = null;',
  14996. '']),
  14997. LinesToStr([ // $mod.$main
  14998. '$mod.Obj.$Execute(1);',
  14999. '$mod.Obj.$Execute(1);',
  15000. '$mod.Obj.$Execute(2);',
  15001. 'var $with1 = $mod.Obj;',
  15002. '$with1.$Execute(1);',
  15003. '$with1.$Execute(1);',
  15004. '$with1.$Execute(3);',
  15005. '']));
  15006. end;
  15007. procedure TTestModule.TestExternalClass_ClassMethod;
  15008. begin
  15009. StartProgram(false);
  15010. Add([
  15011. '{$modeswitch externalclass}',
  15012. 'type',
  15013. ' TExtA = class external name ''ExtObj''',
  15014. ' class procedure DoIt(Id: longint = 1); external name ''$Execute'';',
  15015. ' end;',
  15016. ' TExtB = TExtA;',
  15017. 'begin',
  15018. ' texta.doit;',
  15019. ' texta.doit();',
  15020. ' texta.doit(2);',
  15021. ' with texta do begin',
  15022. ' doit;',
  15023. ' doit();',
  15024. ' doit(3);',
  15025. ' end;',
  15026. ' textb.doit;',
  15027. ' textb.doit();',
  15028. ' textb.doit(4);',
  15029. ' with textb do begin',
  15030. ' doit;',
  15031. ' doit();',
  15032. ' doit(5);',
  15033. ' end;',
  15034. '']);
  15035. ConvertProgram;
  15036. CheckSource('TestExternalClass_ClassMethod',
  15037. LinesToStr([ // statements
  15038. '']),
  15039. LinesToStr([ // $mod.$main
  15040. 'ExtObj.$Execute(1);',
  15041. 'ExtObj.$Execute(1);',
  15042. 'ExtObj.$Execute(2);',
  15043. 'ExtObj.$Execute(1);',
  15044. 'ExtObj.$Execute(1);',
  15045. 'ExtObj.$Execute(3);',
  15046. 'ExtObj.$Execute(1);',
  15047. 'ExtObj.$Execute(1);',
  15048. 'ExtObj.$Execute(4);',
  15049. 'ExtObj.$Execute(1);',
  15050. 'ExtObj.$Execute(1);',
  15051. 'ExtObj.$Execute(5);',
  15052. '']));
  15053. end;
  15054. procedure TTestModule.TestExternalClass_FunctionResultInTypeCast;
  15055. begin
  15056. StartProgram(false);
  15057. Add([
  15058. '{$modeswitch externalclass}',
  15059. 'type',
  15060. ' TBird = class external name ''Array''',
  15061. ' end;',
  15062. 'function GetPtr: Pointer;',
  15063. 'begin',
  15064. 'end;',
  15065. 'procedure Write(const p);',
  15066. 'begin',
  15067. 'end;',
  15068. 'procedure WriteLn; varargs;',
  15069. 'begin',
  15070. 'end;',
  15071. 'begin',
  15072. ' if TBird(GetPtr)=nil then ;',
  15073. ' Write(GetPtr);',
  15074. ' WriteLn(GetPtr);',
  15075. ' Write(TBird(GetPtr));',
  15076. ' WriteLn(TBird(GetPtr));',
  15077. '']);
  15078. ConvertProgram;
  15079. CheckSource('TestFunctionResultInTypeCast',
  15080. LinesToStr([ // statements
  15081. 'this.GetPtr = function () {',
  15082. ' var Result = null;',
  15083. ' return Result;',
  15084. '};',
  15085. 'this.Write = function (p) {',
  15086. '};',
  15087. 'this.WriteLn = function () {',
  15088. '};',
  15089. '']),
  15090. LinesToStr([
  15091. 'if ($mod.GetPtr() === null) ;',
  15092. '$mod.Write($mod.GetPtr());',
  15093. '$mod.WriteLn($mod.GetPtr());',
  15094. '$mod.Write($mod.GetPtr());',
  15095. '$mod.WriteLn($mod.GetPtr());',
  15096. '']));
  15097. end;
  15098. procedure TTestModule.TestExternalClass_NonExternalOverride;
  15099. begin
  15100. StartProgram(false);
  15101. Add('{$modeswitch externalclass}');
  15102. Add('type');
  15103. Add(' TExtA = class external name ''ExtObjA''');
  15104. Add(' procedure ProcA; virtual;');
  15105. Add(' procedure ProcB; virtual;');
  15106. Add(' end;');
  15107. Add(' TExtB = class external name ''ExtObjB'' (TExtA)');
  15108. Add(' end;');
  15109. Add(' TExtC = class (TExtB)');
  15110. Add(' procedure ProcA; override;');
  15111. Add(' end;');
  15112. Add('procedure TExtC.ProcA;');
  15113. Add('begin');
  15114. Add(' ProcA;');
  15115. Add(' Self.ProcA;');
  15116. Add(' ProcB;');
  15117. Add(' Self.ProcB;');
  15118. Add('end;');
  15119. Add('var');
  15120. Add(' A: texta;');
  15121. Add(' B: textb;');
  15122. Add(' C: textc;');
  15123. Add('begin');
  15124. Add(' a.proca;');
  15125. Add(' b.proca;');
  15126. Add(' c.proca;');
  15127. ConvertProgram;
  15128. CheckSource('TestExternalClass_NonExternalOverride',
  15129. LinesToStr([ // statements
  15130. 'rtl.createClassExt($mod, "TExtC", ExtObjB, "", function () {',
  15131. ' this.$init = function () {',
  15132. ' };',
  15133. ' this.$final = function () {',
  15134. ' };',
  15135. ' this.ProcA = function () {',
  15136. ' this.ProcA();',
  15137. ' this.ProcA();',
  15138. ' this.ProcB();',
  15139. ' this.ProcB();',
  15140. ' };',
  15141. '});',
  15142. 'this.A = null;',
  15143. 'this.B = null;',
  15144. 'this.C = null;',
  15145. '']),
  15146. LinesToStr([ // $mod.$main
  15147. '$mod.A.ProcA();',
  15148. '$mod.B.ProcA();',
  15149. '$mod.C.ProcA();',
  15150. '']));
  15151. end;
  15152. procedure TTestModule.TestExternalClass_OverloadHint;
  15153. begin
  15154. StartProgram(false);
  15155. Add([
  15156. '{$modeswitch externalclass}',
  15157. 'type',
  15158. ' TExtA = class external name ''ExtObjA''',
  15159. ' procedure DoIt;',
  15160. ' procedure DoIt(i: longint);',
  15161. ' end;',
  15162. 'begin',
  15163. '']);
  15164. ConvertProgram;
  15165. CheckResolverUnexpectedHints(true);
  15166. CheckSource('TestExternalClass_OverloadHint',
  15167. LinesToStr([ // statements
  15168. '']),
  15169. LinesToStr([ // $mod.$main
  15170. '']));
  15171. end;
  15172. procedure TTestModule.TestExternalClass_SameNamePublishedProperty;
  15173. begin
  15174. StartProgram(false);
  15175. Add([
  15176. '{$modeswitch externalclass}',
  15177. 'type',
  15178. ' JSwiper = class external name ''Swiper''',
  15179. ' constructor New;',
  15180. ' end;',
  15181. ' TObject = class',
  15182. ' private',
  15183. ' FSwiper: JSwiper;',
  15184. ' published',
  15185. ' property Swiper: JSwiper read FSwiper write FSwiper;',
  15186. ' end;',
  15187. 'begin',
  15188. ' JSwiper.new;',
  15189. '']);
  15190. ConvertProgram;
  15191. CheckSource('TestExternalClass_SameNamePublishedProperty',
  15192. LinesToStr([ // statements
  15193. 'rtl.createClass($mod, "TObject", null, function () {',
  15194. ' this.$init = function () {',
  15195. ' this.FSwiper = null;',
  15196. ' };',
  15197. ' this.$final = function () {',
  15198. ' this.FSwiper = undefined;',
  15199. ' };',
  15200. ' var $r = this.$rtti;',
  15201. ' $r.addProperty("Swiper", 0, $mod.$rtti["JSwiper"], "FSwiper", "FSwiper");',
  15202. '});',
  15203. '']),
  15204. LinesToStr([ // $mod.$main
  15205. 'new Swiper();',
  15206. '']));
  15207. end;
  15208. procedure TTestModule.TestExternalClass_Property;
  15209. begin
  15210. StartProgram(false);
  15211. Add([
  15212. '{$modeswitch externalclass}',
  15213. 'type',
  15214. ' TExtA = class external name ''ExtA''',
  15215. ' function getYear: longint;',
  15216. ' procedure setYear(Value: longint);',
  15217. ' property Year: longint read getyear write setyear;',
  15218. ' end;',
  15219. ' TExtB = class (TExtA)',
  15220. ' procedure OtherSetYear(Value: longint);',
  15221. ' property year write othersetyear;',
  15222. ' end;',
  15223. 'procedure textb.othersetyear(value: longint);',
  15224. 'begin',
  15225. ' setYear(Value+4);',
  15226. 'end;',
  15227. 'var',
  15228. ' A: texta;',
  15229. ' B: textb;',
  15230. 'begin',
  15231. ' a.year:=a.year+1;',
  15232. ' b.year:=b.year+2;']);
  15233. ConvertProgram;
  15234. CheckSource('TestExternalClass_NonExternalOverride',
  15235. LinesToStr([ // statements
  15236. 'rtl.createClassExt($mod, "TExtB", ExtA, "", function () {',
  15237. ' this.$init = function () {',
  15238. ' };',
  15239. ' this.$final = function () {',
  15240. ' };',
  15241. ' this.OtherSetYear = function (Value) {',
  15242. ' this.setYear(Value+4);',
  15243. ' };',
  15244. '});',
  15245. 'this.A = null;',
  15246. 'this.B = null;',
  15247. '']),
  15248. LinesToStr([ // $mod.$main
  15249. '$mod.A.setYear($mod.A.getYear()+1);',
  15250. '$mod.B.OtherSetYear($mod.B.getYear()+2);',
  15251. '']));
  15252. end;
  15253. procedure TTestModule.TestExternalClass_PropertyDate;
  15254. begin
  15255. StartProgram(false);
  15256. Add([
  15257. '{$modeswitch externalclass}',
  15258. 'type',
  15259. ' TExtA = class external name ''ExtA''',
  15260. ' end;',
  15261. ' TExtB = class (TExtA)',
  15262. ' FDate: string;',
  15263. ' property Date: string read FDate write FDate;',
  15264. ' property ExtA: string read FDate write FDate;',
  15265. ' end;',
  15266. ' {$M+}',
  15267. ' TObject = class',
  15268. ' FDate: string;',
  15269. ' published',
  15270. ' property Date: string read FDate write FDate;',
  15271. ' property ExtA: string read FDate write FDate;',
  15272. ' end;',
  15273. 'var',
  15274. ' B: textb;',
  15275. ' o: TObject;',
  15276. 'begin',
  15277. ' b.date:=b.exta;',
  15278. ' o.date:=o.exta;']);
  15279. ConvertProgram;
  15280. CheckSource('TestExternalClass_PropertyDate',
  15281. LinesToStr([ // statements
  15282. 'rtl.createClassExt($mod, "TExtB", ExtA, "", function () {',
  15283. ' this.$init = function () {',
  15284. ' this.FDate = "";',
  15285. ' };',
  15286. ' this.$final = function () {',
  15287. ' };',
  15288. '});',
  15289. 'rtl.createClass($mod, "TObject", null, function () {',
  15290. ' this.$init = function () {',
  15291. ' this.FDate = "";',
  15292. ' };',
  15293. ' this.$final = function () {',
  15294. ' };',
  15295. ' var $r = this.$rtti;',
  15296. ' $r.addField("FDate", rtl.string);',
  15297. ' $r.addProperty("Date", 0, rtl.string, "FDate", "FDate");',
  15298. ' $r.addProperty("ExtA", 0, rtl.string, "FDate", "FDate");',
  15299. '});',
  15300. 'this.B = null;',
  15301. 'this.o = null;',
  15302. '']),
  15303. LinesToStr([ // $mod.$main
  15304. '$mod.B.FDate = $mod.B.FDate;',
  15305. '$mod.o.FDate = $mod.o.FDate;',
  15306. '']));
  15307. end;
  15308. procedure TTestModule.TestExternalClass_ClassProperty;
  15309. begin
  15310. StartProgram(false);
  15311. Add('{$modeswitch externalclass}');
  15312. Add('type');
  15313. Add(' TExtA = class external name ''ExtA''');
  15314. Add(' class function getYear: longint;');
  15315. Add(' class procedure setYear(Value: longint);');
  15316. Add(' class property Year: longint read getyear write setyear;');
  15317. Add(' end;');
  15318. Add(' TExtB = class (TExtA)');
  15319. Add(' class function GetCentury: longint;');
  15320. Add(' class procedure SetCentury(Value: longint);');
  15321. Add(' class property Century: longint read getcentury write setcentury;');
  15322. Add(' end;');
  15323. Add('class function textb.getcentury: longint;');
  15324. Add('begin');
  15325. Add('end;');
  15326. Add('class procedure textb.setcentury(value: longint);');
  15327. Add('begin');
  15328. Add(' setyear(value+11);');
  15329. Add(' texta.year:=texta.year+12;');
  15330. Add(' year:=year+13;');
  15331. Add(' textb.century:=textb.century+14;');
  15332. Add(' century:=century+15;');
  15333. Add('end;');
  15334. Add('var');
  15335. Add(' A: texta;');
  15336. Add(' B: textb;');
  15337. Add('begin');
  15338. Add(' texta.year:=texta.year+1;');
  15339. Add(' textb.year:=textb.year+2;');
  15340. Add(' TextA.year:=TextA.year+3;');
  15341. Add(' b.year:=b.year+4;');
  15342. Add(' textb.century:=textb.century+5;');
  15343. Add(' b.century:=b.century+6;');
  15344. ConvertProgram;
  15345. CheckSource('TestExternalClass_ClassProperty',
  15346. LinesToStr([ // statements
  15347. 'rtl.createClassExt($mod, "TExtB", ExtA, "", function () {',
  15348. ' this.$init = function () {',
  15349. ' };',
  15350. ' this.$final = function () {',
  15351. ' };',
  15352. ' this.GetCentury = function () {',
  15353. ' var Result = 0;',
  15354. ' return Result;',
  15355. ' };',
  15356. ' this.SetCentury = function (Value) {',
  15357. ' this.setYear(Value + 11);',
  15358. ' ExtA.setYear(ExtA.getYear() + 12);',
  15359. ' this.setYear(this.getYear() + 13);',
  15360. ' $mod.TExtB.SetCentury($mod.TExtB.GetCentury() + 14);',
  15361. ' this.SetCentury(this.GetCentury() + 15);',
  15362. ' };',
  15363. '});',
  15364. 'this.A = null;',
  15365. 'this.B = null;',
  15366. '']),
  15367. LinesToStr([ // $mod.$main
  15368. 'ExtA.setYear(ExtA.getYear() + 1);',
  15369. '$mod.TExtB.setYear($mod.TExtB.getYear() + 2);',
  15370. 'ExtA.setYear(ExtA.getYear() + 3);',
  15371. '$mod.B.setYear($mod.B.getYear() + 4);',
  15372. '$mod.TExtB.SetCentury($mod.TExtB.GetCentury() + 5);',
  15373. '$mod.B.$class.SetCentury($mod.B.$class.GetCentury() + 6);',
  15374. '']));
  15375. end;
  15376. procedure TTestModule.TestExternalClass_ClassOf;
  15377. begin
  15378. StartProgram(false);
  15379. Add('{$modeswitch externalclass}');
  15380. Add('type');
  15381. Add(' TExtA = class external name ''ExtA''');
  15382. Add(' procedure ProcA; virtual;');
  15383. Add(' procedure ProcB; virtual;');
  15384. Add(' end;');
  15385. Add(' TExtAClass = class of TExtA;');
  15386. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  15387. Add(' end;');
  15388. Add(' TExtBClass = class of TExtB;');
  15389. Add(' TExtC = class (TExtB)');
  15390. Add(' procedure ProcA; override;');
  15391. Add(' end;');
  15392. Add(' TExtCClass = class of TExtC;');
  15393. Add('procedure TExtC.ProcA; begin end;');
  15394. Add('var');
  15395. Add(' A: texta; ClA: TExtAClass;');
  15396. Add(' B: textb; ClB: TExtBClass;');
  15397. Add(' C: textc; ClC: TExtCClass;');
  15398. Add('begin');
  15399. Add(' ClA:=texta;');
  15400. Add(' ClA:=textb;');
  15401. Add(' ClA:=textc;');
  15402. Add(' ClB:=textb;');
  15403. Add(' ClB:=textc;');
  15404. Add(' ClC:=textc;');
  15405. ConvertProgram;
  15406. CheckSource('TestExternalClass_ClassOf',
  15407. LinesToStr([ // statements
  15408. 'rtl.createClassExt($mod, "TExtC", ExtB, "", function () {',
  15409. ' this.$init = function () {',
  15410. ' };',
  15411. ' this.$final = function () {',
  15412. ' };',
  15413. ' this.ProcA = function () {',
  15414. ' };',
  15415. '});',
  15416. 'this.A = null;',
  15417. 'this.ClA = null;',
  15418. 'this.B = null;',
  15419. 'this.ClB = null;',
  15420. 'this.C = null;',
  15421. 'this.ClC = null;',
  15422. '']),
  15423. LinesToStr([ // $mod.$main
  15424. '$mod.ClA = ExtA;',
  15425. '$mod.ClA = ExtB;',
  15426. '$mod.ClA = $mod.TExtC;',
  15427. '$mod.ClB = ExtB;',
  15428. '$mod.ClB = $mod.TExtC;',
  15429. '$mod.ClC = $mod.TExtC;',
  15430. '']));
  15431. end;
  15432. procedure TTestModule.TestExternalClass_ClassOtherUnit;
  15433. begin
  15434. AddModuleWithIntfImplSrc('unit2.pas',
  15435. LinesToStr([
  15436. '{$modeswitch externalclass}',
  15437. 'type',
  15438. ' TExtA = class external name ''ExtA''',
  15439. ' class var Id: longint;',
  15440. ' end;',
  15441. '']),
  15442. '');
  15443. StartUnit(true);
  15444. Add('interface');
  15445. Add('uses unit2;');
  15446. Add('implementation');
  15447. Add('begin');
  15448. Add(' unit2.texta.id:=unit2.texta.id+1;');
  15449. ConvertUnit;
  15450. CheckSource('TestExternalClass_ClassOtherUnit',
  15451. LinesToStr([
  15452. '']),
  15453. LinesToStr([
  15454. 'ExtA.Id = ExtA.Id + 1;',
  15455. '']));
  15456. end;
  15457. procedure TTestModule.TestExternalClass_Is;
  15458. begin
  15459. StartProgram(false);
  15460. Add('{$modeswitch externalclass}');
  15461. Add('type');
  15462. Add(' TExtA = class external name ''ExtA''');
  15463. Add(' end;');
  15464. Add(' TExtAClass = class of TExtA;');
  15465. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  15466. Add(' end;');
  15467. Add(' TExtBClass = class of TExtB;');
  15468. Add(' TExtC = class (TExtB)');
  15469. Add(' end;');
  15470. Add(' TExtCClass = class of TExtC;');
  15471. Add('var');
  15472. Add(' A: texta; ClA: TExtAClass;');
  15473. Add(' B: textb; ClB: TExtBClass;');
  15474. Add(' C: textc; ClC: TExtCClass;');
  15475. Add('begin');
  15476. Add(' if a is textb then ;');
  15477. Add(' if a is textc then ;');
  15478. Add(' if b is textc then ;');
  15479. Add(' if cla is textb then ;');
  15480. Add(' if cla is textc then ;');
  15481. Add(' if clb is textc then ;');
  15482. ConvertProgram;
  15483. CheckSource('TestExternalClass_Is',
  15484. LinesToStr([ // statements
  15485. 'rtl.createClassExt($mod, "TExtC", ExtB, "", function () {',
  15486. ' this.$init = function () {',
  15487. ' };',
  15488. ' this.$final = function () {',
  15489. ' };',
  15490. '});',
  15491. 'this.A = null;',
  15492. 'this.ClA = null;',
  15493. 'this.B = null;',
  15494. 'this.ClB = null;',
  15495. 'this.C = null;',
  15496. 'this.ClC = null;',
  15497. '']),
  15498. LinesToStr([ // $mod.$main
  15499. 'if (rtl.isExt($mod.A, ExtB)) ;',
  15500. 'if ($mod.TExtC.isPrototypeOf($mod.A)) ;',
  15501. 'if ($mod.TExtC.isPrototypeOf($mod.B)) ;',
  15502. 'if (rtl.isExt($mod.ClA, ExtB)) ;',
  15503. 'if (rtl.is($mod.ClA, $mod.TExtC)) ;',
  15504. 'if (rtl.is($mod.ClB, $mod.TExtC)) ;',
  15505. '']));
  15506. end;
  15507. procedure TTestModule.TestExternalClass_As;
  15508. begin
  15509. StartProgram(false);
  15510. Add('{$modeswitch externalclass}');
  15511. Add('type');
  15512. Add(' TExtA = class external name ''ExtA''');
  15513. Add(' end;');
  15514. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  15515. Add(' end;');
  15516. Add(' TExtC = class (TExtB)');
  15517. Add(' end;');
  15518. Add('var');
  15519. Add(' A: texta;');
  15520. Add(' B: textb;');
  15521. Add(' C: textc;');
  15522. Add('begin');
  15523. Add(' b:=a as textb;');
  15524. Add(' c:=a as textc;');
  15525. Add(' c:=b as textc;');
  15526. ConvertProgram;
  15527. CheckSource('TestExternalClass_Is',
  15528. LinesToStr([ // statements
  15529. 'rtl.createClassExt($mod, "TExtC", ExtB, "", function () {',
  15530. ' this.$init = function () {',
  15531. ' };',
  15532. ' this.$final = function () {',
  15533. ' };',
  15534. '});',
  15535. 'this.A = null;',
  15536. 'this.B = null;',
  15537. 'this.C = null;',
  15538. '']),
  15539. LinesToStr([ // $mod.$main
  15540. '$mod.B = rtl.asExt($mod.A, ExtB);',
  15541. '$mod.C = rtl.as($mod.A, $mod.TExtC);',
  15542. '$mod.C = rtl.as($mod.B, $mod.TExtC);',
  15543. '']));
  15544. end;
  15545. procedure TTestModule.TestExternalClass_DestructorFail;
  15546. begin
  15547. StartProgram(false);
  15548. Add('{$modeswitch externalclass}');
  15549. Add('type');
  15550. Add(' TExtA = class external name ''ExtA''');
  15551. Add(' destructor Free;');
  15552. Add(' end;');
  15553. SetExpectedPasResolverError('Pascal element not supported: destructor',
  15554. nPasElementNotSupported);
  15555. ConvertProgram;
  15556. end;
  15557. procedure TTestModule.TestExternalClass_New;
  15558. begin
  15559. StartProgram(false);
  15560. Add('{$modeswitch externalclass}');
  15561. Add('type');
  15562. Add(' TExtA = class external name ''ExtA''');
  15563. Add(' constructor New;');
  15564. Add(' constructor New(i: longint; j: longint = 2);');
  15565. Add(' end;');
  15566. Add('var');
  15567. Add(' A: texta;');
  15568. Add('begin');
  15569. Add(' a:=texta.new;');
  15570. Add(' a:=texta(texta.new);');
  15571. Add(' a:=texta.new();');
  15572. Add(' a:=texta.new(1);');
  15573. Add(' with texta do begin');
  15574. Add(' a:=new;');
  15575. Add(' a:=new();');
  15576. Add(' a:=new(2);');
  15577. Add(' end;');
  15578. Add(' a:=test1.texta.new;');
  15579. Add(' a:=test1.texta.new();');
  15580. Add(' a:=test1.texta.new(3);');
  15581. ConvertProgram;
  15582. CheckSource('TestExternalClass_New',
  15583. LinesToStr([ // statements
  15584. 'this.A = null;',
  15585. '']),
  15586. LinesToStr([ // $mod.$main
  15587. '$mod.A = new ExtA();',
  15588. '$mod.A = new ExtA();',
  15589. '$mod.A = new ExtA();',
  15590. '$mod.A = new ExtA(1,2);',
  15591. '$mod.A = new ExtA();',
  15592. '$mod.A = new ExtA();',
  15593. '$mod.A = new ExtA(2,2);',
  15594. '$mod.A = new ExtA();',
  15595. '$mod.A = new ExtA();',
  15596. '$mod.A = new ExtA(3,2);',
  15597. '']));
  15598. end;
  15599. procedure TTestModule.TestExternalClass_ClassOf_New;
  15600. begin
  15601. StartProgram(false);
  15602. Add('{$modeswitch externalclass}');
  15603. Add('type');
  15604. Add(' TExtAClass = class of TExtA;');
  15605. Add(' TExtA = class external name ''ExtA''');
  15606. Add(' C: TExtAClass;');
  15607. Add(' constructor New;');
  15608. Add(' end;');
  15609. Add('var');
  15610. Add(' A: texta;');
  15611. Add(' C: textaclass;');
  15612. Add('begin');
  15613. Add(' a:=c.new;');
  15614. Add(' a:=c.new();');
  15615. Add(' with C do begin');
  15616. Add(' a:=new;');
  15617. Add(' a:=new();');
  15618. Add(' end;');
  15619. Add(' a:=test1.c.new;');
  15620. Add(' a:=test1.c.new();');
  15621. Add(' a:=A.c.new();');
  15622. ConvertProgram;
  15623. CheckSource('TestExternalClass_ClassOf_New',
  15624. LinesToStr([ // statements
  15625. 'this.A = null;',
  15626. 'this.C = null;',
  15627. '']),
  15628. LinesToStr([ // $mod.$main
  15629. '$mod.A = new $mod.C();',
  15630. '$mod.A = new $mod.C();',
  15631. 'var $with1 = $mod.C;',
  15632. '$mod.A = new $with1();',
  15633. '$mod.A = new $with1();',
  15634. '$mod.A = new $mod.C();',
  15635. '$mod.A = new $mod.C();',
  15636. '$mod.A = new $mod.A.C();',
  15637. '']));
  15638. end;
  15639. procedure TTestModule.TestExternalClass_FuncClassOf_New;
  15640. begin
  15641. StartProgram(false);
  15642. Add([
  15643. '{$modeswitch externalclass}',
  15644. 'type',
  15645. ' TExtAClass = class of TExtA;',
  15646. ' TExtA = class external name ''ExtA''',
  15647. ' constructor New;',
  15648. ' end;',
  15649. 'function GetCreator: TExtAClass;',
  15650. 'begin',
  15651. ' Result:=TExtA;',
  15652. 'end;',
  15653. 'var',
  15654. ' A: texta;',
  15655. 'begin',
  15656. ' a:=getcreator.new;',
  15657. ' a:=getcreator().new;',
  15658. ' a:=getcreator().new();',
  15659. ' a:=getcreator.new();',
  15660. ' with getcreator do begin',
  15661. ' a:=new;',
  15662. ' a:=new();',
  15663. ' end;']);
  15664. ConvertProgram;
  15665. CheckSource('TestExternalClass_FuncClassOf_New',
  15666. LinesToStr([ // statements
  15667. 'this.GetCreator = function () {',
  15668. ' var Result = null;',
  15669. ' Result = ExtA;',
  15670. ' return Result;',
  15671. '};',
  15672. 'this.A = null;',
  15673. '']),
  15674. LinesToStr([ // $mod.$main
  15675. '$mod.A = new ($mod.GetCreator())();',
  15676. '$mod.A = new ($mod.GetCreator())();',
  15677. '$mod.A = new ($mod.GetCreator())();',
  15678. '$mod.A = new ($mod.GetCreator())();',
  15679. 'var $with1 = $mod.GetCreator();',
  15680. '$mod.A = new $with1();',
  15681. '$mod.A = new $with1();',
  15682. '']));
  15683. end;
  15684. procedure TTestModule.TestExternalClass_New_PasClassFail;
  15685. begin
  15686. StartProgram(false);
  15687. Add([
  15688. '{$modeswitch externalclass}',
  15689. 'type',
  15690. ' TExtA = class external name ''ExtA''',
  15691. ' constructor New;',
  15692. ' end;',
  15693. ' TBird = class(TExtA)',
  15694. ' end;',
  15695. 'begin',
  15696. ' TBird.new;',
  15697. '']);
  15698. SetExpectedPasResolverError(sJSNewNotSupported,nJSNewNotSupported);
  15699. ConvertProgram;
  15700. end;
  15701. procedure TTestModule.TestExternalClass_New_PasClassBracketsFail;
  15702. begin
  15703. StartProgram(false);
  15704. Add([
  15705. '{$modeswitch externalclass}',
  15706. 'type',
  15707. ' TExtA = class external name ''ExtA''',
  15708. ' constructor New;',
  15709. ' end;',
  15710. ' TBird = class(TExtA)',
  15711. ' end;',
  15712. 'begin',
  15713. ' TBird.new();',
  15714. '']);
  15715. SetExpectedPasResolverError(sJSNewNotSupported,nJSNewNotSupported);
  15716. ConvertProgram;
  15717. end;
  15718. procedure TTestModule.TestExternalClass_LocalConstSameName;
  15719. begin
  15720. StartProgram(false);
  15721. Add('{$modeswitch externalclass}');
  15722. Add('type');
  15723. Add(' TExtA = class external name ''ExtA''');
  15724. Add(' constructor New;');
  15725. Add(' end;');
  15726. Add('function DoIt: longint;');
  15727. Add('const ExtA: longint = 3;');
  15728. Add('begin');
  15729. Add(' Result:=ExtA;');
  15730. Add('end;');
  15731. Add('var');
  15732. Add(' A: texta;');
  15733. Add('begin');
  15734. Add(' a:=texta.new;');
  15735. ConvertProgram;
  15736. CheckSource('TestExternalClass_LocalConstSameName',
  15737. LinesToStr([ // statements
  15738. 'var ExtA$1 = 3;',
  15739. 'this.DoIt = function () {',
  15740. ' var Result = 0;',
  15741. ' Result = ExtA$1;',
  15742. ' return Result;',
  15743. '};',
  15744. 'this.A = null;',
  15745. '']),
  15746. LinesToStr([ // $mod.$main
  15747. '$mod.A = new ExtA();',
  15748. '']));
  15749. end;
  15750. procedure TTestModule.TestExternalClass_ReintroduceOverload;
  15751. begin
  15752. StartProgram(false);
  15753. Add('{$modeswitch externalclass}');
  15754. Add('type');
  15755. Add(' TExtA = class external name ''ExtA''');
  15756. Add(' procedure DoIt;');
  15757. Add(' end;');
  15758. Add(' TMyA = class(TExtA)');
  15759. Add(' procedure DoIt;');
  15760. Add(' end;');
  15761. Add('procedure TMyA.DoIt; begin end;');
  15762. Add('begin');
  15763. ConvertProgram;
  15764. CheckSource('TestExternalClass_ReintroduceOverload',
  15765. LinesToStr([ // statements
  15766. 'rtl.createClassExt($mod, "TMyA", ExtA, "", function () {',
  15767. ' this.$init = function () {',
  15768. ' };',
  15769. ' this.$final = function () {',
  15770. ' };',
  15771. ' this.DoIt$1 = function () {',
  15772. ' };',
  15773. '});',
  15774. '']),
  15775. LinesToStr([ // $mod.$main
  15776. '']));
  15777. end;
  15778. procedure TTestModule.TestExternalClass_Inherited;
  15779. begin
  15780. StartProgram(false);
  15781. Add('{$modeswitch externalclass}');
  15782. Add('type');
  15783. Add(' TExtA = class external name ''ExtA''');
  15784. Add(' procedure DoIt(i: longint = 1); virtual;');
  15785. Add(' procedure DoSome(j: longint = 2);');
  15786. Add(' end;');
  15787. Add(' TExtB = class external name ''ExtB''(TExtA)');
  15788. Add(' end;');
  15789. Add(' TMyC = class(TExtB)');
  15790. Add(' procedure DoIt(i: longint = 1); override;');
  15791. Add(' procedure DoSome(j: longint = 2); reintroduce;');
  15792. Add(' end;');
  15793. Add('procedure TMyC.DoIt(i: longint);');
  15794. Add('begin');
  15795. Add(' inherited;');
  15796. Add(' inherited DoIt;');
  15797. Add(' inherited DoIt();');
  15798. Add(' inherited DoIt(3);');
  15799. Add(' inherited DoSome;');
  15800. Add(' inherited DoSome();');
  15801. Add(' inherited DoSome(4);');
  15802. Add('end;');
  15803. Add('procedure TMyC.DoSome(j: longint);');
  15804. Add('begin');
  15805. Add(' inherited;');
  15806. Add('end;');
  15807. Add('begin');
  15808. ConvertProgram;
  15809. CheckSource('TestExternalClass_ReintroduceOverload',
  15810. LinesToStr([ // statements
  15811. 'rtl.createClassExt($mod, "TMyC", ExtB, "", function () {',
  15812. ' this.$init = function () {',
  15813. ' };',
  15814. ' this.$final = function () {',
  15815. ' };',
  15816. ' this.DoIt = function (i) {',
  15817. ' ExtB.DoIt.apply(this, arguments);',
  15818. ' ExtB.DoIt.call(this, 1);',
  15819. ' ExtB.DoIt.call(this, 1);',
  15820. ' ExtB.DoIt.call(this, 3);',
  15821. ' ExtB.DoSome.call(this, 2);',
  15822. ' ExtB.DoSome.call(this, 2);',
  15823. ' ExtB.DoSome.call(this, 4);',
  15824. ' };',
  15825. ' this.DoSome$1 = function (j) {',
  15826. ' ExtB.DoSome.apply(this, arguments);',
  15827. ' };',
  15828. '});',
  15829. '']),
  15830. LinesToStr([ // $mod.$main
  15831. '']));
  15832. end;
  15833. procedure TTestModule.TestExternalClass_PascalAncestorFail;
  15834. begin
  15835. StartProgram(false);
  15836. Add('{$modeswitch externalclass}');
  15837. Add('type');
  15838. Add(' TObject = class');
  15839. Add(' end;');
  15840. Add(' TExtA = class external name ''ExtA''(TObject)');
  15841. Add(' end;');
  15842. Add('begin');
  15843. SetExpectedPasResolverError('Ancestor "TObject" is not external',nAncestorIsNotExternal);
  15844. ConvertProgram;
  15845. end;
  15846. procedure TTestModule.TestExternalClass_NewInstance;
  15847. begin
  15848. StartProgram(false);
  15849. Add('{$modeswitch externalclass}');
  15850. Add('type');
  15851. Add(' TExtA = class external name ''ExtA''');
  15852. Add(' end;');
  15853. Add(' TMyB = class(TExtA)');
  15854. Add(' protected');
  15855. Add(' class function NewInstance(fnname: string; const paramarray): TMyB; virtual;');
  15856. Add(' end;');
  15857. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  15858. Add('begin end;');
  15859. Add('begin');
  15860. ConvertProgram;
  15861. CheckSource('TestExternalClass_NewInstance',
  15862. LinesToStr([ // statements
  15863. 'rtl.createClassExt($mod, "TMyB", ExtA, "NewInstance", function () {',
  15864. ' this.$init = function () {',
  15865. ' };',
  15866. ' this.$final = function () {',
  15867. ' };',
  15868. ' this.NewInstance = function (fnname, paramarray) {',
  15869. ' var Result = null;',
  15870. ' return Result;',
  15871. ' };',
  15872. '});',
  15873. '']),
  15874. LinesToStr([ // $mod.$main
  15875. '']));
  15876. end;
  15877. procedure TTestModule.TestExternalClass_NewInstance_NonVirtualFail;
  15878. begin
  15879. StartProgram(false);
  15880. Add('{$modeswitch externalclass}');
  15881. Add('type');
  15882. Add(' TExtA = class external name ''ExtA''');
  15883. Add(' end;');
  15884. Add(' TMyB = class(TExtA)');
  15885. Add(' protected');
  15886. Add(' class function NewInstance(fnname: string; const paramarray): TMyB;');
  15887. Add(' end;');
  15888. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  15889. Add('begin end;');
  15890. Add('begin');
  15891. SetExpectedPasResolverError(sNewInstanceFunctionMustBeVirtual,nNewInstanceFunctionMustBeVirtual);
  15892. ConvertProgram;
  15893. end;
  15894. procedure TTestModule.TestExternalClass_NewInstance_FirstParamNotString_Fail;
  15895. begin
  15896. StartProgram(false);
  15897. Add('{$modeswitch externalclass}');
  15898. Add('type');
  15899. Add(' TExtA = class external name ''ExtA''');
  15900. Add(' end;');
  15901. Add(' TMyB = class(TExtA)');
  15902. Add(' protected');
  15903. Add(' class function NewInstance(fnname: longint; const paramarray): TMyB; virtual;');
  15904. Add(' end;');
  15905. Add('class function TMyB.NewInstance(fnname: longint; const paramarray): TMyB;');
  15906. Add('begin end;');
  15907. Add('begin');
  15908. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Longint", expected "String"',
  15909. nIncompatibleTypeArgNo);
  15910. ConvertProgram;
  15911. end;
  15912. procedure TTestModule.TestExternalClass_NewInstance_SecondParamTyped_Fail;
  15913. begin
  15914. StartProgram(false);
  15915. Add('{$modeswitch externalclass}');
  15916. Add('type');
  15917. Add(' TExtA = class external name ''ExtA''');
  15918. Add(' end;');
  15919. Add(' TMyB = class(TExtA)');
  15920. Add(' protected');
  15921. Add(' class function NewInstance(fnname: string; const paramarray: string): TMyB; virtual;');
  15922. Add(' end;');
  15923. Add('class function TMyB.NewInstance(fnname: string; const paramarray: string): TMyB;');
  15924. Add('begin end;');
  15925. Add('begin');
  15926. SetExpectedPasResolverError('Incompatible type arg no. 2: Got "type", expected "untyped"',
  15927. nIncompatibleTypeArgNo);
  15928. ConvertProgram;
  15929. end;
  15930. procedure TTestModule.TestExternalClass_PascalProperty;
  15931. begin
  15932. StartProgram(false);
  15933. Add('{$modeswitch externalclass}');
  15934. Add('type');
  15935. Add(' TJSElement = class;');
  15936. Add(' TJSNotifyEvent = procedure(Sender: TJSElement) of object;');
  15937. Add(' TJSElement = class external name ''ExtA''');
  15938. Add(' end;');
  15939. Add(' TControl = class(TJSElement)');
  15940. Add(' private');
  15941. Add(' FOnClick: TJSNotifyEvent;');
  15942. Add(' property OnClick: TJSNotifyEvent read FOnClick write FOnClick;');
  15943. Add(' procedure Click(Sender: TJSElement);');
  15944. Add(' end;');
  15945. Add('procedure TControl.Click(Sender: TJSElement);');
  15946. Add('begin');
  15947. Add(' OnClick(Self);');
  15948. Add('end;');
  15949. Add('var');
  15950. Add(' Ctrl: TControl;');
  15951. Add('begin');
  15952. Add(' Ctrl.OnClick:[email protected];');
  15953. Add(' Ctrl.OnClick(Ctrl);');
  15954. ConvertProgram;
  15955. CheckSource('TestExternalClass_PascalProperty',
  15956. LinesToStr([ // statements
  15957. 'rtl.createClassExt($mod, "TControl", ExtA, "", function () {',
  15958. ' this.$init = function () {',
  15959. ' this.FOnClick = null;',
  15960. ' };',
  15961. ' this.$final = function () {',
  15962. ' this.FOnClick = undefined;',
  15963. ' };',
  15964. ' this.Click = function (Sender) {',
  15965. ' this.FOnClick(this);',
  15966. ' };',
  15967. '});',
  15968. 'this.Ctrl = null;',
  15969. '']),
  15970. LinesToStr([ // $mod.$main
  15971. '$mod.Ctrl.FOnClick = rtl.createCallback($mod.Ctrl, "Click");',
  15972. '$mod.Ctrl.FOnClick($mod.Ctrl);',
  15973. '']));
  15974. end;
  15975. procedure TTestModule.TestExternalClass_TypeCastToRootClass;
  15976. begin
  15977. StartProgram(false);
  15978. Add([
  15979. '{$modeswitch externalclass}',
  15980. 'type',
  15981. ' IUnknown = interface end;',
  15982. ' TObject = class',
  15983. ' end;',
  15984. ' TChild = class',
  15985. ' end;',
  15986. ' TExtRootA = class external name ''ExtRootA''',
  15987. ' end;',
  15988. ' TExtChildA = class external name ''ExtChildA''(TExtRootA)',
  15989. ' end;',
  15990. ' TExtRootB = class external name ''ExtRootB''',
  15991. ' end;',
  15992. ' TExtChildB = class external name ''ExtChildB''(TExtRootB)',
  15993. ' end;',
  15994. 'var',
  15995. ' Obj: TObject;',
  15996. ' Child: TChild;',
  15997. ' RootA: TExtRootA;',
  15998. ' ChildA: TExtChildA;',
  15999. ' RootB: TExtRootB;',
  16000. ' ChildB: TExtChildB;',
  16001. ' i: IUnknown;',
  16002. 'begin',
  16003. ' obj:=tobject(roota);',
  16004. ' obj:=tobject(childa);',
  16005. ' child:=tchild(tobject(roota));',
  16006. ' roota:=textroota(obj);',
  16007. ' roota:=textroota(child);',
  16008. ' roota:=textroota(rootb);',
  16009. ' roota:=textroota(childb);',
  16010. ' childa:=textchilda(textroota(obj));',
  16011. ' roota:=TExtRootA(i)',
  16012. '']);
  16013. ConvertProgram;
  16014. CheckSource('TestExternalClass_TypeCastToRootClass',
  16015. LinesToStr([ // statements
  16016. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  16017. 'rtl.createClass($mod, "TObject", null, function () {',
  16018. ' this.$init = function () {',
  16019. ' };',
  16020. ' this.$final = function () {',
  16021. ' };',
  16022. '});',
  16023. 'rtl.createClass($mod, "TChild", $mod.TObject, function () {',
  16024. '});',
  16025. 'this.Obj = null;',
  16026. 'this.Child = null;',
  16027. 'this.RootA = null;',
  16028. 'this.ChildA = null;',
  16029. 'this.RootB = null;',
  16030. 'this.ChildB = null;',
  16031. 'this.i = null;',
  16032. '']),
  16033. LinesToStr([ // $mod.$main
  16034. '$mod.Obj = $mod.RootA;',
  16035. '$mod.Obj = $mod.ChildA;',
  16036. '$mod.Child = $mod.RootA;',
  16037. '$mod.RootA = $mod.Obj;',
  16038. '$mod.RootA = $mod.Child;',
  16039. '$mod.RootA = $mod.RootB;',
  16040. '$mod.RootA = $mod.ChildB;',
  16041. '$mod.ChildA = $mod.Obj;',
  16042. '$mod.RootA = $mod.i;',
  16043. '']));
  16044. end;
  16045. procedure TTestModule.TestExternalClass_TypeCastToJSObject;
  16046. begin
  16047. StartProgram(false);
  16048. Add([
  16049. '{$modeswitch externalclass}',
  16050. 'type',
  16051. ' IUnknown = interface end;',
  16052. ' IBird = interface(IUnknown) end;',
  16053. ' TClass = class of TObject;',
  16054. ' TObject = class',
  16055. ' end;',
  16056. ' TChild = class',
  16057. ' end;',
  16058. ' TJSObject = class external name ''Object''',
  16059. ' end;',
  16060. ' TRec = record end;',
  16061. 'var',
  16062. ' Obj: TObject;',
  16063. ' Child: TChild;',
  16064. ' i: IUnknown;',
  16065. ' Bird: IBird;',
  16066. ' j: TJSObject;',
  16067. ' r: TRec;',
  16068. ' c: TClass;',
  16069. 'begin',
  16070. ' j:=tjsobject(IUnknown);',
  16071. ' j:=tjsobject(IBird);',
  16072. ' j:=tjsobject(TObject);',
  16073. ' j:=tjsobject(TChild);',
  16074. ' j:=tjsobject(TRec);',
  16075. ' j:=tjsobject(Obj);',
  16076. ' j:=tjsobject(Child);',
  16077. ' j:=tjsobject(i);',
  16078. ' j:=tjsobject(Bird);',
  16079. ' j:=tjsobject(r);',
  16080. ' j:=tjsobject(c);',
  16081. '']);
  16082. ConvertProgram;
  16083. CheckSource('TestExternalClass_TypeCastToJSObject',
  16084. LinesToStr([ // statements
  16085. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  16086. 'rtl.createInterface($mod, "IBird", "{4B0D080B-C0F6-396E-AE88-000B87785074}", [], $mod.IUnknown);',
  16087. 'rtl.createClass($mod, "TObject", null, function () {',
  16088. ' this.$init = function () {',
  16089. ' };',
  16090. ' this.$final = function () {',
  16091. ' };',
  16092. '});',
  16093. 'rtl.createClass($mod, "TChild", $mod.TObject, function () {',
  16094. '});',
  16095. 'rtl.recNewT($mod, "TRec", function () {',
  16096. ' this.$eq = function (b) {',
  16097. ' return true;',
  16098. ' };',
  16099. ' this.$assign = function (s) {',
  16100. ' return this;',
  16101. ' };',
  16102. '});',
  16103. 'this.Obj = null;',
  16104. 'this.Child = null;',
  16105. 'this.i = null;',
  16106. 'this.Bird = null;',
  16107. 'this.j = null;',
  16108. 'this.r = $mod.TRec.$new();',
  16109. 'this.c = null;',
  16110. '']),
  16111. LinesToStr([ // $mod.$main
  16112. '$mod.j = $mod.IUnknown;',
  16113. '$mod.j = $mod.IBird;',
  16114. '$mod.j = $mod.TObject;',
  16115. '$mod.j = $mod.TChild;',
  16116. '$mod.j = $mod.TRec;',
  16117. '$mod.j = $mod.Obj;',
  16118. '$mod.j = $mod.Child;',
  16119. '$mod.j = $mod.i;',
  16120. '$mod.j = $mod.Bird;',
  16121. '$mod.j = $mod.r;',
  16122. '$mod.j = $mod.c;',
  16123. '']));
  16124. end;
  16125. procedure TTestModule.TestExternalClass_TypeCastStringToExternalString;
  16126. begin
  16127. StartProgram(false);
  16128. Add('{$modeswitch externalclass}');
  16129. Add('type');
  16130. Add(' TJSString = class external name ''String''');
  16131. Add(' class function fromCharCode() : string; varargs;');
  16132. Add(' function anchor(const aName : string) : string;');
  16133. Add(' end;');
  16134. Add('var');
  16135. Add(' s: string;');
  16136. Add('begin');
  16137. Add(' s:=TJSString.fromCharCode(65,66);');
  16138. Add(' s:=TJSString(s).anchor(s);');
  16139. Add(' s:=TJSString(''foo'').anchor(s);');
  16140. ConvertProgram;
  16141. CheckSource('TestExternalClass_TypeCastStringToExternalString',
  16142. LinesToStr([ // statements
  16143. 'this.s = "";',
  16144. '']),
  16145. LinesToStr([ // $mod.$main
  16146. '$mod.s = String.fromCharCode(65, 66);',
  16147. '$mod.s = $mod.s.anchor($mod.s);',
  16148. '$mod.s = "foo".anchor($mod.s);',
  16149. '']));
  16150. end;
  16151. procedure TTestModule.TestExternalClass_TypeCastToJSFunction;
  16152. begin
  16153. StartProgram(false);
  16154. Add([
  16155. '{$modeswitch externalclass}',
  16156. 'type',
  16157. ' TJSObject = class external name ''Object'' end;',
  16158. ' TJSFunction = class external name ''Function''',
  16159. ' function bind(thisArg: TJSObject): TJSFunction; varargs;',
  16160. ' function call(thisArg: TJSObject): JSValue; varargs;',
  16161. ' end;',
  16162. ' TObject = class',
  16163. ' procedure DoIt(i: longint);',
  16164. ' end;',
  16165. ' TFuncInt = function(o: TObject): longint;',
  16166. 'function GetIt(o: TObject): longint;',
  16167. ' procedure Sub; begin end;',
  16168. 'var',
  16169. ' f: TJSFunction;',
  16170. ' fi: TFuncInt;',
  16171. 'begin',
  16172. ' fi:=TFuncInt(f);',
  16173. ' f:=TJSFunction(fi);',
  16174. ' f:=TJSFunction(@GetIt);',
  16175. ' f:=TJSFunction(@GetIt).bind(nil,3);',
  16176. ' f:=TJSFunction(@Sub);',
  16177. ' f:=TJSFunction(@o.doit);',
  16178. ' f:=TJSFunction(fi).bind(nil,4)',
  16179. 'end;',
  16180. 'procedure TObject.DoIt(i: longint);',
  16181. ' procedure Sub; begin end;',
  16182. 'var f: TJSFunction;',
  16183. 'begin',
  16184. ' f:=TJSFunction(@DoIt);',
  16185. ' f:=TJSFunction(@DoIt).bind(nil,13);',
  16186. ' f:=TJSFunction(@Sub);',
  16187. ' f:=TJSFunction(@GetIt);',
  16188. 'end;',
  16189. 'begin']);
  16190. ConvertProgram;
  16191. CheckSource('TestExternalClass_TypeCastToJSFunction',
  16192. LinesToStr([ // statements
  16193. 'rtl.createClass($mod, "TObject", null, function () {',
  16194. ' this.$init = function () {',
  16195. ' };',
  16196. ' this.$final = function () {',
  16197. ' };',
  16198. ' this.DoIt = function (i) {',
  16199. ' var $Self = this;',
  16200. ' function Sub() {',
  16201. ' };',
  16202. ' var f = null;',
  16203. ' f = rtl.createCallback($Self, "DoIt");',
  16204. ' f = rtl.createCallback($Self, "DoIt").bind(null, 13);',
  16205. ' f = Sub;',
  16206. ' f = $mod.GetIt;',
  16207. ' };',
  16208. '});',
  16209. 'this.GetIt = function (o) {',
  16210. ' var Result = 0;',
  16211. ' function Sub() {',
  16212. ' };',
  16213. ' var f = null;',
  16214. ' var fi = null;',
  16215. ' fi = f;',
  16216. ' f = fi;',
  16217. ' f = $mod.GetIt;',
  16218. ' f = $mod.GetIt.bind(null, 3);',
  16219. ' f = Sub;',
  16220. ' f = rtl.createCallback(o, "DoIt");',
  16221. ' f = fi.bind(null, 4);',
  16222. ' return Result;',
  16223. '};',
  16224. '']),
  16225. LinesToStr([ // $mod.$main
  16226. '']));
  16227. end;
  16228. procedure TTestModule.TestExternalClass_TypeCastDelphiUnrelated;
  16229. begin
  16230. StartProgram(false);
  16231. Add([
  16232. '{$mode delphi}',
  16233. '{$modeswitch externalclass}',
  16234. 'type',
  16235. ' TJSObject = class external name ''Object'' end;',
  16236. ' TJSWindow = class external name ''Window''(TJSObject)',
  16237. ' procedure Open;',
  16238. ' end;',
  16239. ' TJSEventTarget = class external name ''Event''(TJSObject)',
  16240. ' procedure Execute;',
  16241. ' end;',
  16242. 'procedure Fly;',
  16243. 'var',
  16244. ' w: TJSWindow;',
  16245. ' e: TJSEventTarget;',
  16246. 'begin',
  16247. ' w:=TJSWindow(e);',
  16248. ' e:=TJSEventTarget(w);',
  16249. 'end;',
  16250. 'begin']);
  16251. ConvertProgram;
  16252. CheckSource('TestExternalClass_TypeCastDelphiUnrelated',
  16253. LinesToStr([ // statements
  16254. 'this.Fly = function () {',
  16255. ' var w = null;',
  16256. ' var e = null;',
  16257. ' w = e;',
  16258. ' e = w;',
  16259. '};',
  16260. '']),
  16261. LinesToStr([ // $mod.$main
  16262. '']));
  16263. end;
  16264. procedure TTestModule.TestExternalClass_CallClassFunctionOfInstanceFail;
  16265. begin
  16266. StartProgram(false);
  16267. Add('{$modeswitch externalclass}');
  16268. Add('type');
  16269. Add(' TJSString = class external name ''String''');
  16270. Add(' class function fromCharCode() : string; varargs;');
  16271. Add(' end;');
  16272. Add('var');
  16273. Add(' s: string;');
  16274. Add(' sObj: TJSString;');
  16275. Add('begin');
  16276. Add(' s:=sObj.fromCharCode(65,66);');
  16277. SetExpectedPasResolverError('External class instance cannot access static class function fromCharCode',
  16278. nExternalClassInstanceCannotAccessStaticX);
  16279. ConvertProgram;
  16280. end;
  16281. procedure TTestModule.TestExternalClass_BracketAccessor;
  16282. begin
  16283. StartProgram(false);
  16284. Add([
  16285. '{$modeswitch externalclass}',
  16286. 'type',
  16287. ' TJSArray = class external name ''Array2''',
  16288. ' function GetItems(Index: longint): jsvalue; external name ''[]'';',
  16289. ' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';',
  16290. ' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;',
  16291. ' end;',
  16292. 'procedure DoIt(vI: JSValue; const vJ: jsvalue; var vK: jsvalue; out vL: jsvalue);',
  16293. 'begin end;',
  16294. 'var',
  16295. ' Arr: tjsarray;',
  16296. ' s: string;',
  16297. ' i: longint;',
  16298. ' v: jsvalue;',
  16299. 'begin',
  16300. ' v:=arr[0];',
  16301. ' v:=arr.items[1];',
  16302. ' arr[2]:=s;',
  16303. ' arr.items[3]:=s;',
  16304. ' arr[4]:=i;',
  16305. ' arr[5]:=arr[6];',
  16306. ' arr.items[7]:=arr.items[8];',
  16307. ' with arr do items[9]:=items[10];',
  16308. ' doit(arr[7],arr[8],arr[9],arr[10]);',
  16309. ' with arr do begin',
  16310. ' v:=GetItems(14);',
  16311. ' setitems(15,16);',
  16312. ' end;',
  16313. ' v:=test1.arr.items[17];',
  16314. ' test1.arr.items[18]:=v;',
  16315. '']);
  16316. ConvertProgram;
  16317. CheckSource('TestExternalClass_BracketAccessor',
  16318. LinesToStr([ // statements
  16319. 'this.DoIt = function (vI, vJ, vK, vL) {',
  16320. '};',
  16321. 'this.Arr = null;',
  16322. 'this.s = "";',
  16323. 'this.i = 0;',
  16324. 'this.v = undefined;',
  16325. '']),
  16326. LinesToStr([ // $mod.$main
  16327. '$mod.v = $mod.Arr[0];',
  16328. '$mod.v = $mod.Arr[1];',
  16329. '$mod.Arr[2] = $mod.s;',
  16330. '$mod.Arr[3] = $mod.s;',
  16331. '$mod.Arr[4] = $mod.i;',
  16332. '$mod.Arr[5] = $mod.Arr[6];',
  16333. '$mod.Arr[7] = $mod.Arr[8];',
  16334. 'var $with1 = $mod.Arr;',
  16335. '$with1[9] = $with1[10];',
  16336. '$mod.DoIt($mod.Arr[7], $mod.Arr[8], {',
  16337. ' a: 9,',
  16338. ' p: $mod.Arr,',
  16339. ' get: function () {',
  16340. ' return this.p[this.a];',
  16341. ' },',
  16342. ' set: function (v) {',
  16343. ' this.p[this.a] = v;',
  16344. ' }',
  16345. '}, {',
  16346. ' a: 10,',
  16347. ' p: $mod.Arr,',
  16348. ' get: function () {',
  16349. ' return this.p[this.a];',
  16350. ' },',
  16351. ' set: function (v) {',
  16352. ' this.p[this.a] = v;',
  16353. ' }',
  16354. '});',
  16355. 'var $with2 = $mod.Arr;',
  16356. '$mod.v = $with2[14];',
  16357. '$with2[15] = 16;',
  16358. '$mod.v = $mod.Arr[17];',
  16359. '$mod.Arr[18] = $mod.v;',
  16360. '']));
  16361. end;
  16362. procedure TTestModule.TestExternalClass_BracketAccessor_Call;
  16363. begin
  16364. StartProgram(false);
  16365. Add([
  16366. '{$modeswitch externalclass}',
  16367. 'type',
  16368. ' TJSArray = class external name ''Array2''',
  16369. ' function GetItems(Index: longint): jsvalue; external name ''[]'';',
  16370. ' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';',
  16371. ' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;',
  16372. ' end;',
  16373. ' TMyArr = class(TJSArray)',
  16374. ' procedure DoIt;',
  16375. ' end;',
  16376. 'procedure tmyarr.DoIt;',
  16377. 'begin',
  16378. ' Items[1]:=Items[2];',
  16379. ' SetItems(3,getItems(4));',
  16380. 'end;',
  16381. 'var',
  16382. ' Arr: tmyarr;',
  16383. ' s: string;',
  16384. ' i: longint;',
  16385. ' v: jsvalue;',
  16386. 'begin',
  16387. ' v:=arr[0];',
  16388. ' v:=arr.items[1];',
  16389. ' arr[2]:=s;',
  16390. ' arr.items[3]:=s;',
  16391. ' arr[4]:=i;',
  16392. ' arr[5]:=arr[6];',
  16393. ' arr.items[7]:=arr.items[8];',
  16394. ' with arr do items[9]:=items[10];',
  16395. ' with arr do begin',
  16396. ' v:=GetItems(14);',
  16397. ' setitems(15,16);',
  16398. ' end;',
  16399. '']);
  16400. ConvertProgram;
  16401. CheckSource('TestExternalClass_BracketAccessor_Call',
  16402. LinesToStr([ // statements
  16403. 'rtl.createClassExt($mod, "TMyArr", Array2, "", function () {',
  16404. ' this.$init = function () {',
  16405. ' };',
  16406. ' this.$final = function () {',
  16407. ' };',
  16408. ' this.DoIt = function () {',
  16409. ' this[1] = this[2];',
  16410. ' this[3] = this[4];',
  16411. ' };',
  16412. '});',
  16413. 'this.Arr = null;',
  16414. 'this.s = "";',
  16415. 'this.i = 0;',
  16416. 'this.v = undefined;',
  16417. '']),
  16418. LinesToStr([ // $mod.$main
  16419. '$mod.v = $mod.Arr[0];',
  16420. '$mod.v = $mod.Arr[1];',
  16421. '$mod.Arr[2] = $mod.s;',
  16422. '$mod.Arr[3] = $mod.s;',
  16423. '$mod.Arr[4] = $mod.i;',
  16424. '$mod.Arr[5] = $mod.Arr[6];',
  16425. '$mod.Arr[7] = $mod.Arr[8];',
  16426. 'var $with1 = $mod.Arr;',
  16427. '$with1[9] = $with1[10];',
  16428. 'var $with2 = $mod.Arr;',
  16429. '$mod.v = $with2[14];',
  16430. '$with2[15] = 16;',
  16431. '']));
  16432. end;
  16433. procedure TTestModule.TestExternalClass_BracketAccessor_2ParamsFail;
  16434. begin
  16435. StartProgram(false);
  16436. Add('{$modeswitch externalclass}');
  16437. Add('type');
  16438. Add(' TJSArray = class external name ''Array2''');
  16439. Add(' function GetItems(Index1, Index2: longint): jsvalue; external name ''[]'';');
  16440. Add(' procedure SetItems(Index1, Index2: longint; Value: jsvalue); external name ''[]'';');
  16441. Add(' property Items[Index1, Index2: longint]: jsvalue read GetItems write SetItems; default;');
  16442. Add(' end;');
  16443. Add('begin');
  16444. SetExpectedPasResolverError(sBracketAccessorOfExternalClassMustHaveOneParameter,
  16445. nBracketAccessorOfExternalClassMustHaveOneParameter);
  16446. ConvertProgram;
  16447. end;
  16448. procedure TTestModule.TestExternalClass_BracketAccessor_ReadOnly;
  16449. begin
  16450. StartProgram(false);
  16451. Add('{$modeswitch externalclass}');
  16452. Add('type');
  16453. Add(' TJSArray = class external name ''Array2''');
  16454. Add(' function GetItems(Index: longint): jsvalue; external name ''[]'';');
  16455. Add(' property Items[Index: longint]: jsvalue read GetItems; default;');
  16456. Add(' end;');
  16457. Add('procedure DoIt(vI: JSValue; const vJ: jsvalue);');
  16458. Add('begin end;');
  16459. Add('var');
  16460. Add(' Arr: tjsarray;');
  16461. Add(' v: jsvalue;');
  16462. Add('begin');
  16463. Add(' v:=arr[0];');
  16464. Add(' v:=arr.items[1];');
  16465. Add(' with arr do v:=items[2];');
  16466. Add(' doit(arr[3],arr[4]);');
  16467. ConvertProgram;
  16468. CheckSource('TestExternalClass_BracketAccessor_ReadOnly',
  16469. LinesToStr([ // statements
  16470. 'this.DoIt = function (vI, vJ) {',
  16471. '};',
  16472. 'this.Arr = null;',
  16473. 'this.v = undefined;',
  16474. '']),
  16475. LinesToStr([ // $mod.$main
  16476. '$mod.v = $mod.Arr[0];',
  16477. '$mod.v = $mod.Arr[1];',
  16478. 'var $with1 = $mod.Arr;',
  16479. '$mod.v = $with1[2];',
  16480. '$mod.DoIt($mod.Arr[3], $mod.Arr[4]);',
  16481. '']));
  16482. end;
  16483. procedure TTestModule.TestExternalClass_BracketAccessor_WriteOnly;
  16484. begin
  16485. StartProgram(false);
  16486. Add('{$modeswitch externalclass}');
  16487. Add('type');
  16488. Add(' TJSArray = class external name ''Array2''');
  16489. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  16490. Add(' property Items[Index: longint]: jsvalue write SetItems; default;');
  16491. Add(' end;');
  16492. Add('var');
  16493. Add(' Arr: tjsarray;');
  16494. Add(' s: string;');
  16495. Add(' i: longint;');
  16496. Add(' v: jsvalue;');
  16497. Add('begin');
  16498. Add(' arr[2]:=s;');
  16499. Add(' arr.items[3]:=s;');
  16500. Add(' arr[4]:=i;');
  16501. Add(' with arr do items[5]:=i;');
  16502. ConvertProgram;
  16503. CheckSource('TestExternalClass_BracketAccessor_WriteOnly',
  16504. LinesToStr([ // statements
  16505. 'this.Arr = null;',
  16506. 'this.s = "";',
  16507. 'this.i = 0;',
  16508. 'this.v = undefined;',
  16509. '']),
  16510. LinesToStr([ // $mod.$main
  16511. '$mod.Arr[2] = $mod.s;',
  16512. '$mod.Arr[3] = $mod.s;',
  16513. '$mod.Arr[4] = $mod.i;',
  16514. 'var $with1 = $mod.Arr;',
  16515. '$with1[5] = $mod.i;',
  16516. '']));
  16517. end;
  16518. procedure TTestModule.TestExternalClass_BracketAccessor_MultiType;
  16519. begin
  16520. StartProgram(false);
  16521. Add('{$modeswitch externalclass}');
  16522. Add('type');
  16523. Add(' TJSArray = class external name ''Array2''');
  16524. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  16525. Add(' property Items[Index: longint]: jsvalue write SetItems; default;');
  16526. Add(' procedure SetNumbers(Index: longint; Value: longint); external name ''[]'';');
  16527. Add(' property Numbers[Index: longint]: longint write SetNumbers;');
  16528. Add(' end;');
  16529. Add('var');
  16530. Add(' Arr: tjsarray;');
  16531. Add(' s: string;');
  16532. Add(' i: longint;');
  16533. Add(' v: jsvalue;');
  16534. Add('begin');
  16535. Add(' arr[2]:=s;');
  16536. Add(' arr.items[3]:=s;');
  16537. Add(' arr.numbers[4]:=i;');
  16538. Add(' with arr do items[5]:=i;');
  16539. Add(' with arr do numbers[6]:=i;');
  16540. ConvertProgram;
  16541. CheckSource('TestExternalClass_BracketAccessor_MultiType',
  16542. LinesToStr([ // statements
  16543. 'this.Arr = null;',
  16544. 'this.s = "";',
  16545. 'this.i = 0;',
  16546. 'this.v = undefined;',
  16547. '']),
  16548. LinesToStr([ // $mod.$main
  16549. '$mod.Arr[2] = $mod.s;',
  16550. '$mod.Arr[3] = $mod.s;',
  16551. '$mod.Arr[4] = $mod.i;',
  16552. 'var $with1 = $mod.Arr;',
  16553. '$with1[5] = $mod.i;',
  16554. 'var $with2 = $mod.Arr;',
  16555. '$with2[6] = $mod.i;',
  16556. '']));
  16557. end;
  16558. procedure TTestModule.TestExternalClass_BracketAccessor_Index;
  16559. begin
  16560. StartProgram(false);
  16561. Add('{$modeswitch externalclass}');
  16562. Add('type');
  16563. Add(' TJSArray = class external name ''Array2''');
  16564. Add(' function GetItems(Index: longint): jsvalue; external name ''[]'';');
  16565. Add(' procedure SetItems(Index: longint; Value: jsvalue); external name ''[]'';');
  16566. Add(' property Items[Index: longint]: jsvalue read GetItems write SetItems; default;');
  16567. Add(' end;');
  16568. Add('var');
  16569. Add(' Arr: tjsarray;');
  16570. Add(' i: longint;');
  16571. Add(' IntArr: array of longint;');
  16572. Add(' v: jsvalue;');
  16573. Add('begin');
  16574. Add(' v:=arr.items[i];');
  16575. Add(' arr[longint(v)]:=arr.items[intarr[0]];');
  16576. Add(' arr.items[intarr[1]]:=arr[IntArr[2]];');
  16577. ConvertProgram;
  16578. CheckSource('TestExternalClass_BracketAccessor_Index',
  16579. LinesToStr([ // statements
  16580. 'this.Arr = null;',
  16581. 'this.i = 0;',
  16582. 'this.IntArr = [];',
  16583. 'this.v = undefined;',
  16584. '']),
  16585. LinesToStr([ // $mod.$main
  16586. '$mod.v = $mod.Arr[$mod.i];',
  16587. '$mod.Arr[Math.floor($mod.v)] = $mod.Arr[$mod.IntArr[0]];',
  16588. '$mod.Arr[$mod.IntArr[1]] = $mod.Arr[$mod.IntArr[2]];',
  16589. '']));
  16590. end;
  16591. procedure TTestModule.TestExternalClass_ForInJSObject;
  16592. begin
  16593. StartProgram(false);
  16594. Add([
  16595. '{$modeswitch externalclass}',
  16596. 'type',
  16597. ' TJSObject = class external name ''Object''',
  16598. ' end;',
  16599. 'var',
  16600. ' o: TJSObject;',
  16601. ' key: string;',
  16602. 'begin',
  16603. ' for key in o do',
  16604. ' if key=''abc'' then ;',
  16605. '']);
  16606. ConvertProgram;
  16607. CheckSource('TestExternalClass_ForInJSObject',
  16608. LinesToStr([ // statements
  16609. 'this.o = null;',
  16610. 'this.key = "";',
  16611. '']),
  16612. LinesToStr([ // $mod.$main
  16613. 'for ($mod.key in $mod.o) if ($mod.key === "abc") ;',
  16614. '']));
  16615. end;
  16616. procedure TTestModule.TestExternalClass_ForInJSArray;
  16617. begin
  16618. StartProgram(false);
  16619. Add([
  16620. '{$modeswitch externalclass}',
  16621. 'type',
  16622. ' TJSInt8Array = class external name ''Int8Array''',
  16623. ' private',
  16624. ' flength: NativeInt external name ''length'';',
  16625. ' function getValue(Index: NativeInt): shortint; external name ''[]'';',
  16626. ' public',
  16627. ' property values[Index: NativeInt]: Shortint Read getValue; default;',
  16628. ' property Length: NativeInt read flength;',
  16629. ' end;',
  16630. 'var',
  16631. ' a: TJSInt8Array;',
  16632. ' value: shortint;',
  16633. 'begin',
  16634. ' for value in a do',
  16635. ' if value=3 then ;',
  16636. '']);
  16637. ConvertProgram;
  16638. CheckSource('TestExternalClass_ForInJSArray',
  16639. LinesToStr([ // statements
  16640. 'this.a = null;',
  16641. 'this.value = 0;',
  16642. '']),
  16643. LinesToStr([ // $mod.$main
  16644. 'for (var $in1 = $mod.a, $l2 = 0, $end3 = rtl.length($in1) - 1; $l2 <= $end3; $l2++) {',
  16645. ' $mod.value = $in1[$l2];',
  16646. ' if ($mod.value === 3) ;',
  16647. '};',
  16648. '']));
  16649. end;
  16650. procedure TTestModule.TestExternalClass_IncompatibleArgDuplicateIdentifier;
  16651. begin
  16652. AddModuleWithIntfImplSrc('unit2.pas',
  16653. LinesToStr([
  16654. '{$modeswitch externalclass}',
  16655. 'type',
  16656. ' TJSBufferSource = class external name ''BufferSource''',
  16657. ' end;',
  16658. 'procedure DoIt(s: TJSBufferSource); external name ''DoIt'';',
  16659. '']),
  16660. '');
  16661. AddModuleWithIntfImplSrc('unit3.pas',
  16662. LinesToStr([
  16663. '{$modeswitch externalclass}',
  16664. 'type',
  16665. ' TJSBufferSource = class external name ''BufferSource''',
  16666. ' end;',
  16667. '']),
  16668. '');
  16669. StartUnit(true);
  16670. Add([
  16671. 'interface',
  16672. 'uses unit2, unit3;',
  16673. 'procedure DoSome(s: TJSBufferSource);',
  16674. 'implementation',
  16675. 'procedure DoSome(s: TJSBufferSource);',
  16676. 'begin',
  16677. ' DoIt(s);',
  16678. 'end;',
  16679. '']);
  16680. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "unit3.TJSBufferSource", expected "unit2.TJSBufferSource"',
  16681. nIncompatibleTypeArgNo);
  16682. ConvertUnit;
  16683. end;
  16684. procedure TTestModule.TestClassInterface_Corba;
  16685. begin
  16686. StartProgram(false);
  16687. Add([
  16688. '{$interfaces corba}',
  16689. 'type',
  16690. ' IUnknown = interface;',
  16691. ' IUnknown = interface',
  16692. ' [''{00000000-0000-0000-C000-000000000046}'']',
  16693. ' end;',
  16694. ' IInterface = IUnknown;',
  16695. ' IBird = interface(IInterface)',
  16696. ' function GetSize: longint;',
  16697. ' procedure SetSize(i: longint);',
  16698. ' property Size: longint read GetSize write SetSize;',
  16699. ' procedure DoIt(i: longint);',
  16700. ' end;',
  16701. ' TObject = class',
  16702. ' end;',
  16703. ' TBird = class(TObject,IBird)',
  16704. ' function GetSize: longint; virtual; abstract;',
  16705. ' procedure SetSize(i: longint); virtual; abstract;',
  16706. ' procedure DoIt(i: longint); virtual; abstract;',
  16707. ' end;',
  16708. 'var',
  16709. ' BirdIntf: IBird;',
  16710. 'begin',
  16711. ' BirdIntf.Size:=BirdIntf.Size;',
  16712. '']);
  16713. ConvertProgram;
  16714. CheckSource('TestClassInterface_Corba',
  16715. LinesToStr([ // statements
  16716. 'rtl.createInterface($mod, "IUnknown", "{00000000-0000-0000-C000-000000000046}", [], null);',
  16717. 'rtl.createInterface($mod, "IBird", "{5BD1A53B-69BB-37EE-AF32-BEFB86D85B03}", ["GetSize", "SetSize", "DoIt"], $mod.IUnknown);',
  16718. 'rtl.createClass($mod, "TObject", null, function () {',
  16719. ' this.$init = function () {',
  16720. ' };',
  16721. ' this.$final = function () {',
  16722. ' };',
  16723. '});',
  16724. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16725. ' rtl.addIntf(this, $mod.IBird);',
  16726. '});',
  16727. 'this.BirdIntf = null;',
  16728. '']),
  16729. LinesToStr([ // $mod.$main
  16730. ' $mod.BirdIntf.SetSize($mod.BirdIntf.GetSize());',
  16731. '']));
  16732. end;
  16733. procedure TTestModule.TestClassInterface_ProcExternalFail;
  16734. begin
  16735. StartProgram(false);
  16736. Add([
  16737. '{$interfaces corba}',
  16738. 'type',
  16739. ' IUnknown = interface',
  16740. ' procedure DoIt; external name ''foo'';',
  16741. ' end;',
  16742. 'begin']);
  16743. SetExpectedParserError(
  16744. 'Fields are not allowed in interface at token "Identifier external" in file test1.pp at line 6 column 21',
  16745. nParserNoFieldsAllowed);
  16746. ConvertProgram;
  16747. end;
  16748. procedure TTestModule.TestClassInterface_Overloads;
  16749. begin
  16750. StartProgram(false);
  16751. Add([
  16752. '{$interfaces corba}',
  16753. 'type',
  16754. ' integer = longint;',
  16755. ' IUnknown = interface',
  16756. ' procedure DoIt(i: integer);',
  16757. ' procedure DoIt(s: string);',
  16758. ' end;',
  16759. ' IBird = interface(IUnknown)',
  16760. ' procedure DoIt(b: boolean); overload;',
  16761. ' end;',
  16762. ' TObject = class',
  16763. ' end;',
  16764. ' TBird = class(TObject,IBird)',
  16765. ' procedure DoIt(o: TObject);',
  16766. ' procedure DoIt(s: string);',
  16767. ' procedure DoIt(i: integer);',
  16768. ' procedure DoIt(b: boolean);',
  16769. ' end;',
  16770. 'procedure TBird.DoIt(o: TObject); begin end;',
  16771. 'procedure TBird.DoIt(s: string); begin end;',
  16772. 'procedure TBird.DoIt(i: integer); begin end;',
  16773. 'procedure TBird.DoIt(b: boolean); begin end;',
  16774. 'var',
  16775. ' BirdIntf: IBird;',
  16776. 'begin',
  16777. ' BirdIntf.DoIt(3);',
  16778. ' BirdIntf.DoIt(''abc'');',
  16779. ' BirdIntf.DoIt(true);',
  16780. '']);
  16781. ConvertProgram;
  16782. CheckSource('TestClassInterface_Overloads',
  16783. LinesToStr([ // statements
  16784. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-BDC4-8A2AE2C59400}", ["DoIt", "DoIt$1"], null);',
  16785. 'rtl.createInterface($mod, "IBird", "{8285DD5E-EA3E-396E-AE88-000B86AABF05}", ["DoIt$2"], $mod.IUnknown);',
  16786. 'rtl.createClass($mod, "TObject", null, function () {',
  16787. ' this.$init = function () {',
  16788. ' };',
  16789. ' this.$final = function () {',
  16790. ' };',
  16791. '});',
  16792. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16793. ' this.DoIt = function (o) {',
  16794. ' };',
  16795. ' this.DoIt$1 = function (s) {',
  16796. ' };',
  16797. ' this.DoIt$2 = function (i) {',
  16798. ' };',
  16799. ' this.DoIt$3 = function (b) {',
  16800. ' };',
  16801. ' rtl.addIntf(this, $mod.IBird, {',
  16802. ' DoIt$2: "DoIt$3",',
  16803. ' DoIt: "DoIt$2"',
  16804. ' });',
  16805. '});',
  16806. 'this.BirdIntf = null;',
  16807. '']),
  16808. LinesToStr([ // $mod.$main
  16809. '$mod.BirdIntf.DoIt(3);',
  16810. '$mod.BirdIntf.DoIt$1("abc");',
  16811. '$mod.BirdIntf.DoIt$2(true);',
  16812. '']));
  16813. end;
  16814. procedure TTestModule.TestClassInterface_DuplicateGUIInIntfListFail;
  16815. begin
  16816. StartProgram(false);
  16817. Add([
  16818. '{$interfaces corba}',
  16819. 'type',
  16820. ' IBird = interface',
  16821. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16822. ' end;',
  16823. ' IDog = interface',
  16824. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16825. ' end;',
  16826. ' TObject = class(IBird,IDog)',
  16827. ' end;',
  16828. 'begin']);
  16829. SetExpectedPasResolverError('Duplicate GUID {4B3BA825-E0EC-4799-A19C-55F714A07959} in IDog and IBird',
  16830. nDuplicateGUIDXInYZ);
  16831. ConvertProgram;
  16832. end;
  16833. procedure TTestModule.TestClassInterface_DuplicateGUIInAncestorFail;
  16834. begin
  16835. StartProgram(false);
  16836. Add([
  16837. '{$interfaces corba}',
  16838. 'type',
  16839. ' IAnimal = interface',
  16840. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16841. ' end;',
  16842. ' IBird = interface(IAnimal)',
  16843. ' end;',
  16844. ' IHawk = interface(IBird)',
  16845. ' [''{4B3BA825-E0EC-4799-A19C-55F714A07959}'']',
  16846. ' end;',
  16847. 'begin']);
  16848. SetExpectedPasResolverError('Duplicate GUID {4B3BA825-E0EC-4799-A19C-55F714A07959} in IHawk and IAnimal',
  16849. nDuplicateGUIDXInYZ);
  16850. ConvertProgram;
  16851. end;
  16852. procedure TTestModule.TestClassInterface_AncestorImpl;
  16853. begin
  16854. StartProgram(false);
  16855. Add([
  16856. '{$interfaces corba}',
  16857. 'type',
  16858. ' integer = longint;',
  16859. ' IUnknown = interface',
  16860. ' procedure DoIt(i: integer);',
  16861. ' end;',
  16862. ' IBird = interface',
  16863. ' procedure Fly(i: integer);',
  16864. ' end;',
  16865. ' TObject = class(IUnknown)',
  16866. ' procedure DoIt(i: integer);',
  16867. ' end;',
  16868. ' TBird = class(IBird)',
  16869. ' procedure Fly(i: integer);',
  16870. ' end;',
  16871. 'procedure TObject.DoIt(i: integer); begin end;',
  16872. 'procedure TBird.Fly(i: integer); begin end;',
  16873. 'begin',
  16874. '']);
  16875. ConvertProgram;
  16876. CheckSource('TestClassInterface_AncestorIntf',
  16877. LinesToStr([ // statements
  16878. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-BDC4-8A2800000000}", ["DoIt"], null);',
  16879. 'rtl.createInterface($mod, "IBird", "{B92D5841-6264-3AE3-BF20-000000000000}", ["Fly"], null);',
  16880. 'rtl.createClass($mod, "TObject", null, function () {',
  16881. ' this.$init = function () {',
  16882. ' };',
  16883. ' this.$final = function () {',
  16884. ' };',
  16885. ' this.DoIt = function (i) {',
  16886. ' };',
  16887. ' rtl.addIntf(this, $mod.IUnknown);',
  16888. '});',
  16889. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16890. ' this.Fly = function (i) {',
  16891. ' };',
  16892. ' rtl.addIntf(this, $mod.IBird);',
  16893. ' rtl.addIntf(this, $mod.IUnknown);',
  16894. '});',
  16895. '']),
  16896. LinesToStr([ // $mod.$main
  16897. '']));
  16898. end;
  16899. procedure TTestModule.TestClassInterface_ImplReintroduce;
  16900. begin
  16901. StartProgram(false);
  16902. Add([
  16903. '{$interfaces corba}',
  16904. 'type',
  16905. ' integer = longint;',
  16906. ' IBird = interface',
  16907. ' procedure DoIt(i: integer);',
  16908. ' end;',
  16909. ' TObject = class',
  16910. ' procedure DoIt(i: integer);',
  16911. ' end;',
  16912. ' TBird = class(IBird)',
  16913. ' procedure DoIt(i: integer); virtual; reintroduce;',
  16914. ' end;',
  16915. 'procedure TObject.DoIt(i: integer); begin end;',
  16916. 'procedure TBird.DoIt(i: integer); begin end;',
  16917. 'begin',
  16918. '']);
  16919. ConvertProgram;
  16920. CheckSource('TestClassInterface_ImplReintroduce',
  16921. LinesToStr([ // statements
  16922. 'rtl.createInterface($mod, "IBird", "{B92D5841-6264-3AE2-8594-000000000000}", ["DoIt"], null);',
  16923. 'rtl.createClass($mod, "TObject", null, function () {',
  16924. ' this.$init = function () {',
  16925. ' };',
  16926. ' this.$final = function () {',
  16927. ' };',
  16928. ' this.DoIt = function (i) {',
  16929. ' };',
  16930. '});',
  16931. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16932. ' this.DoIt$1 = function (i) {',
  16933. ' };',
  16934. ' rtl.addIntf(this, $mod.IBird, {',
  16935. ' DoIt: "DoIt$1"',
  16936. ' });',
  16937. '});',
  16938. '']),
  16939. LinesToStr([ // $mod.$main
  16940. '']));
  16941. end;
  16942. procedure TTestModule.TestClassInterface_MethodResolution;
  16943. begin
  16944. StartProgram(false);
  16945. Add([
  16946. '{$interfaces corba}',
  16947. 'type',
  16948. ' IUnknown = interface',
  16949. ' procedure Walk(i: longint);',
  16950. ' end;',
  16951. ' IBird = interface(IUnknown)',
  16952. ' procedure Walk(b: boolean); overload;',
  16953. ' procedure Fly(s: string);',
  16954. ' end;',
  16955. ' TObject = class',
  16956. ' end;',
  16957. ' TBird = class(TObject,IBird)',
  16958. ' procedure IBird.Fly = Move;',
  16959. ' procedure IBird.Walk = Hop;',
  16960. ' procedure Hop(i: longint);',
  16961. ' procedure Move(s: string);',
  16962. ' procedure Hop(b: boolean);',
  16963. ' end;',
  16964. 'procedure TBird.Move(s: string); begin end;',
  16965. 'procedure TBird.Hop(i: longint); begin end;',
  16966. 'procedure TBird.Hop(b: boolean); begin end;',
  16967. 'var',
  16968. ' BirdIntf: IBird;',
  16969. 'begin',
  16970. ' BirdIntf.Walk(3);',
  16971. ' BirdIntf.Walk(true);',
  16972. ' BirdIntf.Fly(''abc'');',
  16973. '']);
  16974. ConvertProgram;
  16975. CheckSource('TestClassInterface_MethodResolution',
  16976. LinesToStr([ // statements
  16977. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-BDD7-23D600000000}", ["Walk"], null);',
  16978. 'rtl.createInterface($mod, "IBird", "{CF8A4986-80F6-396E-AE88-000B86AAE208}", ["Walk$1", "Fly"], $mod.IUnknown);',
  16979. 'rtl.createClass($mod, "TObject", null, function () {',
  16980. ' this.$init = function () {',
  16981. ' };',
  16982. ' this.$final = function () {',
  16983. ' };',
  16984. '});',
  16985. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  16986. ' this.Hop = function (i) {',
  16987. ' };',
  16988. ' this.Move = function (s) {',
  16989. ' };',
  16990. ' this.Hop$1 = function (b) {',
  16991. ' };',
  16992. ' rtl.addIntf(this, $mod.IBird, {',
  16993. ' Walk$1: "Hop$1",',
  16994. ' Fly: "Move",',
  16995. ' Walk: "Hop"',
  16996. ' });',
  16997. '});',
  16998. 'this.BirdIntf = null;',
  16999. '']),
  17000. LinesToStr([ // $mod.$main
  17001. '$mod.BirdIntf.Walk(3);',
  17002. '$mod.BirdIntf.Walk$1(true);',
  17003. '$mod.BirdIntf.Fly("abc");',
  17004. '']));
  17005. end;
  17006. procedure TTestModule.TestClassInterface_AncestorMoreInterfaces;
  17007. begin
  17008. StartProgram(false);
  17009. Add([
  17010. '{$interfaces com}',
  17011. 'type',
  17012. ' IUnknown = interface',
  17013. ' function _AddRef: longint;',
  17014. ' procedure Walk;',
  17015. ' end;',
  17016. ' IBird = interface end;',
  17017. ' IDog = interface end;',
  17018. ' TObject = class(IBird,IDog)',
  17019. ' function _AddRef: longint; virtual; abstract;',
  17020. ' procedure Walk; virtual; abstract;',
  17021. ' end;',
  17022. ' TBird = class(IUnknown)',
  17023. ' end;',
  17024. 'begin',
  17025. '']);
  17026. ConvertProgram;
  17027. CheckSource('TestClassInterface_COM_AncestorLess',
  17028. LinesToStr([ // statements
  17029. 'rtl.createInterface($mod, "IUnknown", "{8F2D5841-758A-322B-BDDF-21CD521DD723}", ["_AddRef", "Walk"], null);',
  17030. 'rtl.createInterface($mod, "IBird", "{CCE11D4C-6504-3AEE-AE88-000B86AAE675}", [], $mod.IUnknown);',
  17031. 'rtl.createInterface($mod, "IDog", "{CCE11D4C-6504-3AEE-AE88-000B8E5FC675}", [], $mod.IUnknown);',
  17032. 'rtl.createClass($mod, "TObject", null, function () {',
  17033. ' this.$init = function () {',
  17034. ' };',
  17035. ' this.$final = function () {',
  17036. ' };',
  17037. ' rtl.addIntf(this, $mod.IBird);',
  17038. ' rtl.addIntf(this, $mod.IDog);',
  17039. '});',
  17040. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17041. ' rtl.addIntf(this, $mod.IUnknown);',
  17042. ' rtl.addIntf(this, $mod.IBird);',
  17043. ' rtl.addIntf(this, $mod.IDog);',
  17044. '});',
  17045. '']),
  17046. LinesToStr([ // $mod.$main
  17047. '']));
  17048. end;
  17049. procedure TTestModule.TestClassInterface_MethodOverride;
  17050. begin
  17051. StartProgram(false);
  17052. Add([
  17053. '{$interfaces corba}',
  17054. 'type',
  17055. ' IUnknown = interface',
  17056. ' [''{D6D98E5B-8A10-4FEC-856A-7BFC847FE74B}'']',
  17057. ' procedure Go;',
  17058. ' end;',
  17059. ' TObject = class(IUnknown)',
  17060. ' procedure Go; virtual; abstract;',
  17061. ' end;',
  17062. ' TBird = class',
  17063. ' procedure Go; override;',
  17064. ' end;',
  17065. ' TCat = class(TObject)',
  17066. ' procedure Go; override;',
  17067. ' end;',
  17068. ' TDog = class(TObject, IUnknown)',
  17069. ' procedure Go; override;',
  17070. ' end;',
  17071. 'procedure TBird.Go; begin end;',
  17072. 'procedure TCat.Go; begin end;',
  17073. 'procedure TDog.Go; begin end;',
  17074. 'begin',
  17075. '']);
  17076. ConvertProgram;
  17077. CheckSource('TestClassInterface_MethodOverride',
  17078. LinesToStr([ // statements
  17079. 'rtl.createInterface($mod, "IUnknown", "{D6D98E5B-8A10-4FEC-856A-7BFC847FE74B}", ["Go"], null);',
  17080. 'rtl.createClass($mod, "TObject", null, function () {',
  17081. ' this.$init = function () {',
  17082. ' };',
  17083. ' this.$final = function () {',
  17084. ' };',
  17085. ' rtl.addIntf(this, $mod.IUnknown);',
  17086. '});',
  17087. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17088. ' this.Go = function () {',
  17089. ' };',
  17090. ' rtl.addIntf(this, $mod.IUnknown);',
  17091. '});',
  17092. 'rtl.createClass($mod, "TCat", $mod.TObject, function () {',
  17093. ' this.Go = function () {',
  17094. ' };',
  17095. ' rtl.addIntf(this, $mod.IUnknown);',
  17096. '});',
  17097. 'rtl.createClass($mod, "TDog", $mod.TObject, function () {',
  17098. ' this.Go = function () {',
  17099. ' };',
  17100. ' rtl.addIntf(this, $mod.IUnknown);',
  17101. '});',
  17102. '']),
  17103. LinesToStr([ // $mod.$main
  17104. '']));
  17105. end;
  17106. procedure TTestModule.TestClassInterface_Corba_Delegation;
  17107. begin
  17108. StartProgram(false);
  17109. Add([
  17110. '{$interfaces corba}',
  17111. 'type',
  17112. ' IUnknown = interface',
  17113. ' end;',
  17114. ' IBird = interface(IUnknown)',
  17115. ' procedure Fly(s: string);',
  17116. ' end;',
  17117. ' IEagle = interface(IBird)',
  17118. ' end;',
  17119. ' IDove = interface(IBird)',
  17120. ' end;',
  17121. ' ISwallow = interface(IBird)',
  17122. ' end;',
  17123. ' TObject = class',
  17124. ' end;',
  17125. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  17126. ' procedure Fly(s: string); virtual; abstract;',
  17127. ' end;',
  17128. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  17129. ' FBirdIntf: IBird;',
  17130. ' property BirdIntf: IBird read FBirdIntf implements IBird;',
  17131. ' function GetEagleIntf: IEagle; virtual; abstract;',
  17132. ' property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  17133. ' FDoveObj: TBird;',
  17134. ' property DoveObj: TBird read FDoveObj implements IDove;',
  17135. ' function GetSwallowObj: TBird; virtual; abstract;',
  17136. ' property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  17137. ' end;',
  17138. 'begin',
  17139. '']);
  17140. ConvertProgram;
  17141. CheckSource('TestClassInterface_Delegation',
  17142. LinesToStr([ // statements
  17143. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17144. 'rtl.createInterface($mod, "IBird", "{478D080B-C0F6-396E-AE88-000B87785B07}", ["Fly"], $mod.IUnknown);',
  17145. 'rtl.createInterface($mod, "IEagle", "{489289DE-FDE2-34A6-8288-39119022B1B4}", [], $mod.IBird);',
  17146. 'rtl.createInterface($mod, "IDove", "{489289DE-FDE2-34A6-8288-39118EF16074}", [], $mod.IBird);',
  17147. 'rtl.createInterface($mod, "ISwallow", "{B89289DE-FDE2-34A6-8288-3911CBDCB359}", [], $mod.IBird);',
  17148. 'rtl.createClass($mod, "TObject", null, function () {',
  17149. ' this.$init = function () {',
  17150. ' };',
  17151. ' this.$final = function () {',
  17152. ' };',
  17153. '});',
  17154. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17155. ' rtl.addIntf(this, $mod.IBird);',
  17156. ' rtl.addIntf(this, $mod.IEagle);',
  17157. ' rtl.addIntf(this, $mod.IDove);',
  17158. ' rtl.addIntf(this, $mod.ISwallow);',
  17159. '});',
  17160. 'rtl.createClass($mod, "TBat", $mod.TObject, function () {',
  17161. ' this.$init = function () {',
  17162. ' $mod.TObject.$init.call(this);',
  17163. ' this.FBirdIntf = null;',
  17164. ' this.FDoveObj = null;',
  17165. ' };',
  17166. ' this.$final = function () {',
  17167. ' this.FBirdIntf = undefined;',
  17168. ' this.FDoveObj = undefined;',
  17169. ' $mod.TObject.$final.call(this);',
  17170. ' };',
  17171. ' this.$intfmaps = {',
  17172. ' "{478D080B-C0F6-396E-AE88-000B87785B07}": function () {',
  17173. ' return this.FBirdIntf;',
  17174. ' },',
  17175. ' "{489289DE-FDE2-34A6-8288-39119022B1B4}": function () {',
  17176. ' return this.GetEagleIntf();',
  17177. ' },',
  17178. ' "{489289DE-FDE2-34A6-8288-39118EF16074}": function () {',
  17179. ' return rtl.getIntfT(this.FDoveObj, $mod.IDove);',
  17180. ' },',
  17181. ' "{B89289DE-FDE2-34A6-8288-3911CBDCB359}": function () {',
  17182. ' return rtl.getIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  17183. ' }',
  17184. ' };',
  17185. '});',
  17186. '']),
  17187. LinesToStr([ // $mod.$main
  17188. '']));
  17189. end;
  17190. procedure TTestModule.TestClassInterface_Corba_DelegationStatic;
  17191. begin
  17192. StartProgram(false);
  17193. Add([
  17194. '{$interfaces corba}',
  17195. 'type',
  17196. ' IUnknown = interface',
  17197. ' end;',
  17198. ' IBird = interface(IUnknown)',
  17199. ' procedure Fly(s: string);',
  17200. ' end;',
  17201. ' IEagle = interface(IBird)',
  17202. ' end;',
  17203. ' IDove = interface(IBird)',
  17204. ' end;',
  17205. ' ISwallow = interface(IBird)',
  17206. ' end;',
  17207. ' TObject = class',
  17208. ' end;',
  17209. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  17210. ' procedure Fly(s: string); virtual; abstract;',
  17211. ' end;',
  17212. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  17213. ' private',
  17214. ' class var FBirdIntf: IBird;',
  17215. ' class var FDoveObj: TBird;',
  17216. ' class function GetEagleIntf: IEagle; virtual; abstract;',
  17217. ' class function GetSwallowObj: TBird; virtual; abstract;',
  17218. ' protected',
  17219. ' class property BirdIntf: IBird read FBirdIntf implements IBird;',
  17220. ' class property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  17221. ' class property DoveObj: TBird read FDoveObj implements IDove;',
  17222. ' class property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  17223. ' end;',
  17224. 'begin',
  17225. '']);
  17226. ConvertProgram;
  17227. CheckSource('TestClassInterface_DelegationStatic',
  17228. LinesToStr([ // statements
  17229. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17230. 'rtl.createInterface($mod, "IBird", "{478D080B-C0F6-396E-AE88-000B87785B07}", ["Fly"], $mod.IUnknown);',
  17231. 'rtl.createInterface($mod, "IEagle", "{489289DE-FDE2-34A6-8288-39119022B1B4}", [], $mod.IBird);',
  17232. 'rtl.createInterface($mod, "IDove", "{489289DE-FDE2-34A6-8288-39118EF16074}", [], $mod.IBird);',
  17233. 'rtl.createInterface($mod, "ISwallow", "{B89289DE-FDE2-34A6-8288-3911CBDCB359}", [], $mod.IBird);',
  17234. 'rtl.createClass($mod, "TObject", null, function () {',
  17235. ' this.$init = function () {',
  17236. ' };',
  17237. ' this.$final = function () {',
  17238. ' };',
  17239. '});',
  17240. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17241. ' rtl.addIntf(this, $mod.IBird);',
  17242. ' rtl.addIntf(this, $mod.IEagle);',
  17243. ' rtl.addIntf(this, $mod.IDove);',
  17244. ' rtl.addIntf(this, $mod.ISwallow);',
  17245. '});',
  17246. 'rtl.createClass($mod, "TBat", $mod.TObject, function () {',
  17247. ' this.FBirdIntf = null;',
  17248. ' this.FDoveObj = null;',
  17249. ' this.$intfmaps = {',
  17250. ' "{478D080B-C0F6-396E-AE88-000B87785B07}": function () {',
  17251. ' return this.FBirdIntf;',
  17252. ' },',
  17253. ' "{489289DE-FDE2-34A6-8288-39119022B1B4}": function () {',
  17254. ' return this.$class.GetEagleIntf();',
  17255. ' },',
  17256. ' "{489289DE-FDE2-34A6-8288-39118EF16074}": function () {',
  17257. ' return rtl.getIntfT(this.FDoveObj, $mod.IDove);',
  17258. ' },',
  17259. ' "{B89289DE-FDE2-34A6-8288-3911CBDCB359}": function () {',
  17260. ' return rtl.getIntfT(this.$class.GetSwallowObj(), $mod.ISwallow);',
  17261. ' }',
  17262. ' };',
  17263. '});',
  17264. '']),
  17265. LinesToStr([ // $mod.$main
  17266. '']));
  17267. end;
  17268. procedure TTestModule.TestClassInterface_Corba_Operators;
  17269. begin
  17270. StartProgram(false);
  17271. Add([
  17272. '{$interfaces corba}',
  17273. 'type',
  17274. ' IUnknown = interface',
  17275. ' end;',
  17276. ' IBird = interface(IUnknown)',
  17277. ' function GetItems(Index: longint): longint;',
  17278. ' procedure SetItems(Index: longint; Value: longint);',
  17279. ' property Items[Index: longint]: longint read GetItems write SetItems; default;',
  17280. ' end;',
  17281. ' TObject = class',
  17282. ' end;',
  17283. ' TBird = class(TObject,IBird)',
  17284. ' function GetItems(Index: longint): longint; virtual; abstract;',
  17285. ' procedure SetItems(Index: longint; Value: longint); virtual; abstract;',
  17286. ' end;',
  17287. 'var',
  17288. ' IntfVar: IBird = nil;',
  17289. ' IntfVar2: IBird;',
  17290. ' ObjVar: TBird;',
  17291. ' v: JSValue;',
  17292. 'begin',
  17293. ' IntfVar:=nil;',
  17294. ' IntfVar[3]:=IntfVar[4];',
  17295. ' if Assigned(IntfVar) then ;',
  17296. ' IntfVar:=IntfVar2;',
  17297. ' IntfVar:=ObjVar;',
  17298. ' if IntfVar=IntfVar2 then ;',
  17299. ' if IntfVar<>IntfVar2 then ;',
  17300. ' if IntfVar is IBird then ;',
  17301. ' if IntfVar is TBird then ;',
  17302. ' if ObjVar is IBird then ;',
  17303. ' IntfVar:=IntfVar2 as IBird;',
  17304. ' ObjVar:=IntfVar2 as TBird;',
  17305. ' IntfVar:=ObjVar as IBird;',
  17306. ' IntfVar:=IBird(IntfVar2);',
  17307. ' ObjVar:=TBird(IntfVar);',
  17308. ' IntfVar:=IBird(ObjVar);',
  17309. ' v:=IntfVar;',
  17310. ' IntfVar:=IBird(v);',
  17311. ' if v is IBird then ;',
  17312. ' v:=JSValue(IntfVar);',
  17313. ' v:=IBird;',
  17314. '']);
  17315. ConvertProgram;
  17316. CheckSource('TestClassInterface_Corba_Operators',
  17317. LinesToStr([ // statements
  17318. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17319. 'rtl.createInterface($mod, "IBird", "{D53FED90-DE59-3202-B1AE-000B87785B08}", ["GetItems", "SetItems"], $mod.IUnknown);',
  17320. 'rtl.createClass($mod, "TObject", null, function () {',
  17321. ' this.$init = function () {',
  17322. ' };',
  17323. ' this.$final = function () {',
  17324. ' };',
  17325. '});',
  17326. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  17327. ' rtl.addIntf(this, $mod.IBird);',
  17328. '});',
  17329. 'this.IntfVar = null;',
  17330. 'this.IntfVar2 = null;',
  17331. 'this.ObjVar = null;',
  17332. 'this.v = undefined;',
  17333. '']),
  17334. LinesToStr([ // $mod.$main
  17335. '$mod.IntfVar = null;',
  17336. '$mod.IntfVar.SetItems(3, $mod.IntfVar.GetItems(4));',
  17337. 'if ($mod.IntfVar != null) ;',
  17338. '$mod.IntfVar = $mod.IntfVar2;',
  17339. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar,$mod.IBird);',
  17340. 'if ($mod.IntfVar === $mod.IntfVar2) ;',
  17341. 'if ($mod.IntfVar !== $mod.IntfVar2) ;',
  17342. 'if ($mod.IBird.isPrototypeOf($mod.IntfVar)) ;',
  17343. 'if (rtl.intfIsClass($mod.IntfVar, $mod.TBird)) ;',
  17344. 'if (rtl.getIntfT($mod.ObjVar, $mod.IBird) !== null) ;',
  17345. '$mod.IntfVar = rtl.as($mod.IntfVar2, $mod.IBird);',
  17346. '$mod.ObjVar = rtl.intfAsClass($mod.IntfVar2, $mod.TBird);',
  17347. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar, $mod.IBird);',
  17348. '$mod.IntfVar = $mod.IntfVar2;',
  17349. '$mod.ObjVar = rtl.intfToClass($mod.IntfVar, $mod.TBird);',
  17350. '$mod.IntfVar = rtl.getIntfT($mod.ObjVar, $mod.IBird);',
  17351. '$mod.v = $mod.IntfVar;',
  17352. '$mod.IntfVar = rtl.getObject($mod.v);',
  17353. 'if (rtl.isExt($mod.v, $mod.IBird, 1)) ;',
  17354. '$mod.v = $mod.IntfVar;',
  17355. '$mod.v = $mod.IBird;',
  17356. '']));
  17357. end;
  17358. procedure TTestModule.TestClassInterface_Corba_Args;
  17359. begin
  17360. StartProgram(false);
  17361. Add([
  17362. '{$interfaces corba}',
  17363. 'type',
  17364. ' IUnknown = interface',
  17365. ' end;',
  17366. ' IBird = interface(IUnknown)',
  17367. ' end;',
  17368. ' TObject = class',
  17369. ' end;',
  17370. ' TBird = class(TObject,IBird)',
  17371. ' end;',
  17372. 'procedure DoIt(var u; i: IBird; const j: IBird);',
  17373. 'begin',
  17374. ' DoIt(i,i,i);',
  17375. 'end;',
  17376. 'procedure Change(var i: IBird; out j: IBird);',
  17377. 'begin',
  17378. ' DoIt(i,i,i);',
  17379. ' Change(i,i);',
  17380. 'end;',
  17381. 'var',
  17382. ' i: IBird;',
  17383. ' o: TBird;',
  17384. 'begin',
  17385. ' DoIt(i,i,i);',
  17386. ' Change(i,i);',
  17387. ' DoIt(o,o,o);',
  17388. '']);
  17389. ConvertProgram;
  17390. CheckSource('TestClassInterface_Corba_Args',
  17391. LinesToStr([ // statements
  17392. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17393. 'rtl.createInterface($mod, "IBird", "{4B0D080B-C0F6-396E-AE88-000B87785074}", [], $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.DoIt = function (u, i, j) {',
  17404. ' $mod.DoIt({',
  17405. ' get: function () {',
  17406. ' return i;',
  17407. ' },',
  17408. ' set: function (v) {',
  17409. ' i = v;',
  17410. ' }',
  17411. ' }, i, i);',
  17412. '};',
  17413. 'this.Change = function (i, j) {',
  17414. ' $mod.DoIt(i, i.get(), i.get());',
  17415. ' $mod.Change(i, i);',
  17416. '};',
  17417. 'this.i = null;',
  17418. 'this.o = null;',
  17419. '']),
  17420. LinesToStr([ // $mod.$main
  17421. '$mod.DoIt({',
  17422. ' p: $mod,',
  17423. ' get: function () {',
  17424. ' return this.p.i;',
  17425. ' },',
  17426. ' set: function (v) {',
  17427. ' this.p.i = v;',
  17428. ' }',
  17429. '}, $mod.i, $mod.i);',
  17430. '$mod.Change({',
  17431. ' p: $mod,',
  17432. ' get: function () {',
  17433. ' return this.p.i;',
  17434. ' },',
  17435. ' set: function (v) {',
  17436. ' this.p.i = v;',
  17437. ' }',
  17438. '}, {',
  17439. ' p: $mod,',
  17440. ' get: function () {',
  17441. ' return this.p.i;',
  17442. ' },',
  17443. ' set: function (v) {',
  17444. ' this.p.i = v;',
  17445. ' }',
  17446. '});',
  17447. '$mod.DoIt({',
  17448. ' p: $mod,',
  17449. ' get: function () {',
  17450. ' return this.p.o;',
  17451. ' },',
  17452. ' set: function (v) {',
  17453. ' this.p.o = v;',
  17454. ' }',
  17455. '}, rtl.getIntfT($mod.o, $mod.IBird), rtl.getIntfT($mod.o, $mod.IBird));',
  17456. '']));
  17457. end;
  17458. procedure TTestModule.TestClassInterface_Corba_ForIn;
  17459. begin
  17460. StartProgram(false);
  17461. Add([
  17462. '{$interfaces corba}',
  17463. 'type',
  17464. ' IUnknown = interface end;',
  17465. ' TObject = class',
  17466. ' Id: longint;',
  17467. ' end;',
  17468. ' IEnumerator = interface(IUnknown)',
  17469. ' function GetCurrent: TObject;',
  17470. ' function MoveNext: Boolean;',
  17471. ' property Current: TObject read GetCurrent;',
  17472. ' end;',
  17473. ' IEnumerable = interface(IUnknown)',
  17474. ' function GetEnumerator: IEnumerator;',
  17475. ' end;',
  17476. 'var',
  17477. ' o: TObject;',
  17478. ' i: IEnumerable;',
  17479. 'begin',
  17480. ' for o in i do o.Id:=3;',
  17481. '']);
  17482. ConvertProgram;
  17483. CheckSource('TestClassInterface_Corba_ForIn',
  17484. LinesToStr([ // statements
  17485. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  17486. 'rtl.createClass($mod, "TObject", null, function () {',
  17487. ' this.$init = function () {',
  17488. ' this.Id = 0;',
  17489. ' };',
  17490. ' this.$final = function () {',
  17491. ' };',
  17492. '});',
  17493. 'rtl.createInterface($mod, "IEnumerator", "{95D7745D-ED61-3F13-BBE4-07708161999E}", ["GetCurrent", "MoveNext"], $mod.IUnknown);',
  17494. 'rtl.createInterface($mod, "IEnumerable", "{8CC9D45D-ED7D-3B73-96B6-290B931BB19E}", ["GetEnumerator"], $mod.IUnknown);',
  17495. 'this.o = null;',
  17496. 'this.i = null;',
  17497. '']),
  17498. LinesToStr([ // $mod.$main
  17499. 'var $in1 = $mod.i.GetEnumerator();',
  17500. 'while ($in1.MoveNext()) {',
  17501. ' $mod.o = $in1.GetCurrent();',
  17502. ' $mod.o.Id = 3;',
  17503. '};',
  17504. '']));
  17505. end;
  17506. procedure TTestModule.TestClassInterface_COM_AssignVar;
  17507. begin
  17508. StartProgram(false);
  17509. Add([
  17510. '{$interfaces com}',
  17511. 'type',
  17512. ' IUnknown = interface',
  17513. ' function _AddRef: longint;',
  17514. ' function _Release: longint;',
  17515. ' end;',
  17516. ' TObject = class(IUnknown)',
  17517. ' function _AddRef: longint; virtual; abstract;',
  17518. ' function _Release: longint; virtual; abstract;',
  17519. ' end;',
  17520. 'var',
  17521. ' i: IUnknown;',
  17522. 'procedure DoGlobal(o: TObject);',
  17523. 'begin',
  17524. ' i:=nil;',
  17525. ' i:=o;',
  17526. ' i:=i;',
  17527. 'end;',
  17528. 'procedure DoLocal(o: TObject);',
  17529. 'const k: IUnknown = nil;',
  17530. 'var j: IUnknown;',
  17531. 'begin',
  17532. ' k:=o;',
  17533. ' k:=i;',
  17534. ' j:=o;',
  17535. ' j:=i;',
  17536. 'end;',
  17537. 'var o: TObject;',
  17538. 'begin',
  17539. ' i:=nil;',
  17540. ' i:=o;',
  17541. '']);
  17542. ConvertProgram;
  17543. CheckSource('TestClassInterface_COM_AssignVar',
  17544. LinesToStr([ // statements
  17545. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17546. 'rtl.createClass($mod, "TObject", null, function () {',
  17547. ' this.$init = function () {',
  17548. ' };',
  17549. ' this.$final = function () {',
  17550. ' };',
  17551. ' rtl.addIntf(this, $mod.IUnknown);',
  17552. '});',
  17553. 'this.i = null;',
  17554. 'this.DoGlobal = function (o) {',
  17555. ' rtl.setIntfP($mod, "i", null);',
  17556. ' rtl.setIntfP($mod, "i", rtl.queryIntfT(o, $mod.IUnknown), true);',
  17557. ' rtl.setIntfP($mod, "i", $mod.i);',
  17558. '};',
  17559. 'var k = null;',
  17560. 'this.DoLocal = function (o) {',
  17561. ' var j = null;',
  17562. ' try{',
  17563. ' k = rtl.setIntfL(k, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17564. ' k = rtl.setIntfL(k, $mod.i);',
  17565. ' j = rtl.setIntfL(j, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17566. ' j = rtl.setIntfL(j, $mod.i);',
  17567. ' }finally{',
  17568. ' rtl._Release(j);',
  17569. ' };',
  17570. '};',
  17571. 'this.o = null;',
  17572. '']),
  17573. LinesToStr([ // $mod.$main
  17574. 'rtl.setIntfP($mod, "i", null);',
  17575. 'rtl.setIntfP($mod, "i", rtl.queryIntfT($mod.o, $mod.IUnknown), true);',
  17576. '']));
  17577. end;
  17578. procedure TTestModule.TestClassInterface_COM_AssignArg;
  17579. begin
  17580. StartProgram(false);
  17581. Add([
  17582. '{$interfaces com}',
  17583. 'type',
  17584. ' IUnknown = interface',
  17585. ' function _AddRef: longint;',
  17586. ' function _Release: longint;',
  17587. ' end;',
  17588. ' TObject = class(IUnknown)',
  17589. ' function _AddRef: longint; virtual; abstract;',
  17590. ' function _Release: longint; virtual; abstract;',
  17591. ' end;',
  17592. 'procedure DoDefault(i, j: IUnknown);',
  17593. 'begin',
  17594. ' i:=nil;',
  17595. ' i:=j;',
  17596. 'end;',
  17597. 'begin',
  17598. '']);
  17599. ConvertProgram;
  17600. CheckSource('TestClassInterface_COM_AssignArg',
  17601. LinesToStr([ // statements
  17602. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17603. 'rtl.createClass($mod, "TObject", null, function () {',
  17604. ' this.$init = function () {',
  17605. ' };',
  17606. ' this.$final = function () {',
  17607. ' };',
  17608. ' rtl.addIntf(this, $mod.IUnknown);',
  17609. '});',
  17610. 'this.DoDefault = function (i, j) {',
  17611. ' rtl._AddRef(i);',
  17612. ' try {',
  17613. ' i = rtl.setIntfL(i, null);',
  17614. ' i = rtl.setIntfL(i, j);',
  17615. ' } finally {',
  17616. ' rtl._Release(i);',
  17617. ' };',
  17618. '};',
  17619. '']),
  17620. LinesToStr([ // $mod.$main
  17621. '']));
  17622. end;
  17623. procedure TTestModule.TestClassInterface_COM_FunctionResult;
  17624. begin
  17625. StartProgram(false);
  17626. Add([
  17627. '{$interfaces com}',
  17628. 'type',
  17629. ' IUnknown = interface',
  17630. ' function _AddRef: longint;',
  17631. ' function _Release: longint;',
  17632. ' end;',
  17633. ' TObject = class(IUnknown)',
  17634. ' function _AddRef: longint; virtual; abstract;',
  17635. ' function _Release: longint; virtual; abstract;',
  17636. ' end;',
  17637. 'function DoDefault(i: IUnknown): IUnknown;',
  17638. 'begin',
  17639. ' Result:=i;',
  17640. ' if Result<>nil then exit;',
  17641. 'end;',
  17642. 'begin',
  17643. '']);
  17644. ConvertProgram;
  17645. CheckSource('TestClassInterface_COM_FunctionResult',
  17646. LinesToStr([ // statements
  17647. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17648. 'rtl.createClass($mod, "TObject", null, function () {',
  17649. ' this.$init = function () {',
  17650. ' };',
  17651. ' this.$final = function () {',
  17652. ' };',
  17653. ' rtl.addIntf(this, $mod.IUnknown);',
  17654. '});',
  17655. 'this.DoDefault = function (i) {',
  17656. ' var Result = null;',
  17657. ' var $ok = false;',
  17658. ' try {',
  17659. ' Result = rtl.setIntfL(Result, i);',
  17660. ' if(Result !== null){',
  17661. ' $ok = true;',
  17662. ' return Result;',
  17663. ' };',
  17664. ' $ok = true;',
  17665. ' } finally {',
  17666. ' if(!$ok) rtl._Release(Result);',
  17667. ' };',
  17668. ' return Result;',
  17669. '};',
  17670. '']),
  17671. LinesToStr([ // $mod.$main
  17672. '']));
  17673. end;
  17674. procedure TTestModule.TestClassInterface_COM_InheritedFuncResult;
  17675. begin
  17676. StartProgram(false);
  17677. Add([
  17678. '{$interfaces com}',
  17679. 'type',
  17680. ' IUnknown = interface',
  17681. ' function _AddRef: longint;',
  17682. ' function _Release: longint;',
  17683. ' end;',
  17684. ' TObject = class(IUnknown)',
  17685. ' function _AddRef: longint; virtual; abstract;',
  17686. ' function _Release: longint; virtual; abstract;',
  17687. ' function GetIntf: IUnknown; virtual;',
  17688. ' end;',
  17689. ' TMouse = class',
  17690. ' function GetIntf: IUnknown; override;',
  17691. ' end;',
  17692. 'function TObject.GetIntf: IUnknown; begin end;',
  17693. 'function TMouse.GetIntf: IUnknown;',
  17694. 'var i: IUnknown;',
  17695. 'begin',
  17696. ' inherited;',
  17697. ' inherited GetIntf;',
  17698. ' inherited GetIntf();',
  17699. ' Result:=inherited GetIntf;',
  17700. ' Result:=inherited GetIntf();',
  17701. ' i:=inherited GetIntf;',
  17702. ' i:=inherited GetIntf();',
  17703. 'end;',
  17704. 'begin',
  17705. '']);
  17706. ConvertProgram;
  17707. CheckSource('TestClassInterface_COM_InheritedFuncResult',
  17708. LinesToStr([ // statements
  17709. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17710. 'rtl.createClass($mod, "TObject", null, function () {',
  17711. ' this.$init = function () {',
  17712. ' };',
  17713. ' this.$final = function () {',
  17714. ' };',
  17715. ' this.GetIntf = function () {',
  17716. ' var Result = null;',
  17717. ' return Result;',
  17718. ' };',
  17719. ' rtl.addIntf(this, $mod.IUnknown);',
  17720. '});',
  17721. 'rtl.createClass($mod, "TMouse", $mod.TObject, function () {',
  17722. ' this.GetIntf = function () {',
  17723. ' var Result = null;',
  17724. ' var i = null;',
  17725. ' var $ir = rtl.createIntfRefs();',
  17726. ' var $ok = false;',
  17727. ' try {',
  17728. ' $ir.ref(1, $mod.TObject.GetIntf.call(this));',
  17729. ' $ir.ref(2, $mod.TObject.GetIntf.call(this));',
  17730. ' $ir.ref(3, $mod.TObject.GetIntf.call(this));',
  17731. ' Result = rtl.setIntfL(Result, $mod.TObject.GetIntf.call(this), true);',
  17732. ' Result = rtl.setIntfL(Result, $mod.TObject.GetIntf.call(this), true);',
  17733. ' i = rtl.setIntfL(i, $mod.TObject.GetIntf.call(this), true);',
  17734. ' i = rtl.setIntfL(i, $mod.TObject.GetIntf.call(this), true);',
  17735. ' $ok = true;',
  17736. ' } finally {',
  17737. ' $ir.free();',
  17738. ' rtl._Release(i);',
  17739. ' if (!$ok) rtl._Release(Result);',
  17740. ' };',
  17741. ' return Result;',
  17742. ' };',
  17743. ' rtl.addIntf(this, $mod.IUnknown);',
  17744. '});',
  17745. '']),
  17746. LinesToStr([ // $mod.$main
  17747. '']));
  17748. end;
  17749. procedure TTestModule.TestClassInterface_COM_IsAsTypeCasts;
  17750. begin
  17751. StartProgram(false);
  17752. Add([
  17753. '{$interfaces com}',
  17754. 'type',
  17755. ' IUnknown = interface',
  17756. ' function _AddRef: longint;',
  17757. ' function _Release: longint;',
  17758. ' end;',
  17759. ' TObject = class(IUnknown)',
  17760. ' function _AddRef: longint; virtual; abstract;',
  17761. ' function _Release: longint; virtual; abstract;',
  17762. ' end;',
  17763. 'procedure DoDefault(i, j: IUnknown; o: TObject);',
  17764. 'begin',
  17765. ' if i is IUnknown then ;',
  17766. ' if o is IUnknown then ;',
  17767. ' if i is TObject then ;',
  17768. ' i:=j as IUnknown;',
  17769. ' i:=o as IUnknown;',
  17770. ' o:=j as TObject;',
  17771. ' i:=IUnknown(j);',
  17772. ' i:=IUnknown(o);',
  17773. ' o:=TObject(i);',
  17774. 'end;',
  17775. 'begin',
  17776. '']);
  17777. ConvertProgram;
  17778. CheckSource('TestClassInterface_COM_IsAsTypeCasts',
  17779. LinesToStr([ // statements
  17780. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17781. 'rtl.createClass($mod, "TObject", null, function () {',
  17782. ' this.$init = function () {',
  17783. ' };',
  17784. ' this.$final = function () {',
  17785. ' };',
  17786. ' rtl.addIntf(this, $mod.IUnknown);',
  17787. '});',
  17788. 'this.DoDefault = function (i, j, o) {',
  17789. ' rtl._AddRef(i);',
  17790. ' try {',
  17791. ' if ($mod.IUnknown.isPrototypeOf(i)) ;',
  17792. ' if (rtl.queryIntfIsT(o, $mod.IUnknown)) ;',
  17793. ' if (rtl.intfIsClass(i, $mod.TObject)) ;',
  17794. ' i = rtl.setIntfL(i, rtl.as(j, $mod.IUnknown));',
  17795. ' i = rtl.setIntfL(i, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17796. ' o = rtl.intfAsClass(j, $mod.TObject);',
  17797. ' i = rtl.setIntfL(i, j);',
  17798. ' i = rtl.setIntfL(i, rtl.queryIntfT(o, $mod.IUnknown), true);',
  17799. ' o = rtl.intfToClass(i, $mod.TObject);',
  17800. ' } finally {',
  17801. ' rtl._Release(i);',
  17802. ' };',
  17803. '};',
  17804. '']),
  17805. LinesToStr([ // $mod.$main
  17806. '']));
  17807. end;
  17808. procedure TTestModule.TestClassInterface_COM_PassAsArg;
  17809. begin
  17810. StartProgram(false);
  17811. Add([
  17812. '{$interfaces com}',
  17813. 'type',
  17814. ' IUnknown = interface',
  17815. ' function _AddRef: longint;',
  17816. ' function _Release: longint;',
  17817. ' end;',
  17818. ' TObject = class(IUnknown)',
  17819. ' function _AddRef: longint; virtual; abstract;',
  17820. ' function _Release: longint; virtual; abstract;',
  17821. ' end;',
  17822. 'procedure DoIt(v: IUnknown; const j: IUnknown; var k: IUnknown; out l: IUnknown);',
  17823. 'var o: TObject;',
  17824. 'begin',
  17825. ' DoIt(v,v,v,v);',
  17826. ' DoIt(o,o,k,k);',
  17827. 'end;',
  17828. 'procedure DoSome;',
  17829. 'var v: IUnknown;',
  17830. 'begin',
  17831. ' DoIt(v,v,v,v);',
  17832. 'end;',
  17833. 'var i: IUnknown;',
  17834. 'begin',
  17835. ' DoIt(i,i,i,i);',
  17836. '']);
  17837. ConvertProgram;
  17838. CheckSource('TestClassInterface_COM_PassAsArg',
  17839. LinesToStr([ // statements
  17840. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17841. 'rtl.createClass($mod, "TObject", null, function () {',
  17842. ' this.$init = function () {',
  17843. ' };',
  17844. ' this.$final = function () {',
  17845. ' };',
  17846. ' rtl.addIntf(this, $mod.IUnknown);',
  17847. '});',
  17848. 'this.DoIt = function (v, j, k, l) {',
  17849. ' var o = null;',
  17850. ' var $ir = rtl.createIntfRefs();',
  17851. ' rtl._AddRef(v);',
  17852. ' try {',
  17853. ' $mod.DoIt(v, v, {',
  17854. ' get: function () {',
  17855. ' return v;',
  17856. ' },',
  17857. ' set: function (w) {',
  17858. ' v = rtl.setIntfL(v, w);',
  17859. ' }',
  17860. ' }, {',
  17861. ' get: function () {',
  17862. ' return v;',
  17863. ' },',
  17864. ' set: function (w) {',
  17865. ' v = rtl.setIntfL(v, w);',
  17866. ' }',
  17867. ' });',
  17868. ' $mod.DoIt($ir.ref(1, rtl.queryIntfT(o, $mod.IUnknown)), $ir.ref(2, rtl.queryIntfT(o, $mod.IUnknown)), k, k);',
  17869. ' } finally {',
  17870. ' $ir.free();',
  17871. ' rtl._Release(v);',
  17872. ' };',
  17873. '};',
  17874. 'this.DoSome = function () {',
  17875. ' var v = null;',
  17876. ' try {',
  17877. ' $mod.DoIt(v, v, {',
  17878. ' get: function () {',
  17879. ' return v;',
  17880. ' },',
  17881. ' set: function (w) {',
  17882. ' v = rtl.setIntfL(v, w);',
  17883. ' }',
  17884. ' }, {',
  17885. ' get: function () {',
  17886. ' return v;',
  17887. ' },',
  17888. ' set: function (w) {',
  17889. ' v = rtl.setIntfL(v, w);',
  17890. ' }',
  17891. ' });',
  17892. ' } finally {',
  17893. ' rtl._Release(v);',
  17894. ' };',
  17895. '};',
  17896. 'this.i = null;',
  17897. '']),
  17898. LinesToStr([ // $mod.$main
  17899. '$mod.DoIt($mod.i, $mod.i, {',
  17900. ' p: $mod,',
  17901. ' get: function () {',
  17902. ' return this.p.i;',
  17903. ' },',
  17904. ' set: function (v) {',
  17905. ' rtl.setIntfP(this.p, "i", v);',
  17906. ' }',
  17907. '}, {',
  17908. ' p: $mod,',
  17909. ' get: function () {',
  17910. ' return this.p.i;',
  17911. ' },',
  17912. ' set: function (v) {',
  17913. ' rtl.setIntfP(this.p, "i", v);',
  17914. ' }',
  17915. '});',
  17916. '']));
  17917. end;
  17918. procedure TTestModule.TestClassInterface_COM_PassToUntypedParam;
  17919. begin
  17920. StartProgram(false);
  17921. Add([
  17922. '{$interfaces com}',
  17923. 'type',
  17924. ' IUnknown = interface',
  17925. ' function _AddRef: longint;',
  17926. ' function _Release: longint;',
  17927. ' end;',
  17928. ' TObject = class(IUnknown)',
  17929. ' function _AddRef: longint; virtual; abstract;',
  17930. ' function _Release: longint; virtual; abstract;',
  17931. ' end;',
  17932. 'procedure DoIt(out i);',
  17933. 'begin end;',
  17934. 'procedure DoSome;',
  17935. 'var v: IUnknown;',
  17936. 'begin',
  17937. ' DoIt(v);',
  17938. 'end;',
  17939. 'function GetIt: IUnknown;',
  17940. 'begin',
  17941. ' DoIt(Result);',
  17942. 'end;',
  17943. 'var i: IUnknown;',
  17944. 'begin',
  17945. ' DoIt(i);',
  17946. '']);
  17947. ConvertProgram;
  17948. CheckSource('TestClassInterface_COM_PassToUntypedParam',
  17949. LinesToStr([ // statements
  17950. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  17951. 'rtl.createClass($mod, "TObject", null, function () {',
  17952. ' this.$init = function () {',
  17953. ' };',
  17954. ' this.$final = function () {',
  17955. ' };',
  17956. ' rtl.addIntf(this, $mod.IUnknown);',
  17957. '});',
  17958. 'this.DoIt = function (i) {',
  17959. '};',
  17960. 'this.DoSome = function () {',
  17961. ' var v = null;',
  17962. ' try {',
  17963. ' $mod.DoIt({',
  17964. ' get: function () {',
  17965. ' return v;',
  17966. ' },',
  17967. ' set: function (w) {',
  17968. ' v = w;',
  17969. ' }',
  17970. ' });',
  17971. ' } finally {',
  17972. ' rtl._Release(v);',
  17973. ' };',
  17974. '};',
  17975. 'this.GetIt = function () {',
  17976. ' var Result = null;',
  17977. ' var $ok = false;',
  17978. ' try {',
  17979. ' $mod.DoIt({',
  17980. ' get: function () {',
  17981. ' return Result;',
  17982. ' },',
  17983. ' set: function (v) {',
  17984. ' Result = v;',
  17985. ' }',
  17986. ' });',
  17987. ' $ok = true;',
  17988. ' } finally {',
  17989. ' if (!$ok) rtl._Release(Result);',
  17990. ' };',
  17991. ' return Result;',
  17992. '};',
  17993. 'this.i = null;',
  17994. '']),
  17995. LinesToStr([ // $mod.$main
  17996. 'try {',
  17997. ' $mod.DoIt({',
  17998. ' p: $mod,',
  17999. ' get: function () {',
  18000. ' return this.p.i;',
  18001. ' },',
  18002. ' set: function (v) {',
  18003. ' this.p.i = v;',
  18004. ' }',
  18005. ' });',
  18006. '} finally {',
  18007. ' rtl._Release($mod.i);',
  18008. '};',
  18009. '']));
  18010. end;
  18011. procedure TTestModule.TestClassInterface_COM_FunctionInExpr;
  18012. begin
  18013. StartProgram(false);
  18014. Add([
  18015. '{$interfaces com}',
  18016. 'type',
  18017. ' IUnknown = interface',
  18018. ' function _AddRef: longint;',
  18019. ' function _Release: longint;',
  18020. ' end;',
  18021. ' TObject = class(IUnknown)',
  18022. ' function _AddRef: longint; virtual; abstract;',
  18023. ' function _Release: longint; virtual; abstract;',
  18024. ' end;',
  18025. 'function GetIt: IUnknown;',
  18026. 'begin',
  18027. 'end;',
  18028. 'procedure DoSome;',
  18029. 'var v: IUnknown;',
  18030. ' i: longint;',
  18031. 'begin',
  18032. ' v:=GetIt;',
  18033. ' v:=GetIt();',
  18034. ' GetIt()._AddRef;',
  18035. ' i:=GetIt()._AddRef;',
  18036. 'end;',
  18037. 'var v: IUnknown;',
  18038. ' i: longint;',
  18039. 'begin',
  18040. ' v:=GetIt;',
  18041. ' v:=GetIt();',
  18042. ' GetIt()._AddRef;',
  18043. ' i:=GetIt()._AddRef;',
  18044. '']);
  18045. ConvertProgram;
  18046. CheckSource('TestClassInterface_COM_FunctionInExpr',
  18047. LinesToStr([ // statements
  18048. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18049. 'rtl.createClass($mod, "TObject", null, function () {',
  18050. ' this.$init = function () {',
  18051. ' };',
  18052. ' this.$final = function () {',
  18053. ' };',
  18054. ' rtl.addIntf(this, $mod.IUnknown);',
  18055. '});',
  18056. 'this.GetIt = function () {',
  18057. ' var Result = null;',
  18058. ' return Result;',
  18059. '};',
  18060. 'this.DoSome = function () {',
  18061. ' var v = null;',
  18062. ' var i = 0;',
  18063. ' var $ir = rtl.createIntfRefs();',
  18064. ' try {',
  18065. ' v = rtl.setIntfL(v, $mod.GetIt(), true);',
  18066. ' v = rtl.setIntfL(v, $mod.GetIt(), true);',
  18067. ' $ir.ref(1, $mod.GetIt())._AddRef();',
  18068. ' i = $ir.ref(2, $mod.GetIt())._AddRef();',
  18069. ' } finally {',
  18070. ' $ir.free();',
  18071. ' rtl._Release(v);',
  18072. ' };',
  18073. '};',
  18074. 'this.v = null;',
  18075. 'this.i = 0;',
  18076. '']),
  18077. LinesToStr([ // $mod.$main
  18078. 'var $ir = rtl.createIntfRefs();',
  18079. 'try {',
  18080. ' rtl.setIntfP($mod, "v", $mod.GetIt(), true);',
  18081. ' rtl.setIntfP($mod, "v", $mod.GetIt(), true);',
  18082. ' $ir.ref(1, $mod.GetIt())._AddRef();',
  18083. ' $mod.i = $ir.ref(2, $mod.GetIt())._AddRef();',
  18084. '} finally {',
  18085. ' $ir.free();',
  18086. '};',
  18087. '']));
  18088. end;
  18089. procedure TTestModule.TestClassInterface_COM_Property;
  18090. begin
  18091. StartProgram(false);
  18092. Add([
  18093. '{$interfaces com}',
  18094. 'type',
  18095. ' IUnknown = interface',
  18096. ' function _AddRef: longint;',
  18097. ' function _Release: longint;',
  18098. ' end;',
  18099. ' TObject = class(IUnknown)',
  18100. ' FAnt: IUnknown;',
  18101. ' function _AddRef: longint; virtual; abstract;',
  18102. ' function _Release: longint; virtual; abstract;',
  18103. ' function GetBird: IUnknown; virtual; abstract;',
  18104. ' procedure SetBird(Value: IUnknown); virtual; abstract;',
  18105. ' function GetItems(Index: longint): IUnknown; virtual; abstract;',
  18106. ' procedure SetItems(Index: longint; Value: IUnknown); virtual; abstract;',
  18107. ' property Ant: IUnknown read FAnt write FAnt;',
  18108. ' property Bird: IUnknown read GetBird write SetBird;',
  18109. ' property Items[Index: longint]: IUnknown read GetItems write SetItems; default;',
  18110. ' end;',
  18111. 'procedure DoIt;',
  18112. 'var',
  18113. ' o: TObject;',
  18114. ' v: IUnknown;',
  18115. 'begin',
  18116. ' v:=o.Ant;',
  18117. ' o.Ant:=v;',
  18118. ' o.Ant:=o.Ant;',
  18119. ' v:=o.Bird;',
  18120. ' o.Bird:=v;',
  18121. ' o.Bird:=o.Bird;',
  18122. ' v:=o.Items[1];',
  18123. ' o.Items[2]:=v;',
  18124. ' o.Items[3]:=o.Items[4];',
  18125. ' v:=o[5];',
  18126. ' o[6]:=v;',
  18127. ' o[7]:=o[8];',
  18128. 'end;',
  18129. 'begin',
  18130. '']);
  18131. ConvertProgram;
  18132. CheckSource('TestClassInterface_COM_Property',
  18133. LinesToStr([ // statements
  18134. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18135. 'rtl.createClass($mod, "TObject", null, function () {',
  18136. ' this.$init = function () {',
  18137. ' this.FAnt = null;',
  18138. ' };',
  18139. ' this.$final = function () {',
  18140. ' this.FAnt = undefined;',
  18141. ' };',
  18142. ' rtl.addIntf(this, $mod.IUnknown);',
  18143. '});',
  18144. 'this.DoIt = function () {',
  18145. ' var o = null;',
  18146. ' var v = null;',
  18147. ' var $ir = rtl.createIntfRefs();',
  18148. ' try {',
  18149. ' v = rtl.setIntfL(v, o.FAnt);',
  18150. ' rtl.setIntfP(o, "FAnt", v);',
  18151. ' rtl.setIntfP(o, "FAnt", o.FAnt);',
  18152. ' v = rtl.setIntfL(v, o.GetBird(), true);',
  18153. ' o.SetBird(v);',
  18154. ' o.SetBird($ir.ref(1, o.GetBird()));',
  18155. ' v = rtl.setIntfL(v, o.GetItems(1), true);',
  18156. ' o.SetItems(2, v);',
  18157. ' o.SetItems(3, $ir.ref(2, o.GetItems(4)));',
  18158. ' v = rtl.setIntfL(v, o.GetItems(5), true);',
  18159. ' o.SetItems(6, v);',
  18160. ' o.SetItems(7, $ir.ref(3, o.GetItems(8)));',
  18161. ' } finally {',
  18162. ' $ir.free();',
  18163. ' rtl._Release(v);',
  18164. ' };',
  18165. '};',
  18166. '']),
  18167. LinesToStr([ // $mod.$main
  18168. '']));
  18169. end;
  18170. procedure TTestModule.TestClassInterface_COM_IntfProperty;
  18171. begin
  18172. StartProgram(false);
  18173. Add([
  18174. '{$interfaces com}',
  18175. 'type',
  18176. ' IUnknown = interface',
  18177. ' function _AddRef: longint;',
  18178. ' function _Release: longint;',
  18179. ' function GetBird: IUnknown;',
  18180. ' procedure SetBird(Value: IUnknown);',
  18181. ' function GetItems(Index: longint): IUnknown;',
  18182. ' procedure SetItems(Index: longint; Value: IUnknown);',
  18183. ' property Bird: IUnknown read GetBird write SetBird;',
  18184. ' property Items[Index: longint]: IUnknown read GetItems write SetItems; default;',
  18185. ' end;',
  18186. ' TObject = class(IUnknown)',
  18187. ' function _AddRef: longint; virtual; abstract;',
  18188. ' function _Release: longint; virtual; abstract;',
  18189. ' function GetBird: IUnknown; virtual; abstract;',
  18190. ' procedure SetBird(Value: IUnknown); virtual; abstract;',
  18191. ' function GetItems(Index: longint): IUnknown; virtual; abstract;',
  18192. ' procedure SetItems(Index: longint; Value: IUnknown); virtual; abstract;',
  18193. ' end;',
  18194. 'procedure DoIt;',
  18195. 'var',
  18196. ' o: TObject;',
  18197. ' v: IUnknown;',
  18198. 'begin',
  18199. ' v:=v.Items[1];',
  18200. ' v.Items[2]:=v;',
  18201. ' v.Items[3]:=v.Items[4];',
  18202. ' v:=v[5];',
  18203. ' v[6]:=v;',
  18204. ' v[7]:=v[8];',
  18205. ' v[9].Bird.Bird:=v;',
  18206. ' v:=v.Bird[10].Bird',
  18207. 'end;',
  18208. 'begin',
  18209. '']);
  18210. ConvertProgram;
  18211. CheckSource('TestClassInterface_COM_IntfProperty',
  18212. LinesToStr([ // statements
  18213. 'rtl.createInterface($mod, "IUnknown", "{385F5482-571B-338C-8130-4E97F330543B}", [',
  18214. ' "_AddRef",',
  18215. ' "_Release",',
  18216. ' "GetBird",',
  18217. ' "SetBird",',
  18218. ' "GetItems",',
  18219. ' "SetItems"',
  18220. '], null);',
  18221. 'rtl.createClass($mod, "TObject", null, function () {',
  18222. ' this.$init = function () {',
  18223. ' };',
  18224. ' this.$final = function () {',
  18225. ' };',
  18226. ' rtl.addIntf(this, $mod.IUnknown);',
  18227. '});',
  18228. 'this.DoIt = function () {',
  18229. ' var o = null;',
  18230. ' var v = null;',
  18231. ' var $ir = rtl.createIntfRefs();',
  18232. ' try {',
  18233. ' v = rtl.setIntfL(v, v.GetItems(1), true);',
  18234. ' v.SetItems(2, v);',
  18235. ' v.SetItems(3, $ir.ref(1, v.GetItems(4)));',
  18236. ' v = rtl.setIntfL(v, v.GetItems(5), true);',
  18237. ' v.SetItems(6, v);',
  18238. ' v.SetItems(7, $ir.ref(2, v.GetItems(8)));',
  18239. ' $ir.ref(4, $ir.ref(3, v.GetItems(9)).GetBird()).SetBird(v);',
  18240. ' v = rtl.setIntfL(v, $ir.ref(6, $ir.ref(5, v.GetBird()).GetItems(10)).GetBird(), true);',
  18241. ' } finally {',
  18242. ' $ir.free();',
  18243. ' rtl._Release(v);',
  18244. ' };',
  18245. '};',
  18246. '']),
  18247. LinesToStr([ // $mod.$main
  18248. '']));
  18249. end;
  18250. procedure TTestModule.TestClassInterface_COM_Delegation;
  18251. begin
  18252. StartProgram(false);
  18253. Add([
  18254. '{$interfaces com}',
  18255. 'type',
  18256. ' IUnknown = interface',
  18257. ' function _AddRef: longint;',
  18258. ' function _Release: longint;',
  18259. ' end;',
  18260. ' IBird = interface(IUnknown)',
  18261. ' procedure Fly(s: string);',
  18262. ' end;',
  18263. ' IEagle = interface(IBird) end;',
  18264. ' IDove = interface(IBird) end;',
  18265. ' ISwallow = interface(IBird) end;',
  18266. ' TObject = class',
  18267. ' end;',
  18268. ' TBird = class(TObject,IBird,IEagle,IDove,ISwallow)',
  18269. ' function _AddRef: longint; virtual; abstract;',
  18270. ' function _Release: longint; virtual; abstract;',
  18271. ' procedure Fly(s: string); virtual; abstract;',
  18272. ' end;',
  18273. ' TBat = class(IBird,IEagle,IDove,ISwallow)',
  18274. ' function _AddRef: longint; virtual; abstract;',
  18275. ' function _Release: longint; virtual; abstract;',
  18276. ' FBirdIntf: IBird;',
  18277. ' property BirdIntf: IBird read FBirdIntf implements IBird;',
  18278. ' function GetEagleIntf: IEagle; virtual; abstract;',
  18279. ' property EagleIntf: IEagle read GetEagleIntf implements IEagle;',
  18280. ' FDoveObj: TBird;',
  18281. ' property DoveObj: TBird read FDoveObj implements IDove;',
  18282. ' function GetSwallowObj: TBird; virtual; abstract;',
  18283. ' property SwallowObj: TBird read GetSwallowObj implements ISwallow;',
  18284. ' end;',
  18285. 'begin',
  18286. '']);
  18287. ConvertProgram;
  18288. CheckSource('TestClassInterface_COM_Delegation',
  18289. LinesToStr([ // statements
  18290. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  18291. 'rtl.createInterface($mod, "IBird", "{CC440C7F-7623-3DEE-AE88-000B86AAF108}", ["Fly"], $mod.IUnknown);',
  18292. 'rtl.createInterface($mod, "IEagle", "{4B6A41C9-B020-3D7C-B688-96D19022B1B4}", [], $mod.IBird);',
  18293. 'rtl.createInterface($mod, "IDove", "{4B6A41C9-B020-3D7C-B688-96D18EF16074}", [], $mod.IBird);',
  18294. 'rtl.createInterface($mod, "ISwallow", "{BB6A41C9-B020-3D7C-B688-96D1CBDCB359}", [], $mod.IBird);',
  18295. 'rtl.createClass($mod, "TObject", null, function () {',
  18296. ' this.$init = function () {',
  18297. ' };',
  18298. ' this.$final = function () {',
  18299. ' };',
  18300. '});',
  18301. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  18302. ' rtl.addIntf(this, $mod.IBird);',
  18303. ' rtl.addIntf(this, $mod.IEagle);',
  18304. ' rtl.addIntf(this, $mod.IDove);',
  18305. ' rtl.addIntf(this, $mod.ISwallow);',
  18306. '});',
  18307. 'rtl.createClass($mod, "TBat", $mod.TObject, function () {',
  18308. ' this.$init = function () {',
  18309. ' $mod.TObject.$init.call(this);',
  18310. ' this.FBirdIntf = null;',
  18311. ' this.FDoveObj = null;',
  18312. ' };',
  18313. ' this.$final = function () {',
  18314. ' this.FBirdIntf = undefined;',
  18315. ' this.FDoveObj = undefined;',
  18316. ' $mod.TObject.$final.call(this);',
  18317. ' };',
  18318. ' this.$intfmaps = {',
  18319. ' "{CC440C7F-7623-3DEE-AE88-000B86AAF108}": function () {',
  18320. ' return rtl._AddRef(this.FBirdIntf);',
  18321. ' },',
  18322. ' "{4B6A41C9-B020-3D7C-B688-96D19022B1B4}": function () {',
  18323. ' return this.GetEagleIntf();',
  18324. ' },',
  18325. ' "{4B6A41C9-B020-3D7C-B688-96D18EF16074}": function () {',
  18326. ' return rtl.queryIntfT(this.FDoveObj, $mod.IDove);',
  18327. ' },',
  18328. ' "{BB6A41C9-B020-3D7C-B688-96D1CBDCB359}": function () {',
  18329. ' return rtl.queryIntfT(this.GetSwallowObj(), $mod.ISwallow);',
  18330. ' }',
  18331. ' };',
  18332. '});',
  18333. '']),
  18334. LinesToStr([ // $mod.$main
  18335. '']));
  18336. end;
  18337. procedure TTestModule.TestClassInterface_COM_With;
  18338. begin
  18339. StartProgram(false);
  18340. Add([
  18341. '{$interfaces com}',
  18342. 'type',
  18343. ' IUnknown = interface',
  18344. ' function _AddRef: longint;',
  18345. ' function _Release: longint;',
  18346. ' function GetAnt: IUnknown;',
  18347. ' property Ant: IUnknown read GetAnt;',
  18348. ' end;',
  18349. ' TObject = class(IUnknown)',
  18350. ' function _AddRef: longint; virtual; abstract;',
  18351. ' function _Release: longint; virtual; abstract;',
  18352. ' function GetAnt: IUnknown; virtual; abstract;',
  18353. ' property Ant: IUnknown read GetAnt;',
  18354. ' end;',
  18355. 'procedure DoIt;',
  18356. 'var',
  18357. ' i: IUnknown;',
  18358. 'begin',
  18359. ' with i do ',
  18360. ' GetAnt;',
  18361. ' with i.Ant, Ant do ',
  18362. ' GetAnt;',
  18363. 'end;',
  18364. 'begin',
  18365. '']);
  18366. ConvertProgram;
  18367. CheckSource('TestClassInterface_COM_With',
  18368. LinesToStr([ // statements
  18369. 'rtl.createInterface($mod, "IUnknown", "{D7ADB00D-C6B6-39FB-BDDF-21CD521DDFA9}", ["_AddRef", "_Release", "GetAnt"], null);',
  18370. 'rtl.createClass($mod, "TObject", null, function () {',
  18371. ' this.$init = function () {',
  18372. ' };',
  18373. ' this.$final = function () {',
  18374. ' };',
  18375. ' rtl.addIntf(this, $mod.IUnknown);',
  18376. '});',
  18377. 'this.DoIt = function () {',
  18378. ' var i = null;',
  18379. ' var $ir = rtl.createIntfRefs();',
  18380. ' try {',
  18381. ' $ir.ref(1, i.GetAnt());',
  18382. ' var $with1 = $ir.ref(2, i.GetAnt());',
  18383. ' var $with2 = $ir.ref(3, $with1.GetAnt());',
  18384. ' $ir.ref(4, $with2.GetAnt());',
  18385. ' } finally {',
  18386. ' $ir.free();',
  18387. ' };',
  18388. '};',
  18389. '']),
  18390. LinesToStr([ // $mod.$main
  18391. '']));
  18392. end;
  18393. procedure TTestModule.TestClassInterface_COM_ForIn;
  18394. begin
  18395. StartProgram(false);
  18396. Add([
  18397. '{$interfaces com}',
  18398. 'type',
  18399. ' IUnknown = interface end;',
  18400. ' TObject = class',
  18401. ' Id: longint;',
  18402. ' end;',
  18403. ' IEnumerator = interface(IUnknown)',
  18404. ' function GetCurrent: TObject;',
  18405. ' function MoveNext: Boolean;',
  18406. ' property Current: TObject read GetCurrent;',
  18407. ' end;',
  18408. ' IEnumerable = interface(IUnknown)',
  18409. ' function GetEnumerator: IEnumerator;',
  18410. ' end;',
  18411. 'var',
  18412. ' o: TObject;',
  18413. ' i: IEnumerable;',
  18414. 'begin',
  18415. ' for o in i do o.Id:=3;',
  18416. '']);
  18417. ConvertProgram;
  18418. CheckSource('TestClassInterface_COM_ForIn',
  18419. LinesToStr([ // statements
  18420. 'rtl.createInterface($mod, "IUnknown", "{B92D5841-758A-322B-B800-000000000000}", [], null);',
  18421. 'rtl.createClass($mod, "TObject", null, function () {',
  18422. ' this.$init = function () {',
  18423. ' this.Id = 0;',
  18424. ' };',
  18425. ' this.$final = function () {',
  18426. ' };',
  18427. '});',
  18428. 'rtl.createInterface($mod, "IEnumerator", "{95D7745D-ED61-3F13-BBE4-07708161999E}", ["GetCurrent", "MoveNext"], $mod.IUnknown);',
  18429. 'rtl.createInterface($mod, "IEnumerable", "{8CC9D45D-ED7D-3B73-96B6-290B931BB19E}", ["GetEnumerator"], $mod.IUnknown);',
  18430. 'this.o = null;',
  18431. 'this.i = null;',
  18432. '']),
  18433. LinesToStr([ // $mod.$main
  18434. 'var $in1 = $mod.i.GetEnumerator();',
  18435. 'try {',
  18436. ' while ($in1.MoveNext()) {',
  18437. ' $mod.o = $in1.GetCurrent();',
  18438. ' $mod.o.Id = 3;',
  18439. ' }',
  18440. '} finally {',
  18441. ' rtl._Release($in1)',
  18442. '};',
  18443. '']));
  18444. end;
  18445. procedure TTestModule.TestClassInterface_COM_ArrayOfIntfFail;
  18446. begin
  18447. StartProgram(false);
  18448. Add([
  18449. '{$interfaces com}',
  18450. 'type',
  18451. ' IUnknown = interface',
  18452. ' function _AddRef: longint;',
  18453. ' function _Release: longint;',
  18454. ' end;',
  18455. ' TObject = class',
  18456. ' end;',
  18457. ' TArrOfIntf = array of IUnknown;',
  18458. 'begin',
  18459. '']);
  18460. SetExpectedPasResolverError('Not supported: array of COM-interface',nNotSupportedX);
  18461. ConvertProgram;
  18462. end;
  18463. procedure TTestModule.TestClassInterface_COM_RecordIntfFail;
  18464. begin
  18465. StartProgram(false);
  18466. Add([
  18467. '{$interfaces com}',
  18468. 'type',
  18469. ' IUnknown = interface',
  18470. ' function _AddRef: longint;',
  18471. ' function _Release: longint;',
  18472. ' end;',
  18473. ' TRec = record',
  18474. ' i: IUnknown;',
  18475. ' end;',
  18476. 'begin',
  18477. '']);
  18478. SetExpectedPasResolverError('Not supported: COM-interface as record member',nNotSupportedX);
  18479. ConvertProgram;
  18480. end;
  18481. procedure TTestModule.TestClassInterface_COM_UnitInitialization;
  18482. begin
  18483. StartUnit(false);
  18484. Add([
  18485. '{$interfaces com}',
  18486. 'interface',
  18487. 'implementation',
  18488. 'type',
  18489. ' IUnknown = interface',
  18490. ' function _AddRef: longint;',
  18491. ' end;',
  18492. ' TObject = class(IUnknown)',
  18493. ' function _AddRef: longint;',
  18494. ' end;',
  18495. 'function TObject._AddRef: longint; begin end;',
  18496. 'var i: IUnknown;',
  18497. ' o: TObject;',
  18498. 'initialization',
  18499. ' i:=nil;',
  18500. ' i:=i;',
  18501. ' i:=o;',
  18502. ' if (o as IUnknown)=nil then ;',
  18503. '']);
  18504. ConvertUnit;
  18505. CheckSource('TestClassInterface_COM_UnitInitialization',
  18506. LinesToStr([ // statements
  18507. 'var $impl = $mod.$impl;',
  18508. '']),
  18509. LinesToStr([ // this.$init
  18510. 'var $ir = rtl.createIntfRefs();',
  18511. 'try {',
  18512. ' rtl.setIntfP($impl, "i", null);',
  18513. ' rtl.setIntfP($impl, "i", $impl.i);',
  18514. ' rtl.setIntfP($impl, "i", rtl.queryIntfT($impl.o, $impl.IUnknown), true);',
  18515. ' if ($ir.ref(1, rtl.queryIntfT($impl.o, $impl.IUnknown)) === null) ;',
  18516. '} finally {',
  18517. ' $ir.free();',
  18518. '};',
  18519. '']),
  18520. LinesToStr([ // implementation
  18521. 'rtl.createInterface($impl, "IUnknown", "{B92D5841-758A-322B-BDDF-21CD52180000}", ["_AddRef"], null);',
  18522. 'rtl.createClass($impl, "TObject", null, function () {',
  18523. ' this.$init = function () {',
  18524. ' };',
  18525. ' this.$final = function () {',
  18526. ' };',
  18527. ' this._AddRef = function () {',
  18528. ' var Result = 0;',
  18529. ' return Result;',
  18530. ' };',
  18531. ' rtl.addIntf(this, $impl.IUnknown);',
  18532. '});',
  18533. '$impl.i = null;',
  18534. '$impl.o = null;',
  18535. ''])
  18536. );
  18537. end;
  18538. procedure TTestModule.TestClassInterface_GUID;
  18539. begin
  18540. StartProgram(false);
  18541. Add([
  18542. '{$interfaces corba}',
  18543. 'type',
  18544. ' IUnknown = interface',
  18545. ' [''{f31db68f-3010-D355-4EBA-CDD4EF4A737C}'']',
  18546. ' end;',
  18547. ' TObject = class end;',
  18548. ' TGUID = record D1, D2, D3, D4: word; end;',
  18549. ' TAliasGUID = TGUID;',
  18550. ' TGUIDString = type string;',
  18551. ' TAliasGUIDString = TGUIDString;',
  18552. 'procedure DoConstGUIDIt(const g: TAliasGUID); overload;',
  18553. 'begin end;',
  18554. 'procedure DoDefGUID(g: TAliasGUID); overload;',
  18555. 'begin end;',
  18556. 'procedure DoStr(const s: TAliasGUIDString); overload;',
  18557. 'begin end;',
  18558. 'var',
  18559. ' i: IUnknown;',
  18560. ' g: TAliasGUID = ''{d91c9af4-3C93-420F-A303-BF5BA82BFD23}'';',
  18561. ' s: TAliasGUIDString;',
  18562. 'begin',
  18563. ' DoConstGUIDIt(IUnknown);',
  18564. ' DoDefGUID(IUnknown);',
  18565. ' DoStr(IUnknown);',
  18566. ' DoConstGUIDIt(i);',
  18567. ' DoDefGUID(i);',
  18568. ' DoStr(i);',
  18569. ' DoConstGUIDIt(''{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}'');',
  18570. ' DoDefGUID(''{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}'');',
  18571. ' DoStr(g);',
  18572. ' g:=i;',
  18573. ' g:=IUnknown;',
  18574. ' g:=''{D91C9AF4-3C93-420F-A303-bf5ba82bfd23}'';',
  18575. ' s:=i;',
  18576. ' s:=IUnknown;',
  18577. ' s:=g;',
  18578. ' if g=i then ;',
  18579. ' if i=g then ;',
  18580. ' if g=IUnknown then ;',
  18581. ' if IUnknown=g then ;',
  18582. ' if s=i then ;',
  18583. ' if i=s then ;',
  18584. ' if s=IUnknown then ;',
  18585. ' if IUnknown=s then ;',
  18586. ' if s=g then ;',
  18587. ' if g=s then ;',
  18588. '']);
  18589. ConvertProgram;
  18590. CheckSource('TestClassInterface_GUID',
  18591. LinesToStr([ // statements
  18592. 'rtl.createInterface($mod, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
  18593. 'rtl.createClass($mod, "TObject", null, function () {',
  18594. ' this.$init = function () {',
  18595. ' };',
  18596. ' this.$final = function () {',
  18597. ' };',
  18598. '});',
  18599. 'rtl.recNewT($mod, "TGUID", function () {',
  18600. ' this.D1 = 0;',
  18601. ' this.D2 = 0;',
  18602. ' this.D3 = 0;',
  18603. ' this.D4 = 0;',
  18604. ' this.$eq = function (b) {',
  18605. ' return (this.D1 === b.D1) && (this.D2 === b.D2) && (this.D3 === b.D3) && (this.D4 === b.D4);',
  18606. ' };',
  18607. ' this.$assign = function (s) {',
  18608. ' this.D1 = s.D1;',
  18609. ' this.D2 = s.D2;',
  18610. ' this.D3 = s.D3;',
  18611. ' this.D4 = s.D4;',
  18612. ' return this;',
  18613. ' };',
  18614. '});',
  18615. 'this.DoConstGUIDIt = function (g) {',
  18616. '};',
  18617. 'this.DoDefGUID = function (g) {',
  18618. '};',
  18619. 'this.DoStr = function (s) {',
  18620. '};',
  18621. 'this.i = null;',
  18622. 'this.g = $mod.TGUID.$clone({',
  18623. ' D1: 0xD91C9AF4,',
  18624. ' D2: 0x3C93,',
  18625. ' D3: 0x420F,',
  18626. ' D4: [',
  18627. ' 0xA3,',
  18628. ' 0x03,',
  18629. ' 0xBF,',
  18630. ' 0x5B,',
  18631. ' 0xA8,',
  18632. ' 0x2B,',
  18633. ' 0xFD,',
  18634. ' 0x23',
  18635. ' ]',
  18636. '});',
  18637. 'this.s = "";',
  18638. '']),
  18639. LinesToStr([ // $mod.$main
  18640. '$mod.DoConstGUIDIt(rtl.getIntfGUIDR($mod.IUnknown));',
  18641. '$mod.DoDefGUID($mod.TGUID.$clone(rtl.getIntfGUIDR($mod.IUnknown)));',
  18642. '$mod.DoStr($mod.IUnknown.$guid);',
  18643. '$mod.DoConstGUIDIt(rtl.getIntfGUIDR($mod.i));',
  18644. '$mod.DoDefGUID($mod.TGUID.$clone(rtl.getIntfGUIDR($mod.i)));',
  18645. '$mod.DoStr($mod.i.$guid);',
  18646. '$mod.DoConstGUIDIt(rtl.strToGUIDR("{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}"));',
  18647. '$mod.DoDefGUID(rtl.strToGUIDR("{D91C9AF4-3c93-420f-A303-BF5BA82BFD23}"));',
  18648. '$mod.DoStr(rtl.guidrToStr($mod.g));',
  18649. '$mod.g.$assign(rtl.getIntfGUIDR($mod.i));',
  18650. '$mod.g.$assign(rtl.getIntfGUIDR($mod.IUnknown));',
  18651. '$mod.g.$assign({',
  18652. ' D1: 0xD91C9AF4,',
  18653. ' D2: 0x3C93,',
  18654. ' D3: 0x420F,',
  18655. ' D4: [',
  18656. ' 0xA3,',
  18657. ' 0x03,',
  18658. ' 0xBF,',
  18659. ' 0x5B,',
  18660. ' 0xA8,',
  18661. ' 0x2B,',
  18662. ' 0xFD,',
  18663. ' 0x23',
  18664. ' ]',
  18665. '});',
  18666. '$mod.s = $mod.i.$guid;',
  18667. '$mod.s = $mod.IUnknown.$guid;',
  18668. '$mod.s = rtl.guidrToStr($mod.g);',
  18669. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.i))) ;',
  18670. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.i))) ;',
  18671. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.IUnknown))) ;',
  18672. 'if ($mod.g.$eq(rtl.getIntfGUIDR($mod.IUnknown))) ;',
  18673. 'if ($mod.s === $mod.i.$guid) ;',
  18674. 'if ($mod.i.$guid === $mod.s) ;',
  18675. 'if ($mod.s === $mod.IUnknown.$guid) ;',
  18676. 'if ($mod.IUnknown.$guid === $mod.s) ;',
  18677. 'if ($mod.g.$eq(rtl.createTGUID($mod.s))) ;',
  18678. 'if ($mod.g.$eq(rtl.createTGUID($mod.s))) ;',
  18679. '']));
  18680. end;
  18681. procedure TTestModule.TestClassInterface_GUIDProperty;
  18682. begin
  18683. StartProgram(false);
  18684. Add([
  18685. '{$interfaces corba}',
  18686. 'type',
  18687. ' IUnknown = interface',
  18688. ' [''{f31db68f-3010-D355-4EBA-CDD4EF4A737C}'']',
  18689. ' end;',
  18690. ' TGUID = record D1, D2, D3, D4: word; end;',
  18691. ' TAliasGUID = TGUID;',
  18692. ' TGUIDString = type string;',
  18693. ' TAliasGUIDString = TGUIDString;',
  18694. ' TObject = class',
  18695. ' function GetG: TAliasGUID; virtual; abstract;',
  18696. ' procedure SetG(const Value: TAliasGUID); virtual; abstract;',
  18697. ' function GetS: TAliasGUIDString; virtual; abstract;',
  18698. ' procedure SetS(const Value: TAliasGUIDString); virtual; abstract;',
  18699. ' property g: TAliasGUID read GetG write SetG;',
  18700. ' property s: TAliasGUIDString read GetS write SetS;',
  18701. ' end;',
  18702. 'var o: TObject;',
  18703. 'begin',
  18704. ' o.g:=IUnknown;',
  18705. ' o.g:=''{D91C9AF4-3C93-420F-A303-bf5ba82bfd23}'';',
  18706. ' o.s:=IUnknown;',
  18707. ' o.s:=o.g;',
  18708. '']);
  18709. ConvertProgram;
  18710. CheckSource('TestClassInterface_GUIDProperty',
  18711. LinesToStr([ // statements
  18712. 'rtl.createInterface($mod, "IUnknown", "{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}", [], null);',
  18713. 'rtl.recNewT($mod, "TGUID", function () {',
  18714. ' this.D1 = 0;',
  18715. ' this.D2 = 0;',
  18716. ' this.D3 = 0;',
  18717. ' this.D4 = 0;',
  18718. ' this.$eq = function (b) {',
  18719. ' return (this.D1 === b.D1) && (this.D2 === b.D2) && (this.D3 === b.D3) && (this.D4 === b.D4);',
  18720. ' };',
  18721. ' this.$assign = function (s) {',
  18722. ' this.D1 = s.D1;',
  18723. ' this.D2 = s.D2;',
  18724. ' this.D3 = s.D3;',
  18725. ' this.D4 = s.D4;',
  18726. ' return this;',
  18727. ' };',
  18728. '});',
  18729. 'rtl.createClass($mod, "TObject", null, function () {',
  18730. ' this.$init = function () {',
  18731. ' };',
  18732. ' this.$final = function () {',
  18733. ' };',
  18734. '});',
  18735. 'this.o = null;',
  18736. '']),
  18737. LinesToStr([ // $mod.$main
  18738. '$mod.o.SetG(rtl.getIntfGUIDR($mod.IUnknown));',
  18739. '$mod.o.SetG({',
  18740. ' D1: 0xD91C9AF4,',
  18741. ' D2: 0x3C93,',
  18742. ' D3: 0x420F,',
  18743. ' D4: [',
  18744. ' 0xA3,',
  18745. ' 0x03,',
  18746. ' 0xBF,',
  18747. ' 0x5B,',
  18748. ' 0xA8,',
  18749. ' 0x2B,',
  18750. ' 0xFD,',
  18751. ' 0x23',
  18752. ' ]',
  18753. '});',
  18754. '$mod.o.SetS($mod.IUnknown.$guid);',
  18755. '$mod.o.SetS(rtl.guidrToStr($mod.o.GetG()));',
  18756. '']));
  18757. end;
  18758. procedure TTestModule.TestClassHelper_ClassVar;
  18759. begin
  18760. StartProgram(false);
  18761. Add([
  18762. 'type',
  18763. ' TObject = class',
  18764. ' end;',
  18765. ' THelper = class helper for TObject',
  18766. ' const',
  18767. ' One = 1;',
  18768. ' Two: word = 2;',
  18769. ' class var',
  18770. ' Glob: word;',
  18771. ' function Foo(w: word): word;',
  18772. ' class function Bar(w: word): word;',
  18773. ' end;',
  18774. 'function THelper.foo(w: word): word;',
  18775. 'begin',
  18776. ' Result:=w;',
  18777. ' Two:=One+w;',
  18778. ' Glob:=Glob;',
  18779. ' Result:=Self.Glob;',
  18780. ' Self.Glob:=Self.Glob;',
  18781. ' with Self do Glob:=Glob;',
  18782. 'end;',
  18783. 'class function THelper.bar(w: word): word;',
  18784. 'begin',
  18785. ' Result:=w;',
  18786. ' Two:=One;',
  18787. ' Glob:=Glob;',
  18788. ' Self.Glob:=Self.Glob;',
  18789. ' with Self do Glob:=Glob;',
  18790. 'end;',
  18791. 'var o: TObject;',
  18792. 'begin',
  18793. ' tobject.two:=tobject.one;',
  18794. ' tobject.Glob:=tobject.Glob;',
  18795. ' with tobject do begin',
  18796. ' two:=one;',
  18797. ' Glob:=Glob;',
  18798. ' end;',
  18799. ' o.two:=o.one;',
  18800. ' o.Glob:=o.Glob;',
  18801. ' with o do begin',
  18802. ' two:=one;',
  18803. ' Glob:=Glob;',
  18804. ' end;',
  18805. '']);
  18806. ConvertProgram;
  18807. CheckSource('TestClassHelper_ClassVar',
  18808. LinesToStr([ // statements
  18809. 'rtl.createClass($mod, "TObject", null, function () {',
  18810. ' this.$init = function () {',
  18811. ' };',
  18812. ' this.$final = function () {',
  18813. ' };',
  18814. '});',
  18815. 'rtl.createHelper($mod, "THelper", null, function () {',
  18816. ' this.One = 1;',
  18817. ' this.Two = 2;',
  18818. ' this.Glob = 0;',
  18819. ' this.Foo = function (w) {',
  18820. ' var Result = 0;',
  18821. ' Result = w;',
  18822. ' $mod.THelper.Two = 1 + w;',
  18823. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18824. ' Result = $mod.THelper.Glob;',
  18825. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18826. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18827. ' return Result;',
  18828. ' };',
  18829. ' this.Bar = function (w) {',
  18830. ' var Result = 0;',
  18831. ' Result = w;',
  18832. ' $mod.THelper.Two = 1;',
  18833. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18834. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18835. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  18836. ' return Result;',
  18837. ' };',
  18838. '});',
  18839. 'this.o = null;',
  18840. '']),
  18841. LinesToStr([ // $mod.$main
  18842. '$mod.THelper.Two = 1;',
  18843. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18844. 'var $with1 = $mod.TObject;',
  18845. '$mod.THelper.Two = 1;',
  18846. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18847. '$mod.THelper.Two = 1;',
  18848. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18849. 'var $with2 = $mod.o;',
  18850. '$mod.THelper.Two = 1;',
  18851. '$mod.THelper.Glob = $mod.THelper.Glob;',
  18852. '']));
  18853. end;
  18854. procedure TTestModule.TestClassHelper_Method_AccessInstanceFields;
  18855. begin
  18856. StartProgram(false);
  18857. Add([
  18858. 'type',
  18859. ' TObject = class',
  18860. ' FSize: word;',
  18861. ' property Size: word read FSize write FSize;',
  18862. ' end;',
  18863. ' THelper = class helper for TObject',
  18864. ' function Foo(w: word = 1): word;',
  18865. ' end;',
  18866. 'function THelper.foo(w: word): word;',
  18867. 'begin',
  18868. ' Result:=Size;',
  18869. ' Size:=Size+2;',
  18870. ' Self.Size:=Self.Size+3;',
  18871. ' FSize:=FSize+4;',
  18872. ' Self.FSize:=Self.FSize+5;',
  18873. ' with Self do begin',
  18874. ' Size:=Size+6;',
  18875. ' FSize:=FSize+7;',
  18876. ' FSize:=FSize+8;',
  18877. ' end;',
  18878. 'end;',
  18879. 'begin',
  18880. '']);
  18881. ConvertProgram;
  18882. CheckSource('TestClassHelper_Method_AccessInstanceFields',
  18883. LinesToStr([ // statements
  18884. 'rtl.createClass($mod, "TObject", null, function () {',
  18885. ' this.$init = function () {',
  18886. ' this.FSize = 0;',
  18887. ' };',
  18888. ' this.$final = function () {',
  18889. ' };',
  18890. '});',
  18891. 'rtl.createHelper($mod, "THelper", null, function () {',
  18892. ' this.Foo = function (w) {',
  18893. ' var Result = 0;',
  18894. ' Result = this.FSize;',
  18895. ' this.FSize = this.FSize + 2;',
  18896. ' this.FSize = this.FSize + 3;',
  18897. ' this.FSize = this.FSize + 4;',
  18898. ' this.FSize = this.FSize + 5;',
  18899. ' this.FSize = this.FSize + 6;',
  18900. ' this.FSize = this.FSize + 7;',
  18901. ' this.FSize = this.FSize + 8;',
  18902. ' return Result;',
  18903. ' };',
  18904. '});',
  18905. '']),
  18906. LinesToStr([ // $mod.$main
  18907. '']));
  18908. end;
  18909. procedure TTestModule.TestClassHelper_Method_Call;
  18910. begin
  18911. StartProgram(false);
  18912. Add([
  18913. 'type',
  18914. ' TObject = class',
  18915. ' procedure Run(w: word = 10);',
  18916. ' end;',
  18917. ' THelper = class helper for TObject',
  18918. ' function Foo(w: word = 1): word;',
  18919. ' end;',
  18920. 'procedure TObject.Run(w: word);',
  18921. 'begin',
  18922. ' Foo;',
  18923. ' Foo();',
  18924. ' Foo(2);',
  18925. ' Self.Foo;',
  18926. ' Self.Foo();',
  18927. ' Self.Foo(3);',
  18928. ' with Self do begin',
  18929. ' Foo;',
  18930. ' Foo();',
  18931. ' Foo(4);',
  18932. ' end;',
  18933. 'end;',
  18934. 'function THelper.foo(w: word): word;',
  18935. 'begin',
  18936. ' Run;',
  18937. ' Run();',
  18938. ' Run(11);',
  18939. ' Foo;',
  18940. ' Foo();',
  18941. ' Foo(12);',
  18942. ' Self.Foo;',
  18943. ' Self.Foo();',
  18944. ' Self.Foo(13);',
  18945. ' with Self do begin',
  18946. ' Foo;',
  18947. ' Foo();',
  18948. ' Foo(14);',
  18949. ' end;',
  18950. 'end;',
  18951. 'var Obj: TObject;',
  18952. 'begin',
  18953. ' obj.Foo;',
  18954. ' obj.Foo();',
  18955. ' obj.Foo(21);',
  18956. ' with obj do begin',
  18957. ' Foo;',
  18958. ' Foo();',
  18959. ' Foo(22);',
  18960. ' end;',
  18961. '']);
  18962. ConvertProgram;
  18963. CheckSource('TestClassHelper_Method_Call',
  18964. LinesToStr([ // statements
  18965. 'rtl.createClass($mod, "TObject", null, function () {',
  18966. ' this.$init = function () {',
  18967. ' };',
  18968. ' this.$final = function () {',
  18969. ' };',
  18970. ' this.Run = function (w) {',
  18971. ' $mod.THelper.Foo.call(this, 1);',
  18972. ' $mod.THelper.Foo.call(this, 1);',
  18973. ' $mod.THelper.Foo.call(this, 2);',
  18974. ' $mod.THelper.Foo.call(this, 1);',
  18975. ' $mod.THelper.Foo.call(this, 1);',
  18976. ' $mod.THelper.Foo.call(this, 3);',
  18977. ' $mod.THelper.Foo.call(this, 1);',
  18978. ' $mod.THelper.Foo.call(this, 1);',
  18979. ' $mod.THelper.Foo.call(this, 4);',
  18980. ' };',
  18981. '});',
  18982. 'rtl.createHelper($mod, "THelper", null, function () {',
  18983. ' this.Foo = function (w) {',
  18984. ' var Result = 0;',
  18985. ' this.Run(10);',
  18986. ' this.Run(10);',
  18987. ' this.Run(11);',
  18988. ' $mod.THelper.Foo.call(this, 1);',
  18989. ' $mod.THelper.Foo.call(this, 1);',
  18990. ' $mod.THelper.Foo.call(this, 12);',
  18991. ' $mod.THelper.Foo.call(this, 1);',
  18992. ' $mod.THelper.Foo.call(this, 1);',
  18993. ' $mod.THelper.Foo.call(this, 13);',
  18994. ' $mod.THelper.Foo.call(this, 1);',
  18995. ' $mod.THelper.Foo.call(this, 1);',
  18996. ' $mod.THelper.Foo.call(this, 14);',
  18997. ' return Result;',
  18998. ' };',
  18999. '});',
  19000. 'this.Obj = null;',
  19001. '']),
  19002. LinesToStr([ // $mod.$main
  19003. '$mod.THelper.Foo.call($mod.Obj, 1);',
  19004. '$mod.THelper.Foo.call($mod.Obj, 1);',
  19005. '$mod.THelper.Foo.call($mod.Obj, 21);',
  19006. 'var $with1 = $mod.Obj;',
  19007. '$mod.THelper.Foo.call($with1, 1);',
  19008. '$mod.THelper.Foo.call($with1, 1);',
  19009. '$mod.THelper.Foo.call($with1, 22);',
  19010. '']));
  19011. end;
  19012. procedure TTestModule.TestClassHelper_Method_Nested_Call;
  19013. begin
  19014. StartProgram(false);
  19015. Add([
  19016. 'type',
  19017. ' TObject = class',
  19018. ' procedure Run(w: word = 10);',
  19019. ' end;',
  19020. ' THelper = class helper for TObject',
  19021. ' function Foo(w: word = 1): word;',
  19022. ' end;',
  19023. 'procedure TObject.Run(w: word);',
  19024. ' procedure Sub(Self: TObject);',
  19025. ' begin',
  19026. ' Foo;',
  19027. ' Foo();',
  19028. ' Self.Foo;',
  19029. ' Self.Foo();',
  19030. ' with Self do begin',
  19031. ' Foo;',
  19032. ' Foo();',
  19033. ' end;',
  19034. ' end;',
  19035. 'begin',
  19036. 'end;',
  19037. 'function THelper.foo(w: word): word;',
  19038. ' procedure Sub(Self: TObject);',
  19039. ' begin',
  19040. ' Run;',
  19041. ' Run();',
  19042. ' Foo;',
  19043. ' Foo();',
  19044. ' Self.Foo;',
  19045. ' Self.Foo();',
  19046. ' with Self do begin',
  19047. ' Foo;',
  19048. ' Foo();',
  19049. ' end;',
  19050. ' end;',
  19051. 'begin',
  19052. 'end;',
  19053. 'begin',
  19054. '']);
  19055. ConvertProgram;
  19056. CheckSource('TestClassHelper_Method_Nested_Call',
  19057. LinesToStr([ // statements
  19058. 'rtl.createClass($mod, "TObject", null, function () {',
  19059. ' this.$init = function () {',
  19060. ' };',
  19061. ' this.$final = function () {',
  19062. ' };',
  19063. ' this.Run = function (w) {',
  19064. ' var $Self = this;',
  19065. ' function Sub(Self) {',
  19066. ' $mod.THelper.Foo.call($Self, 1);',
  19067. ' $mod.THelper.Foo.call($Self, 1);',
  19068. ' $mod.THelper.Foo.call(Self, 1);',
  19069. ' $mod.THelper.Foo.call(Self, 1);',
  19070. ' $mod.THelper.Foo.call(Self, 1);',
  19071. ' $mod.THelper.Foo.call($Self, 1);',
  19072. ' };',
  19073. ' };',
  19074. '});',
  19075. 'rtl.createHelper($mod, "THelper", null, function () {',
  19076. ' this.Foo = function (w) {',
  19077. ' var $Self = this;',
  19078. ' var Result = 0;',
  19079. ' function Sub(Self) {',
  19080. ' $Self.Run(10);',
  19081. ' $Self.Run(10);',
  19082. ' $mod.THelper.Foo.call($Self, 1);',
  19083. ' $mod.THelper.Foo.call($Self, 1);',
  19084. ' $mod.THelper.Foo.call(Self, 1);',
  19085. ' $mod.THelper.Foo.call(Self, 1);',
  19086. ' $mod.THelper.Foo.call(Self, 1);',
  19087. ' $mod.THelper.Foo.call($Self, 1);',
  19088. ' };',
  19089. ' return Result;',
  19090. ' };',
  19091. '});',
  19092. '']),
  19093. LinesToStr([ // $mod.$main
  19094. '']));
  19095. end;
  19096. procedure TTestModule.TestClassHelper_ClassMethod_Call;
  19097. begin
  19098. StartProgram(false);
  19099. Add([
  19100. 'type',
  19101. ' TObject = class',
  19102. ' class procedure Run(w: word = 10);',
  19103. ' end;',
  19104. ' THelper = class helper for TObject',
  19105. ' class function Foo(w: word = 1): word;',
  19106. ' end;',
  19107. 'class procedure TObject.Run(w: word);',
  19108. 'begin',
  19109. ' Foo;',
  19110. ' Foo();',
  19111. ' Self.Foo;',
  19112. ' Self.Foo();',
  19113. ' with Self do begin',
  19114. ' Foo;',
  19115. ' Foo();',
  19116. ' end;',
  19117. 'end;',
  19118. 'class function THelper.foo(w: word): word;',
  19119. 'begin',
  19120. ' Run;',
  19121. ' Run();',
  19122. ' Foo;',
  19123. ' Foo();',
  19124. ' Self.Foo;',
  19125. ' Self.Foo();',
  19126. ' with Self do begin',
  19127. ' Foo;',
  19128. ' Foo();',
  19129. ' end;',
  19130. 'end;',
  19131. 'var',
  19132. ' Obj: TObject;',
  19133. 'begin',
  19134. ' obj.Foo;',
  19135. ' obj.Foo();',
  19136. ' with obj do begin',
  19137. ' Foo;',
  19138. ' Foo();',
  19139. ' end;',
  19140. ' tobject.Foo;',
  19141. ' tobject.Foo();',
  19142. ' with tobject do begin',
  19143. ' Foo;',
  19144. ' Foo();',
  19145. ' end;',
  19146. '']);
  19147. ConvertProgram;
  19148. CheckSource('TestClassHelper_ClassMethod_Call',
  19149. LinesToStr([ // statements
  19150. 'rtl.createClass($mod, "TObject", null, function () {',
  19151. ' this.$init = function () {',
  19152. ' };',
  19153. ' this.$final = function () {',
  19154. ' };',
  19155. ' this.Run = function (w) {',
  19156. ' $mod.THelper.Foo.call(this, 1);',
  19157. ' $mod.THelper.Foo.call(this, 1);',
  19158. ' $mod.THelper.Foo.call(this, 1);',
  19159. ' $mod.THelper.Foo.call(this, 1);',
  19160. ' $mod.THelper.Foo.call(this, 1);',
  19161. ' $mod.THelper.Foo.call(this, 1);',
  19162. ' };',
  19163. '});',
  19164. 'rtl.createHelper($mod, "THelper", null, function () {',
  19165. ' this.Foo = function (w) {',
  19166. ' var Result = 0;',
  19167. ' this.Run(10);',
  19168. ' this.Run(10);',
  19169. ' $mod.THelper.Foo.call(this, 1);',
  19170. ' $mod.THelper.Foo.call(this, 1);',
  19171. ' $mod.THelper.Foo.call(this, 1);',
  19172. ' $mod.THelper.Foo.call(this, 1);',
  19173. ' $mod.THelper.Foo.call(this, 1);',
  19174. ' $mod.THelper.Foo.call(this, 1);',
  19175. ' return Result;',
  19176. ' };',
  19177. '});',
  19178. 'this.Obj = null;',
  19179. '']),
  19180. LinesToStr([ // $mod.$main
  19181. '$mod.THelper.Foo.call($mod.Obj.$class, 1);',
  19182. '$mod.THelper.Foo.call($mod.Obj.$class, 1);',
  19183. 'var $with1 = $mod.Obj;',
  19184. '$mod.THelper.Foo.call($with1.$class, 1);',
  19185. '$mod.THelper.Foo.call($with1.$class, 1);',
  19186. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19187. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19188. 'var $with2 = $mod.TObject;',
  19189. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19190. '$mod.THelper.Foo.call($mod.TObject, 1);',
  19191. '']));
  19192. end;
  19193. procedure TTestModule.TestClassHelper_ClassOf;
  19194. begin
  19195. StartProgram(false);
  19196. Add([
  19197. 'type',
  19198. ' TObject = class',
  19199. ' end;',
  19200. ' TClass = class of TObject;',
  19201. ' THelper = class helper for TObject',
  19202. ' class function Foo(w: word = 1): word;',
  19203. ' end;',
  19204. 'class function THelper.foo(w: word): word;',
  19205. 'begin',
  19206. 'end;',
  19207. 'var',
  19208. ' c: TClass;',
  19209. 'begin',
  19210. ' c.Foo;',
  19211. ' c.Foo();',
  19212. ' with c do begin',
  19213. ' Foo;',
  19214. ' Foo();',
  19215. ' end;',
  19216. '']);
  19217. ConvertProgram;
  19218. CheckSource('TestClassHelper_ClassOf',
  19219. LinesToStr([ // statements
  19220. 'rtl.createClass($mod, "TObject", null, function () {',
  19221. ' this.$init = function () {',
  19222. ' };',
  19223. ' this.$final = function () {',
  19224. ' };',
  19225. '});',
  19226. 'rtl.createHelper($mod, "THelper", null, function () {',
  19227. ' this.Foo = function (w) {',
  19228. ' var Result = 0;',
  19229. ' return Result;',
  19230. ' };',
  19231. '});',
  19232. 'this.c = null;',
  19233. '']),
  19234. LinesToStr([ // $mod.$main
  19235. '$mod.THelper.Foo.call($mod.c, 1);',
  19236. '$mod.THelper.Foo.call($mod.c, 1);',
  19237. 'var $with1 = $mod.c;',
  19238. '$mod.THelper.Foo.call($with1, 1);',
  19239. '$mod.THelper.Foo.call($with1, 1);',
  19240. '']));
  19241. end;
  19242. procedure TTestModule.TestClassHelper_MethodRefObjFPC;
  19243. begin
  19244. StartProgram(false);
  19245. Add([
  19246. '{$mode objfpc}',
  19247. 'type',
  19248. ' TObject = class',
  19249. ' procedure DoIt;',
  19250. ' end;',
  19251. ' THelper = class helper for TObject',
  19252. ' procedure Fly(w: word = 1);',
  19253. ' class procedure Glide(w: word = 1);',
  19254. ' class procedure Run(w: word = 1); static;',
  19255. ' end;',
  19256. ' TFly = procedure(w: word) of object;',
  19257. ' TGlide = TFly;',
  19258. ' TRun = procedure(w: word);',
  19259. 'var',
  19260. ' f: TFly;',
  19261. ' g: TGlide;',
  19262. ' r: TRun;',
  19263. 'procedure TObject.DoIt;',
  19264. 'begin',
  19265. ' f:=@fly;',
  19266. ' g:=@glide;',
  19267. ' r:=@run;',
  19268. ' f:[email protected];',
  19269. ' g:[email protected];',
  19270. ' r:[email protected];',
  19271. ' with self do begin',
  19272. ' f:=@fly;',
  19273. ' g:=@glide;',
  19274. ' r:=@run;',
  19275. ' end;',
  19276. 'end;',
  19277. 'procedure THelper.fly(w: word);',
  19278. 'begin',
  19279. ' f:=@fly;',
  19280. ' g:=@glide;',
  19281. ' r:=@run;',
  19282. 'end;',
  19283. 'class procedure THelper.glide(w: word);',
  19284. 'begin',
  19285. ' g:=@glide;',
  19286. ' r:=@run;',
  19287. 'end;',
  19288. 'class procedure THelper.run(w: word);',
  19289. 'begin',
  19290. ' g:=@glide;',
  19291. ' r:=@run;',
  19292. 'end;',
  19293. 'var',
  19294. ' Obj: TObject;',
  19295. 'begin',
  19296. ' f:[email protected];',
  19297. ' g:[email protected];',
  19298. ' r:[email protected];',
  19299. ' with obj do begin',
  19300. ' f:=@fly;',
  19301. ' g:=@glide;',
  19302. ' r:=@run;',
  19303. ' end;',
  19304. ' g:[email protected];',
  19305. ' r:[email protected];',
  19306. ' with tobject do begin',
  19307. ' g:=@glide;',
  19308. ' r:=@run;',
  19309. ' end;',
  19310. '']);
  19311. ConvertProgram;
  19312. CheckSource('TestClassHelper_MethodRefObjFPC',
  19313. LinesToStr([ // statements
  19314. 'rtl.createClass($mod, "TObject", null, function () {',
  19315. ' this.$init = function () {',
  19316. ' };',
  19317. ' this.$final = function () {',
  19318. ' };',
  19319. ' this.DoIt = function () {',
  19320. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19321. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19322. ' $mod.r = $mod.THelper.Run;',
  19323. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19324. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19325. ' $mod.r = $mod.THelper.Run;',
  19326. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19327. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19328. ' $mod.r = $mod.THelper.Run;',
  19329. ' };',
  19330. '});',
  19331. 'rtl.createHelper($mod, "THelper", null, function () {',
  19332. ' this.Fly = function (w) {',
  19333. ' $mod.f = rtl.createCallback(this, $mod.THelper.Fly);',
  19334. ' $mod.g = rtl.createCallback(this.$class, $mod.THelper.Glide);',
  19335. ' $mod.r = $mod.THelper.Run;',
  19336. ' };',
  19337. ' this.Glide = function (w) {',
  19338. ' $mod.g = rtl.createCallback(this, $mod.THelper.Glide);',
  19339. ' $mod.r = $mod.THelper.Run;',
  19340. ' };',
  19341. ' this.Run = function (w) {',
  19342. ' $mod.g = rtl.createCallback($mod.THelper, $mod.THelper.Glide);',
  19343. ' $mod.r = $mod.THelper.Run;',
  19344. ' };',
  19345. '});',
  19346. 'this.f = null;',
  19347. 'this.g = null;',
  19348. 'this.r = null;',
  19349. 'this.Obj = null;',
  19350. '']),
  19351. LinesToStr([ // $mod.$main
  19352. '$mod.f = rtl.createCallback($mod.Obj, $mod.THelper.Fly);',
  19353. '$mod.g = rtl.createCallback($mod.Obj.$class, $mod.THelper.Glide);',
  19354. '$mod.r = $mod.THelper.Run;',
  19355. 'var $with1 = $mod.Obj;',
  19356. '$mod.f = rtl.createCallback($with1, $mod.THelper.Fly);',
  19357. '$mod.g = rtl.createCallback($with1.$class, $mod.THelper.Glide);',
  19358. '$mod.r = $mod.THelper.Run;',
  19359. '$mod.g = rtl.createCallback($mod.TObject, $mod.THelper.Glide);',
  19360. '$mod.r = $mod.THelper.Run;',
  19361. 'var $with2 = $mod.TObject;',
  19362. '$mod.g = rtl.createCallback($with2, $mod.THelper.Glide);',
  19363. '$mod.r = $mod.THelper.Run;',
  19364. '']));
  19365. end;
  19366. procedure TTestModule.TestClassHelper_Constructor;
  19367. begin
  19368. StartProgram(false);
  19369. Add([
  19370. 'type',
  19371. ' TObject = class',
  19372. ' constructor Create;',
  19373. ' end;',
  19374. ' TClass = class of TObject;',
  19375. ' THelper = class helper for TObject',
  19376. ' constructor NewHlp(w: word);',
  19377. ' end;',
  19378. 'var',
  19379. ' obj: TObject;',
  19380. ' c: TClass;',
  19381. 'constructor TObject.Create;',
  19382. 'begin',
  19383. ' NewHlp(2);', // normal call
  19384. ' tobject.NewHlp(3);', // new instance
  19385. ' c.newhlp(4);', // new instance
  19386. 'end;',
  19387. 'constructor THelper.NewHlp(w: word);',
  19388. 'begin',
  19389. ' create;', // normal call
  19390. ' tobject.create;', // new instance
  19391. ' NewHlp(2);', // normal call
  19392. ' tobject.NewHlp(3);', // new instance
  19393. ' c.newhlp(4);', // new instance
  19394. 'end;',
  19395. 'begin',
  19396. ' obj.newhlp(2);', // normal call
  19397. ' with Obj do newhlp(12);', // normal call
  19398. ' tobject.newhlp(3);', // new instance
  19399. ' with tobject do newhlp(13);', // new instance
  19400. ' c.newhlp(4);', // new instance
  19401. ' with c do newhlp(14);', // new instance
  19402. '']);
  19403. ConvertProgram;
  19404. CheckSource('TestClassHelper_Constructor',
  19405. LinesToStr([ // statements
  19406. 'rtl.createClass($mod, "TObject", null, function () {',
  19407. ' this.$init = function () {',
  19408. ' };',
  19409. ' this.$final = function () {',
  19410. ' };',
  19411. ' this.Create = function () {',
  19412. ' $mod.THelper.NewHlp.call(this, 2);',
  19413. ' $mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  19414. ' $mod.c.$create($mod.THelper.NewHlp, [4]);',
  19415. ' return this;',
  19416. ' };',
  19417. '});',
  19418. 'rtl.createHelper($mod, "THelper", null, function () {',
  19419. ' this.NewHlp = function (w) {',
  19420. ' this.Create();',
  19421. ' $mod.TObject.$create("Create");',
  19422. ' $mod.THelper.NewHlp.call(this, 2);',
  19423. ' $mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  19424. ' $mod.c.$create($mod.THelper.NewHlp, [4]);',
  19425. ' return this;',
  19426. ' };',
  19427. '});',
  19428. 'this.obj = null;',
  19429. 'this.c = null;',
  19430. '']),
  19431. LinesToStr([ // $mod.$main
  19432. '$mod.THelper.NewHlp.call($mod.obj, 2);',
  19433. 'var $with1 = $mod.obj;',
  19434. '$mod.THelper.NewHlp.call($with1, 12);',
  19435. '$mod.TObject.$create($mod.THelper.NewHlp, [3]);',
  19436. 'var $with2 = $mod.TObject;',
  19437. '$with2.$create($mod.THelper.NewHlp, [13]);',
  19438. '$mod.c.$create($mod.THelper.NewHlp, [4]);',
  19439. 'var $with3 = $mod.c;',
  19440. '$with3.$create($mod.THelper.NewHlp, [14]);',
  19441. '']));
  19442. end;
  19443. procedure TTestModule.TestClassHelper_InheritedObjFPC;
  19444. begin
  19445. StartProgram(false);
  19446. Add([
  19447. 'type',
  19448. ' TObject = class',
  19449. ' procedure Fly;',
  19450. ' end;',
  19451. ' TObjHelper = class helper for TObject',
  19452. ' procedure Fly;',
  19453. ' end;',
  19454. ' TBird = class',
  19455. ' procedure Fly;',
  19456. ' end;',
  19457. ' TBirdHelper = class helper for TBird',
  19458. ' procedure Fly;',
  19459. ' procedure Walk(w: word);',
  19460. ' end;',
  19461. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  19462. ' procedure Fly;',
  19463. ' procedure Walk(w: word);',
  19464. ' end;',
  19465. 'procedure Tobject.fly;',
  19466. 'begin',
  19467. ' inherited;', // ignore
  19468. 'end;',
  19469. 'procedure Tobjhelper.fly;',
  19470. 'begin',
  19471. ' {@TObject_Fly}inherited;',
  19472. ' inherited {@TObject_Fly}Fly;',
  19473. 'end;',
  19474. 'procedure Tbird.fly;',
  19475. 'begin',
  19476. ' {@TObjHelper_Fly}inherited;',
  19477. ' inherited {@TObjHelper_Fly}Fly;',
  19478. 'end;',
  19479. 'procedure Tbirdhelper.fly;',
  19480. 'begin',
  19481. ' {@TBird_Fly}inherited;',
  19482. ' inherited {@TBird_Fly}Fly;',
  19483. 'end;',
  19484. 'procedure Tbirdhelper.walk(w: word);',
  19485. 'begin',
  19486. 'end;',
  19487. 'procedure teagleHelper.fly;',
  19488. 'begin',
  19489. ' {@TBird_Fly}inherited;',
  19490. ' inherited {@TBird_Fly}Fly;',
  19491. 'end;',
  19492. 'procedure teagleHelper.walk(w: word);',
  19493. 'begin',
  19494. ' {@TBirdHelper_Walk}inherited;',
  19495. ' inherited {@TBirdHelper_Walk}Walk(3);',
  19496. 'end;',
  19497. 'begin',
  19498. '']);
  19499. ConvertProgram;
  19500. CheckSource('TestClassHelper_InheritedObjFPC',
  19501. LinesToStr([ // statements
  19502. 'rtl.createClass($mod, "TObject", null, function () {',
  19503. ' this.$init = function () {',
  19504. ' };',
  19505. ' this.$final = function () {',
  19506. ' };',
  19507. ' this.Fly = function () {',
  19508. ' };',
  19509. '});',
  19510. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19511. ' this.Fly = function () {',
  19512. ' $mod.TObject.Fly.call(this);',
  19513. ' $mod.TObject.Fly.call(this);',
  19514. ' };',
  19515. '});',
  19516. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19517. ' this.Fly$1 = function () {',
  19518. ' $mod.TObjHelper.Fly.call(this);',
  19519. ' $mod.TObjHelper.Fly.call(this);',
  19520. ' };',
  19521. '});',
  19522. 'rtl.createHelper($mod, "TBirdHelper", null, function () {',
  19523. ' this.Fly = function () {',
  19524. ' $mod.TBird.Fly$1.call(this);',
  19525. ' $mod.TBird.Fly$1.call(this);',
  19526. ' };',
  19527. ' this.Walk = function (w) {',
  19528. ' };',
  19529. '});',
  19530. 'rtl.createHelper($mod, "TEagleHelper", $mod.TBirdHelper, function () {',
  19531. ' this.Fly$1 = function () {',
  19532. ' $mod.TBird.Fly$1.call(this);',
  19533. ' $mod.TBird.Fly$1.call(this);',
  19534. ' };',
  19535. ' this.Walk$1 = function (w) {',
  19536. ' $mod.TBirdHelper.Walk.apply(this, arguments);',
  19537. ' $mod.TBirdHelper.Walk.call(this, 3);',
  19538. ' };',
  19539. '});',
  19540. '']),
  19541. LinesToStr([ // $mod.$main
  19542. '']));
  19543. end;
  19544. procedure TTestModule.TestClassHelper_Property;
  19545. begin
  19546. StartProgram(false);
  19547. Add([
  19548. 'type',
  19549. ' TObject = class',
  19550. ' FSize: word;',
  19551. ' function GetSpeed: word;',
  19552. ' procedure SetSpeed(Value: word);',
  19553. ' end;',
  19554. ' TObjHelper = class helper for TObject',
  19555. ' function GetLeft: word;',
  19556. ' procedure SetLeft(Value: word);',
  19557. ' property Size: word read FSize write FSize;',
  19558. ' property Speed: word read GetSpeed write SetSpeed;',
  19559. ' property Left: word read GetLeft write SetLeft;',
  19560. ' end;',
  19561. ' TBird = class',
  19562. ' property NotRight: word read GetLeft write SetLeft;',
  19563. ' procedure DoIt;',
  19564. ' end;',
  19565. 'var',
  19566. ' b: TBird;',
  19567. 'function Tobject.GetSpeed: word;',
  19568. 'begin',
  19569. ' Size:=Size+11;',
  19570. ' Speed:=Speed+12;',
  19571. ' Result:=Left+13;',
  19572. ' Left:=13;',
  19573. ' Left:=Left+13;',
  19574. ' Self.Size:=Self.Size+21;',
  19575. ' Self.Speed:=Self.Speed+22;',
  19576. ' Self.Left:=Self.Left+23;',
  19577. ' with Self do begin',
  19578. ' Size:=Size+31;',
  19579. ' Speed:=Speed+32;',
  19580. ' Left:=Left+33;',
  19581. ' end;',
  19582. 'end;',
  19583. 'procedure Tobject.SetSpeed(Value: word);',
  19584. 'begin',
  19585. 'end;',
  19586. 'function TObjHelper.GetLeft: word;',
  19587. 'begin',
  19588. ' Size:=Size+11;',
  19589. ' Speed:=Speed+12;',
  19590. ' Left:=Left+13;',
  19591. ' Self.Size:=Self.Size+21;',
  19592. ' Self.Speed:=Self.Speed+22;',
  19593. ' Self.Left:=Self.Left+23;',
  19594. ' with Self do begin',
  19595. ' Size:=Size+31;',
  19596. ' Speed:=Speed+32;',
  19597. ' Left:=Left+33;',
  19598. ' end;',
  19599. 'end;',
  19600. 'procedure TObjHelper.SetLeft(Value: word);',
  19601. 'begin',
  19602. 'end;',
  19603. 'procedure TBird.DoIt;',
  19604. 'begin',
  19605. ' NotRight:=NotRight+11;',
  19606. ' Self.NotRight:=Self.NotRight+21;',
  19607. ' with Self do begin',
  19608. ' NotRight:=NotRight+31;',
  19609. ' end;',
  19610. 'end;',
  19611. 'begin',
  19612. ' b.Size:=b.Size+11;',
  19613. ' b.Speed:=b.Speed+12;',
  19614. ' b.Left:=b.Left+13;',
  19615. ' b.NotRight:=b.NotRight+14;',
  19616. ' with b do begin',
  19617. ' Size:=Size+31;',
  19618. ' Speed:=Speed+32;',
  19619. ' Left:=Left+33;',
  19620. ' NotRight:=NotRight+34;',
  19621. ' end;',
  19622. '']);
  19623. ConvertProgram;
  19624. CheckSource('TestClassHelper_Property',
  19625. LinesToStr([ // statements
  19626. 'rtl.createClass($mod, "TObject", null, function () {',
  19627. ' this.$init = function () {',
  19628. ' this.FSize = 0;',
  19629. ' };',
  19630. ' this.$final = function () {',
  19631. ' };',
  19632. ' this.GetSpeed = function () {',
  19633. ' var Result = 0;',
  19634. ' this.FSize = this.FSize + 11;',
  19635. ' this.SetSpeed(this.GetSpeed() + 12);',
  19636. ' Result = $mod.TObjHelper.GetLeft.call(this) + 13;',
  19637. ' $mod.TObjHelper.SetLeft.call(this, 13);',
  19638. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  19639. ' this.FSize = this.FSize + 21;',
  19640. ' this.SetSpeed(this.GetSpeed() + 22);',
  19641. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  19642. ' this.FSize = this.FSize + 31;',
  19643. ' this.SetSpeed(this.GetSpeed() + 32);',
  19644. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  19645. ' return Result;',
  19646. ' };',
  19647. ' this.SetSpeed = function (Value) {',
  19648. ' };',
  19649. '});',
  19650. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19651. ' this.GetLeft = function () {',
  19652. ' var Result = 0;',
  19653. ' this.FSize = this.FSize + 11;',
  19654. ' this.SetSpeed(this.GetSpeed() + 12);',
  19655. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  19656. ' this.FSize = this.FSize + 21;',
  19657. ' this.SetSpeed(this.GetSpeed() + 22);',
  19658. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  19659. ' this.FSize = this.FSize + 31;',
  19660. ' this.SetSpeed(this.GetSpeed() + 32);',
  19661. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  19662. ' return Result;',
  19663. ' };',
  19664. ' this.SetLeft = function (Value) {',
  19665. ' };',
  19666. '});',
  19667. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19668. ' this.DoIt = function () {',
  19669. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 11);',
  19670. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 21);',
  19671. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 31);',
  19672. ' };',
  19673. '});',
  19674. 'this.b = null;',
  19675. '']),
  19676. LinesToStr([ // $mod.$main
  19677. '$mod.b.FSize = $mod.b.FSize + 11;',
  19678. '$mod.b.SetSpeed($mod.b.GetSpeed() + 12);',
  19679. '$mod.TObjHelper.SetLeft.call($mod.b, $mod.TObjHelper.GetLeft.call($mod.b) + 13);',
  19680. '$mod.TObjHelper.SetLeft.call($mod.b, $mod.TObjHelper.GetLeft.call($mod.b) + 14);',
  19681. 'var $with1 = $mod.b;',
  19682. '$with1.FSize = $with1.FSize + 31;',
  19683. '$with1.SetSpeed($with1.GetSpeed() + 32);',
  19684. '$mod.TObjHelper.SetLeft.call($with1, $mod.TObjHelper.GetLeft.call($with1) + 33);',
  19685. '$mod.TObjHelper.SetLeft.call($with1, $mod.TObjHelper.GetLeft.call($with1) + 34);',
  19686. '']));
  19687. end;
  19688. procedure TTestModule.TestClassHelper_Property_Array;
  19689. begin
  19690. StartProgram(false);
  19691. Add([
  19692. 'type',
  19693. ' TObject = class',
  19694. ' function GetSpeed(Index: boolean): word;',
  19695. ' procedure SetSpeed(Index: boolean; Value: word);',
  19696. ' end;',
  19697. ' TObjHelper = class helper for TObject',
  19698. ' function GetSize(Index: boolean): word;',
  19699. ' procedure SetSize(Index: boolean; Value: word);',
  19700. ' property Size[Index: boolean]: word read GetSize write SetSize;',
  19701. ' property Speed[Index: boolean]: word read GetSpeed write SetSpeed;',
  19702. ' end;',
  19703. ' TBird = class',
  19704. ' property Items[Index: boolean]: word read GetSize write SetSize;',
  19705. ' procedure DoIt;',
  19706. ' end;',
  19707. 'var',
  19708. ' b: TBird;',
  19709. 'function Tobject.GetSpeed(Index: boolean): word;',
  19710. 'begin',
  19711. ' Result:=Size[false];',
  19712. ' Size[true]:=Size[false]+11;',
  19713. ' Speed[true]:=Speed[false]+12;',
  19714. ' Self.Size[true]:=Self.Size[false]+21;',
  19715. ' Self.Speed[true]:=Self.Speed[false]+22;',
  19716. ' with Self do begin',
  19717. ' Size[true]:=Size[false]+31;',
  19718. ' Speed[true]:=Speed[false]+32;',
  19719. ' end;',
  19720. 'end;',
  19721. 'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
  19722. 'begin',
  19723. 'end;',
  19724. 'function TObjHelper.GetSize(Index: boolean): word;',
  19725. 'begin',
  19726. ' Size[true]:=Size[false]+11;',
  19727. ' Speed[true]:=Speed[false]+12;',
  19728. ' Self.Size[true]:=Self.Size[false]+21;',
  19729. ' Self.Speed[true]:=Self.Speed[false]+22;',
  19730. ' with Self do begin',
  19731. ' Size[true]:=Size[false]+31;',
  19732. ' Speed[true]:=Speed[false]+32;',
  19733. ' end;',
  19734. 'end;',
  19735. 'procedure TObjHelper.SetSize(Index: boolean; Value: word);',
  19736. 'begin',
  19737. 'end;',
  19738. 'procedure TBird.DoIt;',
  19739. 'begin',
  19740. ' Items[true]:=Items[false]+11;',
  19741. ' Self.Items[true]:=Self.Items[false]+21;',
  19742. ' with Self do Items[true]:=Items[false]+31;',
  19743. 'end;',
  19744. 'begin',
  19745. ' b.Size[true]:=b.Size[false]+11;',
  19746. ' b.Speed[true]:=b.Speed[false]+12;',
  19747. ' b.Items[true]:=b.Items[false]+13;',
  19748. ' with b do begin',
  19749. ' Size[true]:=Size[false]+21;',
  19750. ' Speed[true]:=Speed[false]+22;',
  19751. ' Items[true]:=Items[false]+23;',
  19752. ' end;',
  19753. '']);
  19754. ConvertProgram;
  19755. CheckSource('TestClassHelper_Property_Array',
  19756. LinesToStr([ // statements
  19757. 'rtl.createClass($mod, "TObject", null, function () {',
  19758. ' this.$init = function () {',
  19759. ' };',
  19760. ' this.$final = function () {',
  19761. ' };',
  19762. ' this.GetSpeed = function (Index) {',
  19763. ' var Result = 0;',
  19764. ' Result = $mod.TObjHelper.GetSize.call(this, false);',
  19765. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  19766. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  19767. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  19768. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  19769. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  19770. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  19771. ' return Result;',
  19772. ' };',
  19773. ' this.SetSpeed = function (Index, Value) {',
  19774. ' };',
  19775. '});',
  19776. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19777. ' this.GetSize = function (Index) {',
  19778. ' var Result = 0;',
  19779. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  19780. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  19781. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  19782. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  19783. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  19784. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  19785. ' return Result;',
  19786. ' };',
  19787. ' this.SetSize = function (Index, Value) {',
  19788. ' };',
  19789. '});',
  19790. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19791. ' this.DoIt = function () {',
  19792. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  19793. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  19794. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  19795. ' };',
  19796. '});',
  19797. 'this.b = null;',
  19798. '']),
  19799. LinesToStr([ // $mod.$main
  19800. '$mod.TObjHelper.SetSize.call($mod.b, true, $mod.TObjHelper.GetSize.call($mod.b, false) + 11);',
  19801. '$mod.b.SetSpeed(true, $mod.b.GetSpeed(false) + 12);',
  19802. '$mod.TObjHelper.SetSize.call($mod.b, true, $mod.TObjHelper.GetSize.call($mod.b, false) + 13);',
  19803. 'var $with1 = $mod.b;',
  19804. '$mod.TObjHelper.SetSize.call($with1, true, $mod.TObjHelper.GetSize.call($with1, false) + 21);',
  19805. '$with1.SetSpeed(true, $with1.GetSpeed(false) + 22);',
  19806. '$mod.TObjHelper.SetSize.call($with1, true, $mod.TObjHelper.GetSize.call($with1, false) + 23);',
  19807. '']));
  19808. end;
  19809. procedure TTestModule.TestClassHelper_Property_Array_Default;
  19810. begin
  19811. StartProgram(false);
  19812. Add([
  19813. 'type',
  19814. ' TObject = class',
  19815. ' function GetSpeed(Index: boolean): word;',
  19816. ' procedure SetSpeed(Index: boolean; Value: word);',
  19817. ' end;',
  19818. ' TObjHelper = class helper for TObject',
  19819. ' property Speed[Index: boolean]: word read GetSpeed write SetSpeed; default;',
  19820. ' end;',
  19821. ' TBird = class',
  19822. ' end;',
  19823. ' TBirdHelper = class helper for TBird',
  19824. ' function GetSize(Index: word): boolean;',
  19825. ' procedure SetSize(Index: word; Value: boolean);',
  19826. ' property Size[Index: word]: boolean read GetSize write SetSize; default;',
  19827. ' end;',
  19828. 'function Tobject.GetSpeed(Index: boolean): word;',
  19829. 'begin',
  19830. ' Self[true]:=Self[false]+1;',
  19831. 'end;',
  19832. 'procedure Tobject.SetSpeed(Index: boolean; Value: word);',
  19833. 'begin',
  19834. 'end;',
  19835. 'function TBirdHelper.GetSize(Index: word): boolean;',
  19836. 'begin',
  19837. ' Self[1]:=not Self[2];',
  19838. 'end;',
  19839. 'procedure TBirdHelper.SetSize(Index: word; Value: boolean);',
  19840. 'begin',
  19841. 'end;',
  19842. 'var',
  19843. ' o: TObject;',
  19844. ' b: TBird;',
  19845. 'begin',
  19846. ' o[true]:=o[false]+1;',
  19847. ' b[3]:=not b[4];',
  19848. '']);
  19849. ConvertProgram;
  19850. CheckSource('TestClassHelper_Property_Array_Default',
  19851. LinesToStr([ // statements
  19852. 'rtl.createClass($mod, "TObject", null, function () {',
  19853. ' this.$init = function () {',
  19854. ' };',
  19855. ' this.$final = function () {',
  19856. ' };',
  19857. ' this.GetSpeed = function (Index) {',
  19858. ' var Result = 0;',
  19859. ' this.SetSpeed(true, this.GetSpeed(false) + 1);',
  19860. ' return Result;',
  19861. ' };',
  19862. ' this.SetSpeed = function (Index, Value) {',
  19863. ' };',
  19864. '});',
  19865. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19866. '});',
  19867. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  19868. '});',
  19869. 'rtl.createHelper($mod, "TBirdHelper", null, function () {',
  19870. ' this.GetSize = function (Index) {',
  19871. ' var Result = false;',
  19872. ' $mod.TBirdHelper.SetSize.call(this, 1, !$mod.TBirdHelper.GetSize.call(this, 2));',
  19873. ' return Result;',
  19874. ' };',
  19875. ' this.SetSize = function (Index, Value) {',
  19876. ' };',
  19877. '});',
  19878. 'this.o = null;',
  19879. 'this.b = null;',
  19880. '']),
  19881. LinesToStr([ // $mod.$main
  19882. '$mod.o.SetSpeed(true, $mod.o.GetSpeed(false) + 1);',
  19883. '$mod.TBirdHelper.SetSize.call($mod.b, 3, !$mod.TBirdHelper.GetSize.call($mod.b, 4));',
  19884. '']));
  19885. end;
  19886. procedure TTestModule.TestClassHelper_Property_Array_DefaultDefault;
  19887. begin
  19888. StartProgram(false);
  19889. Add([
  19890. 'type',
  19891. ' TObject = class',
  19892. ' end;',
  19893. ' TObjHelper = class helper for TObject',
  19894. ' function GetItems(Index: word): TObject;',
  19895. ' procedure SetItems(Index: word; Value: TObject);',
  19896. ' property Items[Index: word]: TObject read GetItems write SetItems; default;',
  19897. ' end;',
  19898. 'function Tobjhelper.GetItems(Index: word): TObject;',
  19899. 'begin',
  19900. ' Self[1][2]:=Self[3][4];',
  19901. 'end;',
  19902. 'procedure Tobjhelper.SetItems(Index: word; Value: TObject);',
  19903. 'begin',
  19904. 'end;',
  19905. 'var',
  19906. ' o: TObject;',
  19907. 'begin',
  19908. ' o[1][2]:=o[3][4];',
  19909. '']);
  19910. ConvertProgram;
  19911. CheckSource('TestClassHelper_Property_Array_DefaultDefault',
  19912. LinesToStr([ // statements
  19913. 'rtl.createClass($mod, "TObject", null, function () {',
  19914. ' this.$init = function () {',
  19915. ' };',
  19916. ' this.$final = function () {',
  19917. ' };',
  19918. '});',
  19919. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  19920. ' this.GetItems = function (Index) {',
  19921. ' var Result = null;',
  19922. ' $mod.TObjHelper.SetItems.call($mod.TObjHelper.GetItems.call(this, 1), 2, $mod.TObjHelper.GetItems.call($mod.TObjHelper.GetItems.call(this, 3), 4));',
  19923. ' return Result;',
  19924. ' };',
  19925. ' this.SetItems = function (Index, Value) {',
  19926. ' };',
  19927. '});',
  19928. 'this.o = null;',
  19929. '']),
  19930. LinesToStr([ // $mod.$main
  19931. '$mod.TObjHelper.SetItems.call($mod.TObjHelper.GetItems.call($mod.o, 1), 2, $mod.TObjHelper.GetItems.call($mod.TObjHelper.GetItems.call($mod.o, 3), 4));',
  19932. '']));
  19933. end;
  19934. procedure TTestModule.TestClassHelper_ClassProperty;
  19935. begin
  19936. StartProgram(false);
  19937. Add([
  19938. 'type',
  19939. ' TObject = class',
  19940. ' class var FSize: word;',
  19941. ' class function GetSpeed: word;',
  19942. ' class procedure SetSpeed(Value: word); virtual; abstract;',
  19943. ' end;',
  19944. ' TObjHelper = class helper for TObject',
  19945. ' class function GetLeft: word;',
  19946. ' class procedure SetLeft(Value: word);',
  19947. ' class property Size: word read FSize write FSize;',
  19948. ' class property Speed: word read GetSpeed write SetSpeed;',
  19949. ' class property Left: word read GetLeft write SetLeft;',
  19950. ' end;',
  19951. ' TBird = class',
  19952. ' class property NotRight: word read GetLeft write SetLeft;',
  19953. ' class procedure DoIt;',
  19954. ' end;',
  19955. ' TBirdClass = class of TBird;',
  19956. 'class function Tobject.GetSpeed: word;',
  19957. 'begin',
  19958. ' Size:=Size+11;',
  19959. ' Speed:=Speed+12;',
  19960. ' Left:=Left+13;',
  19961. ' Self.Size:=Self.Size+21;',
  19962. ' Self.Speed:=Self.Speed+22;',
  19963. ' Self.Left:=Self.Left+23;',
  19964. ' with Self do begin',
  19965. ' Size:=Size+31;',
  19966. ' Speed:=Speed+32;',
  19967. ' Left:=Left+33;',
  19968. ' end;',
  19969. 'end;',
  19970. 'class function TObjHelper.GetLeft: word;',
  19971. 'begin',
  19972. ' Size:=Size+11;',
  19973. ' Speed:=Speed+12;',
  19974. ' Left:=Left+13;',
  19975. ' Self.Size:=Self.Size+21;',
  19976. ' Self.Speed:=Self.Speed+22;',
  19977. ' Self.Left:=Self.Left+23;',
  19978. ' with Self do begin',
  19979. ' Size:=Size+31;',
  19980. ' Speed:=Speed+32;',
  19981. ' Left:=Left+33;',
  19982. ' end;',
  19983. 'end;',
  19984. 'class procedure TObjHelper.SetLeft(Value: word);',
  19985. 'begin',
  19986. 'end;',
  19987. 'class procedure TBird.DoIt;',
  19988. 'begin',
  19989. ' NotRight:=NotRight+11;',
  19990. ' Self.NotRight:=Self.NotRight+21;',
  19991. ' with Self do NotRight:=NotRight+31;',
  19992. 'end;',
  19993. 'var',
  19994. ' b: TBird;',
  19995. ' c: TBirdClass;',
  19996. 'begin',
  19997. ' b.Size:=b.Size+11;',
  19998. ' b.Speed:=b.Speed+12;',
  19999. ' b.Left:=b.Left+13;',
  20000. ' b.NotRight:=b.NotRight+14;',
  20001. ' with b do begin',
  20002. ' Size:=Size+31;',
  20003. ' Speed:=Speed+32;',
  20004. ' Left:=Left+33;',
  20005. ' NotRight:=NotRight+34;',
  20006. ' end;',
  20007. ' c.Size:=c.Size+11;',
  20008. ' c.Speed:=c.Speed+12;',
  20009. ' c.Left:=c.Left+13;',
  20010. ' c.NotRight:=c.NotRight+14;',
  20011. ' with c do begin',
  20012. ' Size:=Size+31;',
  20013. ' Speed:=Speed+32;',
  20014. ' Left:=Left+33;',
  20015. ' NotRight:=NotRight+34;',
  20016. ' end;',
  20017. ' tbird.Size:=tbird.Size+11;',
  20018. ' tbird.Speed:=tbird.Speed+12;',
  20019. ' tbird.Left:=tbird.Left+13;',
  20020. ' tbird.NotRight:=tbird.NotRight+14;',
  20021. ' with tbird do begin',
  20022. ' Size:=Size+31;',
  20023. ' Speed:=Speed+32;',
  20024. ' Left:=Left+33;',
  20025. ' NotRight:=NotRight+34;',
  20026. ' end;',
  20027. '']);
  20028. ConvertProgram;
  20029. CheckSource('TestClassHelper_ClassProperty',
  20030. LinesToStr([ // statements
  20031. 'rtl.createClass($mod, "TObject", null, function () {',
  20032. ' this.FSize = 0;',
  20033. ' this.$init = function () {',
  20034. ' };',
  20035. ' this.$final = function () {',
  20036. ' };',
  20037. ' this.GetSpeed = function () {',
  20038. ' var Result = 0;',
  20039. ' $mod.TObject.FSize = this.FSize + 11;',
  20040. ' this.SetSpeed(this.GetSpeed() + 12);',
  20041. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  20042. ' $mod.TObject.FSize = this.FSize + 21;',
  20043. ' this.SetSpeed(this.GetSpeed() + 22);',
  20044. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  20045. ' $mod.TObject.FSize = this.FSize + 31;',
  20046. ' this.SetSpeed(this.GetSpeed() + 32);',
  20047. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  20048. ' return Result;',
  20049. ' };',
  20050. '});',
  20051. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  20052. ' this.GetLeft = function () {',
  20053. ' var Result = 0;',
  20054. ' $mod.TObject.FSize = this.FSize + 11;',
  20055. ' this.SetSpeed(this.GetSpeed() + 12);',
  20056. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 13);',
  20057. ' $mod.TObject.FSize = this.FSize + 21;',
  20058. ' this.SetSpeed(this.GetSpeed() + 22);',
  20059. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 23);',
  20060. ' $mod.TObject.FSize = this.FSize + 31;',
  20061. ' this.SetSpeed(this.GetSpeed() + 32);',
  20062. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 33);',
  20063. ' return Result;',
  20064. ' };',
  20065. ' this.SetLeft = function (Value) {',
  20066. ' };',
  20067. '});',
  20068. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20069. ' this.DoIt = function () {',
  20070. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 11);',
  20071. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 21);',
  20072. ' $mod.TObjHelper.SetLeft.call(this, $mod.TObjHelper.GetLeft.call(this) + 31);',
  20073. ' };',
  20074. '});',
  20075. 'this.b = null;',
  20076. 'this.c = null;',
  20077. '']),
  20078. LinesToStr([ // $mod.$main
  20079. '$mod.TObject.FSize = $mod.b.FSize + 11;',
  20080. '$mod.b.$class.SetSpeed($mod.b.$class.GetSpeed() + 12);',
  20081. '$mod.TObjHelper.SetLeft.call($mod.b.$class, $mod.TObjHelper.GetLeft.call($mod.b.$class) + 13);',
  20082. '$mod.TObjHelper.SetLeft.call($mod.b.$class, $mod.TObjHelper.GetLeft.call($mod.b.$class) + 14);',
  20083. 'var $with1 = $mod.b;',
  20084. '$mod.TObject.FSize = $with1.FSize + 31;',
  20085. '$with1.$class.SetSpeed($with1.$class.GetSpeed() + 32);',
  20086. '$mod.TObjHelper.SetLeft.call($with1.$class, $mod.TObjHelper.GetLeft.call($with1.$class) + 33);',
  20087. '$mod.TObjHelper.SetLeft.call($with1.$class, $mod.TObjHelper.GetLeft.call($with1.$class) + 34);',
  20088. '$mod.TObject.FSize = $mod.c.FSize + 11;',
  20089. '$mod.c.SetSpeed($mod.c.GetSpeed() + 12);',
  20090. '$mod.TObjHelper.SetLeft.call($mod.c, $mod.TObjHelper.GetLeft.call($mod.c) + 13);',
  20091. '$mod.TObjHelper.SetLeft.call($mod.c, $mod.TObjHelper.GetLeft.call($mod.c) + 14);',
  20092. 'var $with2 = $mod.c;',
  20093. '$mod.TObject.FSize = $with2.FSize + 31;',
  20094. '$with2.SetSpeed($with2.GetSpeed() + 32);',
  20095. '$mod.TObjHelper.SetLeft.call($with2, $mod.TObjHelper.GetLeft.call($with2) + 33);',
  20096. '$mod.TObjHelper.SetLeft.call($with2, $mod.TObjHelper.GetLeft.call($with2) + 34);',
  20097. '$mod.TObject.FSize = $mod.TBird.FSize + 11;',
  20098. '$mod.TBird.SetSpeed($mod.TBird.GetSpeed() + 12);',
  20099. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 13);',
  20100. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 14);',
  20101. 'var $with3 = $mod.TBird;',
  20102. '$mod.TObject.FSize = $with3.FSize + 31;',
  20103. '$with3.SetSpeed($with3.GetSpeed() + 32);',
  20104. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 33);',
  20105. '$mod.TObjHelper.SetLeft.call($mod.TBird, $mod.TObjHelper.GetLeft.call($mod.TBird) + 34);',
  20106. '']));
  20107. end;
  20108. procedure TTestModule.TestClassHelper_ClassPropertyStatic;
  20109. begin
  20110. StartProgram(false);
  20111. Add([
  20112. 'type',
  20113. ' TObject = class',
  20114. ' class function GetSpeed: word; static;',
  20115. ' class procedure SetSpeed(Value: word); static;',
  20116. ' end;',
  20117. ' TObjHelper = class helper for TObject',
  20118. ' class function GetLeft: word; static;',
  20119. ' class procedure SetLeft(Value: word); static;',
  20120. ' class property Speed: word read GetSpeed write SetSpeed;',
  20121. ' class property Left: word read GetLeft write SetLeft;',
  20122. ' end;',
  20123. ' TBird = class',
  20124. ' class property NotRight: word read GetLeft write SetLeft;',
  20125. ' class procedure DoIt; static;',
  20126. ' class procedure DoSome;',
  20127. ' end;',
  20128. ' TBirdClass = class of TBird;',
  20129. 'class function Tobject.GetSpeed: word;',
  20130. 'begin',
  20131. ' Speed:=Speed+12;',
  20132. ' Left:=Left+13;',
  20133. 'end;',
  20134. 'class procedure TObject.SetSpeed(Value: word);',
  20135. 'begin',
  20136. 'end;',
  20137. 'class function TObjHelper.GetLeft: word;',
  20138. 'begin',
  20139. ' Speed:=Speed+12;',
  20140. ' Left:=Left+13;',
  20141. 'end;',
  20142. 'class procedure TObjHelper.SetLeft(Value: word);',
  20143. 'begin',
  20144. 'end;',
  20145. 'class procedure TBird.DoIt;',
  20146. 'begin',
  20147. ' NotRight:=NotRight+11;',
  20148. 'end;',
  20149. 'class procedure TBird.DoSome;',
  20150. 'begin',
  20151. ' Speed:=Speed+12;',
  20152. ' Left:=Left+13;',
  20153. ' Self.Speed:=Self.Speed+22;',
  20154. ' Self.Left:=Self.Left+23;',
  20155. ' with Self do begin',
  20156. ' Speed:=Speed+32;',
  20157. ' Left:=Left+33;',
  20158. ' end;',
  20159. ' NotRight:=NotRight+11;',
  20160. ' Self.NotRight:=Self.NotRight+21;',
  20161. ' with Self do NotRight:=NotRight+31;',
  20162. 'end;',
  20163. 'var',
  20164. ' b: TBird;',
  20165. ' c: TBirdClass;',
  20166. 'begin',
  20167. ' b.Speed:=b.Speed+12;',
  20168. ' b.Left:=b.Left+13;',
  20169. ' b.NotRight:=b.NotRight+14;',
  20170. ' with b do begin',
  20171. ' Speed:=Speed+32;',
  20172. ' Left:=Left+33;',
  20173. ' NotRight:=NotRight+34;',
  20174. ' end;',
  20175. ' c.Speed:=c.Speed+12;',
  20176. ' c.Left:=c.Left+13;',
  20177. ' c.NotRight:=c.NotRight+14;',
  20178. ' with c do begin',
  20179. ' Speed:=Speed+32;',
  20180. ' Left:=Left+33;',
  20181. ' NotRight:=NotRight+34;',
  20182. ' end;',
  20183. ' tbird.Speed:=tbird.Speed+12;',
  20184. ' tbird.Left:=tbird.Left+13;',
  20185. ' tbird.NotRight:=tbird.NotRight+14;',
  20186. ' with tbird do begin',
  20187. ' Speed:=Speed+32;',
  20188. ' Left:=Left+33;',
  20189. ' NotRight:=NotRight+34;',
  20190. ' end;',
  20191. '']);
  20192. ConvertProgram;
  20193. CheckSource('TestClassHelper_ClassPropertyStatic',
  20194. LinesToStr([ // statements
  20195. 'rtl.createClass($mod, "TObject", null, function () {',
  20196. ' this.$init = function () {',
  20197. ' };',
  20198. ' this.$final = function () {',
  20199. ' };',
  20200. ' this.GetSpeed = function () {',
  20201. ' var Result = 0;',
  20202. ' this.SetSpeed(this.GetSpeed() + 12);',
  20203. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20204. ' return Result;',
  20205. ' };',
  20206. ' this.SetSpeed = function (Value) {',
  20207. ' };',
  20208. '});',
  20209. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  20210. ' this.GetLeft = function () {',
  20211. ' var Result = 0;',
  20212. ' this.SetSpeed(this.GetSpeed() + 12);',
  20213. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20214. ' return Result;',
  20215. ' };',
  20216. ' this.SetLeft = function (Value) {',
  20217. ' };',
  20218. '});',
  20219. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20220. ' this.DoIt = function () {',
  20221. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 11);',
  20222. ' };',
  20223. ' this.DoSome = function () {',
  20224. ' this.SetSpeed(this.GetSpeed() + 12);',
  20225. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20226. ' this.SetSpeed(this.GetSpeed() + 22);',
  20227. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 23);',
  20228. ' this.SetSpeed(this.GetSpeed() + 32);',
  20229. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20230. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 11);',
  20231. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 21);',
  20232. ' $mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 31);',
  20233. ' };',
  20234. '});',
  20235. 'this.b = null;',
  20236. 'this.c = null;',
  20237. '']),
  20238. LinesToStr([ // $mod.$main
  20239. '$mod.b.SetSpeed($mod.b.GetSpeed() + 12);',
  20240. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20241. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  20242. 'var $with1 = $mod.b;',
  20243. '$with1.SetSpeed($with1.GetSpeed() + 32);',
  20244. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20245. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  20246. '$mod.c.SetSpeed($mod.c.GetSpeed() + 12);',
  20247. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20248. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  20249. 'var $with2 = $mod.c;',
  20250. '$with2.SetSpeed($with2.GetSpeed() + 32);',
  20251. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20252. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  20253. '$mod.TBird.SetSpeed($mod.TBird.GetSpeed() + 12);',
  20254. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 13);',
  20255. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 14);',
  20256. 'var $with3 = $mod.TBird;',
  20257. '$with3.SetSpeed($with3.GetSpeed() + 32);',
  20258. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 33);',
  20259. '$mod.TObjHelper.SetLeft($mod.TObjHelper.GetLeft() + 34);',
  20260. '']));
  20261. end;
  20262. procedure TTestModule.TestClassHelper_ClassProperty_Array;
  20263. begin
  20264. StartProgram(false);
  20265. Add([
  20266. 'type',
  20267. ' TObject = class',
  20268. ' class function GetSpeed(Index: boolean): word;',
  20269. ' class procedure SetSpeed(Index: boolean; Value: word); virtual; abstract;',
  20270. ' end;',
  20271. ' TObjHelper = class helper for TObject',
  20272. ' class function GetSize(Index: boolean): word;',
  20273. ' class procedure SetSize(Index: boolean; Value: word);',
  20274. ' class property Size[Index: boolean]: word read GetSize write SetSize;',
  20275. ' class property Speed[Index: boolean]: word read GetSpeed write SetSpeed;',
  20276. ' end;',
  20277. ' TBird = class',
  20278. ' class property Items[Index: boolean]: word read GetSize write SetSize;',
  20279. ' class procedure DoIt;',
  20280. ' end;',
  20281. ' TBirdClass = class of TBird;',
  20282. 'class function Tobject.GetSpeed(Index: boolean): word;',
  20283. 'begin',
  20284. ' Size[true]:=Size[false]+11;',
  20285. ' Speed[true]:=Speed[false]+12;',
  20286. ' Self.Size[true]:=Self.Size[false]+21;',
  20287. ' Self.Speed[true]:=Self.Speed[false]+22;',
  20288. ' with Self do begin',
  20289. ' Size[true]:=Size[false]+31;',
  20290. ' Speed[true]:=Speed[false]+32;',
  20291. ' end;',
  20292. 'end;',
  20293. 'class function TObjHelper.GetSize(Index: boolean): word;',
  20294. 'begin',
  20295. ' Size[true]:=Size[false]+11;',
  20296. ' Speed[true]:=Speed[false]+12;',
  20297. ' Self.Size[true]:=Self.Size[false]+21;',
  20298. ' Self.Speed[true]:=Self.Speed[false]+22;',
  20299. ' with Self do begin',
  20300. ' Size[true]:=Size[false]+31;',
  20301. ' Speed[true]:=Speed[false]+32;',
  20302. ' end;',
  20303. 'end;',
  20304. 'class procedure TObjHelper.SetSize(Index: boolean; Value: word);',
  20305. 'begin',
  20306. 'end;',
  20307. 'class procedure TBird.DoIt;',
  20308. 'begin',
  20309. ' Items[true]:=Items[false]+11;',
  20310. ' Self.Items[true]:=Self.Items[false]+21;',
  20311. ' with Self do Items[true]:=Items[false]+31;',
  20312. 'end;',
  20313. 'var',
  20314. ' b: TBird;',
  20315. ' c: TBirdClass;',
  20316. 'begin',
  20317. ' b.Size[true]:=b.Size[false]+11;',
  20318. ' b.Speed[true]:=b.Speed[false]+12;',
  20319. ' b.Items[true]:=b.Items[false]+13;',
  20320. ' with b do begin',
  20321. ' Size[true]:=Size[false]+21;',
  20322. ' Speed[true]:=Speed[false]+22;',
  20323. ' Items[true]:=Items[false]+23;',
  20324. ' end;',
  20325. ' c.Size[true]:=c.Size[false]+11;',
  20326. ' c.Speed[true]:=c.Speed[false]+12;',
  20327. ' c.Items[true]:=c.Items[false]+13;',
  20328. ' with c do begin',
  20329. ' Size[true]:=Size[false]+21;',
  20330. ' Speed[true]:=Speed[false]+22;',
  20331. ' Items[true]:=Items[false]+23;',
  20332. ' end;',
  20333. ' TBird.Size[true]:=TBird.Size[false]+11;',
  20334. ' TBird.Speed[true]:=TBird.Speed[false]+12;',
  20335. ' TBird.Items[true]:=TBird.Items[false]+13;',
  20336. ' with TBird do begin',
  20337. ' Size[true]:=Size[false]+21;',
  20338. ' Speed[true]:=Speed[false]+22;',
  20339. ' Items[true]:=Items[false]+23;',
  20340. ' end;',
  20341. '']);
  20342. ConvertProgram;
  20343. CheckSource('TestClassHelper_ClassProperty_Array',
  20344. LinesToStr([ // statements
  20345. 'rtl.createClass($mod, "TObject", null, function () {',
  20346. ' this.$init = function () {',
  20347. ' };',
  20348. ' this.$final = function () {',
  20349. ' };',
  20350. ' this.GetSpeed = function (Index) {',
  20351. ' var Result = 0;',
  20352. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  20353. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  20354. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  20355. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  20356. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  20357. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  20358. ' return Result;',
  20359. ' };',
  20360. '});',
  20361. 'rtl.createHelper($mod, "TObjHelper", null, function () {',
  20362. ' this.GetSize = function (Index) {',
  20363. ' var Result = 0;',
  20364. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  20365. ' this.SetSpeed(true, this.GetSpeed(false) + 12);',
  20366. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  20367. ' this.SetSpeed(true, this.GetSpeed(false) + 22);',
  20368. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  20369. ' this.SetSpeed(true, this.GetSpeed(false) + 32);',
  20370. ' return Result;',
  20371. ' };',
  20372. ' this.SetSize = function (Index, Value) {',
  20373. ' };',
  20374. '});',
  20375. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20376. ' this.DoIt = function () {',
  20377. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 11);',
  20378. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 21);',
  20379. ' $mod.TObjHelper.SetSize.call(this, true, $mod.TObjHelper.GetSize.call(this, false) + 31);',
  20380. ' };',
  20381. '});',
  20382. 'this.b = null;',
  20383. 'this.c = null;',
  20384. '']),
  20385. LinesToStr([ // $mod.$main
  20386. '$mod.TObjHelper.SetSize.call($mod.b.$class, true, $mod.TObjHelper.GetSize.call($mod.b.$class, false) + 11);',
  20387. '$mod.b.$class.SetSpeed(true, $mod.b.$class.GetSpeed(false) + 12);',
  20388. '$mod.TObjHelper.SetSize.call($mod.b.$class, true, $mod.TObjHelper.GetSize.call($mod.b.$class, false) + 13);',
  20389. 'var $with1 = $mod.b;',
  20390. '$mod.TObjHelper.SetSize.call($with1.$class, true, $mod.TObjHelper.GetSize.call($with1.$class, false) + 21);',
  20391. '$with1.$class.SetSpeed(true, $with1.$class.GetSpeed(false) + 22);',
  20392. '$mod.TObjHelper.SetSize.call($with1.$class, true, $mod.TObjHelper.GetSize.call($with1.$class, false) + 23);',
  20393. '$mod.TObjHelper.SetSize.call($mod.c, true, $mod.TObjHelper.GetSize.call($mod.c, false) + 11);',
  20394. '$mod.c.SetSpeed(true, $mod.c.GetSpeed(false) + 12);',
  20395. '$mod.TObjHelper.SetSize.call($mod.c, true, $mod.TObjHelper.GetSize.call($mod.c, false) + 13);',
  20396. 'var $with2 = $mod.c;',
  20397. '$mod.TObjHelper.SetSize.call($with2, true, $mod.TObjHelper.GetSize.call($with2, false) + 21);',
  20398. '$with2.SetSpeed(true, $with2.GetSpeed(false) + 22);',
  20399. '$mod.TObjHelper.SetSize.call($with2, true, $mod.TObjHelper.GetSize.call($with2, false) + 23);',
  20400. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 11);',
  20401. '$mod.TBird.SetSpeed(true, $mod.TBird.GetSpeed(false) + 12);',
  20402. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 13);',
  20403. 'var $with3 = $mod.TBird;',
  20404. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 21);',
  20405. '$with3.SetSpeed(true, $with3.GetSpeed(false) + 22);',
  20406. '$mod.TObjHelper.SetSize.call($mod.TBird, true, $mod.TObjHelper.GetSize.call($mod.TBird, false) + 23);',
  20407. '']));
  20408. end;
  20409. procedure TTestModule.TestClassHelper_ForIn;
  20410. begin
  20411. StartProgram(false);
  20412. Add([
  20413. 'type',
  20414. ' TObject = class end;',
  20415. ' TItem = TObject;',
  20416. ' TEnumerator = class',
  20417. ' FCurrent: TItem;',
  20418. ' property Current: TItem read FCurrent;',
  20419. ' function MoveNext: boolean;',
  20420. ' end;',
  20421. ' TBird = class',
  20422. ' end;',
  20423. ' TBirdHelper = class helper for TBird',
  20424. ' function GetEnumerator: TEnumerator;',
  20425. ' end;',
  20426. 'function TEnumerator.MoveNext: boolean;',
  20427. 'begin',
  20428. 'end;',
  20429. 'function TBirdHelper.GetEnumerator: TEnumerator;',
  20430. 'begin',
  20431. 'end;',
  20432. 'var',
  20433. ' b: TBird;',
  20434. ' i, i2: TItem;',
  20435. 'begin',
  20436. ' for i in b do i2:=i;']);
  20437. ConvertProgram;
  20438. CheckSource('TestClassHelper_ForIn',
  20439. LinesToStr([ // statements
  20440. 'rtl.createClass($mod, "TObject", null, function () {',
  20441. ' this.$init = function () {',
  20442. ' };',
  20443. ' this.$final = function () {',
  20444. ' };',
  20445. '});',
  20446. 'rtl.createClass($mod, "TEnumerator", $mod.TObject, function () {',
  20447. ' this.$init = function () {',
  20448. ' $mod.TObject.$init.call(this);',
  20449. ' this.FCurrent = null;',
  20450. ' };',
  20451. ' this.$final = function () {',
  20452. ' this.FCurrent = undefined;',
  20453. ' $mod.TObject.$final.call(this);',
  20454. ' };',
  20455. ' this.MoveNext = function () {',
  20456. ' var Result = false;',
  20457. ' return Result;',
  20458. ' };',
  20459. '});',
  20460. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  20461. '});',
  20462. 'rtl.createHelper($mod, "TBirdHelper", null, function () {',
  20463. ' this.GetEnumerator = function () {',
  20464. ' var Result = null;',
  20465. ' return Result;',
  20466. ' };',
  20467. '});',
  20468. 'this.b = null;',
  20469. 'this.i = null;',
  20470. 'this.i2 = null;'
  20471. ]),
  20472. LinesToStr([ // $mod.$main
  20473. 'var $in1 = $mod.TBirdHelper.GetEnumerator.call($mod.b);',
  20474. 'try {',
  20475. ' while ($in1.MoveNext()){',
  20476. ' $mod.i = $in1.FCurrent;',
  20477. ' $mod.i2 = $mod.i;',
  20478. ' }',
  20479. '} finally {',
  20480. ' $in1 = rtl.freeLoc($in1)',
  20481. '};',
  20482. '']));
  20483. end;
  20484. procedure TTestModule.TestClassHelper_PassProperty;
  20485. begin
  20486. StartProgram(false);
  20487. Add([
  20488. 'type',
  20489. ' TObject = class',
  20490. ' FField: TObject;',
  20491. ' property Field: TObject read FField write FField;',
  20492. ' end;',
  20493. ' THelper = class helper for TObject',
  20494. ' procedure Fly;',
  20495. ' class procedure Run;',
  20496. ' class procedure Jump; static;',
  20497. ' end;',
  20498. 'procedure THelper.Fly;',
  20499. 'begin',
  20500. ' Field.Fly;',
  20501. ' Field.Run;',
  20502. ' Field.Jump;',
  20503. ' with Field do begin',
  20504. ' Fly;',
  20505. ' Run;',
  20506. ' Jump;',
  20507. ' end;',
  20508. 'end;',
  20509. 'class procedure THelper.Run;',
  20510. 'begin',
  20511. 'end;',
  20512. 'class procedure THelper.Jump;',
  20513. 'begin',
  20514. 'end;',
  20515. 'var',
  20516. ' b: TObject;',
  20517. 'begin',
  20518. ' b.Field.Fly;',
  20519. ' b.Field.Run;',
  20520. ' b.Field.Jump;',
  20521. ' with b do begin',
  20522. ' Field.Run;',
  20523. ' Field.Fly;',
  20524. ' Field.Jump;',
  20525. ' end;',
  20526. ' with b.Field do begin',
  20527. ' Run;',
  20528. ' Fly;',
  20529. ' Jump;',
  20530. ' end;',
  20531. '']);
  20532. ConvertProgram;
  20533. CheckSource('TestClassHelper_PassProperty',
  20534. LinesToStr([ // statements
  20535. 'rtl.createClass($mod, "TObject", null, function () {',
  20536. ' this.$init = function () {',
  20537. ' this.FField = null;',
  20538. ' };',
  20539. ' this.$final = function () {',
  20540. ' this.FField = undefined;',
  20541. ' };',
  20542. '});',
  20543. 'rtl.createHelper($mod, "THelper", null, function () {',
  20544. ' this.Fly = function () {',
  20545. ' $mod.THelper.Fly.call(this.FField);',
  20546. ' $mod.THelper.Run.call(this.FField.$class);',
  20547. ' $mod.THelper.Jump();',
  20548. ' var $with1 = this.FField;',
  20549. ' $mod.THelper.Fly.call($with1);',
  20550. ' $mod.THelper.Run.call($with1.$class);',
  20551. ' $mod.THelper.Jump();',
  20552. ' };',
  20553. ' this.Run = function () {',
  20554. ' };',
  20555. ' this.Jump = function () {',
  20556. ' };',
  20557. '});',
  20558. 'this.b = null;',
  20559. '']),
  20560. LinesToStr([ // $mod.$main
  20561. '$mod.THelper.Fly.call($mod.b.FField);',
  20562. '$mod.THelper.Run.call($mod.b.FField.$class);',
  20563. '$mod.THelper.Jump();',
  20564. 'var $with1 = $mod.b;',
  20565. '$mod.THelper.Run.call($with1.FField.$class);',
  20566. '$mod.THelper.Fly.call($with1.FField);',
  20567. '$mod.THelper.Jump();',
  20568. 'var $with2 = $mod.b.FField;',
  20569. '$mod.THelper.Run.call($with2.$class);',
  20570. '$mod.THelper.Fly.call($with2);',
  20571. '$mod.THelper.Jump();',
  20572. '']));
  20573. end;
  20574. procedure TTestModule.TestExtClassHelper_ClassVar;
  20575. begin
  20576. StartProgram(false);
  20577. Add([
  20578. '{$modeswitch externalclass}',
  20579. 'type',
  20580. ' TExtA = class external name ''ExtObj''',
  20581. ' end;',
  20582. ' THelper = class helper for TExtA',
  20583. ' const',
  20584. ' One = 1;',
  20585. ' Two: word = 2;',
  20586. ' class var',
  20587. ' Glob: word;',
  20588. ' function Foo(w: word): word;',
  20589. ' class function Bar(w: word): word; static;',
  20590. ' end;',
  20591. 'function THelper.foo(w: word): word;',
  20592. 'begin',
  20593. ' Result:=w;',
  20594. ' Two:=One+w;',
  20595. ' Glob:=Glob;',
  20596. ' Result:=Self.Glob;',
  20597. ' Self.Glob:=Self.Glob;',
  20598. ' with Self do Glob:=Glob;',
  20599. 'end;',
  20600. 'class function THelper.bar(w: word): word;',
  20601. 'begin',
  20602. ' Result:=w;',
  20603. ' Two:=One;',
  20604. ' Glob:=Glob;',
  20605. 'end;',
  20606. 'var o: TExtA;',
  20607. 'begin',
  20608. ' texta.two:=texta.one;',
  20609. ' texta.Glob:=texta.Glob;',
  20610. ' with texta do begin',
  20611. ' two:=one;',
  20612. ' Glob:=Glob;',
  20613. ' end;',
  20614. ' o.two:=o.one;',
  20615. ' o.Glob:=o.Glob;',
  20616. ' with o do begin',
  20617. ' two:=one;',
  20618. ' Glob:=Glob;',
  20619. ' end;',
  20620. '']);
  20621. ConvertProgram;
  20622. CheckSource('TestExtClassHelper_ClassVar',
  20623. LinesToStr([ // statements
  20624. 'rtl.createHelper($mod, "THelper", null, function () {',
  20625. ' this.One = 1;',
  20626. ' this.Two = 2;',
  20627. ' this.Glob = 0;',
  20628. ' this.Foo = function (w) {',
  20629. ' var Result = 0;',
  20630. ' Result = w;',
  20631. ' $mod.THelper.Two = 1 + w;',
  20632. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20633. ' Result = $mod.THelper.Glob;',
  20634. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20635. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20636. ' return Result;',
  20637. ' };',
  20638. ' this.Bar = function (w) {',
  20639. ' var Result = 0;',
  20640. ' Result = w;',
  20641. ' $mod.THelper.Two = 1;',
  20642. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20643. ' return Result;',
  20644. ' };',
  20645. '});',
  20646. 'this.o = null;',
  20647. '']),
  20648. LinesToStr([ // $mod.$main
  20649. '$mod.THelper.Two = 1;',
  20650. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20651. '$mod.THelper.Two = 1;',
  20652. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20653. '$mod.THelper.Two = 1;',
  20654. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20655. 'var $with1 = $mod.o;',
  20656. '$mod.THelper.Two = 1;',
  20657. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20658. '']));
  20659. end;
  20660. procedure TTestModule.TestExtClassHelper_Method_Call;
  20661. begin
  20662. StartProgram(false);
  20663. Add([
  20664. '{$modeswitch externalclass}',
  20665. 'type',
  20666. ' TFly = function(w: word): word of object;',
  20667. ' TExtA = class external name ''ExtObj''',
  20668. ' procedure Run(w: word = 10);',
  20669. ' end;',
  20670. ' THelper = class helper for TExtA',
  20671. ' function Foo(w: word = 1): word;',
  20672. ' function Fly(w: word = 2): word; external name ''Fly'';',
  20673. ' end;',
  20674. 'var p: TFly;',
  20675. 'function THelper.foo(w: word): word;',
  20676. 'begin',
  20677. ' Run;',
  20678. ' Run();',
  20679. ' Run(11);',
  20680. ' Foo;',
  20681. ' Foo();',
  20682. ' Foo(12);',
  20683. ' Self.Foo;',
  20684. ' Self.Foo();',
  20685. ' Self.Foo(13);',
  20686. ' Fly;',
  20687. ' Fly();',
  20688. ' with Self do begin',
  20689. ' Foo;',
  20690. ' Foo();',
  20691. ' Foo(14);',
  20692. ' Fly;',
  20693. ' Fly();',
  20694. ' end;',
  20695. ' p:=@Fly;',
  20696. 'end;',
  20697. 'var Obj: TExtA;',
  20698. 'begin',
  20699. ' obj.Foo;',
  20700. ' obj.Foo();',
  20701. ' obj.Foo(21);',
  20702. ' obj.Fly;',
  20703. ' obj.Fly();',
  20704. ' with obj do begin',
  20705. ' Foo;',
  20706. ' Foo();',
  20707. ' Foo(22);',
  20708. ' Fly;',
  20709. ' Fly();',
  20710. ' end;',
  20711. ' p:[email protected];',
  20712. '']);
  20713. ConvertProgram;
  20714. CheckSource('TestExtClassHelper_Method_Call',
  20715. LinesToStr([ // statements
  20716. 'rtl.createHelper($mod, "THelper", null, function () {',
  20717. ' this.Foo = function (w) {',
  20718. ' var Result = 0;',
  20719. ' this.Run(10);',
  20720. ' this.Run(10);',
  20721. ' this.Run(11);',
  20722. ' $mod.THelper.Foo.call(this, 1);',
  20723. ' $mod.THelper.Foo.call(this, 1);',
  20724. ' $mod.THelper.Foo.call(this, 12);',
  20725. ' $mod.THelper.Foo.call(this, 1);',
  20726. ' $mod.THelper.Foo.call(this, 1);',
  20727. ' $mod.THelper.Foo.call(this, 13);',
  20728. ' this.Fly(2);',
  20729. ' this.Fly(2);',
  20730. ' $mod.THelper.Foo.call(this, 1);',
  20731. ' $mod.THelper.Foo.call(this, 1);',
  20732. ' $mod.THelper.Foo.call(this, 14);',
  20733. ' this.Fly(2);',
  20734. ' this.Fly(2);',
  20735. ' $mod.p = rtl.createCallback(this, "Fly");',
  20736. ' return Result;',
  20737. ' };',
  20738. '});',
  20739. 'this.p = null;',
  20740. 'this.Obj = null;',
  20741. '']),
  20742. LinesToStr([ // $mod.$main
  20743. '$mod.THelper.Foo.call($mod.Obj, 1);',
  20744. '$mod.THelper.Foo.call($mod.Obj, 1);',
  20745. '$mod.THelper.Foo.call($mod.Obj, 21);',
  20746. '$mod.Obj.Fly(2);',
  20747. '$mod.Obj.Fly(2);',
  20748. 'var $with1 = $mod.Obj;',
  20749. '$mod.THelper.Foo.call($with1, 1);',
  20750. '$mod.THelper.Foo.call($with1, 1);',
  20751. '$mod.THelper.Foo.call($with1, 22);',
  20752. '$with1.Fly(2);',
  20753. '$with1.Fly(2);',
  20754. '$mod.p = rtl.createCallback($mod.Obj, "Fly");',
  20755. '']));
  20756. end;
  20757. procedure TTestModule.TestRecordHelper_ClassVar;
  20758. begin
  20759. StartProgram(false);
  20760. Add([
  20761. 'type',
  20762. ' TRec = record',
  20763. ' end;',
  20764. ' THelper = record helper for TRec',
  20765. ' const',
  20766. ' One = 1;',
  20767. ' Two: word = 2;',
  20768. ' class var',
  20769. ' Glob: word;',
  20770. ' function Foo(w: word): word;',
  20771. ' class function Bar(w: word): word; static;',
  20772. ' end;',
  20773. 'function THelper.foo(w: word): word;',
  20774. 'begin',
  20775. ' Result:=w;',
  20776. ' Two:=One+w;',
  20777. ' Glob:=Glob;',
  20778. ' Result:=Self.Glob;',
  20779. ' Self.Glob:=Self.Glob;',
  20780. ' with Self do Glob:=Glob;',
  20781. ' Self:=Self;',
  20782. 'end;',
  20783. 'class function THelper.bar(w: word): word;',
  20784. 'begin',
  20785. ' Result:=w;',
  20786. ' Two:=One;',
  20787. ' Glob:=Glob;',
  20788. 'end;',
  20789. 'var r: TRec;',
  20790. 'begin',
  20791. ' trec.two:=trec.one;',
  20792. ' trec.Glob:=trec.Glob;',
  20793. ' with trec do begin',
  20794. ' two:=one;',
  20795. ' Glob:=Glob;',
  20796. ' end;',
  20797. ' r.two:=r.one;',
  20798. ' r.Glob:=r.Glob;',
  20799. ' with r do begin',
  20800. ' two:=one;',
  20801. ' Glob:=Glob;',
  20802. ' end;',
  20803. '']);
  20804. ConvertProgram;
  20805. CheckSource('TestRecordHelper_ClassVar',
  20806. LinesToStr([ // statements
  20807. 'rtl.recNewT($mod, "TRec", function () {',
  20808. ' this.$eq = function (b) {',
  20809. ' return true;',
  20810. ' };',
  20811. ' this.$assign = function (s) {',
  20812. ' return this;',
  20813. ' };',
  20814. '});',
  20815. 'rtl.createHelper($mod, "THelper", null, function () {',
  20816. ' this.One = 1;',
  20817. ' this.Two = 2;',
  20818. ' this.Glob = 0;',
  20819. ' this.Foo = function (w) {',
  20820. ' var Result = 0;',
  20821. ' Result = w;',
  20822. ' $mod.THelper.Two = 1 + w;',
  20823. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20824. ' Result = $mod.THelper.Glob;',
  20825. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20826. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20827. ' this.$assign(this);',
  20828. ' return Result;',
  20829. ' };',
  20830. ' this.Bar = function (w) {',
  20831. ' var Result = 0;',
  20832. ' Result = w;',
  20833. ' $mod.THelper.Two = 1;',
  20834. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  20835. ' return Result;',
  20836. ' };',
  20837. '});',
  20838. 'this.r = $mod.TRec.$new();',
  20839. '']),
  20840. LinesToStr([ // $mod.$main
  20841. '$mod.THelper.Two = 1;',
  20842. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20843. 'var $with1 = $mod.TRec;',
  20844. '$mod.THelper.Two = 1;',
  20845. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20846. '$mod.THelper.Two = 1;',
  20847. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20848. 'var $with2 = $mod.r;',
  20849. '$mod.THelper.Two = 1;',
  20850. '$mod.THelper.Glob = $mod.THelper.Glob;',
  20851. '']));
  20852. end;
  20853. procedure TTestModule.TestRecordHelper_Method_Call;
  20854. begin
  20855. StartProgram(false);
  20856. Add([
  20857. '{$modeswitch AdvancedRecords}',
  20858. 'type',
  20859. ' TRec = record',
  20860. ' procedure Run(w: word = 10);',
  20861. ' end;',
  20862. ' THelper = record helper for TRec',
  20863. ' function Foo(w: word = 1): word;',
  20864. ' end;',
  20865. 'procedure TRec.Run(w: word);',
  20866. 'begin',
  20867. ' Foo;',
  20868. ' Foo();',
  20869. ' Foo(2);',
  20870. ' Self.Foo;',
  20871. ' Self.Foo();',
  20872. ' Self.Foo(3);',
  20873. ' with Self do begin',
  20874. ' Foo;',
  20875. ' Foo();',
  20876. ' Foo(4);',
  20877. ' end;',
  20878. 'end;',
  20879. 'function THelper.foo(w: word): word;',
  20880. 'begin',
  20881. ' Run;',
  20882. ' Run();',
  20883. ' Run(11);',
  20884. ' Foo;',
  20885. ' Foo();',
  20886. ' Foo(12);',
  20887. ' Self.Foo;',
  20888. ' Self.Foo();',
  20889. ' Self.Foo(13);',
  20890. ' with Self do begin',
  20891. ' Foo;',
  20892. ' Foo();',
  20893. ' Foo(14);',
  20894. ' end;',
  20895. 'end;',
  20896. 'var Rec: TRec;',
  20897. 'begin',
  20898. ' Rec.Foo;',
  20899. ' Rec.Foo();',
  20900. ' Rec.Foo(21);',
  20901. ' with Rec do begin',
  20902. ' Foo;',
  20903. ' Foo();',
  20904. ' Foo(22);',
  20905. ' end;',
  20906. '']);
  20907. ConvertProgram;
  20908. CheckSource('TestRecordHelper_Method_Call',
  20909. LinesToStr([ // statements
  20910. 'rtl.recNewT($mod, "TRec", function () {',
  20911. ' this.$eq = function (b) {',
  20912. ' return true;',
  20913. ' };',
  20914. ' this.$assign = function (s) {',
  20915. ' return this;',
  20916. ' };',
  20917. ' this.Run = function (w) {',
  20918. ' $mod.THelper.Foo.call(this, 1);',
  20919. ' $mod.THelper.Foo.call(this, 1);',
  20920. ' $mod.THelper.Foo.call(this, 2);',
  20921. ' $mod.THelper.Foo.call(this, 1);',
  20922. ' $mod.THelper.Foo.call(this, 1);',
  20923. ' $mod.THelper.Foo.call(this, 3);',
  20924. ' $mod.THelper.Foo.call(this, 1);',
  20925. ' $mod.THelper.Foo.call(this, 1);',
  20926. ' $mod.THelper.Foo.call(this, 4);',
  20927. ' };',
  20928. '});',
  20929. 'rtl.createHelper($mod, "THelper", null, function () {',
  20930. ' this.Foo = function (w) {',
  20931. ' var Result = 0;',
  20932. ' this.Run(10);',
  20933. ' this.Run(10);',
  20934. ' this.Run(11);',
  20935. ' $mod.THelper.Foo.call(this, 1);',
  20936. ' $mod.THelper.Foo.call(this, 1);',
  20937. ' $mod.THelper.Foo.call(this, 12);',
  20938. ' $mod.THelper.Foo.call(this, 1);',
  20939. ' $mod.THelper.Foo.call(this, 1);',
  20940. ' $mod.THelper.Foo.call(this, 13);',
  20941. ' $mod.THelper.Foo.call(this, 1);',
  20942. ' $mod.THelper.Foo.call(this, 1);',
  20943. ' $mod.THelper.Foo.call(this, 14);',
  20944. ' return Result;',
  20945. ' };',
  20946. '});',
  20947. 'this.Rec = $mod.TRec.$new();',
  20948. '']),
  20949. LinesToStr([ // $mod.$main
  20950. '$mod.THelper.Foo.call($mod.Rec, 1);',
  20951. '$mod.THelper.Foo.call($mod.Rec, 1);',
  20952. '$mod.THelper.Foo.call($mod.Rec, 21);',
  20953. 'var $with1 = $mod.Rec;',
  20954. '$mod.THelper.Foo.call($with1, 1);',
  20955. '$mod.THelper.Foo.call($with1, 1);',
  20956. '$mod.THelper.Foo.call($with1, 22);',
  20957. '']));
  20958. end;
  20959. procedure TTestModule.TestRecordHelper_Constructor;
  20960. begin
  20961. StartProgram(false);
  20962. Add([
  20963. '{$modeswitch AdvancedRecords}',
  20964. 'type',
  20965. ' TRec = record',
  20966. ' constructor Create(w: word);',
  20967. ' end;',
  20968. ' THelper = record helper for TRec',
  20969. ' constructor NewHlp(w: word);',
  20970. ' end;',
  20971. 'var',
  20972. ' Rec: TRec;',
  20973. 'constructor TRec.Create(w: word);',
  20974. 'begin',
  20975. ' NewHlp(2);', // normal call
  20976. ' trec.NewHlp(3);', // new instance
  20977. 'end;',
  20978. 'constructor THelper.NewHlp(w: word);',
  20979. 'begin',
  20980. ' create(2);', // normal call
  20981. ' trec.create(3);', // new instance
  20982. ' NewHlp(4);', // normal call
  20983. ' trec.NewHlp(5);', // new instance
  20984. 'end;',
  20985. 'begin',
  20986. ' rec.newhlp(2);', // normal call
  20987. ' with rec do newhlp(12);', // normal call
  20988. ' trec.newhlp(3);', // new instance
  20989. ' with trec do newhlp(13);', // new instance
  20990. '']);
  20991. ConvertProgram;
  20992. CheckSource('TestRecordHelper_Constructor',
  20993. LinesToStr([ // statements
  20994. 'rtl.recNewT($mod, "TRec", function () {',
  20995. ' this.$eq = function (b) {',
  20996. ' return true;',
  20997. ' };',
  20998. ' this.$assign = function (s) {',
  20999. ' return this;',
  21000. ' };',
  21001. ' this.Create = function (w) {',
  21002. ' $mod.THelper.NewHlp.call(this, 2);',
  21003. ' $mod.THelper.$new("NewHlp", [3]);',
  21004. ' return this;',
  21005. ' };',
  21006. '}, true);',
  21007. 'rtl.createHelper($mod, "THelper", null, function () {',
  21008. ' this.NewHlp = function (w) {',
  21009. ' this.Create(2);',
  21010. ' $mod.TRec.$new().Create(3);',
  21011. ' $mod.THelper.NewHlp.call(this, 4);',
  21012. ' $mod.THelper.$new("NewHlp", [5]);',
  21013. ' return this;',
  21014. ' };',
  21015. ' this.$new = function (fn, args) {',
  21016. ' return this[fn].apply($mod.TRec.$new(), args);',
  21017. ' };',
  21018. '});',
  21019. 'this.Rec = $mod.TRec.$new();',
  21020. '']),
  21021. LinesToStr([ // $mod.$main
  21022. '$mod.THelper.NewHlp.call($mod.Rec, 2);',
  21023. 'var $with1 = $mod.Rec;',
  21024. '$mod.THelper.NewHlp.call($with1, 12);',
  21025. '$mod.THelper.$new("NewHlp", [3]);',
  21026. 'var $with2 = $mod.TRec;',
  21027. '$mod.THelper.$new("NewHlp", [13]);',
  21028. '']));
  21029. end;
  21030. procedure TTestModule.TestTypeHelper_ClassVar;
  21031. begin
  21032. StartProgram(false);
  21033. Add([
  21034. '{$modeswitch typehelpers}',
  21035. 'type',
  21036. ' THelper = type helper for byte',
  21037. ' const',
  21038. ' One = 1;',
  21039. ' Two: word = 2;',
  21040. ' class var',
  21041. ' Glob: word;',
  21042. ' function Foo(w: word): word;',
  21043. ' class function Bar(w: word): word; static;',
  21044. ' end;',
  21045. 'function THelper.foo(w: word): word;',
  21046. 'begin',
  21047. ' Result:=w;',
  21048. ' Two:=One+w;',
  21049. ' Glob:=Glob;',
  21050. ' Result:=Self.Glob;',
  21051. ' Self.Glob:=Self.Glob;',
  21052. ' with Self do Glob:=Glob;',
  21053. 'end;',
  21054. 'class function THelper.bar(w: word): word;',
  21055. 'begin',
  21056. ' Result:=w;',
  21057. ' Two:=One;',
  21058. ' Glob:=Glob;',
  21059. 'end;',
  21060. 'var b: byte;',
  21061. 'begin',
  21062. ' byte.two:=byte.one;',
  21063. ' byte.Glob:=byte.Glob;',
  21064. ' with byte do begin',
  21065. ' two:=one;',
  21066. ' Glob:=Glob;',
  21067. ' end;',
  21068. ' b.two:=b.one;',
  21069. ' b.Glob:=b.Glob;',
  21070. ' with b do begin',
  21071. ' two:=one;',
  21072. ' Glob:=Glob;',
  21073. ' end;',
  21074. '']);
  21075. ConvertProgram;
  21076. CheckSource('TestTypeHelper_ClassVar',
  21077. LinesToStr([ // statements
  21078. 'rtl.createHelper($mod, "THelper", null, function () {',
  21079. ' this.One = 1;',
  21080. ' this.Two = 2;',
  21081. ' this.Glob = 0;',
  21082. ' this.Foo = function (w) {',
  21083. ' var Result = 0;',
  21084. ' Result = w;',
  21085. ' $mod.THelper.Two = 1 + w;',
  21086. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21087. ' Result = $mod.THelper.Glob;',
  21088. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21089. ' var $with1 = this.get();',
  21090. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21091. ' return Result;',
  21092. ' };',
  21093. ' this.Bar = function (w) {',
  21094. ' var Result = 0;',
  21095. ' Result = w;',
  21096. ' $mod.THelper.Two = 1;',
  21097. ' $mod.THelper.Glob = $mod.THelper.Glob;',
  21098. ' return Result;',
  21099. ' };',
  21100. '});',
  21101. 'this.b = 0;',
  21102. '']),
  21103. LinesToStr([ // $mod.$main
  21104. '$mod.THelper.Two = 1;',
  21105. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21106. '$mod.THelper.Two = 1;',
  21107. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21108. '$mod.THelper.Two = 1;',
  21109. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21110. 'var $with1 = $mod.b;',
  21111. '$mod.THelper.Two = 1;',
  21112. '$mod.THelper.Glob = $mod.THelper.Glob;',
  21113. '']));
  21114. end;
  21115. procedure TTestModule.TestTypeHelper_PassResultElement;
  21116. begin
  21117. StartProgram(false);
  21118. Add([
  21119. '{$modeswitch typehelpers}',
  21120. 'type',
  21121. ' THelper = type helper for word',
  21122. ' procedure DoIt(e: byte = 123);',
  21123. ' class procedure DoSome(e: byte = 456); static;',
  21124. ' end;',
  21125. 'procedure THelper.DoIt(e: byte);',
  21126. 'begin',
  21127. 'end;',
  21128. 'class procedure THelper.DoSome(e: byte);',
  21129. 'begin',
  21130. 'end;',
  21131. 'function Foo(w: word): word;',
  21132. 'begin',
  21133. ' Result.DoIt;',
  21134. ' Result.DoIt();',
  21135. ' Result.DoSome;',
  21136. ' Result.DoSome();',
  21137. ' with Result do begin',
  21138. ' DoIt;',
  21139. ' DoIt();',
  21140. ' DoSome;',
  21141. ' DoSome();',
  21142. ' end;',
  21143. 'end;',
  21144. 'begin',
  21145. '']);
  21146. ConvertProgram;
  21147. CheckSource('TestTypeHelper_PassResultElement',
  21148. LinesToStr([ // statements
  21149. 'rtl.createHelper($mod, "THelper", null, function () {',
  21150. ' this.DoIt = function (e) {',
  21151. ' };',
  21152. ' this.DoSome = function (e) {',
  21153. ' };',
  21154. '});',
  21155. 'this.Foo = function (w) {',
  21156. ' var Result = 0;',
  21157. ' $mod.THelper.DoIt.call({',
  21158. ' get: function () {',
  21159. ' return Result;',
  21160. ' },',
  21161. ' set: function (v) {',
  21162. ' Result = v;',
  21163. ' }',
  21164. ' }, 123);',
  21165. ' $mod.THelper.DoIt.call({',
  21166. ' get: function () {',
  21167. ' return Result;',
  21168. ' },',
  21169. ' set: function (v) {',
  21170. ' Result = v;',
  21171. ' }',
  21172. ' }, 123);',
  21173. ' $mod.THelper.DoSome(456);',
  21174. ' $mod.THelper.DoSome(456);',
  21175. ' $mod.THelper.DoIt.call({',
  21176. ' get: function () {',
  21177. ' return Result;',
  21178. ' },',
  21179. ' set: function (v) {',
  21180. ' Result = v;',
  21181. ' }',
  21182. ' }, 123);',
  21183. ' $mod.THelper.DoIt.call({',
  21184. ' get: function () {',
  21185. ' return Result;',
  21186. ' },',
  21187. ' set: function (v) {',
  21188. ' Result = v;',
  21189. ' }',
  21190. ' }, 123);',
  21191. ' $mod.THelper.DoSome(456);',
  21192. ' $mod.THelper.DoSome(456);',
  21193. ' return Result;',
  21194. '};',
  21195. '']),
  21196. LinesToStr([ // $mod.$main
  21197. '']));
  21198. end;
  21199. procedure TTestModule.TestTypeHelper_PassArgs;
  21200. begin
  21201. StartProgram(false);
  21202. Add([
  21203. '{$modeswitch typehelpers}',
  21204. 'type',
  21205. ' THelper = type helper for word',
  21206. ' procedure DoIt(e: byte = 123);',
  21207. ' end;',
  21208. 'procedure THelper.DoIt(e: byte);',
  21209. 'begin',
  21210. 'end;',
  21211. 'procedure FooDefault(a: word);',
  21212. 'begin',
  21213. ' a.DoIt;',
  21214. ' with a do DoIt;',
  21215. 'end;',
  21216. 'procedure FooConst(const a: word);',
  21217. 'begin',
  21218. ' a.DoIt;',
  21219. ' with a do DoIt;',
  21220. 'end;',
  21221. 'procedure FooVar(var a: word);',
  21222. 'begin',
  21223. ' a.DoIt;',
  21224. ' with a do DoIt;',
  21225. 'end;',
  21226. 'begin',
  21227. '']);
  21228. ConvertProgram;
  21229. CheckSource('TestTypeHelper_PassArgs',
  21230. LinesToStr([ // statements
  21231. 'rtl.createHelper($mod, "THelper", null, function () {',
  21232. ' this.DoIt = function (e) {',
  21233. ' };',
  21234. '});',
  21235. 'this.FooDefault = function (a) {',
  21236. ' $mod.THelper.DoIt.call({',
  21237. ' get: function () {',
  21238. ' return a;',
  21239. ' },',
  21240. ' set: function (v) {',
  21241. ' a = v;',
  21242. ' }',
  21243. ' }, 123);',
  21244. ' $mod.THelper.DoIt.call({',
  21245. ' get: function () {',
  21246. ' return a;',
  21247. ' },',
  21248. ' set: function (v) {',
  21249. ' a = v;',
  21250. ' }',
  21251. ' }, 123);',
  21252. '};',
  21253. 'this.FooConst = function (a) {',
  21254. ' $mod.THelper.DoIt.call({',
  21255. ' get: function () {',
  21256. ' return a;',
  21257. ' },',
  21258. ' set: function (v) {',
  21259. ' rtl.raiseE("EPropReadOnly");',
  21260. ' }',
  21261. ' }, 123);',
  21262. ' $mod.THelper.DoIt.call({',
  21263. ' get: function () {',
  21264. ' return a;',
  21265. ' },',
  21266. ' set: function () {',
  21267. ' rtl.raiseE("EPropReadOnly");',
  21268. ' }',
  21269. ' }, 123);',
  21270. '};',
  21271. 'this.FooVar = function (a) {',
  21272. ' $mod.THelper.DoIt.call(a, 123);',
  21273. ' var $with1 = a.get();',
  21274. ' $mod.THelper.DoIt.call(a, 123);',
  21275. '};',
  21276. '']),
  21277. LinesToStr([ // $mod.$main
  21278. '']));
  21279. end;
  21280. procedure TTestModule.TestTypeHelper_PassVarConst;
  21281. begin
  21282. StartProgram(false);
  21283. Add([
  21284. '{$modeswitch typehelpers}',
  21285. 'type',
  21286. ' THelper = type helper for word',
  21287. ' procedure DoIt(e: byte = 123);',
  21288. ' end;',
  21289. 'procedure THelper.DoIt(e: byte);',
  21290. 'begin',
  21291. 'end;',
  21292. 'var a: word;',
  21293. 'const c: word = 2;',
  21294. '{$writeableconst off}',
  21295. 'const r: word = 3;',
  21296. 'begin',
  21297. ' a.DoIt;',
  21298. ' with a do DoIt;',
  21299. ' c.DoIt;',
  21300. ' with c do DoIt;',
  21301. ' r.DoIt;',
  21302. ' with r do DoIt;',
  21303. '']);
  21304. ConvertProgram;
  21305. CheckSource('TestTypeHelper_PassVarConst',
  21306. LinesToStr([ // statements
  21307. 'rtl.createHelper($mod, "THelper", null, function () {',
  21308. ' this.DoIt = function (e) {',
  21309. ' };',
  21310. '});',
  21311. 'this.a = 0;',
  21312. 'this.c = 2;',
  21313. 'this.r = 3;',
  21314. '']),
  21315. LinesToStr([ // $mod.$main
  21316. '$mod.THelper.DoIt.call({',
  21317. ' p: $mod,',
  21318. ' get: function () {',
  21319. ' return this.p.a;',
  21320. ' },',
  21321. ' set: function (v) {',
  21322. ' this.p.a = v;',
  21323. ' }',
  21324. '}, 123);',
  21325. 'var $with1 = $mod.a;',
  21326. '$mod.THelper.DoIt.call({',
  21327. ' get: function () {',
  21328. ' return $with1;',
  21329. ' },',
  21330. ' set: function (v) {',
  21331. ' $with1 = v;',
  21332. ' }',
  21333. '}, 123);',
  21334. '$mod.THelper.DoIt.call({',
  21335. ' p: $mod,',
  21336. ' get: function () {',
  21337. ' return this.p.c;',
  21338. ' },',
  21339. ' set: function (v) {',
  21340. ' this.p.c = v;',
  21341. ' }',
  21342. '}, 123);',
  21343. 'var $with2 = $mod.c;',
  21344. '$mod.THelper.DoIt.call({',
  21345. ' get: function () {',
  21346. ' return $with2;',
  21347. ' },',
  21348. ' set: function (v) {',
  21349. ' $with2 = v;',
  21350. ' }',
  21351. '}, 123);',
  21352. '$mod.THelper.DoIt.call({',
  21353. ' get: function () {',
  21354. ' return 3;',
  21355. ' },',
  21356. ' set: function (v) {',
  21357. ' rtl.raiseE("EPropReadOnly");',
  21358. ' }',
  21359. '}, 123);',
  21360. 'var $with3 = 3;',
  21361. ' $mod.THelper.DoIt.call({',
  21362. ' get: function () {',
  21363. ' return $with3;',
  21364. ' },',
  21365. ' set: function () {',
  21366. ' rtl.raiseE("EPropReadOnly");',
  21367. ' }',
  21368. ' }, 123);',
  21369. '']));
  21370. end;
  21371. procedure TTestModule.TestTypeHelper_PassFuncResult;
  21372. begin
  21373. StartProgram(false);
  21374. Add([
  21375. '{$modeswitch typehelpers}',
  21376. 'type',
  21377. ' THelper = type helper for word',
  21378. ' procedure DoIt(e: byte = 123);',
  21379. ' end;',
  21380. 'procedure THelper.DoIt(e: byte);',
  21381. 'begin',
  21382. 'end;',
  21383. 'function Foo(b: byte = 1): word;',
  21384. 'begin',
  21385. 'end;',
  21386. 'begin',
  21387. ' Foo.DoIt;',
  21388. ' Foo().DoIt;',
  21389. ' with Foo do DoIt;',
  21390. ' with Foo() do DoIt;',
  21391. '']);
  21392. ConvertProgram;
  21393. CheckSource('TestTypeHelper_PassFuncResult',
  21394. LinesToStr([ // statements
  21395. 'rtl.createHelper($mod, "THelper", null, function () {',
  21396. ' this.DoIt = function (e) {',
  21397. ' };',
  21398. '});',
  21399. 'this.Foo = function (b) {',
  21400. ' var Result = 0;',
  21401. ' return Result;',
  21402. '};',
  21403. '']),
  21404. LinesToStr([ // $mod.$main
  21405. '$mod.THelper.DoIt.call({',
  21406. ' a: $mod.Foo(1),',
  21407. ' get: function () {',
  21408. ' return this.a;',
  21409. ' },',
  21410. ' set: function (v) {',
  21411. ' this.a = v;',
  21412. ' }',
  21413. '}, 123);',
  21414. '$mod.THelper.DoIt.call({',
  21415. ' a: $mod.Foo(1),',
  21416. ' get: function () {',
  21417. ' return this.a;',
  21418. ' },',
  21419. ' set: function (v) {',
  21420. ' this.a = v;',
  21421. ' }',
  21422. '}, 123);',
  21423. 'var $with1 = $mod.Foo(1);',
  21424. '$mod.THelper.DoIt.call({',
  21425. ' get: function () {',
  21426. ' return $with1;',
  21427. ' },',
  21428. ' set: function (v) {',
  21429. ' $with1 = v;',
  21430. ' }',
  21431. '}, 123);',
  21432. 'var $with2 = $mod.Foo(1);',
  21433. '$mod.THelper.DoIt.call({',
  21434. ' get: function () {',
  21435. ' return $with2;',
  21436. ' },',
  21437. ' set: function (v) {',
  21438. ' $with2 = v;',
  21439. ' }',
  21440. '}, 123);',
  21441. '']));
  21442. end;
  21443. procedure TTestModule.TestTypeHelper_PassPropertyField;
  21444. begin
  21445. StartProgram(false);
  21446. Add([
  21447. '{$modeswitch typehelpers}',
  21448. 'type',
  21449. ' TObject = class',
  21450. ' FField: word;',
  21451. ' procedure SetField(Value: word);',
  21452. ' property Field: word read FField write SetField;',
  21453. ' end;',
  21454. ' THelper = type helper for word',
  21455. ' procedure Fly;',
  21456. ' class procedure Run; static;',
  21457. ' end;',
  21458. 'procedure TObject.SetField(Value: word);',
  21459. 'begin',
  21460. ' Field.Fly;',
  21461. ' Field.Run;',
  21462. ' Self.Field.Fly;',
  21463. ' Self.Field.Run;',
  21464. ' with Self do begin',
  21465. ' Field.Fly;',
  21466. ' Field.Run;',
  21467. ' end;',
  21468. ' with Self.Field do begin',
  21469. ' Fly;',
  21470. ' Run;',
  21471. ' end;',
  21472. 'end;',
  21473. 'procedure THelper.Fly;',
  21474. 'begin',
  21475. 'end;',
  21476. 'class procedure THelper.Run;',
  21477. 'begin',
  21478. 'end;',
  21479. 'var',
  21480. ' o: TObject;',
  21481. 'begin',
  21482. ' o.Field.Fly;',
  21483. ' o.Field.Run;',
  21484. ' with o do begin',
  21485. ' Field.Fly;',
  21486. ' Field.Run;',
  21487. ' end;',
  21488. ' with o.Field do begin',
  21489. ' Fly;',
  21490. ' Run;',
  21491. ' end;',
  21492. '']);
  21493. ConvertProgram;
  21494. CheckSource('TestTypeHelper_PassPropertyField',
  21495. LinesToStr([ // statements
  21496. 'rtl.createClass($mod, "TObject", null, function () {',
  21497. ' this.$init = function () {',
  21498. ' this.FField = 0;',
  21499. ' };',
  21500. ' this.$final = function () {',
  21501. ' };',
  21502. ' this.SetField = function (Value) {',
  21503. ' $mod.THelper.Fly.call({',
  21504. ' p: this,',
  21505. ' get: function () {',
  21506. ' return this.p.FField;',
  21507. ' },',
  21508. ' set: function (v) {',
  21509. ' this.p.FField = v;',
  21510. ' }',
  21511. ' });',
  21512. ' $mod.THelper.Run();',
  21513. ' $mod.THelper.Fly.call({',
  21514. ' p: this,',
  21515. ' get: function () {',
  21516. ' return this.p.FField;',
  21517. ' },',
  21518. ' set: function (v) {',
  21519. ' this.p.FField = v;',
  21520. ' }',
  21521. ' });',
  21522. ' $mod.THelper.Run();',
  21523. ' $mod.THelper.Fly.call({',
  21524. ' p: this,',
  21525. ' get: function () {',
  21526. ' return this.p.FField;',
  21527. ' },',
  21528. ' set: function (v) {',
  21529. ' this.p.FField = v;',
  21530. ' }',
  21531. ' });',
  21532. ' $mod.THelper.Run();',
  21533. ' var $with1 = this.FField;',
  21534. ' $mod.THelper.Fly.call({',
  21535. ' get: function () {',
  21536. ' return $with1;',
  21537. ' },',
  21538. ' set: function (v) {',
  21539. ' $with1 = v;',
  21540. ' }',
  21541. ' });',
  21542. ' $mod.THelper.Run();',
  21543. ' };',
  21544. '});',
  21545. 'rtl.createHelper($mod, "THelper", null, function () {',
  21546. ' this.Fly = function () {',
  21547. ' };',
  21548. ' this.Run = function () {',
  21549. ' };',
  21550. '});',
  21551. 'this.o = null;',
  21552. '']),
  21553. LinesToStr([ // $mod.$main
  21554. '$mod.THelper.Fly.call({',
  21555. ' p: $mod.o,',
  21556. ' get: function () {',
  21557. ' return this.p.FField;',
  21558. ' },',
  21559. ' set: function (v) {',
  21560. ' this.p.FField = v;',
  21561. ' }',
  21562. '});',
  21563. '$mod.THelper.Run();',
  21564. 'var $with1 = $mod.o;',
  21565. '$mod.THelper.Fly.call({',
  21566. ' p: $with1,',
  21567. ' get: function () {',
  21568. ' return this.p.FField;',
  21569. ' },',
  21570. ' set: function (v) {',
  21571. ' this.p.FField = v;',
  21572. ' }',
  21573. '});',
  21574. '$mod.THelper.Run();',
  21575. 'var $with2 = $mod.o.FField;',
  21576. '$mod.THelper.Fly.call({',
  21577. ' get: function () {',
  21578. ' return $with2;',
  21579. ' },',
  21580. ' set: function (v) {',
  21581. ' $with2 = v;',
  21582. ' }',
  21583. '});',
  21584. '$mod.THelper.Run();',
  21585. '']));
  21586. end;
  21587. procedure TTestModule.TestTypeHelper_PassPropertyGetter;
  21588. begin
  21589. StartProgram(false);
  21590. Add([
  21591. '{$modeswitch typehelpers}',
  21592. 'type',
  21593. ' TObject = class',
  21594. ' FField: word;',
  21595. ' function GetField: word;',
  21596. ' property Field: word read GetField write FField;',
  21597. ' end;',
  21598. ' THelper = type helper for word',
  21599. ' procedure Fly;',
  21600. ' class procedure Run; static;',
  21601. ' end;',
  21602. 'function TObject.GetField: word;',
  21603. 'begin',
  21604. ' Field.Fly;',
  21605. ' Field.Run;',
  21606. ' Self.Field.Fly;',
  21607. ' Self.Field.Run;',
  21608. ' with Self do begin',
  21609. ' Field.Fly;',
  21610. ' Field.Run;',
  21611. ' end;',
  21612. ' with Self.Field do begin',
  21613. ' Fly;',
  21614. ' Run;',
  21615. ' end;',
  21616. 'end;',
  21617. 'procedure THelper.Fly;',
  21618. 'begin',
  21619. 'end;',
  21620. 'class procedure THelper.Run;',
  21621. 'begin',
  21622. 'end;',
  21623. 'var',
  21624. ' o: TObject;',
  21625. 'begin',
  21626. ' o.Field.Fly;',
  21627. ' o.Field.Run;',
  21628. ' with o do begin',
  21629. ' Field.Fly;',
  21630. ' Field.Run;',
  21631. ' end;',
  21632. ' with o.Field do begin',
  21633. ' Fly;',
  21634. ' Run;',
  21635. ' end;',
  21636. '']);
  21637. ConvertProgram;
  21638. CheckSource('TestTypeHelper_PassPropertyGetter',
  21639. LinesToStr([ // statements
  21640. 'rtl.createClass($mod, "TObject", null, function () {',
  21641. ' this.$init = function () {',
  21642. ' this.FField = 0;',
  21643. ' };',
  21644. ' this.$final = function () {',
  21645. ' };',
  21646. ' this.GetField = function () {',
  21647. ' var Result = 0;',
  21648. ' $mod.THelper.Fly.call({',
  21649. ' p: this.GetField(),',
  21650. ' get: function () {',
  21651. ' return this.p;',
  21652. ' },',
  21653. ' set: function (v) {',
  21654. ' this.p = v;',
  21655. ' }',
  21656. ' });',
  21657. ' $mod.THelper.Run();',
  21658. ' $mod.THelper.Fly.call({',
  21659. ' p: this.GetField(),',
  21660. ' get: function () {',
  21661. ' return this.p;',
  21662. ' },',
  21663. ' set: function (v) {',
  21664. ' this.p = v;',
  21665. ' }',
  21666. ' });',
  21667. ' $mod.THelper.Run();',
  21668. ' $mod.THelper.Fly.call({',
  21669. ' p: this.GetField(),',
  21670. ' get: function () {',
  21671. ' return this.p;',
  21672. ' },',
  21673. ' set: function (v) {',
  21674. ' this.p = v;',
  21675. ' }',
  21676. ' });',
  21677. ' $mod.THelper.Run();',
  21678. ' var $with1 = this.GetField();',
  21679. ' $mod.THelper.Fly.call({',
  21680. ' get: function () {',
  21681. ' return $with1;',
  21682. ' },',
  21683. ' set: function (v) {',
  21684. ' $with1 = v;',
  21685. ' }',
  21686. ' });',
  21687. ' $mod.THelper.Run();',
  21688. ' return Result;',
  21689. ' };',
  21690. '});',
  21691. 'rtl.createHelper($mod, "THelper", null, function () {',
  21692. ' this.Fly = function () {',
  21693. ' };',
  21694. ' this.Run = function () {',
  21695. ' };',
  21696. '});',
  21697. 'this.o = null;',
  21698. '']),
  21699. LinesToStr([ // $mod.$main
  21700. '$mod.THelper.Fly.call({',
  21701. ' p: $mod.o.GetField(),',
  21702. ' get: function () {',
  21703. ' return this.p;',
  21704. ' },',
  21705. ' set: function (v) {',
  21706. ' this.p = v;',
  21707. ' }',
  21708. '});',
  21709. '$mod.THelper.Run();',
  21710. 'var $with1 = $mod.o;',
  21711. '$mod.THelper.Fly.call({',
  21712. ' p: $with1.GetField(),',
  21713. ' get: function () {',
  21714. ' return this.p;',
  21715. ' },',
  21716. ' set: function (v) {',
  21717. ' this.p = v;',
  21718. ' }',
  21719. '});',
  21720. '$mod.THelper.Run();',
  21721. 'var $with2 = $mod.o.GetField();',
  21722. '$mod.THelper.Fly.call({',
  21723. ' get: function () {',
  21724. ' return $with2;',
  21725. ' },',
  21726. ' set: function (v) {',
  21727. ' $with2 = v;',
  21728. ' }',
  21729. '});',
  21730. '$mod.THelper.Run();',
  21731. '']));
  21732. end;
  21733. procedure TTestModule.TestTypeHelper_PassClassPropertyField;
  21734. begin
  21735. StartProgram(false);
  21736. Add([
  21737. '{$modeswitch typehelpers}',
  21738. 'type',
  21739. ' TObject = class',
  21740. ' class var FField: word;',
  21741. ' class procedure SetField(Value: word);',
  21742. ' class property Field: word read FField write SetField;',
  21743. ' end;',
  21744. ' THelper = type helper for word',
  21745. ' procedure Fly(n: byte);',
  21746. ' end;',
  21747. 'class procedure TObject.SetField(Value: word);',
  21748. 'begin',
  21749. ' Field.Fly(1);',
  21750. ' Self.Field.Fly(2);',
  21751. ' with Self do Field.Fly(3);',
  21752. ' with Self.Field do Fly(4);',
  21753. ' TObject.Field.Fly(5);',
  21754. ' with TObject do Field.Fly(6);',
  21755. ' with TObject.Field do Fly(7);',
  21756. 'end;',
  21757. 'procedure THelper.Fly(n: byte);',
  21758. 'begin',
  21759. 'end;',
  21760. 'var',
  21761. ' o: TObject;',
  21762. 'begin',
  21763. ' o.Field.Fly(11);',
  21764. ' with o do Field.Fly(12);',
  21765. ' with o.Field do Fly(13);',
  21766. ' TObject.Field.Fly(14);',
  21767. ' with TObject do Field.Fly(15);',
  21768. ' with TObject.Field do Fly(16);',
  21769. '']);
  21770. ConvertProgram;
  21771. CheckSource('TestTypeHelper_PassClassPropertyField',
  21772. LinesToStr([ // statements
  21773. 'rtl.createClass($mod, "TObject", null, function () {',
  21774. ' this.FField = 0;',
  21775. ' this.$init = function () {',
  21776. ' };',
  21777. ' this.$final = function () {',
  21778. ' };',
  21779. ' this.SetField = function (Value) {',
  21780. ' $mod.THelper.Fly.call({',
  21781. ' p: this,',
  21782. ' get: function () {',
  21783. ' return this.p.FField;',
  21784. ' },',
  21785. ' set: function (v) {',
  21786. ' $mod.TObject.FField = v;',
  21787. ' }',
  21788. ' }, 1);',
  21789. ' $mod.THelper.Fly.call({',
  21790. ' p: this,',
  21791. ' get: function () {',
  21792. ' return this.p.FField;',
  21793. ' },',
  21794. ' set: function (v) {',
  21795. ' $mod.TObject.FField = v;',
  21796. ' }',
  21797. ' }, 2);',
  21798. ' $mod.THelper.Fly.call({',
  21799. ' p: this,',
  21800. ' get: function () {',
  21801. ' return this.p.FField;',
  21802. ' },',
  21803. ' set: function (v) {',
  21804. ' $mod.TObject.FField = v;',
  21805. ' }',
  21806. ' }, 3);',
  21807. ' var $with1 = this.FField;',
  21808. ' $mod.THelper.Fly.call({',
  21809. ' get: function () {',
  21810. ' return $with1;',
  21811. ' },',
  21812. ' set: function (v) {',
  21813. ' $with1 = v;',
  21814. ' }',
  21815. ' }, 4);',
  21816. ' $mod.THelper.Fly.call({',
  21817. ' p: $mod.TObject,',
  21818. ' get: function () {',
  21819. ' return this.p.FField;',
  21820. ' },',
  21821. ' set: function (v) {',
  21822. ' $mod.TObject.FField = v;',
  21823. ' }',
  21824. ' }, 5);',
  21825. ' var $with2 = $mod.TObject;',
  21826. ' $mod.THelper.Fly.call({',
  21827. ' p: $with2,',
  21828. ' get: function () {',
  21829. ' return this.p.FField;',
  21830. ' },',
  21831. ' set: function (v) {',
  21832. ' $mod.TObject.FField = v;',
  21833. ' }',
  21834. ' }, 6);',
  21835. ' var $with3 = $mod.TObject.FField;',
  21836. ' $mod.THelper.Fly.call({',
  21837. ' get: function () {',
  21838. ' return $with3;',
  21839. ' },',
  21840. ' set: function (v) {',
  21841. ' $with3 = v;',
  21842. ' }',
  21843. ' }, 7);',
  21844. ' };',
  21845. '});',
  21846. 'rtl.createHelper($mod, "THelper", null, function () {',
  21847. ' this.Fly = function (n) {',
  21848. ' };',
  21849. '});',
  21850. 'this.o = null;',
  21851. '']),
  21852. LinesToStr([ // $mod.$main
  21853. '$mod.THelper.Fly.call({',
  21854. ' p: $mod.o,',
  21855. ' get: function () {',
  21856. ' return this.p.FField;',
  21857. ' },',
  21858. ' set: function (v) {',
  21859. ' $mod.TObject.FField = v;',
  21860. ' }',
  21861. '}, 11);',
  21862. 'var $with1 = $mod.o;',
  21863. '$mod.THelper.Fly.call({',
  21864. ' p: $with1,',
  21865. ' get: function () {',
  21866. ' return this.p.FField;',
  21867. ' },',
  21868. ' set: function (v) {',
  21869. ' $mod.TObject.FField = v;',
  21870. ' }',
  21871. '}, 12);',
  21872. 'var $with2 = $mod.o.FField;',
  21873. '$mod.THelper.Fly.call({',
  21874. ' get: function () {',
  21875. ' return $with2;',
  21876. ' },',
  21877. ' set: function (v) {',
  21878. ' $with2 = v;',
  21879. ' }',
  21880. '}, 13);',
  21881. '$mod.THelper.Fly.call({',
  21882. ' p: $mod.TObject,',
  21883. ' get: function () {',
  21884. ' return this.p.FField;',
  21885. ' },',
  21886. ' set: function (v) {',
  21887. ' $mod.TObject.FField = v;',
  21888. ' }',
  21889. '}, 14);',
  21890. 'var $with3 = $mod.TObject;',
  21891. '$mod.THelper.Fly.call({',
  21892. ' p: $with3,',
  21893. ' get: function () {',
  21894. ' return this.p.FField;',
  21895. ' },',
  21896. ' set: function (v) {',
  21897. ' $mod.TObject.FField = v;',
  21898. ' }',
  21899. '}, 15);',
  21900. 'var $with4 = $mod.TObject.FField;',
  21901. '$mod.THelper.Fly.call({',
  21902. ' get: function () {',
  21903. ' return $with4;',
  21904. ' },',
  21905. ' set: function (v) {',
  21906. ' $with4 = v;',
  21907. ' }',
  21908. '}, 16);',
  21909. '']));
  21910. end;
  21911. procedure TTestModule.TestTypeHelper_PassClassPropertyGetterStatic;
  21912. begin
  21913. StartProgram(false);
  21914. Add([
  21915. '{$modeswitch typehelpers}',
  21916. 'type',
  21917. ' TObject = class',
  21918. ' class var FField: word;',
  21919. ' class function GetField: word; static;',
  21920. ' class property Field: word read GetField write FField;',
  21921. ' end;',
  21922. ' THelper = type helper for word',
  21923. ' procedure Fly(n: byte);',
  21924. ' end;',
  21925. 'class function TObject.GetField: word;',
  21926. 'begin',
  21927. ' Field.Fly(1);',
  21928. ' TObject.Field.Fly(5);',
  21929. ' with TObject do Field.Fly(6);',
  21930. ' with TObject.Field do Fly(7);',
  21931. 'end;',
  21932. 'procedure THelper.Fly(n: byte);',
  21933. 'begin',
  21934. 'end;',
  21935. 'var',
  21936. ' o: TObject;',
  21937. 'begin',
  21938. ' o.Field.Fly(11);',
  21939. ' with o do Field.Fly(12);',
  21940. ' with o.Field do Fly(13);',
  21941. '']);
  21942. ConvertProgram;
  21943. CheckSource('TestTypeHelper_PassClassPropertyGetterStatic',
  21944. LinesToStr([ // statements
  21945. 'rtl.createClass($mod, "TObject", null, function () {',
  21946. ' this.FField = 0;',
  21947. ' this.$init = function () {',
  21948. ' };',
  21949. ' this.$final = function () {',
  21950. ' };',
  21951. ' this.GetField = function () {',
  21952. ' var Result = 0;',
  21953. ' $mod.THelper.Fly.call({',
  21954. ' p: this.GetField(),',
  21955. ' get: function () {',
  21956. ' return this.p;',
  21957. ' },',
  21958. ' set: function (v) {',
  21959. ' this.p = v;',
  21960. ' }',
  21961. ' }, 1);',
  21962. ' $mod.THelper.Fly.call({',
  21963. ' p: $mod.TObject.GetField(),',
  21964. ' get: function () {',
  21965. ' return this.p;',
  21966. ' },',
  21967. ' set: function (v) {',
  21968. ' this.p = v;',
  21969. ' }',
  21970. ' }, 5);',
  21971. ' var $with1 = $mod.TObject;',
  21972. ' $mod.THelper.Fly.call({',
  21973. ' p: $with1.GetField(),',
  21974. ' get: function () {',
  21975. ' return this.p;',
  21976. ' },',
  21977. ' set: function (v) {',
  21978. ' this.p = v;',
  21979. ' }',
  21980. ' }, 6);',
  21981. ' var $with2 = $mod.TObject.GetField();',
  21982. ' $mod.THelper.Fly.call({',
  21983. ' get: function () {',
  21984. ' return $with2;',
  21985. ' },',
  21986. ' set: function (v) {',
  21987. ' $with2 = v;',
  21988. ' }',
  21989. ' }, 7);',
  21990. ' return Result;',
  21991. ' };',
  21992. '});',
  21993. 'rtl.createHelper($mod, "THelper", null, function () {',
  21994. ' this.Fly = function (n) {',
  21995. ' };',
  21996. '});',
  21997. 'this.o = null;',
  21998. '']),
  21999. LinesToStr([ // $mod.$main
  22000. '$mod.THelper.Fly.call({',
  22001. ' p: $mod.o.GetField(),',
  22002. ' get: function () {',
  22003. ' return this.p;',
  22004. ' },',
  22005. ' set: function (v) {',
  22006. ' this.p = v;',
  22007. ' }',
  22008. '}, 11);',
  22009. 'var $with1 = $mod.o;',
  22010. '$mod.THelper.Fly.call({',
  22011. ' p: $with1.GetField(),',
  22012. ' get: function () {',
  22013. ' return this.p;',
  22014. ' },',
  22015. ' set: function (v) {',
  22016. ' this.p = v;',
  22017. ' }',
  22018. '}, 12);',
  22019. 'var $with2 = $mod.o.GetField();',
  22020. '$mod.THelper.Fly.call({',
  22021. ' get: function () {',
  22022. ' return $with2;',
  22023. ' },',
  22024. ' set: function (v) {',
  22025. ' $with2 = v;',
  22026. ' }',
  22027. '}, 13);',
  22028. '']));
  22029. end;
  22030. procedure TTestModule.TestTypeHelper_PassClassPropertyGetterNonStatic;
  22031. begin
  22032. StartProgram(false);
  22033. Add([
  22034. '{$modeswitch typehelpers}',
  22035. 'type',
  22036. ' TObject = class',
  22037. ' class var FField: word;',
  22038. ' class function GetField: word;',
  22039. ' class property Field: word read GetField write FField;',
  22040. ' end;',
  22041. ' TClass = class of TObject;',
  22042. ' THelper = type helper for word',
  22043. ' procedure Fly(n: byte);',
  22044. ' end;',
  22045. 'class function TObject.GetField: word;',
  22046. 'begin',
  22047. ' Field.Fly(1);',
  22048. ' Self.Field.Fly(5);',
  22049. ' with Self do Field.Fly(6);',
  22050. ' with Self.Field do Fly(7);',
  22051. 'end;',
  22052. 'procedure THelper.Fly(n: byte);',
  22053. 'begin',
  22054. 'end;',
  22055. 'var',
  22056. ' o: TObject;',
  22057. ' c: TClass;',
  22058. 'begin',
  22059. ' o.Field.Fly(11);',
  22060. ' with o do Field.Fly(12);',
  22061. ' with o.Field do Fly(13);',
  22062. ' c.Field.Fly(14);',
  22063. ' with c do Field.Fly(15);',
  22064. ' with c.Field do Fly(16);',
  22065. '']);
  22066. ConvertProgram;
  22067. CheckSource('TestTypeHelper_PassClassPropertyGetterNonStatic',
  22068. LinesToStr([ // statements
  22069. 'rtl.createClass($mod, "TObject", null, function () {',
  22070. ' this.FField = 0;',
  22071. ' this.$init = function () {',
  22072. ' };',
  22073. ' this.$final = function () {',
  22074. ' };',
  22075. ' this.GetField = function () {',
  22076. ' var Result = 0;',
  22077. ' $mod.THelper.Fly.call({',
  22078. ' p: this.GetField(),',
  22079. ' get: function () {',
  22080. ' return this.p;',
  22081. ' },',
  22082. ' set: function (v) {',
  22083. ' this.p = v;',
  22084. ' }',
  22085. ' }, 1);',
  22086. ' $mod.THelper.Fly.call({',
  22087. ' p: this.GetField(),',
  22088. ' get: function () {',
  22089. ' return this.p;',
  22090. ' },',
  22091. ' set: function (v) {',
  22092. ' this.p = v;',
  22093. ' }',
  22094. ' }, 5);',
  22095. ' $mod.THelper.Fly.call({',
  22096. ' p: this.GetField(),',
  22097. ' get: function () {',
  22098. ' return this.p;',
  22099. ' },',
  22100. ' set: function (v) {',
  22101. ' this.p = v;',
  22102. ' }',
  22103. ' }, 6);',
  22104. ' var $with1 = this.GetField();',
  22105. ' $mod.THelper.Fly.call({',
  22106. ' get: function () {',
  22107. ' return $with1;',
  22108. ' },',
  22109. ' set: function (v) {',
  22110. ' $with1 = v;',
  22111. ' }',
  22112. ' }, 7);',
  22113. ' return Result;',
  22114. ' };',
  22115. '});',
  22116. 'rtl.createHelper($mod, "THelper", null, function () {',
  22117. ' this.Fly = function (n) {',
  22118. ' };',
  22119. '});',
  22120. 'this.o = null;',
  22121. 'this.c = null;',
  22122. '']),
  22123. LinesToStr([ // $mod.$main
  22124. '$mod.THelper.Fly.call({',
  22125. ' p: $mod.o.$class.GetField(),',
  22126. ' get: function () {',
  22127. ' return this.p;',
  22128. ' },',
  22129. ' set: function (v) {',
  22130. ' this.p = v;',
  22131. ' }',
  22132. '}, 11);',
  22133. 'var $with1 = $mod.o;',
  22134. '$mod.THelper.Fly.call({',
  22135. ' p: $with1.$class.GetField(),',
  22136. ' get: function () {',
  22137. ' return this.p;',
  22138. ' },',
  22139. ' set: function (v) {',
  22140. ' this.p = v;',
  22141. ' }',
  22142. '}, 12);',
  22143. 'var $with2 = $mod.o.$class.GetField();',
  22144. '$mod.THelper.Fly.call({',
  22145. ' get: function () {',
  22146. ' return $with2;',
  22147. ' },',
  22148. ' set: function (v) {',
  22149. ' $with2 = v;',
  22150. ' }',
  22151. '}, 13);',
  22152. '$mod.THelper.Fly.call({',
  22153. ' p: $mod.c.GetField(),',
  22154. ' get: function () {',
  22155. ' return this.p;',
  22156. ' },',
  22157. ' set: function (v) {',
  22158. ' this.p = v;',
  22159. ' }',
  22160. '}, 14);',
  22161. 'var $with3 = $mod.c;',
  22162. '$mod.THelper.Fly.call({',
  22163. ' p: $with3.GetField(),',
  22164. ' get: function () {',
  22165. ' return this.p;',
  22166. ' },',
  22167. ' set: function (v) {',
  22168. ' this.p = v;',
  22169. ' }',
  22170. '}, 15);',
  22171. 'var $with4 = $mod.c.GetField();',
  22172. '$mod.THelper.Fly.call({',
  22173. ' get: function () {',
  22174. ' return $with4;',
  22175. ' },',
  22176. ' set: function (v) {',
  22177. ' $with4 = v;',
  22178. ' }',
  22179. '}, 16);',
  22180. '']));
  22181. end;
  22182. procedure TTestModule.TestTypeHelper_Property;
  22183. begin
  22184. StartProgram(false);
  22185. Add([
  22186. '{$modeswitch typehelpers}',
  22187. 'type',
  22188. ' THelper = type helper for word',
  22189. ' function GetSize: longint;',
  22190. ' procedure SetSize(Value: longint);',
  22191. ' property Size: longint read GetSize write SetSize;',
  22192. ' end;',
  22193. 'function THelper.GetSize: longint;',
  22194. 'begin',
  22195. ' Result:=Size+1;',
  22196. ' Size:=2;',
  22197. ' Result:=Self.Size+3;',
  22198. ' Self.Size:=4;',
  22199. ' with Self do begin',
  22200. ' Result:=Size+5;',
  22201. ' Size:=6;',
  22202. ' end;',
  22203. 'end;',
  22204. 'procedure THelper.SetSize(Value: longint);',
  22205. 'begin',
  22206. 'end;',
  22207. 'var w: word;',
  22208. 'begin',
  22209. ' w:=w.Size+7;',
  22210. ' w.Size:=w+8;',
  22211. ' with w do begin',
  22212. ' w:=Size+9;',
  22213. ' Size:=w+10;',
  22214. ' end;',
  22215. '']);
  22216. ConvertProgram;
  22217. CheckSource('TestTypeHelper_Property',
  22218. LinesToStr([ // statements
  22219. 'rtl.createHelper($mod, "THelper", null, function () {',
  22220. ' this.GetSize = function () {',
  22221. ' var Result = 0;',
  22222. ' Result = $mod.THelper.GetSize.call(this) + 1;',
  22223. ' $mod.THelper.SetSize.call(this, 2);',
  22224. ' Result = $mod.THelper.GetSize.call(this) + 3;',
  22225. ' $mod.THelper.SetSize.call(this, 4);',
  22226. ' var $with1 = this.get();',
  22227. ' Result = $mod.THelper.GetSize.call(this) + 5;',
  22228. ' $mod.THelper.SetSize.call(this, 6);',
  22229. ' return Result;',
  22230. ' };',
  22231. ' this.SetSize = function (Value) {',
  22232. ' };',
  22233. '});',
  22234. 'this.w = 0;',
  22235. '']),
  22236. LinesToStr([ // $mod.$main
  22237. '$mod.w = $mod.THelper.GetSize.call({',
  22238. ' p: $mod,',
  22239. ' get: function () {',
  22240. ' return this.p.w;',
  22241. ' },',
  22242. ' set: function (v) {',
  22243. ' this.p.w = v;',
  22244. ' }',
  22245. '}) + 7;',
  22246. '$mod.THelper.SetSize.call({',
  22247. ' p: $mod,',
  22248. ' get: function () {',
  22249. ' return this.p.w;',
  22250. ' },',
  22251. ' set: function (v) {',
  22252. ' this.p.w = v;',
  22253. ' }',
  22254. '}, $mod.w + 8);',
  22255. 'var $with1 = $mod.w;',
  22256. '$mod.w = $mod.THelper.GetSize.call({',
  22257. ' get: function () {',
  22258. ' return $with1;',
  22259. ' },',
  22260. ' set: function (v) {',
  22261. ' $with1 = v;',
  22262. ' }',
  22263. '}) + 9;',
  22264. '$mod.THelper.SetSize.call({',
  22265. ' get: function () {',
  22266. ' return $with1;',
  22267. ' },',
  22268. ' set: function (v) {',
  22269. ' $with1 = v;',
  22270. ' }',
  22271. '}, $mod.w + 10);',
  22272. '']));
  22273. end;
  22274. procedure TTestModule.TestTypeHelper_Property_Array;
  22275. begin
  22276. StartProgram(false);
  22277. Add([
  22278. '{$modeswitch typehelpers}',
  22279. 'type',
  22280. ' THelper = type helper for word',
  22281. ' function GetItems(Index: byte): boolean;',
  22282. ' procedure SetItems(Index: byte; Value: boolean);',
  22283. ' property Items[Index: byte]: boolean read GetItems write SetItems;',
  22284. ' end;',
  22285. 'function THelper.GetItems(Index: byte): boolean;',
  22286. 'begin',
  22287. ' Result:=Items[1];',
  22288. ' Items[2]:=false;',
  22289. ' Result:=Self.Items[3];',
  22290. ' Self.Items[4]:=true;',
  22291. ' with Self do begin',
  22292. ' Result:=Items[5];',
  22293. ' Items[6]:=false;',
  22294. ' end;',
  22295. 'end;',
  22296. 'procedure THelper.SetItems(Index: byte; Value: boolean);',
  22297. 'begin',
  22298. 'end;',
  22299. 'var',
  22300. ' w: word;',
  22301. ' b: boolean;',
  22302. 'begin',
  22303. ' b:=w.Items[1];',
  22304. ' w.Items[2]:=b;',
  22305. ' with w do begin',
  22306. ' b:=Items[3];',
  22307. ' Items[4]:=b;',
  22308. ' end;',
  22309. '']);
  22310. ConvertProgram;
  22311. CheckSource('TestTypeHelper_Property_Array',
  22312. LinesToStr([ // statements
  22313. 'rtl.createHelper($mod, "THelper", null, function () {',
  22314. ' this.GetItems = function (Index) {',
  22315. ' var Result = false;',
  22316. ' Result = $mod.THelper.GetItems.call(this, 1);',
  22317. ' $mod.THelper.SetItems.call(this, 2, false);',
  22318. ' Result = $mod.THelper.GetItems.call(this, 3);',
  22319. ' $mod.THelper.SetItems.call(this, 4, true);',
  22320. ' var $with1 = this.get();',
  22321. ' Result = $mod.THelper.GetItems.call(this, 5);',
  22322. ' $mod.THelper.SetItems.call(this, 6, false);',
  22323. ' return Result;',
  22324. ' };',
  22325. ' this.SetItems = function (Index, Value) {',
  22326. ' };',
  22327. '});',
  22328. 'this.w = 0;',
  22329. 'this.b = false;',
  22330. '']),
  22331. LinesToStr([ // $mod.$main
  22332. '$mod.b = $mod.THelper.GetItems.call({',
  22333. ' p: $mod,',
  22334. ' get: function () {',
  22335. ' return this.p.w;',
  22336. ' },',
  22337. ' set: function (v) {',
  22338. ' this.p.w = v;',
  22339. ' }',
  22340. '}, 1);',
  22341. '$mod.THelper.SetItems.call({',
  22342. ' p: $mod,',
  22343. ' get: function () {',
  22344. ' return this.p.w;',
  22345. ' },',
  22346. ' set: function (v) {',
  22347. ' this.p.w = v;',
  22348. ' }',
  22349. '}, 2, $mod.b);',
  22350. 'var $with1 = $mod.w;',
  22351. '$mod.b = $mod.THelper.GetItems.call({',
  22352. ' get: function () {',
  22353. ' return $with1;',
  22354. ' },',
  22355. ' set: function (v) {',
  22356. ' $with1 = v;',
  22357. ' }',
  22358. '}, 3);',
  22359. '$mod.THelper.SetItems.call({',
  22360. ' get: function () {',
  22361. ' return $with1;',
  22362. ' },',
  22363. ' set: function (v) {',
  22364. ' $with1 = v;',
  22365. ' }',
  22366. '}, 4, $mod.b);',
  22367. '']));
  22368. end;
  22369. procedure TTestModule.TestTypeHelper_ClassProperty;
  22370. begin
  22371. StartProgram(false);
  22372. Add([
  22373. '{$modeswitch typehelpers}',
  22374. 'type',
  22375. ' THelper = type helper for word',
  22376. ' class function GetSize: longint; static;',
  22377. ' class procedure SetSize(Value: longint); static;',
  22378. ' class property Size: longint read GetSize write SetSize;',
  22379. ' end;',
  22380. 'class function THelper.GetSize: longint;',
  22381. 'begin',
  22382. ' Result:=Size+1;',
  22383. ' Size:=2;',
  22384. 'end;',
  22385. 'class procedure THelper.SetSize(Value: longint);',
  22386. 'begin',
  22387. 'end;',
  22388. 'begin',
  22389. '']);
  22390. ConvertProgram;
  22391. CheckSource('TestTypeHelper_ClassProperty',
  22392. LinesToStr([ // statements
  22393. 'rtl.createHelper($mod, "THelper", null, function () {',
  22394. ' this.GetSize = function () {',
  22395. ' var Result = 0;',
  22396. ' Result = $mod.THelper.GetSize() + 1;',
  22397. ' $mod.THelper.SetSize(2);',
  22398. ' return Result;',
  22399. ' };',
  22400. ' this.SetSize = function (Value) {',
  22401. ' };',
  22402. '});',
  22403. '']),
  22404. LinesToStr([ // $mod.$main
  22405. '']));
  22406. end;
  22407. procedure TTestModule.TestTypeHelper_ClassProperty_Array;
  22408. begin
  22409. StartProgram(false);
  22410. Add([
  22411. '{$modeswitch typehelpers}',
  22412. 'type',
  22413. ' THelper = type helper for word',
  22414. ' class function GetItems(Index: byte): boolean; static;',
  22415. ' class procedure SetItems(Index: byte; Value: boolean); static;',
  22416. ' class property Items[Index: byte]: boolean read GetItems write SetItems;',
  22417. ' end;',
  22418. 'class function THelper.GetItems(Index: byte): boolean;',
  22419. 'begin',
  22420. ' Result:=Items[1];',
  22421. ' Items[2]:=false;',
  22422. 'end;',
  22423. 'class procedure THelper.SetItems(Index: byte; Value: boolean);',
  22424. 'begin',
  22425. 'end;',
  22426. 'var',
  22427. ' w: word;',
  22428. ' b: boolean;',
  22429. 'begin',
  22430. ' b:=w.Items[1];',
  22431. ' w.Items[2]:=b;',
  22432. ' with w do begin',
  22433. ' b:=Items[3];',
  22434. ' Items[4]:=b;',
  22435. ' end;',
  22436. '']);
  22437. ConvertProgram;
  22438. CheckSource('TestTypeHelper_ClassProperty_Array',
  22439. LinesToStr([ // statements
  22440. 'rtl.createHelper($mod, "THelper", null, function () {',
  22441. ' this.GetItems = function (Index) {',
  22442. ' var Result = false;',
  22443. ' Result = $mod.THelper.GetItems(1);',
  22444. ' $mod.THelper.SetItems(2, false);',
  22445. ' return Result;',
  22446. ' };',
  22447. ' this.SetItems = function (Index, Value) {',
  22448. ' };',
  22449. '});',
  22450. 'this.w = 0;',
  22451. 'this.b = false;',
  22452. '']),
  22453. LinesToStr([ // $mod.$main
  22454. '$mod.b = $mod.THelper.GetItems(1);',
  22455. '$mod.THelper.SetItems(2, $mod.b);',
  22456. 'var $with1 = $mod.w;',
  22457. '$mod.b = $mod.THelper.GetItems(3);',
  22458. '$mod.THelper.SetItems(4, $mod.b);',
  22459. '']));
  22460. end;
  22461. procedure TTestModule.TestTypeHelper_ClassMethod;
  22462. begin
  22463. StartProgram(false);
  22464. Add([
  22465. '{$modeswitch typehelpers}',
  22466. 'type',
  22467. ' THelper = type helper for word',
  22468. ' class procedure DoStatic; static;',
  22469. ' end;',
  22470. 'class procedure THelper.DoStatic;',
  22471. 'begin',
  22472. ' DoStatic;',
  22473. ' DoStatic();',
  22474. 'end;',
  22475. 'var w: word;',
  22476. 'begin',
  22477. ' w.DoStatic;',
  22478. ' w.DoStatic();',
  22479. '']);
  22480. ConvertProgram;
  22481. CheckSource('TestTypeHelper_ClassMethod',
  22482. LinesToStr([ // statements
  22483. 'rtl.createHelper($mod, "THelper", null, function () {',
  22484. ' this.DoStatic = function () {',
  22485. ' $mod.THelper.DoStatic();',
  22486. ' $mod.THelper.DoStatic();',
  22487. ' };',
  22488. '});',
  22489. 'this.w = 0;',
  22490. '']),
  22491. LinesToStr([ // $mod.$main
  22492. '$mod.THelper.DoStatic();',
  22493. '$mod.THelper.DoStatic();',
  22494. '']));
  22495. end;
  22496. procedure TTestModule.TestTypeHelper_ExtClassMethodFail;
  22497. begin
  22498. StartProgram(false);
  22499. Add([
  22500. '{$modeswitch typehelpers}',
  22501. 'type',
  22502. ' THelper = type helper for word',
  22503. ' procedure Run; external name ''Run'';',
  22504. ' end;',
  22505. 'var w: word;',
  22506. 'begin',
  22507. ' w.Run;',
  22508. '']);
  22509. SetExpectedPasResolverError('Not supported: external method in type helper',nNotSupportedX);
  22510. ConvertProgram;
  22511. end;
  22512. procedure TTestModule.TestTypeHelper_Constructor;
  22513. begin
  22514. StartProgram(false);
  22515. Add([
  22516. '{$modeswitch typehelpers}',
  22517. 'type',
  22518. ' THelper = type helper for word',
  22519. ' constructor Init(e: longint);',
  22520. ' end;',
  22521. 'constructor THelper.Init(e: longint);',
  22522. 'begin',
  22523. ' Self:=e;',
  22524. ' Init(e+1);',
  22525. 'end;',
  22526. 'var w: word;',
  22527. 'begin',
  22528. ' w:=word.Init(2);',
  22529. ' w:=w.Init(3);',
  22530. ' with word do w:=Init(4);',
  22531. ' with w do w:=Init(5);',
  22532. '']);
  22533. ConvertProgram;
  22534. CheckSource('TestTypeHelper_Constructor',
  22535. LinesToStr([ // statements
  22536. 'rtl.createHelper($mod, "THelper", null, function () {',
  22537. ' this.Init = function (e) {',
  22538. ' this.set(e);',
  22539. ' $mod.THelper.Init.call(this, e + 1);',
  22540. ' return this.get();',
  22541. ' };',
  22542. ' this.$new = function (fn, args) {',
  22543. ' return this[fn].apply({',
  22544. ' p: 0,',
  22545. ' get: function () {',
  22546. ' return this.p;',
  22547. ' },',
  22548. ' set: function (v) {',
  22549. ' this.p = v;',
  22550. ' }',
  22551. ' }, args);',
  22552. ' };',
  22553. '});',
  22554. 'this.w = 0;',
  22555. '']),
  22556. LinesToStr([ // $mod.$main
  22557. '$mod.w = $mod.THelper.$new("Init", [2]);',
  22558. '$mod.w = $mod.THelper.Init.call({',
  22559. ' p: $mod,',
  22560. ' get: function () {',
  22561. ' return this.p.w;',
  22562. ' },',
  22563. ' set: function (v) {',
  22564. ' this.p.w = v;',
  22565. ' }',
  22566. '}, 3);',
  22567. '$mod.w = $mod.THelper.$new("Init", [4]);',
  22568. 'var $with1 = $mod.w;',
  22569. '$mod.w = $mod.THelper.Init.call({',
  22570. ' get: function () {',
  22571. ' return $with1;',
  22572. ' },',
  22573. ' set: function (v) {',
  22574. ' $with1 = v;',
  22575. ' }',
  22576. '}, 5);',
  22577. '']));
  22578. end;
  22579. procedure TTestModule.TestTypeHelper_Word;
  22580. begin
  22581. StartProgram(false);
  22582. Add([
  22583. '{$modeswitch typehelpers}',
  22584. 'type',
  22585. ' THelper = type helper for word',
  22586. ' procedure DoIt(e: byte = 123);',
  22587. ' end;',
  22588. 'procedure THelper.DoIt(e: byte);',
  22589. 'begin',
  22590. ' Self:=e;',
  22591. ' Self:=Self+1;',
  22592. ' with Self do Doit;',
  22593. 'end;',
  22594. 'begin',
  22595. ' word(3).DoIt;',
  22596. '']);
  22597. ConvertProgram;
  22598. CheckSource('TestTypeHelper_Word',
  22599. LinesToStr([ // statements
  22600. 'rtl.createHelper($mod, "THelper", null, function () {',
  22601. ' this.DoIt = function (e) {',
  22602. ' this.set(e);',
  22603. ' this.set(this.get() + 1);',
  22604. ' var $with1 = this.get();',
  22605. ' $mod.THelper.DoIt.call(this, 123);',
  22606. ' };',
  22607. '});',
  22608. '']),
  22609. LinesToStr([ // $mod.$main
  22610. '$mod.THelper.DoIt.call({',
  22611. ' get: function () {',
  22612. ' return 3;',
  22613. ' },',
  22614. ' set: function (v) {',
  22615. ' rtl.raiseE("EPropReadOnly");',
  22616. ' }',
  22617. '}, 123);',
  22618. '']));
  22619. end;
  22620. procedure TTestModule.TestTypeHelper_Double;
  22621. begin
  22622. StartProgram(false);
  22623. Add([
  22624. '{$modeswitch typehelpers}',
  22625. 'type',
  22626. ' Float = type double;',
  22627. ' THelper = type helper for double',
  22628. ' const NPI = 3.141592;',
  22629. ' function ToStr: String;',
  22630. ' end;',
  22631. 'function THelper.ToStr: String;',
  22632. 'begin',
  22633. 'end;',
  22634. 'procedure DoIt(s: string);',
  22635. 'begin',
  22636. 'end;',
  22637. 'var f: Float;',
  22638. 'begin',
  22639. ' DoIt(f.toStr);',
  22640. ' DoIt(f.toStr());',
  22641. ' (f*f).toStr;',
  22642. ' DoIt((f*f).toStr);',
  22643. '']);
  22644. ConvertProgram;
  22645. CheckSource('TestTypeHelper_Double',
  22646. LinesToStr([ // statements
  22647. 'rtl.createHelper($mod, "THelper", null, function () {',
  22648. ' this.NPI = 3.141592;',
  22649. ' this.ToStr = function () {',
  22650. ' var Result = "";',
  22651. ' return Result;',
  22652. ' };',
  22653. '});',
  22654. 'this.DoIt = function (s) {',
  22655. '};',
  22656. 'this.f = 0.0;',
  22657. '']),
  22658. LinesToStr([ // $mod.$main
  22659. '$mod.DoIt($mod.THelper.ToStr.call({',
  22660. ' p: $mod,',
  22661. ' get: function () {',
  22662. ' return this.p.f;',
  22663. ' },',
  22664. ' set: function (v) {',
  22665. ' this.p.f = v;',
  22666. ' }',
  22667. '}));',
  22668. '$mod.DoIt($mod.THelper.ToStr.call({',
  22669. ' p: $mod,',
  22670. ' get: function () {',
  22671. ' return this.p.f;',
  22672. ' },',
  22673. ' set: function (v) {',
  22674. ' this.p.f = v;',
  22675. ' }',
  22676. '}));',
  22677. '$mod.THelper.ToStr.call({',
  22678. ' a: $mod.f * $mod.f,',
  22679. ' get: function () {',
  22680. ' return this.a;',
  22681. ' },',
  22682. ' set: function (v) {',
  22683. ' rtl.raiseE("EPropReadOnly");',
  22684. ' }',
  22685. '});',
  22686. '$mod.DoIt($mod.THelper.ToStr.call({',
  22687. ' a: $mod.f * $mod.f,',
  22688. ' get: function () {',
  22689. ' return this.a;',
  22690. ' },',
  22691. ' set: function (v) {',
  22692. ' rtl.raiseE("EPropReadOnly");',
  22693. ' }',
  22694. '}));',
  22695. '']));
  22696. end;
  22697. procedure TTestModule.TestTypeHelper_StringChar;
  22698. begin
  22699. StartProgram(false);
  22700. Add([
  22701. '{$modeswitch typehelpers}',
  22702. 'type',
  22703. ' TStringHelper = type helper for string',
  22704. ' procedure DoIt(e: byte = 123);',
  22705. ' end;',
  22706. ' TCharHelper = type helper for char',
  22707. ' procedure Fly;',
  22708. ' end;',
  22709. 'procedure TStringHelper.DoIt(e: byte);',
  22710. 'begin',
  22711. ' Self[1]:=''c'';',
  22712. ' Self[2]:=Self[3];',
  22713. 'end;',
  22714. 'procedure TCharHelper.Fly;',
  22715. 'begin',
  22716. ' Self:=''c'';',
  22717. 'end;',
  22718. 'begin',
  22719. ' ''abc''.DoIt;',
  22720. ' ''xyz''.DoIt();',
  22721. ' ''c''.Fly();',
  22722. '']);
  22723. ConvertProgram;
  22724. CheckSource('TestTypeHelper_StringChar',
  22725. LinesToStr([ // statements
  22726. 'rtl.createHelper($mod, "TStringHelper", null, function () {',
  22727. ' this.DoIt = function (e) {',
  22728. ' this.set(rtl.setCharAt(this.get(), 0, "c"));',
  22729. ' this.set(rtl.setCharAt(this.get(), 1, this.get().charAt(2)));',
  22730. ' };',
  22731. '});',
  22732. 'rtl.createHelper($mod, "TCharHelper", null, function () {',
  22733. ' this.Fly = function () {',
  22734. ' this.set("c");',
  22735. ' };',
  22736. '});',
  22737. '']),
  22738. LinesToStr([ // $mod.$main
  22739. '$mod.TStringHelper.DoIt.call({',
  22740. ' get: function () {',
  22741. ' return "abc";',
  22742. ' },',
  22743. ' set: function (v) {',
  22744. ' rtl.raiseE("EPropReadOnly");',
  22745. ' }',
  22746. '}, 123);',
  22747. '$mod.TStringHelper.DoIt.call({',
  22748. ' get: function () {',
  22749. ' return "xyz";',
  22750. ' },',
  22751. ' set: function (v) {',
  22752. ' rtl.raiseE("EPropReadOnly");',
  22753. ' }',
  22754. '}, 123);',
  22755. '$mod.TCharHelper.Fly.call({',
  22756. ' get: function () {',
  22757. ' return "c";',
  22758. ' },',
  22759. ' set: function (v) {',
  22760. ' rtl.raiseE("EPropReadOnly");',
  22761. ' }',
  22762. '});',
  22763. '']));
  22764. end;
  22765. procedure TTestModule.TestTypeHelper_Array;
  22766. begin
  22767. StartProgram(false);
  22768. Add([
  22769. '{$modeswitch typehelpers}',
  22770. 'type',
  22771. ' TArrOfBool = array of boolean;',
  22772. ' TArrOfJS = array of jsvalue;',
  22773. ' THelper = type helper for TArrOfBool',
  22774. ' procedure DoIt(e: byte = 123);',
  22775. ' end;',
  22776. 'procedure THelper.DoIt(e: byte);',
  22777. 'begin',
  22778. ' Self[1]:=true;',
  22779. ' Self[2]:=not Self[3];',
  22780. ' SetLength(Self,4);',
  22781. 'end;',
  22782. 'var',
  22783. ' b: TArrOfBool;',
  22784. ' j: TArrOfJS;',
  22785. 'begin',
  22786. ' b.DoIt;',
  22787. ' TArrOfBool(j).DoIt();',
  22788. '']);
  22789. ConvertProgram;
  22790. CheckSource('TestTypeHelper_Array',
  22791. LinesToStr([ // statements
  22792. 'rtl.createHelper($mod, "THelper", null, function () {',
  22793. ' this.DoIt = function (e) {',
  22794. ' this.get()[1] = true;',
  22795. ' this.get()[2] = !this.get()[3];',
  22796. ' this.set(rtl.arraySetLength(this.get(), false, 4));',
  22797. ' };',
  22798. '});',
  22799. 'this.b = [];',
  22800. 'this.j = [];',
  22801. '']),
  22802. LinesToStr([ // $mod.$main
  22803. '$mod.THelper.DoIt.call({',
  22804. ' p: $mod,',
  22805. ' get: function () {',
  22806. ' return this.p.b;',
  22807. ' },',
  22808. ' set: function (v) {',
  22809. ' this.p.b = v;',
  22810. ' }',
  22811. '}, 123);',
  22812. '$mod.THelper.DoIt.call({',
  22813. ' p: $mod,',
  22814. ' get: function () {',
  22815. ' return this.p.j;',
  22816. ' },',
  22817. ' set: function (v) {',
  22818. ' this.p.j = v;',
  22819. ' }',
  22820. '}, 123);',
  22821. '']));
  22822. end;
  22823. procedure TTestModule.TestTypeHelper_EnumType;
  22824. begin
  22825. StartProgram(false);
  22826. Add([
  22827. '{$modeswitch typehelpers}',
  22828. 'type',
  22829. ' TEnum = (red,blue);',
  22830. ' THelper = type helper for TEnum',
  22831. ' procedure DoIt(e: byte = 123);',
  22832. ' class procedure Swing(w: word); static;',
  22833. ' end;',
  22834. 'procedure THelper.DoIt(e: byte);',
  22835. 'begin',
  22836. ' Self:=red;',
  22837. ' Self:=succ(Self);',
  22838. ' with Self do Doit;',
  22839. 'end;',
  22840. 'class procedure THelper.Swing(w: word);',
  22841. 'begin',
  22842. 'end;',
  22843. 'var e: TEnum;',
  22844. 'begin',
  22845. ' e.DoIt;',
  22846. ' red.DoIt;',
  22847. ' TEnum.blue.DoIt;',
  22848. ' TEnum(1).DoIt;',
  22849. ' TEnum.Swing(3);',
  22850. '']);
  22851. ConvertProgram;
  22852. CheckSource('TestTypeHelper_EnumType',
  22853. LinesToStr([ // statements
  22854. 'this.TEnum = {',
  22855. ' "0": "red",',
  22856. ' red: 0,',
  22857. ' "1": "blue",',
  22858. ' blue: 1',
  22859. '};',
  22860. 'rtl.createHelper($mod, "THelper", null, function () {',
  22861. ' this.DoIt = function (e) {',
  22862. ' this.set($mod.TEnum.red);',
  22863. ' this.set(this.get() + 1);',
  22864. ' var $with1 = this.get();',
  22865. ' $mod.THelper.DoIt.call(this, 123);',
  22866. ' };',
  22867. ' this.Swing = function (w) {',
  22868. ' };',
  22869. '});',
  22870. 'this.e = 0;',
  22871. '']),
  22872. LinesToStr([ // $mod.$main
  22873. '$mod.THelper.DoIt.call({',
  22874. ' p: $mod,',
  22875. ' get: function () {',
  22876. ' return this.p.e;',
  22877. ' },',
  22878. ' set: function (v) {',
  22879. ' this.p.e = v;',
  22880. ' }',
  22881. '}, 123);',
  22882. '$mod.THelper.DoIt.call({',
  22883. ' p: $mod.TEnum,',
  22884. ' get: function () {',
  22885. ' return this.p.red;',
  22886. ' },',
  22887. ' set: function (v) {',
  22888. ' rtl.raiseE("EPropReadOnly");',
  22889. ' }',
  22890. '}, 123);',
  22891. '$mod.THelper.DoIt.call({',
  22892. ' p: $mod.TEnum,',
  22893. ' get: function () {',
  22894. ' return this.p.blue;',
  22895. ' },',
  22896. ' set: function (v) {',
  22897. ' rtl.raiseE("EPropReadOnly");',
  22898. ' }',
  22899. '}, 123);',
  22900. '$mod.THelper.DoIt.call({',
  22901. ' get: function () {',
  22902. ' return 1;',
  22903. ' },',
  22904. ' set: function (v) {',
  22905. ' rtl.raiseE("EPropReadOnly");',
  22906. ' }',
  22907. '}, 123);',
  22908. '$mod.THelper.Swing(3);',
  22909. '']));
  22910. end;
  22911. procedure TTestModule.TestTypeHelper_SetType;
  22912. begin
  22913. StartProgram(false);
  22914. Add([
  22915. '{$modeswitch typehelpers}',
  22916. 'type',
  22917. ' TEnum = (red,blue);',
  22918. ' TSetOfEnum = set of TEnum;',
  22919. ' THelper = type helper for TSetOfEnum',
  22920. ' procedure DoIt(e: byte = 123);',
  22921. ' constructor Init(e: TEnum);',
  22922. ' constructor InitEmpty;',
  22923. ' end;',
  22924. 'procedure THelper.DoIt(e: byte);',
  22925. 'begin',
  22926. ' Self:=[];',
  22927. ' Self:=[red];',
  22928. ' Include(Self,blue);',
  22929. 'end;',
  22930. 'constructor THelper.Init(e: TEnum);',
  22931. 'begin',
  22932. ' Self:=[];',
  22933. ' Self:=[e];',
  22934. ' Include(Self,blue);',
  22935. 'end;',
  22936. 'constructor THelper.InitEmpty;',
  22937. 'begin',
  22938. 'end;',
  22939. 'var s: TSetOfEnum;',
  22940. 'begin',
  22941. ' s.DoIt;',
  22942. //' [red].DoIt;',
  22943. //' with s do DoIt;',
  22944. //' with [red,blue] do DoIt;',
  22945. ' s:=TSetOfEnum.Init(blue);',
  22946. ' s:=s.Init(blue);',
  22947. '']);
  22948. ConvertProgram;
  22949. CheckSource('TestTypeHelper_SetType',
  22950. LinesToStr([ // statements
  22951. 'this.TEnum = {',
  22952. ' "0": "red",',
  22953. ' red: 0,',
  22954. ' "1": "blue",',
  22955. ' blue: 1',
  22956. '};',
  22957. 'rtl.createHelper($mod, "THelper", null, function () {',
  22958. ' this.DoIt = function (e) {',
  22959. ' this.set({});',
  22960. ' this.set(rtl.createSet($mod.TEnum.red));',
  22961. ' this.set(rtl.includeSet(this.get(), $mod.TEnum.blue));',
  22962. ' };',
  22963. ' this.Init = function (e) {',
  22964. ' this.set({});',
  22965. ' this.set(rtl.createSet(e));',
  22966. ' this.set(rtl.includeSet(this.get(), $mod.TEnum.blue));',
  22967. ' return this.get();',
  22968. ' };',
  22969. ' this.InitEmpty = function () {',
  22970. ' return this.get();',
  22971. ' };',
  22972. ' this.$new = function (fn, args) {',
  22973. ' return this[fn].apply({',
  22974. ' p: {},',
  22975. ' get: function () {',
  22976. ' return this.p;',
  22977. ' },',
  22978. ' set: function (v) {',
  22979. ' this.p = v;',
  22980. ' }',
  22981. ' }, args);',
  22982. ' };',
  22983. '});',
  22984. 'this.s = {};',
  22985. '']),
  22986. LinesToStr([ // $mod.$main
  22987. '$mod.THelper.DoIt.call({',
  22988. ' p: $mod,',
  22989. ' get: function () {',
  22990. ' return this.p.s;',
  22991. ' },',
  22992. ' set: function (v) {',
  22993. ' this.p.s = v;',
  22994. ' }',
  22995. '}, 123);',
  22996. '$mod.s = rtl.refSet($mod.THelper.$new("Init", [$mod.TEnum.blue]));',
  22997. '$mod.s = rtl.refSet($mod.THelper.Init.call({',
  22998. ' p: $mod,',
  22999. ' get: function () {',
  23000. ' return this.p.s;',
  23001. ' },',
  23002. ' set: function (v) {',
  23003. ' this.p.s = v;',
  23004. ' }',
  23005. '}, $mod.TEnum.blue));',
  23006. '']));
  23007. end;
  23008. procedure TTestModule.TestTypeHelper_InterfaceType;
  23009. begin
  23010. StartProgram(false);
  23011. Add([
  23012. '{$interfaces com}',
  23013. '{$modeswitch typehelpers}',
  23014. 'type',
  23015. ' IUnknown = interface',
  23016. ' function _AddRef: longint;',
  23017. ' function _Release: longint;',
  23018. ' end;',
  23019. ' TObject = class(IUnknown)',
  23020. ' function _AddRef: longint; virtual; abstract;',
  23021. ' function _Release: longint; virtual; abstract;',
  23022. ' end;',
  23023. ' THelper = type helper for IUnknown',
  23024. ' procedure Fly(e: byte = 123);',
  23025. ' class procedure Run; static;',
  23026. ' end;',
  23027. 'var',
  23028. ' i: IUnknown;',
  23029. ' o: TObject;',
  23030. 'procedure THelper.Fly(e: byte);',
  23031. 'begin',
  23032. ' i:=Self;',
  23033. ' o:=Self as TObject;',
  23034. ' Self:=nil;',
  23035. ' Self:=i;',
  23036. ' Self:=o;',
  23037. ' with Self do begin',
  23038. ' Fly;',
  23039. ' Fly();',
  23040. ' end;',
  23041. 'end;',
  23042. 'class procedure THelper.Run;',
  23043. 'var l: IUnknown;',
  23044. 'begin',
  23045. ' l.Fly;',
  23046. ' l.Fly();',
  23047. 'end;',
  23048. 'begin',
  23049. ' i.Fly;',
  23050. ' i.Fly();',
  23051. ' i.Run;',
  23052. ' i.Run();',
  23053. ' IUnknown.Run;',
  23054. ' IUnknown.Run();',
  23055. '']);
  23056. ConvertProgram;
  23057. CheckSource('TestTypeHelper_InterfaceType',
  23058. LinesToStr([ // statements
  23059. 'rtl.createInterface($mod, "IUnknown", "{D7ADB0E1-758A-322B-BDDF-21CD521DDFA9}", ["_AddRef", "_Release"], null);',
  23060. 'rtl.createClass($mod, "TObject", null, function () {',
  23061. ' this.$init = function () {',
  23062. ' };',
  23063. ' this.$final = function () {',
  23064. ' };',
  23065. ' rtl.addIntf(this, $mod.IUnknown);',
  23066. '});',
  23067. 'rtl.createHelper($mod, "THelper", null, function () {',
  23068. ' this.Fly = function (e) {',
  23069. ' var $ir = rtl.createIntfRefs();',
  23070. ' try {',
  23071. ' rtl.setIntfP($mod, "i", this.get());',
  23072. ' $mod.o = rtl.intfAsClass(this.get(), $mod.TObject);',
  23073. ' this.set(null);',
  23074. ' this.set($mod.i);',
  23075. ' this.set($ir.ref(1, rtl.queryIntfT($mod.o, $mod.IUnknown)));',
  23076. ' var $with1 = this.get();',
  23077. ' $mod.THelper.Fly.call(this, 123);',
  23078. ' $mod.THelper.Fly.call(this, 123);',
  23079. ' } finally {',
  23080. ' $ir.free();',
  23081. ' };',
  23082. ' };',
  23083. ' this.Run = function () {',
  23084. ' var l = null;',
  23085. ' try {',
  23086. ' $mod.THelper.Fly.call({',
  23087. ' get: function () {',
  23088. ' return l;',
  23089. ' },',
  23090. ' set: function (v) {',
  23091. ' l = rtl.setIntfL(l, v);',
  23092. ' }',
  23093. ' }, 123);',
  23094. ' $mod.THelper.Fly.call({',
  23095. ' get: function () {',
  23096. ' return l;',
  23097. ' },',
  23098. ' set: function (v) {',
  23099. ' l = rtl.setIntfL(l, v);',
  23100. ' }',
  23101. ' }, 123);',
  23102. ' } finally {',
  23103. ' rtl._Release(l);',
  23104. ' };',
  23105. ' };',
  23106. '});',
  23107. 'this.i = null;',
  23108. 'this.o = null;',
  23109. '']),
  23110. LinesToStr([ // $mod.$main
  23111. '$mod.THelper.Fly.call({',
  23112. ' p: $mod,',
  23113. ' get: function () {',
  23114. ' return this.p.i;',
  23115. ' },',
  23116. ' set: function (v) {',
  23117. ' rtl.setIntfP(this.p, "i", v);',
  23118. ' }',
  23119. '}, 123);',
  23120. '$mod.THelper.Fly.call({',
  23121. ' p: $mod,',
  23122. ' get: function () {',
  23123. ' return this.p.i;',
  23124. ' },',
  23125. ' set: function (v) {',
  23126. ' rtl.setIntfP(this.p, "i", v);',
  23127. ' }',
  23128. '}, 123);',
  23129. '$mod.THelper.Run();',
  23130. '$mod.THelper.Run();',
  23131. '$mod.THelper.Run();',
  23132. '$mod.THelper.Run();',
  23133. '']));
  23134. end;
  23135. procedure TTestModule.TestProcType;
  23136. begin
  23137. StartProgram(false);
  23138. Add([
  23139. 'type',
  23140. ' TProcInt = procedure(vI: longint = 1);',
  23141. 'procedure DoIt(vJ: longint);',
  23142. 'begin end;',
  23143. 'var',
  23144. ' b: boolean;',
  23145. ' vP, vQ: tprocint;',
  23146. 'begin',
  23147. ' vp:=nil;',
  23148. ' vp:=vp;',
  23149. ' vp:=@doit;',
  23150. ' vp;',
  23151. ' vp();',
  23152. ' vp(2);',
  23153. ' b:=vp=nil;',
  23154. ' b:=nil=vp;',
  23155. ' b:=vp=vq;',
  23156. ' b:=vp=@doit;',
  23157. ' b:=@doit=vp;',
  23158. ' b:=vp<>nil;',
  23159. ' b:=nil<>vp;',
  23160. ' b:=vp<>vq;',
  23161. ' b:=vp<>@doit;',
  23162. ' b:=@doit<>vp;',
  23163. ' b:=Assigned(vp);',
  23164. ' if Assigned(vp) then ;']);
  23165. ConvertProgram;
  23166. CheckSource('TestProcType',
  23167. LinesToStr([ // statements
  23168. 'this.DoIt = function(vJ) {',
  23169. '};',
  23170. 'this.b = false;',
  23171. 'this.vP = null;',
  23172. 'this.vQ = null;'
  23173. ]),
  23174. LinesToStr([ // $mod.$main
  23175. '$mod.vP = null;',
  23176. '$mod.vP = $mod.vP;',
  23177. '$mod.vP = $mod.DoIt;',
  23178. '$mod.vP(1);',
  23179. '$mod.vP(1);',
  23180. '$mod.vP(2);',
  23181. '$mod.b = $mod.vP === null;',
  23182. '$mod.b = null === $mod.vP;',
  23183. '$mod.b = rtl.eqCallback($mod.vP,$mod.vQ);',
  23184. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  23185. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  23186. '$mod.b = $mod.vP !== null;',
  23187. '$mod.b = null !== $mod.vP;',
  23188. '$mod.b = !rtl.eqCallback($mod.vP,$mod.vQ);',
  23189. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  23190. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  23191. '$mod.b = $mod.vP != null;',
  23192. 'if ($mod.vP != null) ;',
  23193. '']));
  23194. end;
  23195. procedure TTestModule.TestProcType_Arg;
  23196. begin
  23197. StartProgram(false);
  23198. Add([
  23199. 'type',
  23200. ' TProcInt = procedure(vI: longint = 1);',
  23201. 'procedure DoIt(vJ: longint); begin end;',
  23202. 'procedure DoSome(vP, vQ: TProcInt);',
  23203. 'var',
  23204. ' b: boolean;',
  23205. 'begin',
  23206. ' vp:=nil;',
  23207. ' vp:=vp;',
  23208. ' vp:=@doit;',
  23209. ' vp;',
  23210. ' vp();',
  23211. ' vp(2);',
  23212. ' b:=vp=nil;',
  23213. ' b:=nil=vp;',
  23214. ' b:=vp=vq;',
  23215. ' b:=vp=@doit;',
  23216. ' b:=@doit=vp;',
  23217. ' b:=vp<>nil;',
  23218. ' b:=nil<>vp;',
  23219. ' b:=vp<>vq;',
  23220. ' b:=vp<>@doit;',
  23221. ' b:=@doit<>vp;',
  23222. ' b:=Assigned(vp);',
  23223. ' if Assigned(vp) then ;',
  23224. 'end;',
  23225. 'begin',
  23226. ' DoSome(@DoIt,nil);']);
  23227. ConvertProgram;
  23228. CheckSource('TestProcType_Arg',
  23229. LinesToStr([ // statements
  23230. 'this.DoIt = function(vJ) {',
  23231. '};',
  23232. 'this.DoSome = function(vP, vQ) {',
  23233. ' var b = false;',
  23234. ' vP = null;',
  23235. ' vP = vP;',
  23236. ' vP = $mod.DoIt;',
  23237. ' vP(1);',
  23238. ' vP(1);',
  23239. ' vP(2);',
  23240. ' b = vP === null;',
  23241. ' b = null === vP;',
  23242. ' b = rtl.eqCallback(vP,vQ);',
  23243. ' b = rtl.eqCallback(vP, $mod.DoIt);',
  23244. ' b = rtl.eqCallback($mod.DoIt, vP);',
  23245. ' b = vP !== null;',
  23246. ' b = null !== vP;',
  23247. ' b = !rtl.eqCallback(vP, vQ);',
  23248. ' b = !rtl.eqCallback(vP, $mod.DoIt);',
  23249. ' b = !rtl.eqCallback($mod.DoIt, vP);',
  23250. ' b = vP != null;',
  23251. ' if (vP != null) ;',
  23252. '};',
  23253. '']),
  23254. LinesToStr([ // $mod.$main
  23255. '$mod.DoSome($mod.DoIt,null);',
  23256. '']));
  23257. end;
  23258. procedure TTestModule.TestProcType_FunctionFPC;
  23259. begin
  23260. StartProgram(false);
  23261. Add('type');
  23262. Add(' TFuncInt = function(vA: longint = 1): longint;');
  23263. Add('function DoIt(vI: longint): longint;');
  23264. Add('begin end;');
  23265. Add('var');
  23266. Add(' b: boolean;');
  23267. Add(' vP, vQ: tfuncint;');
  23268. Add('begin');
  23269. Add(' vp:=nil;');
  23270. Add(' vp:=vp;');
  23271. Add(' vp:=@doit;'); // ok in fpc and delphi
  23272. //Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  23273. Add(' vp;'); // ok in fpc and delphi
  23274. Add(' vp();');
  23275. Add(' vp(2);');
  23276. Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  23277. Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  23278. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  23279. Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  23280. Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  23281. //Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  23282. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  23283. Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  23284. Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  23285. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  23286. Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  23287. Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  23288. //Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  23289. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  23290. Add(' b:=Assigned(vp);');
  23291. //Add(' doit(vp);'); // illegal in fpc, ok in delphi
  23292. Add(' doit(vp());'); // ok in fpc and delphi
  23293. Add(' doit(vp(2));'); // ok in fpc and delphi
  23294. ConvertProgram;
  23295. CheckSource('TestProcType_FunctionFPC',
  23296. LinesToStr([ // statements
  23297. 'this.DoIt = function(vI) {',
  23298. ' var Result = 0;',
  23299. ' return Result;',
  23300. '};',
  23301. 'this.b = false;',
  23302. 'this.vP = null;',
  23303. 'this.vQ = null;'
  23304. ]),
  23305. LinesToStr([ // $mod.$main
  23306. '$mod.vP = null;',
  23307. '$mod.vP = $mod.vP;',
  23308. '$mod.vP = $mod.DoIt;',
  23309. '$mod.vP(1);',
  23310. '$mod.vP(1);',
  23311. '$mod.vP(2);',
  23312. '$mod.b = $mod.vP === null;',
  23313. '$mod.b = null === $mod.vP;',
  23314. '$mod.b = rtl.eqCallback($mod.vP,$mod.vQ);',
  23315. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  23316. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  23317. '$mod.b = 4 === $mod.vP(1);',
  23318. '$mod.b = $mod.vP !== null;',
  23319. '$mod.b = null !== $mod.vP;',
  23320. '$mod.b = !rtl.eqCallback($mod.vP,$mod.vQ);',
  23321. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  23322. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  23323. '$mod.b = 6 !== $mod.vP(1);',
  23324. '$mod.b = $mod.vP != null;',
  23325. '$mod.DoIt($mod.vP(1));',
  23326. '$mod.DoIt($mod.vP(2));',
  23327. '']));
  23328. end;
  23329. procedure TTestModule.TestProcType_FunctionDelphi;
  23330. begin
  23331. StartProgram(false);
  23332. Add('{$mode Delphi}');
  23333. Add('type');
  23334. Add(' TFuncInt = function(vA: longint = 1): longint;');
  23335. Add('function DoIt(vI: longint): longint;');
  23336. Add('begin end;');
  23337. Add('var');
  23338. Add(' b: boolean;');
  23339. Add(' vP, vQ: tfuncint;');
  23340. Add('begin');
  23341. Add(' vp:=nil;');
  23342. Add(' vp:=vp;');
  23343. Add(' vp:=@doit;'); // ok in fpc and delphi
  23344. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  23345. Add(' vp;'); // ok in fpc and delphi
  23346. Add(' vp();');
  23347. Add(' vp(2);');
  23348. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  23349. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  23350. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  23351. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  23352. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  23353. Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  23354. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  23355. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  23356. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  23357. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  23358. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  23359. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  23360. Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  23361. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  23362. Add(' b:=Assigned(vp);');
  23363. Add(' doit(vp);'); // illegal in fpc, ok in delphi
  23364. Add(' doit(vp());'); // ok in fpc and delphi
  23365. Add(' doit(vp(2));'); // ok in fpc and delphi *)
  23366. ConvertProgram;
  23367. CheckSource('TestProcType_FunctionDelphi',
  23368. LinesToStr([ // statements
  23369. 'this.DoIt = function(vI) {',
  23370. ' var Result = 0;',
  23371. ' return Result;',
  23372. '};',
  23373. 'this.b = false;',
  23374. 'this.vP = null;',
  23375. 'this.vQ = null;'
  23376. ]),
  23377. LinesToStr([ // $mod.$main
  23378. '$mod.vP = null;',
  23379. '$mod.vP = $mod.vP;',
  23380. '$mod.vP = $mod.DoIt;',
  23381. '$mod.vP = $mod.DoIt;',
  23382. '$mod.vP(1);',
  23383. '$mod.vP(1);',
  23384. '$mod.vP(2);',
  23385. '$mod.b = $mod.vP(1) === $mod.vQ(1);',
  23386. '$mod.b = $mod.vP(1) === 3;',
  23387. '$mod.b = 4 === $mod.vP(1);',
  23388. '$mod.b = $mod.vP(1) !== $mod.vQ(1);',
  23389. '$mod.b = $mod.vP(1) !== 5;',
  23390. '$mod.b = 6 !== $mod.vP(1);',
  23391. '$mod.b = $mod.vP != null;',
  23392. '$mod.DoIt($mod.vP(1));',
  23393. '$mod.DoIt($mod.vP(1));',
  23394. '$mod.DoIt($mod.vP(2));',
  23395. '']));
  23396. end;
  23397. procedure TTestModule.TestProcType_ProcedureDelphi;
  23398. begin
  23399. StartProgram(false);
  23400. Add('{$mode Delphi}');
  23401. Add('type');
  23402. Add(' TProc = procedure;');
  23403. Add('procedure DoIt;');
  23404. Add('begin end;');
  23405. Add('var');
  23406. Add(' b: boolean;');
  23407. Add(' vP, vQ: tproc;');
  23408. Add('begin');
  23409. Add(' vp:=nil;');
  23410. Add(' vp:=vp;');
  23411. Add(' vp:=vq;');
  23412. 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
  23413. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  23414. //Add(' vp:=@doit;'); // illegal in fpc, ok in delphi (because Delphi treats @F as Pointer), not supported by resolver
  23415. Add(' vp;'); // ok in fpc and delphi
  23416. Add(' vp();');
  23417. // equal
  23418. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  23419. Add(' b:=@@vp=nil;'); // ok in fpc delphi mode, ok in delphi
  23420. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  23421. Add(' b:=nil=@@vp;'); // ok in fpc delphi mode, ok in delphi
  23422. Add(' b:=@@vp=@@vq;'); // ok in fpc delphi mode, ok in Delphi
  23423. //Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  23424. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  23425. Add(' b:=@@vp=@doit;'); // ok in fpc delphi mode, ok in delphi
  23426. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  23427. Add(' b:=@doit=@@vp;'); // ok in fpc delphi mode, ok in delphi
  23428. // unequal
  23429. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  23430. Add(' b:=@@vp<>nil;'); // ok in fpc mode delphi, ok in delphi
  23431. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  23432. Add(' b:=nil<>@@vp;'); // ok in fpc mode delphi, ok in delphi
  23433. //Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  23434. Add(' b:=@@vp<>@@vq;'); // ok in fpc mode delphi, ok in delphi
  23435. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  23436. Add(' b:=@@vp<>@doit;'); // ok in fpc mode delphi, illegal in delphi
  23437. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  23438. Add(' b:=@doit<>@@vp;'); // ok in fpc mode delphi, illegal in delphi
  23439. Add(' b:=Assigned(vp);');
  23440. ConvertProgram;
  23441. CheckSource('TestProcType_ProcedureDelphi',
  23442. LinesToStr([ // statements
  23443. 'this.DoIt = function() {',
  23444. '};',
  23445. 'this.b = false;',
  23446. 'this.vP = null;',
  23447. 'this.vQ = null;'
  23448. ]),
  23449. LinesToStr([ // $mod.$main
  23450. '$mod.vP = null;',
  23451. '$mod.vP = $mod.vP;',
  23452. '$mod.vP = $mod.vQ;',
  23453. '$mod.vP = $mod.DoIt;',
  23454. '$mod.vP = $mod.DoIt;',
  23455. '$mod.vP();',
  23456. '$mod.vP();',
  23457. '$mod.b = $mod.vP === null;',
  23458. '$mod.b = null === $mod.vP;',
  23459. '$mod.b = rtl.eqCallback($mod.vP, $mod.vQ);',
  23460. '$mod.b = rtl.eqCallback($mod.vP, $mod.DoIt);',
  23461. '$mod.b = rtl.eqCallback($mod.DoIt, $mod.vP);',
  23462. '$mod.b = $mod.vP !== null;',
  23463. '$mod.b = null !== $mod.vP;',
  23464. '$mod.b = !rtl.eqCallback($mod.vP, $mod.vQ);',
  23465. '$mod.b = !rtl.eqCallback($mod.vP, $mod.DoIt);',
  23466. '$mod.b = !rtl.eqCallback($mod.DoIt, $mod.vP);',
  23467. '$mod.b = $mod.vP != null;',
  23468. '']));
  23469. end;
  23470. procedure TTestModule.TestProcType_AsParam;
  23471. begin
  23472. StartProgram(false);
  23473. Add('type');
  23474. Add(' TFuncInt = function(vA: longint = 1): longint;');
  23475. Add('procedure DoIt(vG: tfuncint; const vH: tfuncint; var vI: tfuncint);');
  23476. Add('var vJ: tfuncint;');
  23477. Add('begin');
  23478. Add(' vg:=vg;');
  23479. Add(' vj:=vh;');
  23480. Add(' vi:=vi;');
  23481. Add(' doit(vg,vg,vg);');
  23482. Add(' doit(vh,vh,vj);');
  23483. Add(' doit(vi,vi,vi);');
  23484. Add(' doit(vj,vj,vj);');
  23485. Add('end;');
  23486. Add('var i: tfuncint;');
  23487. Add('begin');
  23488. Add(' doit(i,i,i);');
  23489. ConvertProgram;
  23490. CheckSource('TestProcType_AsParam',
  23491. LinesToStr([ // statements
  23492. 'this.DoIt = function (vG,vH,vI) {',
  23493. ' var vJ = null;',
  23494. ' vG = vG;',
  23495. ' vJ = vH;',
  23496. ' vI.set(vI.get());',
  23497. ' $mod.DoIt(vG, vG, {',
  23498. ' get: function () {',
  23499. ' return vG;',
  23500. ' },',
  23501. ' set: function (v) {',
  23502. ' vG = v;',
  23503. ' }',
  23504. ' });',
  23505. ' $mod.DoIt(vH, vH, {',
  23506. ' get: function () {',
  23507. ' return vJ;',
  23508. ' },',
  23509. ' set: function (v) {',
  23510. ' vJ = v;',
  23511. ' }',
  23512. ' });',
  23513. ' $mod.DoIt(vI.get(), vI.get(), vI);',
  23514. ' $mod.DoIt(vJ, vJ, {',
  23515. ' get: function () {',
  23516. ' return vJ;',
  23517. ' },',
  23518. ' set: function (v) {',
  23519. ' vJ = v;',
  23520. ' }',
  23521. ' });',
  23522. '};',
  23523. 'this.i = null;'
  23524. ]),
  23525. LinesToStr([
  23526. '$mod.DoIt($mod.i,$mod.i,{',
  23527. ' p: $mod,',
  23528. ' get: function () {',
  23529. ' return this.p.i;',
  23530. ' },',
  23531. ' set: function (v) {',
  23532. ' this.p.i = v;',
  23533. ' }',
  23534. '});'
  23535. ]));
  23536. end;
  23537. procedure TTestModule.TestProcType_MethodFPC;
  23538. begin
  23539. StartProgram(false);
  23540. Add('type');
  23541. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23542. Add(' TObject = class');
  23543. Add(' function DoIt(vA: longint = 1): longint;');
  23544. Add(' end;');
  23545. Add('function TObject.DoIt(vA: longint = 1): longint;');
  23546. Add('begin');
  23547. Add('end;');
  23548. Add('var');
  23549. Add(' Obj: TObject;');
  23550. Add(' vP: tfuncint;');
  23551. Add(' b: boolean;');
  23552. Add('begin');
  23553. Add(' vp:[email protected];'); // ok in fpc and delphi
  23554. //Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  23555. Add(' vp;'); // ok in fpc and delphi
  23556. Add(' vp();');
  23557. Add(' vp(2);');
  23558. Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  23559. Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  23560. Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  23561. Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  23562. ConvertProgram;
  23563. CheckSource('TestProcType_MethodFPC',
  23564. LinesToStr([ // statements
  23565. 'rtl.createClass($mod, "TObject", null, function () {',
  23566. ' this.$init = function () {',
  23567. ' };',
  23568. ' this.$final = function () {',
  23569. ' };',
  23570. ' this.DoIt = function (vA) {',
  23571. ' var Result = 0;',
  23572. ' return Result;',
  23573. ' };',
  23574. '});',
  23575. 'this.Obj = null;',
  23576. 'this.vP = null;',
  23577. 'this.b = false;'
  23578. ]),
  23579. LinesToStr([
  23580. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  23581. '$mod.vP(1);',
  23582. '$mod.vP(1);',
  23583. '$mod.vP(2);',
  23584. '$mod.b = rtl.eqCallback($mod.vP, rtl.createCallback($mod.Obj, "DoIt"));',
  23585. '$mod.b = rtl.eqCallback(rtl.createCallback($mod.Obj, "DoIt"), $mod.vP);',
  23586. '$mod.b = !rtl.eqCallback($mod.vP, rtl.createCallback($mod.Obj, "DoIt"));',
  23587. '$mod.b = !rtl.eqCallback(rtl.createCallback($mod.Obj, "DoIt"), $mod.vP);',
  23588. '']));
  23589. end;
  23590. procedure TTestModule.TestProcType_MethodDelphi;
  23591. begin
  23592. StartProgram(false);
  23593. Add('{$mode delphi}');
  23594. Add('type');
  23595. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23596. Add(' TObject = class');
  23597. Add(' function DoIt(vA: longint = 1): longint;');
  23598. Add(' end;');
  23599. Add('function TObject.DoIt(vA: longint = 1): longint;');
  23600. Add('begin');
  23601. Add('end;');
  23602. Add('var');
  23603. Add(' Obj: TObject;');
  23604. Add(' vP: tfuncint;');
  23605. Add(' b: boolean;');
  23606. Add('begin');
  23607. Add(' vp:[email protected];'); // ok in fpc and delphi
  23608. Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  23609. Add(' vp;'); // ok in fpc and delphi
  23610. Add(' vp();');
  23611. Add(' vp(2);');
  23612. //Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  23613. //Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  23614. //Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  23615. //Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  23616. ConvertProgram;
  23617. CheckSource('TestProcType_MethodDelphi',
  23618. LinesToStr([ // statements
  23619. 'rtl.createClass($mod, "TObject", null, function () {',
  23620. ' this.$init = function () {',
  23621. ' };',
  23622. ' this.$final = function () {',
  23623. ' };',
  23624. ' this.DoIt = function (vA) {',
  23625. ' var Result = 0;',
  23626. ' return Result;',
  23627. ' };',
  23628. '});',
  23629. 'this.Obj = null;',
  23630. 'this.vP = null;',
  23631. 'this.b = false;'
  23632. ]),
  23633. LinesToStr([
  23634. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  23635. '$mod.vP = rtl.createCallback($mod.Obj, "DoIt");',
  23636. '$mod.vP(1);',
  23637. '$mod.vP(1);',
  23638. '$mod.vP(2);',
  23639. '']));
  23640. end;
  23641. procedure TTestModule.TestProcType_PropertyFPC;
  23642. begin
  23643. StartProgram(false);
  23644. Add('type');
  23645. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23646. Add(' TObject = class');
  23647. Add(' FOnFoo: TFuncInt;');
  23648. Add(' function DoIt(vA: longint = 1): longint;');
  23649. Add(' function GetFoo: TFuncInt;');
  23650. Add(' procedure SetFoo(const Value: TFuncInt);');
  23651. Add(' function GetEvents(Index: longint): TFuncInt;');
  23652. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  23653. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  23654. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  23655. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  23656. Add(' end;');
  23657. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  23658. Add('function tobject.getfoo: tfuncint; begin end;');
  23659. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  23660. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  23661. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  23662. Add('var');
  23663. Add(' Obj: TObject;');
  23664. Add(' vP: tfuncint;');
  23665. Add(' b: boolean;');
  23666. Add('begin');
  23667. Add(' obj.onfoo:=nil;');
  23668. Add(' obj.onbar:=nil;');
  23669. Add(' obj.events[1]:=nil;');
  23670. Add(' obj.onfoo:=obj.onfoo;');
  23671. Add(' obj.onbar:=obj.onbar;');
  23672. Add(' obj.events[2]:=obj.events[3];');
  23673. Add(' obj.onfoo:[email protected];');
  23674. Add(' obj.onbar:[email protected];');
  23675. Add(' obj.events[4]:[email protected];');
  23676. //Add(' obj.onfoo:=obj.doit;'); // delphi
  23677. //Add(' obj.onbar:=obj.doit;'); // delphi
  23678. //Add(' obj.events[4]:=obj.doit;'); // delphi
  23679. Add(' obj.onfoo;');
  23680. Add(' obj.onbar;');
  23681. //Add(' obj.events[5];'); ToDo in pasresolver
  23682. Add(' obj.onfoo();');
  23683. Add(' obj.onbar();');
  23684. Add(' obj.events[6]();');
  23685. Add(' b:=obj.onfoo=nil;');
  23686. Add(' b:=obj.onbar=nil;');
  23687. Add(' b:=obj.events[7]=nil;');
  23688. Add(' b:=obj.onfoo<>nil;');
  23689. Add(' b:=obj.onbar<>nil;');
  23690. Add(' b:=obj.events[8]<>nil;');
  23691. Add(' b:=obj.onfoo=vp;');
  23692. Add(' b:=obj.onbar=vp;');
  23693. Add(' b:=obj.events[9]=vp;');
  23694. Add(' b:=obj.onfoo=obj.onfoo;');
  23695. Add(' b:=obj.onbar=obj.onfoo;');
  23696. Add(' b:=obj.events[10]=obj.onfoo;');
  23697. Add(' b:=obj.onfoo<>obj.onfoo;');
  23698. Add(' b:=obj.onbar<>obj.onfoo;');
  23699. Add(' b:=obj.events[11]<>obj.onfoo;');
  23700. Add(' b:[email protected];');
  23701. Add(' b:[email protected];');
  23702. Add(' b:=obj.events[12][email protected];');
  23703. Add(' b:=obj.onfoo<>@obj.doit;');
  23704. Add(' b:=obj.onbar<>@obj.doit;');
  23705. Add(' b:=obj.events[12]<>@obj.doit;');
  23706. Add(' b:=Assigned(obj.onfoo);');
  23707. Add(' b:=Assigned(obj.onbar);');
  23708. Add(' b:=Assigned(obj.events[13]);');
  23709. ConvertProgram;
  23710. CheckSource('TestProcType_PropertyFPC',
  23711. LinesToStr([ // statements
  23712. 'rtl.createClass($mod, "TObject", null, function () {',
  23713. ' this.$init = function () {',
  23714. ' this.FOnFoo = null;',
  23715. ' };',
  23716. ' this.$final = function () {',
  23717. ' this.FOnFoo = undefined;',
  23718. ' };',
  23719. ' this.DoIt = function (vA) {',
  23720. ' var Result = 0;',
  23721. ' return Result;',
  23722. ' };',
  23723. 'this.GetFoo = function () {',
  23724. ' var Result = null;',
  23725. ' return Result;',
  23726. '};',
  23727. 'this.SetFoo = function (Value) {',
  23728. '};',
  23729. 'this.GetEvents = function (Index) {',
  23730. ' var Result = null;',
  23731. ' return Result;',
  23732. '};',
  23733. 'this.SetEvents = function (Index, Value) {',
  23734. '};',
  23735. '});',
  23736. 'this.Obj = null;',
  23737. 'this.vP = null;',
  23738. 'this.b = false;'
  23739. ]),
  23740. LinesToStr([
  23741. '$mod.Obj.FOnFoo = null;',
  23742. '$mod.Obj.SetFoo(null);',
  23743. '$mod.Obj.SetEvents(1, null);',
  23744. '$mod.Obj.FOnFoo = $mod.Obj.FOnFoo;',
  23745. '$mod.Obj.SetFoo($mod.Obj.GetFoo());',
  23746. '$mod.Obj.SetEvents(2, $mod.Obj.GetEvents(3));',
  23747. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  23748. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  23749. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  23750. '$mod.Obj.FOnFoo(1);',
  23751. '$mod.Obj.GetFoo();',
  23752. '$mod.Obj.FOnFoo(1);',
  23753. '$mod.Obj.GetFoo()(1);',
  23754. '$mod.Obj.GetEvents(6)(1);',
  23755. '$mod.b = $mod.Obj.FOnFoo === null;',
  23756. '$mod.b = $mod.Obj.GetFoo() === null;',
  23757. '$mod.b = $mod.Obj.GetEvents(7) === null;',
  23758. '$mod.b = $mod.Obj.FOnFoo !== null;',
  23759. '$mod.b = $mod.Obj.GetFoo() !== null;',
  23760. '$mod.b = $mod.Obj.GetEvents(8) !== null;',
  23761. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, $mod.vP);',
  23762. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), $mod.vP);',
  23763. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(9), $mod.vP);',
  23764. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, $mod.Obj.FOnFoo);',
  23765. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), $mod.Obj.FOnFoo);',
  23766. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(10), $mod.Obj.FOnFoo);',
  23767. '$mod.b = !rtl.eqCallback($mod.Obj.FOnFoo, $mod.Obj.FOnFoo);',
  23768. '$mod.b = !rtl.eqCallback($mod.Obj.GetFoo(), $mod.Obj.FOnFoo);',
  23769. '$mod.b = !rtl.eqCallback($mod.Obj.GetEvents(11), $mod.Obj.FOnFoo);',
  23770. '$mod.b = rtl.eqCallback($mod.Obj.FOnFoo, rtl.createCallback($mod.Obj, "DoIt"));',
  23771. '$mod.b = rtl.eqCallback($mod.Obj.GetFoo(), rtl.createCallback($mod.Obj, "DoIt"));',
  23772. '$mod.b = rtl.eqCallback($mod.Obj.GetEvents(12), rtl.createCallback($mod.Obj, "DoIt"));',
  23773. '$mod.b = !rtl.eqCallback($mod.Obj.FOnFoo, rtl.createCallback($mod.Obj, "DoIt"));',
  23774. '$mod.b = !rtl.eqCallback($mod.Obj.GetFoo(), rtl.createCallback($mod.Obj, "DoIt"));',
  23775. '$mod.b = !rtl.eqCallback($mod.Obj.GetEvents(12), rtl.createCallback($mod.Obj, "DoIt"));',
  23776. '$mod.b = $mod.Obj.FOnFoo != null;',
  23777. '$mod.b = $mod.Obj.GetFoo() != null;',
  23778. '$mod.b = $mod.Obj.GetEvents(13) != null;',
  23779. '']));
  23780. end;
  23781. procedure TTestModule.TestProcType_PropertyDelphi;
  23782. begin
  23783. StartProgram(false);
  23784. Add('{$mode delphi}');
  23785. Add('type');
  23786. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23787. Add(' TObject = class');
  23788. Add(' FOnFoo: TFuncInt;');
  23789. Add(' function DoIt(vA: longint = 1): longint;');
  23790. Add(' function GetFoo: TFuncInt;');
  23791. Add(' procedure SetFoo(const Value: TFuncInt);');
  23792. Add(' function GetEvents(Index: longint): TFuncInt;');
  23793. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  23794. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  23795. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  23796. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  23797. Add(' end;');
  23798. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  23799. Add('function tobject.getfoo: tfuncint; begin end;');
  23800. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  23801. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  23802. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  23803. Add('var');
  23804. Add(' Obj: TObject;');
  23805. Add(' vP: tfuncint;');
  23806. Add(' b: boolean;');
  23807. Add('begin');
  23808. Add(' obj.onfoo:=nil;');
  23809. Add(' obj.onbar:=nil;');
  23810. Add(' obj.events[1]:=nil;');
  23811. Add(' obj.onfoo:=obj.onfoo;');
  23812. Add(' obj.onbar:=obj.onbar;');
  23813. Add(' obj.events[2]:=obj.events[3];');
  23814. Add(' obj.onfoo:[email protected];');
  23815. Add(' obj.onbar:[email protected];');
  23816. Add(' obj.events[4]:[email protected];');
  23817. Add(' obj.onfoo:=obj.doit;'); // delphi
  23818. Add(' obj.onbar:=obj.doit;'); // delphi
  23819. Add(' obj.events[4]:=obj.doit;'); // delphi
  23820. Add(' obj.onfoo;');
  23821. Add(' obj.onbar;');
  23822. //Add(' obj.events[5];'); ToDo in pasresolver
  23823. Add(' obj.onfoo();');
  23824. Add(' obj.onbar();');
  23825. Add(' obj.events[6]();');
  23826. //Add(' b:=obj.onfoo=nil;'); // fpc
  23827. //Add(' b:=obj.onbar=nil;'); // fpc
  23828. //Add(' b:=obj.events[7]=nil;'); // fpc
  23829. //Add(' b:=obj.onfoo<>nil;'); // fpc
  23830. //Add(' b:=obj.onbar<>nil;'); // fpc
  23831. //Add(' b:=obj.events[8]<>nil;'); // fpc
  23832. Add(' b:=obj.onfoo=vp;');
  23833. Add(' b:=obj.onbar=vp;');
  23834. //Add(' b:=obj.events[9]=vp;'); ToDo in pasresolver
  23835. Add(' b:=obj.onfoo=obj.onfoo;');
  23836. Add(' b:=obj.onbar=obj.onfoo;');
  23837. //Add(' b:=obj.events[10]=obj.onfoo;'); // ToDo in pasresolver
  23838. Add(' b:=obj.onfoo<>obj.onfoo;');
  23839. Add(' b:=obj.onbar<>obj.onfoo;');
  23840. //Add(' b:=obj.events[11]<>obj.onfoo;'); // ToDo in pasresolver
  23841. //Add(' b:[email protected];'); // fpc
  23842. //Add(' b:[email protected];'); // fpc
  23843. //Add(' b:=obj.events[12][email protected];'); // fpc
  23844. //Add(' b:=obj.onfoo<>@obj.doit;'); // fpc
  23845. //Add(' b:=obj.onbar<>@obj.doit;'); // fpc
  23846. //Add(' b:=obj.events[12]<>@obj.doit;'); // fpc
  23847. Add(' b:=Assigned(obj.onfoo);');
  23848. Add(' b:=Assigned(obj.onbar);');
  23849. Add(' b:=Assigned(obj.events[13]);');
  23850. ConvertProgram;
  23851. CheckSource('TestProcType_PropertyDelphi',
  23852. LinesToStr([ // statements
  23853. 'rtl.createClass($mod, "TObject", null, function () {',
  23854. ' this.$init = function () {',
  23855. ' this.FOnFoo = null;',
  23856. ' };',
  23857. ' this.$final = function () {',
  23858. ' this.FOnFoo = undefined;',
  23859. ' };',
  23860. ' this.DoIt = function (vA) {',
  23861. ' var Result = 0;',
  23862. ' return Result;',
  23863. ' };',
  23864. 'this.GetFoo = function () {',
  23865. ' var Result = null;',
  23866. ' return Result;',
  23867. '};',
  23868. 'this.SetFoo = function (Value) {',
  23869. '};',
  23870. 'this.GetEvents = function (Index) {',
  23871. ' var Result = null;',
  23872. ' return Result;',
  23873. '};',
  23874. 'this.SetEvents = function (Index, Value) {',
  23875. '};',
  23876. '});',
  23877. 'this.Obj = null;',
  23878. 'this.vP = null;',
  23879. 'this.b = false;'
  23880. ]),
  23881. LinesToStr([
  23882. '$mod.Obj.FOnFoo = null;',
  23883. '$mod.Obj.SetFoo(null);',
  23884. '$mod.Obj.SetEvents(1, null);',
  23885. '$mod.Obj.FOnFoo = $mod.Obj.FOnFoo;',
  23886. '$mod.Obj.SetFoo($mod.Obj.GetFoo());',
  23887. '$mod.Obj.SetEvents(2, $mod.Obj.GetEvents(3));',
  23888. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  23889. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  23890. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  23891. '$mod.Obj.FOnFoo = rtl.createCallback($mod.Obj, "DoIt");',
  23892. '$mod.Obj.SetFoo(rtl.createCallback($mod.Obj, "DoIt"));',
  23893. '$mod.Obj.SetEvents(4, rtl.createCallback($mod.Obj, "DoIt"));',
  23894. '$mod.Obj.FOnFoo(1);',
  23895. '$mod.Obj.GetFoo();',
  23896. '$mod.Obj.FOnFoo(1);',
  23897. '$mod.Obj.GetFoo()(1);',
  23898. '$mod.Obj.GetEvents(6)(1);',
  23899. '$mod.b = $mod.Obj.FOnFoo(1) === $mod.vP(1);',
  23900. '$mod.b = $mod.Obj.GetFoo() === $mod.vP(1);',
  23901. '$mod.b = $mod.Obj.FOnFoo(1) === $mod.Obj.FOnFoo(1);',
  23902. '$mod.b = $mod.Obj.GetFoo() === $mod.Obj.FOnFoo(1);',
  23903. '$mod.b = $mod.Obj.FOnFoo(1) !== $mod.Obj.FOnFoo(1);',
  23904. '$mod.b = $mod.Obj.GetFoo() !== $mod.Obj.FOnFoo(1);',
  23905. '$mod.b = $mod.Obj.FOnFoo != null;',
  23906. '$mod.b = $mod.Obj.GetFoo() != null;',
  23907. '$mod.b = $mod.Obj.GetEvents(13) != null;',
  23908. '']));
  23909. end;
  23910. procedure TTestModule.TestProcType_WithClassInstDoPropertyFPC;
  23911. begin
  23912. StartProgram(false);
  23913. Add('type');
  23914. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  23915. Add(' TObject = class');
  23916. Add(' FOnFoo: TFuncInt;');
  23917. Add(' function DoIt(vA: longint = 1): longint;');
  23918. Add(' function GetFoo: TFuncInt;');
  23919. Add(' procedure SetFoo(const Value: TFuncInt);');
  23920. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  23921. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  23922. Add(' end;');
  23923. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  23924. Add('function tobject.getfoo: tfuncint; begin end;');
  23925. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  23926. Add('var');
  23927. Add(' Obj: TObject;');
  23928. Add(' vP: tfuncint;');
  23929. Add(' b: boolean;');
  23930. Add('begin');
  23931. Add('with obj do begin');
  23932. Add(' fonfoo:=nil;');
  23933. Add(' onfoo:=nil;');
  23934. Add(' onbar:=nil;');
  23935. Add(' fonfoo:=fonfoo;');
  23936. Add(' onfoo:=onfoo;');
  23937. Add(' onbar:=onbar;');
  23938. Add(' fonfoo:=@doit;');
  23939. Add(' onfoo:=@doit;');
  23940. Add(' onbar:=@doit;');
  23941. //Add(' fonfoo:=doit;'); // delphi
  23942. //Add(' onfoo:=doit;'); // delphi
  23943. //Add(' onbar:=doit;'); // delphi
  23944. Add(' fonfoo;');
  23945. Add(' onfoo;');
  23946. Add(' onbar;');
  23947. Add(' fonfoo();');
  23948. Add(' onfoo();');
  23949. Add(' onbar();');
  23950. Add(' b:=fonfoo=nil;');
  23951. Add(' b:=onfoo=nil;');
  23952. Add(' b:=onbar=nil;');
  23953. Add(' b:=fonfoo<>nil;');
  23954. Add(' b:=onfoo<>nil;');
  23955. Add(' b:=onbar<>nil;');
  23956. Add(' b:=fonfoo=vp;');
  23957. Add(' b:=onfoo=vp;');
  23958. Add(' b:=onbar=vp;');
  23959. Add(' b:=fonfoo=fonfoo;');
  23960. Add(' b:=onfoo=onfoo;');
  23961. Add(' b:=onbar=onfoo;');
  23962. Add(' b:=fonfoo<>fonfoo;');
  23963. Add(' b:=onfoo<>onfoo;');
  23964. Add(' b:=onbar<>onfoo;');
  23965. Add(' b:=fonfoo=@doit;');
  23966. Add(' b:=onfoo=@doit;');
  23967. Add(' b:=onbar=@doit;');
  23968. Add(' b:=fonfoo<>@doit;');
  23969. Add(' b:=onfoo<>@doit;');
  23970. Add(' b:=onbar<>@doit;');
  23971. Add(' b:=Assigned(fonfoo);');
  23972. Add(' b:=Assigned(onfoo);');
  23973. Add(' b:=Assigned(onbar);');
  23974. Add('end;');
  23975. ConvertProgram;
  23976. CheckSource('TestProcType_WithClassInstDoPropertyFPC',
  23977. LinesToStr([ // statements
  23978. 'rtl.createClass($mod, "TObject", null, function () {',
  23979. ' this.$init = function () {',
  23980. ' this.FOnFoo = null;',
  23981. ' };',
  23982. ' this.$final = function () {',
  23983. ' this.FOnFoo = undefined;',
  23984. ' };',
  23985. ' this.DoIt = function (vA) {',
  23986. ' var Result = 0;',
  23987. ' return Result;',
  23988. ' };',
  23989. ' this.GetFoo = function () {',
  23990. ' var Result = null;',
  23991. ' return Result;',
  23992. ' };',
  23993. ' this.SetFoo = function (Value) {',
  23994. ' };',
  23995. '});',
  23996. 'this.Obj = null;',
  23997. 'this.vP = null;',
  23998. 'this.b = false;'
  23999. ]),
  24000. LinesToStr([
  24001. 'var $with1 = $mod.Obj;',
  24002. '$with1.FOnFoo = null;',
  24003. '$with1.FOnFoo = null;',
  24004. '$with1.SetFoo(null);',
  24005. '$with1.FOnFoo = $with1.FOnFoo;',
  24006. '$with1.FOnFoo = $with1.FOnFoo;',
  24007. '$with1.SetFoo($with1.GetFoo());',
  24008. '$with1.FOnFoo = rtl.createCallback($with1, "DoIt");',
  24009. '$with1.FOnFoo = rtl.createCallback($with1, "DoIt");',
  24010. '$with1.SetFoo(rtl.createCallback($with1, "DoIt"));',
  24011. '$with1.FOnFoo(1);',
  24012. '$with1.FOnFoo(1);',
  24013. '$with1.GetFoo();',
  24014. '$with1.FOnFoo(1);',
  24015. '$with1.FOnFoo(1);',
  24016. '$with1.GetFoo()(1);',
  24017. '$mod.b = $with1.FOnFoo === null;',
  24018. '$mod.b = $with1.FOnFoo === null;',
  24019. '$mod.b = $with1.GetFoo() === null;',
  24020. '$mod.b = $with1.FOnFoo !== null;',
  24021. '$mod.b = $with1.FOnFoo !== null;',
  24022. '$mod.b = $with1.GetFoo() !== null;',
  24023. '$mod.b = rtl.eqCallback($with1.FOnFoo, $mod.vP);',
  24024. '$mod.b = rtl.eqCallback($with1.FOnFoo, $mod.vP);',
  24025. '$mod.b = rtl.eqCallback($with1.GetFoo(), $mod.vP);',
  24026. '$mod.b = rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24027. '$mod.b = rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24028. '$mod.b = rtl.eqCallback($with1.GetFoo(), $with1.FOnFoo);',
  24029. '$mod.b = !rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24030. '$mod.b = !rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  24031. '$mod.b = !rtl.eqCallback($with1.GetFoo(), $with1.FOnFoo);',
  24032. '$mod.b = rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24033. '$mod.b = rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24034. '$mod.b = rtl.eqCallback($with1.GetFoo(), rtl.createCallback($with1, "DoIt"));',
  24035. '$mod.b = !rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24036. '$mod.b = !rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  24037. '$mod.b = !rtl.eqCallback($with1.GetFoo(), rtl.createCallback($with1, "DoIt"));',
  24038. '$mod.b = $with1.FOnFoo != null;',
  24039. '$mod.b = $with1.FOnFoo != null;',
  24040. '$mod.b = $with1.GetFoo() != null;',
  24041. '']));
  24042. end;
  24043. procedure TTestModule.TestProcType_Nested;
  24044. begin
  24045. StartProgram(false);
  24046. Add([
  24047. 'type',
  24048. ' TProcInt = procedure(vI: longint = 1);',
  24049. 'procedure DoIt(vJ: longint);',
  24050. 'var aProc: TProcInt;',
  24051. ' b: boolean;',
  24052. ' procedure Sub(vK: longint);',
  24053. ' var aSub: TProcInt;',
  24054. ' procedure SubSub(vK: longint);',
  24055. ' var aSubSub: TProcInt;',
  24056. ' begin;',
  24057. ' aProc:=@DoIt;',
  24058. ' aSub:=@DoIt;',
  24059. ' aSubSub:=@DoIt;',
  24060. ' aProc:=@Sub;',
  24061. ' aSub:=@Sub;',
  24062. ' aSubSub:=@Sub;',
  24063. ' aProc:=@SubSub;',
  24064. ' aSub:=@SubSub;',
  24065. ' aSubSub:=@SubSub;',
  24066. ' end;',
  24067. ' begin;',
  24068. ' end;',
  24069. 'begin;',
  24070. ' aProc:=@Sub;',
  24071. ' b:=aProc=@Sub;',
  24072. ' b:=@Sub=aProc;',
  24073. 'end;',
  24074. 'begin',
  24075. '']);
  24076. ConvertProgram;
  24077. CheckSource('TestProcType_Nested',
  24078. LinesToStr([ // statements
  24079. 'this.DoIt = function (vJ) {',
  24080. ' var aProc = null;',
  24081. ' var b = false;',
  24082. ' function Sub(vK) {',
  24083. ' var aSub = null;',
  24084. ' function SubSub(vK) {',
  24085. ' var aSubSub = null;',
  24086. ' aProc = $mod.DoIt;',
  24087. ' aSub = $mod.DoIt;',
  24088. ' aSubSub = $mod.DoIt;',
  24089. ' aProc = Sub;',
  24090. ' aSub = Sub;',
  24091. ' aSubSub = Sub;',
  24092. ' aProc = SubSub;',
  24093. ' aSub = SubSub;',
  24094. ' aSubSub = SubSub;',
  24095. ' };',
  24096. ' };',
  24097. ' aProc = Sub;',
  24098. ' b = rtl.eqCallback(aProc, Sub);',
  24099. ' b = rtl.eqCallback(Sub, aProc);',
  24100. '};',
  24101. '']),
  24102. LinesToStr([ // $mod.$main
  24103. '']));
  24104. end;
  24105. procedure TTestModule.TestProcType_NestedOfObject;
  24106. begin
  24107. StartProgram(false);
  24108. Add([
  24109. 'type',
  24110. ' TProcInt = procedure(vI: longint = 1) of object;',
  24111. ' TObject = class',
  24112. ' procedure DoIt(vJ: longint);',
  24113. ' end;',
  24114. 'procedure TObject.DoIt(vJ: longint);',
  24115. 'var aProc: TProcInt;',
  24116. ' b: boolean;',
  24117. ' procedure Sub(vK: longint);',
  24118. ' var aSub: TProcInt;',
  24119. ' procedure SubSub(vK: longint);',
  24120. ' var aSubSub: TProcInt;',
  24121. ' begin;',
  24122. ' aProc:=@DoIt;',
  24123. ' aSub:=@DoIt;',
  24124. ' aSubSub:=@DoIt;',
  24125. ' aProc:=@Sub;',
  24126. ' aSub:=@Sub;',
  24127. ' aSubSub:=@Sub;',
  24128. ' aProc:=@SubSub;',
  24129. ' aSub:=@SubSub;',
  24130. ' aSubSub:=@SubSub;',
  24131. ' end;',
  24132. ' begin;',
  24133. ' end;',
  24134. 'begin;',
  24135. ' aProc:=@Sub;',
  24136. ' b:=aProc=@Sub;',
  24137. ' b:=@Sub=aProc;',
  24138. 'end;',
  24139. 'begin',
  24140. '']);
  24141. ConvertProgram;
  24142. CheckSource('TestProcType_Nested',
  24143. LinesToStr([ // statements
  24144. 'rtl.createClass($mod, "TObject", null, function () {',
  24145. ' this.$init = function () {',
  24146. ' };',
  24147. ' this.$final = function () {',
  24148. ' };',
  24149. ' this.DoIt = function (vJ) {',
  24150. ' var $Self = this;',
  24151. ' var aProc = null;',
  24152. ' var b = false;',
  24153. ' function Sub(vK) {',
  24154. ' var aSub = null;',
  24155. ' function SubSub(vK) {',
  24156. ' var aSubSub = null;',
  24157. ' aProc = rtl.createCallback($Self, "DoIt");',
  24158. ' aSub = rtl.createCallback($Self, "DoIt");',
  24159. ' aSubSub = rtl.createCallback($Self, "DoIt");',
  24160. ' aProc = Sub;',
  24161. ' aSub = Sub;',
  24162. ' aSubSub = Sub;',
  24163. ' aProc = SubSub;',
  24164. ' aSub = SubSub;',
  24165. ' aSubSub = SubSub;',
  24166. ' };',
  24167. ' };',
  24168. ' aProc = Sub;',
  24169. ' b = rtl.eqCallback(aProc, Sub);',
  24170. ' b = rtl.eqCallback(Sub, aProc);',
  24171. ' };',
  24172. '});',
  24173. '']),
  24174. LinesToStr([ // $mod.$main
  24175. '']));
  24176. end;
  24177. procedure TTestModule.TestProcType_ReferenceToProc;
  24178. begin
  24179. StartProgram(false);
  24180. Add([
  24181. 'type',
  24182. ' TProcRef = reference to procedure(i: longint = 0);',
  24183. ' TFuncRef = reference to function(i: longint = 0): longint;',
  24184. 'var',
  24185. ' p: TProcRef;',
  24186. ' f: TFuncRef;',
  24187. 'procedure DoIt(i: longint);',
  24188. 'begin',
  24189. 'end;',
  24190. 'function GetIt(i: longint): longint;',
  24191. 'begin',
  24192. ' p:=@DoIt;',
  24193. ' f:=@GetIt;',
  24194. ' f;',
  24195. ' f();',
  24196. ' f(1);',
  24197. 'end;',
  24198. 'begin',
  24199. ' p:=@DoIt;',
  24200. ' f:=@GetIt;',
  24201. ' f;',
  24202. ' f();',
  24203. ' f(1);',
  24204. ' p:=TProcRef(f);',
  24205. '']);
  24206. ConvertProgram;
  24207. CheckSource('TestProcType_ReferenceToProc',
  24208. LinesToStr([ // statements
  24209. 'this.p = null;',
  24210. 'this.f = null;',
  24211. 'this.DoIt = function (i) {',
  24212. '};',
  24213. 'this.GetIt = function (i) {',
  24214. ' var Result = 0;',
  24215. ' $mod.p = $mod.DoIt;',
  24216. ' $mod.f = $mod.GetIt;',
  24217. ' $mod.f(0);',
  24218. ' $mod.f(0);',
  24219. ' $mod.f(1);',
  24220. ' return Result;',
  24221. '};',
  24222. '']),
  24223. LinesToStr([ // $mod.$main
  24224. '$mod.p = $mod.DoIt;',
  24225. '$mod.f = $mod.GetIt;',
  24226. '$mod.f(0);',
  24227. '$mod.f(0);',
  24228. '$mod.f(1);',
  24229. '$mod.p = $mod.f;',
  24230. '']));
  24231. end;
  24232. procedure TTestModule.TestProcType_ReferenceToMethod;
  24233. begin
  24234. StartProgram(false);
  24235. Add([
  24236. 'type',
  24237. ' TFuncRef = reference to function(i: longint = 5): longint;',
  24238. ' TObject = class',
  24239. ' function Grow(s: longint): longint;',
  24240. ' end;',
  24241. 'var',
  24242. ' f: tfuncref;',
  24243. 'function tobject.grow(s: longint): longint;',
  24244. ' function GrowSub(i: longint): longint;',
  24245. ' begin',
  24246. ' f:=@grow;',
  24247. ' f:=@growsub;',
  24248. ' end;',
  24249. 'begin',
  24250. ' f:=@grow;',
  24251. ' f:=@growsub;',
  24252. 'end;',
  24253. 'begin',
  24254. '']);
  24255. ConvertProgram;
  24256. CheckSource('TestProcType_ReferenceToMethod',
  24257. LinesToStr([ // statements
  24258. 'rtl.createClass($mod, "TObject", null, function () {',
  24259. ' this.$init = function () {',
  24260. ' };',
  24261. ' this.$final = function () {',
  24262. ' };',
  24263. ' this.Grow = function (s) {',
  24264. ' var $Self = this;',
  24265. ' var Result = 0;',
  24266. ' function GrowSub(i) {',
  24267. ' var Result = 0;',
  24268. ' $mod.f = rtl.createCallback($Self, "Grow");',
  24269. ' $mod.f = GrowSub;',
  24270. ' return Result;',
  24271. ' };',
  24272. ' $mod.f = rtl.createCallback($Self, "Grow");',
  24273. ' $mod.f = GrowSub;',
  24274. ' return Result;',
  24275. ' };',
  24276. '});',
  24277. 'this.f = null;',
  24278. '']),
  24279. LinesToStr([ // $mod.$main
  24280. '']));
  24281. end;
  24282. procedure TTestModule.TestProcType_Typecast;
  24283. begin
  24284. StartProgram(false);
  24285. Add([
  24286. 'type',
  24287. ' TNotifyEvent = procedure(Sender: Pointer) of object;',
  24288. ' TEvent = procedure of object;',
  24289. ' TGetter = function:longint of object;',
  24290. ' TProcA = procedure(i: longint);',
  24291. ' TFuncB = function(i, j: longint): longint;',
  24292. 'procedure DoIt(); varargs; begin end;',
  24293. 'var',
  24294. ' Notify: tnotifyevent;',
  24295. ' Event: tevent;',
  24296. ' Getter: tgetter;',
  24297. ' ProcA: tproca;',
  24298. ' FuncB: tfuncb;',
  24299. ' p: pointer;',
  24300. 'begin',
  24301. ' notify:=tnotifyevent(event);',
  24302. ' event:=tevent(event);',
  24303. ' event:=tevent(notify);',
  24304. ' event:=tevent(getter);',
  24305. ' event:=tevent(proca);',
  24306. ' proca:=tproca(funcb);',
  24307. ' funcb:=tfuncb(funcb);',
  24308. ' funcb:=tfuncb(proca);',
  24309. ' funcb:=tfuncb(getter);',
  24310. ' proca:=tproca(p);',
  24311. ' funcb:=tfuncb(p);',
  24312. ' getter:=tgetter(p);',
  24313. ' p:=pointer(notify);',
  24314. ' p:=notify;',
  24315. ' p:=pointer(proca);',
  24316. ' p:=proca;',
  24317. ' p:=pointer(funcb);',
  24318. ' p:=funcb;',
  24319. ' doit(Pointer(notify),pointer(event),pointer(proca));',
  24320. '']);
  24321. ConvertProgram;
  24322. CheckSource('TestProcType_Typecast',
  24323. LinesToStr([ // statements
  24324. 'this.DoIt = function () {',
  24325. '};',
  24326. 'this.Notify = null;',
  24327. 'this.Event = null;',
  24328. 'this.Getter = null;',
  24329. 'this.ProcA = null;',
  24330. 'this.FuncB = null;',
  24331. 'this.p = null;',
  24332. '']),
  24333. LinesToStr([ // $mod.$main
  24334. '$mod.Notify = $mod.Event;',
  24335. '$mod.Event = $mod.Event;',
  24336. '$mod.Event = $mod.Notify;',
  24337. '$mod.Event = $mod.Getter;',
  24338. '$mod.Event = $mod.ProcA;',
  24339. '$mod.ProcA = $mod.FuncB;',
  24340. '$mod.FuncB = $mod.FuncB;',
  24341. '$mod.FuncB = $mod.ProcA;',
  24342. '$mod.FuncB = $mod.Getter;',
  24343. '$mod.ProcA = $mod.p;',
  24344. '$mod.FuncB = $mod.p;',
  24345. '$mod.Getter = $mod.p;',
  24346. '$mod.p = $mod.Notify;',
  24347. '$mod.p = $mod.Notify;',
  24348. '$mod.p = $mod.ProcA;',
  24349. '$mod.p = $mod.ProcA;',
  24350. '$mod.p = $mod.FuncB;',
  24351. '$mod.p = $mod.FuncB;',
  24352. '$mod.DoIt($mod.Notify, $mod.Event, $mod.ProcA);',
  24353. '']));
  24354. end;
  24355. procedure TTestModule.TestProcType_PassProcToUntyped;
  24356. begin
  24357. StartProgram(false);
  24358. Add([
  24359. 'type',
  24360. ' TEvent = procedure of object;',
  24361. ' TFunc = function: longint;',
  24362. 'procedure DoIt(); varargs; begin end;',
  24363. 'procedure DoSome(const a; var b; p: pointer); begin end;',
  24364. 'var',
  24365. ' Event: tevent;',
  24366. ' Func: TFunc;',
  24367. 'begin',
  24368. ' doit(event,func);',
  24369. ' dosome(event,event,event);',
  24370. ' dosome(func,func,func);',
  24371. '']);
  24372. ConvertProgram;
  24373. CheckSource('TestProcType_PassProcToUntyped',
  24374. LinesToStr([ // statements
  24375. 'this.DoIt = function () {',
  24376. '};',
  24377. 'this.DoSome = function (a, b, p) {',
  24378. '};',
  24379. 'this.Event = null;',
  24380. 'this.Func = null;',
  24381. '']),
  24382. LinesToStr([ // $mod.$main
  24383. '$mod.DoIt($mod.Event, $mod.Func);',
  24384. '$mod.DoSome($mod.Event, {',
  24385. ' p: $mod,',
  24386. ' get: function () {',
  24387. ' return this.p.Event;',
  24388. ' },',
  24389. ' set: function (v) {',
  24390. ' this.p.Event = v;',
  24391. ' }',
  24392. '}, $mod.Event);',
  24393. '$mod.DoSome($mod.Func, {',
  24394. ' p: $mod,',
  24395. ' get: function () {',
  24396. ' return this.p.Func;',
  24397. ' },',
  24398. ' set: function (v) {',
  24399. ' this.p.Func = v;',
  24400. ' }',
  24401. '}, $mod.Func);',
  24402. '']));
  24403. end;
  24404. procedure TTestModule.TestProcType_PassProcToArray;
  24405. begin
  24406. StartProgram(false);
  24407. Add([
  24408. 'type',
  24409. ' TFunc = function: longint;',
  24410. ' TArrFunc = array of TFunc;',
  24411. 'procedure DoIt(Arr: TArrFunc); begin end;',
  24412. 'function GetIt: longint; begin end;',
  24413. 'var',
  24414. ' Func: tfunc;',
  24415. 'begin',
  24416. ' doit([]);',
  24417. ' doit([@GetIt]);',
  24418. ' doit([Func]);',
  24419. '']);
  24420. ConvertProgram;
  24421. CheckSource('TestProcType_PassProcToArray',
  24422. LinesToStr([ // statements
  24423. 'this.DoIt = function (Arr) {',
  24424. '};',
  24425. 'this.GetIt = function () {',
  24426. ' var Result = 0;',
  24427. ' return Result;',
  24428. '};',
  24429. 'this.Func = null;',
  24430. '']),
  24431. LinesToStr([ // $mod.$main
  24432. '$mod.DoIt([]);',
  24433. '$mod.DoIt([$mod.GetIt]);',
  24434. '$mod.DoIt([$mod.Func]);',
  24435. '']));
  24436. end;
  24437. procedure TTestModule.TestPointer;
  24438. begin
  24439. StartProgram(false);
  24440. Add(['type',
  24441. ' TObject = class end;',
  24442. ' TClass = class of TObject;',
  24443. ' TArrInt = array of longint;',
  24444. 'const',
  24445. ' n = nil;',
  24446. 'var',
  24447. ' v: jsvalue;',
  24448. ' Obj: tobject;',
  24449. ' C: tclass;',
  24450. ' a: tarrint;',
  24451. ' p: Pointer = nil;',
  24452. ' s: string;',
  24453. 'begin',
  24454. ' p:=p;',
  24455. ' p:=nil;',
  24456. ' if p=nil then;',
  24457. ' if nil=p then;',
  24458. ' if Assigned(p) then;',
  24459. ' p:=Pointer(v);',
  24460. ' p:=obj;',
  24461. ' p:=c;',
  24462. ' p:=a;',
  24463. ' p:=tobject;',
  24464. ' obj:=TObject(p);',
  24465. ' c:=TClass(p);',
  24466. ' a:=TArrInt(p);',
  24467. ' p:=n;',
  24468. ' p:=Pointer(a);',
  24469. ' p:=pointer(s);',
  24470. ' s:=string(p);',
  24471. '']);
  24472. ConvertProgram;
  24473. CheckSource('TestPointer',
  24474. LinesToStr([ // statements
  24475. 'rtl.createClass($mod, "TObject", null, function () {',
  24476. ' this.$init = function () {',
  24477. ' };',
  24478. ' this.$final = function () {',
  24479. ' };',
  24480. '});',
  24481. 'this.n = null;',
  24482. 'this.v = undefined;',
  24483. 'this.Obj = null;',
  24484. 'this.C = null;',
  24485. 'this.a = [];',
  24486. 'this.p = null;',
  24487. 'this.s = "";',
  24488. '']),
  24489. LinesToStr([ // $mod.$main
  24490. '$mod.p = $mod.p;',
  24491. '$mod.p = null;',
  24492. 'if ($mod.p === null) ;',
  24493. 'if (null === $mod.p) ;',
  24494. 'if ($mod.p != null) ;',
  24495. '$mod.p = $mod.v;',
  24496. '$mod.p = $mod.Obj;',
  24497. '$mod.p = $mod.C;',
  24498. '$mod.p = $mod.a;',
  24499. '$mod.p = $mod.TObject;',
  24500. '$mod.Obj = $mod.p;',
  24501. '$mod.C = $mod.p;',
  24502. '$mod.a = $mod.p;',
  24503. '$mod.p = null;',
  24504. '$mod.p = $mod.a;',
  24505. '$mod.p = $mod.s;',
  24506. '$mod.s = $mod.p;',
  24507. '']));
  24508. end;
  24509. procedure TTestModule.TestPointer_Proc;
  24510. begin
  24511. StartProgram(false);
  24512. Add('type');
  24513. Add(' TObject = class');
  24514. Add(' procedure DoIt; virtual; abstract;');
  24515. Add(' end;');
  24516. Add('procedure DoSome; begin end;');
  24517. Add('var');
  24518. Add(' o: TObject;');
  24519. Add(' p: Pointer;');
  24520. Add('begin');
  24521. Add(' p:=@DoSome;');
  24522. Add(' p:[email protected];');
  24523. ConvertProgram;
  24524. CheckSource('TestPointer_Proc',
  24525. LinesToStr([ // statements
  24526. 'rtl.createClass($mod, "TObject", null, function () {',
  24527. ' this.$init = function () {',
  24528. ' };',
  24529. ' this.$final = function () {',
  24530. ' };',
  24531. '});',
  24532. 'this.DoSome = function () {',
  24533. '};',
  24534. 'this.o = null;',
  24535. 'this.p = null;',
  24536. '']),
  24537. LinesToStr([ // $mod.$main
  24538. '$mod.p = $mod.DoSome;',
  24539. '$mod.p = rtl.createCallback($mod.o, "DoIt");',
  24540. '']));
  24541. end;
  24542. procedure TTestModule.TestPointer_AssignRecordFail;
  24543. begin
  24544. StartProgram(false);
  24545. Add('type');
  24546. Add(' TRec = record end;');
  24547. Add('var');
  24548. Add(' p: Pointer;');
  24549. Add(' r: TRec;');
  24550. Add('begin');
  24551. Add(' p:=r;');
  24552. SetExpectedPasResolverError('Incompatible types: got "TRec" expected "Pointer"',
  24553. nIncompatibleTypesGotExpected);
  24554. ConvertProgram;
  24555. end;
  24556. procedure TTestModule.TestPointer_AssignStaticArrayFail;
  24557. begin
  24558. StartProgram(false);
  24559. Add('type');
  24560. Add(' TArr = array[boolean] of longint;');
  24561. Add('var');
  24562. Add(' p: Pointer;');
  24563. Add(' a: TArr;');
  24564. Add('begin');
  24565. Add(' p:=a;');
  24566. SetExpectedPasResolverError('Incompatible types: got "TArr" expected "Pointer"',
  24567. nIncompatibleTypesGotExpected);
  24568. ConvertProgram;
  24569. end;
  24570. procedure TTestModule.TestPointer_TypeCastJSValueToPointer;
  24571. begin
  24572. StartProgram(false);
  24573. Add([
  24574. 'procedure DoIt(args: array of jsvalue); begin end;',
  24575. 'procedure DoAll; varargs; begin end;',
  24576. 'var',
  24577. ' v: jsvalue;',
  24578. 'begin',
  24579. ' DoIt([pointer(v)]);',
  24580. ' DoAll(pointer(v));',
  24581. '']);
  24582. ConvertProgram;
  24583. CheckSource('TestPointer_TypeCastJSValueToPointer',
  24584. LinesToStr([ // statements
  24585. 'this.DoIt = function (args) {',
  24586. '};',
  24587. 'this.DoAll = function () {',
  24588. '};',
  24589. 'this.v = undefined;',
  24590. '']),
  24591. LinesToStr([ // $mod.$main
  24592. '$mod.DoIt([$mod.v]);',
  24593. '$mod.DoAll($mod.v);',
  24594. '']));
  24595. end;
  24596. procedure TTestModule.TestPointer_NonRecordFail;
  24597. begin
  24598. StartProgram(false);
  24599. Add([
  24600. 'type',
  24601. ' p = ^longint;',
  24602. 'begin',
  24603. '']);
  24604. SetExpectedPasResolverError('Not supported: pointer of Longint',nNotSupportedX);
  24605. ConvertProgram;
  24606. end;
  24607. procedure TTestModule.TestPointer_AnonymousArgTypeFail;
  24608. begin
  24609. StartProgram(false);
  24610. Add([
  24611. 'procedure DoIt(p: ^longint); begin end;',
  24612. 'begin',
  24613. '']);
  24614. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  24615. ConvertProgram;
  24616. end;
  24617. procedure TTestModule.TestPointer_AnonymousVarTypeFail;
  24618. begin
  24619. StartProgram(false);
  24620. Add([
  24621. 'var p: ^longint;',
  24622. 'begin',
  24623. '']);
  24624. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  24625. ConvertProgram;
  24626. end;
  24627. procedure TTestModule.TestPointer_AnonymousResultTypeFail;
  24628. begin
  24629. StartProgram(false);
  24630. Add([
  24631. 'function DoIt: ^longint; begin end;',
  24632. 'begin',
  24633. '']);
  24634. SetExpectedPasResolverError('Not supported: pointer',nNotSupportedX);
  24635. ConvertProgram;
  24636. end;
  24637. procedure TTestModule.TestPointer_AddrOperatorFail;
  24638. begin
  24639. StartProgram(false);
  24640. Add([
  24641. 'var i: longint;',
  24642. 'begin',
  24643. ' if @i=nil then ;',
  24644. '']);
  24645. SetExpectedConverterError('illegal qualifier "@" in front of "i:Longint"',nIllegalQualifierInFrontOf);
  24646. ConvertProgram;
  24647. end;
  24648. procedure TTestModule.TestPointer_ArrayParamsFail;
  24649. begin
  24650. StartProgram(false);
  24651. Add([
  24652. 'var',
  24653. ' p: Pointer;',
  24654. 'begin',
  24655. ' p:=p[1];',
  24656. '']);
  24657. SetExpectedPasResolverError('illegal qualifier "[" after "Pointer"',nIllegalQualifierAfter);
  24658. ConvertProgram;
  24659. end;
  24660. procedure TTestModule.TestPointer_PointerAddFail;
  24661. begin
  24662. StartProgram(false);
  24663. Add([
  24664. 'var',
  24665. ' p: Pointer;',
  24666. 'begin',
  24667. ' p:=p+1;',
  24668. '']);
  24669. SetExpectedPasResolverError('Operator is not overloaded: "Pointer" + "Longint"',nOperatorIsNotOverloadedAOpB);
  24670. ConvertProgram;
  24671. end;
  24672. procedure TTestModule.TestPointer_IncPointerFail;
  24673. begin
  24674. StartProgram(false);
  24675. Add([
  24676. 'var',
  24677. ' p: Pointer;',
  24678. 'begin',
  24679. ' inc(p,1);',
  24680. '']);
  24681. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Pointer", expected "integer"',
  24682. nIncompatibleTypeArgNo);
  24683. ConvertProgram;
  24684. end;
  24685. procedure TTestModule.TestPointer_Record;
  24686. begin
  24687. StartProgram(false);
  24688. Add([
  24689. 'type',
  24690. ' TRec = record x: longint; end;',
  24691. ' PRec = ^TRec;',
  24692. 'var',
  24693. ' r: TRec;',
  24694. ' p: PRec;',
  24695. ' q: ^TRec;',
  24696. ' Ptr: pointer;',
  24697. 'begin',
  24698. ' new(p);',
  24699. ' p:=@r;',
  24700. ' r:=p^;',
  24701. ' r.x:=p^.x;',
  24702. ' p^.x:=r.x;',
  24703. ' if p^.x=3 then ;',
  24704. ' if 4=p^.x then ;',
  24705. ' dispose(p);',
  24706. ' new(q);',
  24707. ' dispose(q);',
  24708. ' Ptr:=p;',
  24709. ' p:=PRec(ptr);',
  24710. '']);
  24711. ConvertProgram;
  24712. CheckSource('TestPointer_Record',
  24713. LinesToStr([ // statements
  24714. 'rtl.recNewT($mod, "TRec", function () {',
  24715. ' this.x = 0;',
  24716. ' this.$eq = function (b) {',
  24717. ' return this.x === b.x;',
  24718. ' };',
  24719. ' this.$assign = function (s) {',
  24720. ' this.x = s.x;',
  24721. ' return this;',
  24722. ' };',
  24723. '});',
  24724. 'this.r = $mod.TRec.$new();',
  24725. 'this.p = null;',
  24726. 'this.q = null;',
  24727. 'this.Ptr = null;',
  24728. '']),
  24729. LinesToStr([ // $mod.$main
  24730. '$mod.p = $mod.TRec.$new();',
  24731. '$mod.p = $mod.r;',
  24732. '$mod.r.$assign($mod.p);',
  24733. '$mod.r.x = $mod.p.x;',
  24734. '$mod.p.x = $mod.r.x;',
  24735. 'if ($mod.p.x === 3) ;',
  24736. 'if (4 === $mod.p.x) ;',
  24737. '$mod.p = null;',
  24738. '$mod.q = $mod.TRec.$new();',
  24739. '$mod.q = null;',
  24740. '$mod.Ptr = $mod.p;',
  24741. '$mod.p = $mod.Ptr;',
  24742. '']));
  24743. end;
  24744. procedure TTestModule.TestPointer_RecordArg;
  24745. begin
  24746. StartProgram(false);
  24747. Add([
  24748. '{$modeswitch autoderef}',
  24749. 'type',
  24750. ' TRec = record x: longint; end;',
  24751. ' PRec = ^TRec;',
  24752. 'function DoIt(const a: PRec; var b: PRec; out c: PRec): TRec;',
  24753. 'begin',
  24754. ' a.x:=a.x;',
  24755. ' a^.x:=a^.x;',
  24756. ' with a^ do',
  24757. ' x:=x;',
  24758. 'end;',
  24759. 'function GetIt(p: PRec): PRec;',
  24760. 'begin',
  24761. ' p.x:=p.x;',
  24762. ' p^.x:=p^.x;',
  24763. ' with p^ do',
  24764. ' x:=x;',
  24765. 'end;',
  24766. 'var',
  24767. ' r: TRec;',
  24768. ' p: PRec;',
  24769. 'begin',
  24770. ' p:=GetIt(p);',
  24771. ' p^:=GetIt(@r)^;',
  24772. ' DoIt(p,p,p);',
  24773. ' DoIt(@r,p,p);',
  24774. '']);
  24775. ConvertProgram;
  24776. CheckSource('TestPointer_Record',
  24777. LinesToStr([ // statements
  24778. 'rtl.recNewT($mod, "TRec", function () {',
  24779. ' this.x = 0;',
  24780. ' this.$eq = function (b) {',
  24781. ' return this.x === b.x;',
  24782. ' };',
  24783. ' this.$assign = function (s) {',
  24784. ' this.x = s.x;',
  24785. ' return this;',
  24786. ' };',
  24787. '});',
  24788. 'this.DoIt = function (a, b, c) {',
  24789. ' var Result = $mod.TRec.$new();',
  24790. ' a.x = a.x;',
  24791. ' a.x = a.x;',
  24792. ' a.x = a.x;',
  24793. ' return Result;',
  24794. '};',
  24795. 'this.GetIt = function (p) {',
  24796. ' var Result = null;',
  24797. ' p.x = p.x;',
  24798. ' p.x = p.x;',
  24799. ' p.x = p.x;',
  24800. ' return Result;',
  24801. '};',
  24802. 'this.r = $mod.TRec.$new();',
  24803. 'this.p = null;',
  24804. '']),
  24805. LinesToStr([ // $mod.$main
  24806. '$mod.p = $mod.GetIt($mod.p);',
  24807. '$mod.p.$assign($mod.GetIt($mod.r));',
  24808. '$mod.DoIt($mod.p, {',
  24809. ' p: $mod,',
  24810. ' get: function () {',
  24811. ' return this.p.p;',
  24812. ' },',
  24813. ' set: function (v) {',
  24814. ' this.p.p = v;',
  24815. ' }',
  24816. '}, {',
  24817. ' p: $mod,',
  24818. ' get: function () {',
  24819. ' return this.p.p;',
  24820. ' },',
  24821. ' set: function (v) {',
  24822. ' this.p.p = v;',
  24823. ' }',
  24824. '});',
  24825. '$mod.DoIt($mod.r, {',
  24826. ' p: $mod,',
  24827. ' get: function () {',
  24828. ' return this.p.p;',
  24829. ' },',
  24830. ' set: function (v) {',
  24831. ' this.p.p = v;',
  24832. ' }',
  24833. '}, {',
  24834. ' p: $mod,',
  24835. ' get: function () {',
  24836. ' return this.p.p;',
  24837. ' },',
  24838. ' set: function (v) {',
  24839. ' this.p.p = v;',
  24840. ' }',
  24841. '});',
  24842. '']));
  24843. end;
  24844. procedure TTestModule.TestJSValue_AssignToJSValue;
  24845. begin
  24846. StartProgram(false);
  24847. Add('var');
  24848. Add(' v: jsvalue;');
  24849. Add(' i: longint;');
  24850. Add(' s: string;');
  24851. Add(' b: boolean;');
  24852. Add(' d: double;');
  24853. Add(' p: pointer;');
  24854. Add('begin');
  24855. Add(' v:=v;');
  24856. Add(' v:=1;');
  24857. Add(' v:=i;');
  24858. Add(' v:='''';');
  24859. Add(' v:=''c'';');
  24860. Add(' v:=''foo'';');
  24861. Add(' v:=s;');
  24862. Add(' v:=false;');
  24863. Add(' v:=true;');
  24864. Add(' v:=b;');
  24865. Add(' v:=0.1;');
  24866. Add(' v:=d;');
  24867. Add(' v:=nil;');
  24868. Add(' v:=p;');
  24869. ConvertProgram;
  24870. CheckSource('TestJSValue_AssignToJSValue',
  24871. LinesToStr([ // statements
  24872. 'this.v = undefined;',
  24873. 'this.i = 0;',
  24874. 'this.s = "";',
  24875. 'this.b = false;',
  24876. 'this.d = 0.0;',
  24877. 'this.p = null;',
  24878. '']),
  24879. LinesToStr([ // $mod.$main
  24880. '$mod.v = $mod.v;',
  24881. '$mod.v = 1;',
  24882. '$mod.v = $mod.i;',
  24883. '$mod.v = "";',
  24884. '$mod.v = "c";',
  24885. '$mod.v = "foo";',
  24886. '$mod.v = $mod.s;',
  24887. '$mod.v = false;',
  24888. '$mod.v = true;',
  24889. '$mod.v = $mod.b;',
  24890. '$mod.v = 0.1;',
  24891. '$mod.v = $mod.d;',
  24892. '$mod.v = null;',
  24893. '$mod.v = $mod.p;',
  24894. '']));
  24895. end;
  24896. procedure TTestModule.TestJSValue_TypeCastToBaseType;
  24897. begin
  24898. StartProgram(false);
  24899. Add('type');
  24900. Add(' integer = longint;');
  24901. Add(' TYesNo = boolean;');
  24902. Add(' TFloat = double;');
  24903. Add(' TCaption = string;');
  24904. Add(' TChar = char;');
  24905. Add('var');
  24906. Add(' v: jsvalue;');
  24907. Add(' i: integer;');
  24908. Add(' s: TCaption;');
  24909. Add(' b: TYesNo;');
  24910. Add(' d: TFloat;');
  24911. Add(' c: char;');
  24912. Add('begin');
  24913. Add(' i:=longint(v);');
  24914. Add(' i:=integer(v);');
  24915. Add(' s:=string(v);');
  24916. Add(' s:=TCaption(v);');
  24917. Add(' b:=boolean(v);');
  24918. Add(' b:=TYesNo(v);');
  24919. Add(' d:=double(v);');
  24920. Add(' d:=TFloat(v);');
  24921. Add(' c:=char(v);');
  24922. Add(' c:=TChar(v);');
  24923. ConvertProgram;
  24924. CheckSource('TestJSValue_TypeCastToBaseType',
  24925. LinesToStr([ // statements
  24926. 'this.v = undefined;',
  24927. 'this.i = 0;',
  24928. 'this.s = "";',
  24929. 'this.b = false;',
  24930. 'this.d = 0.0;',
  24931. 'this.c = "";',
  24932. '']),
  24933. LinesToStr([ // $mod.$main
  24934. '$mod.i = Math.floor($mod.v);',
  24935. '$mod.i = Math.floor($mod.v);',
  24936. '$mod.s = "" + $mod.v;',
  24937. '$mod.s = "" + $mod.v;',
  24938. '$mod.b = !($mod.v == false);',
  24939. '$mod.b = !($mod.v == false);',
  24940. '$mod.d = rtl.getNumber($mod.v);',
  24941. '$mod.d = rtl.getNumber($mod.v);',
  24942. '$mod.c = rtl.getChar($mod.v);',
  24943. '$mod.c = rtl.getChar($mod.v);',
  24944. '']));
  24945. end;
  24946. procedure TTestModule.TestJSValue_TypecastToJSValue;
  24947. begin
  24948. StartProgram(false);
  24949. Add([
  24950. 'type',
  24951. ' TArr = array of word;',
  24952. ' TRec = record end;',
  24953. ' TSet = set of boolean;',
  24954. 'procedure Fly(v: jsvalue);',
  24955. 'begin',
  24956. 'end;',
  24957. 'var',
  24958. ' a: TArr;',
  24959. ' r: TRec;',
  24960. ' s: TSet;',
  24961. 'begin',
  24962. ' Fly(jsvalue(a));',
  24963. ' Fly(jsvalue(r));',
  24964. ' Fly(jsvalue(s));',
  24965. '']);
  24966. ConvertProgram;
  24967. CheckSource('TestJSValue_TypecastToJSValue',
  24968. LinesToStr([ // statements
  24969. 'rtl.recNewT($mod, "TRec", function () {',
  24970. ' this.$eq = function (b) {',
  24971. ' return true;',
  24972. ' };',
  24973. ' this.$assign = function (s) {',
  24974. ' return this;',
  24975. ' };',
  24976. '});',
  24977. 'this.Fly = function (v) {',
  24978. '};',
  24979. 'this.a = [];',
  24980. 'this.r = $mod.TRec.$new();',
  24981. 'this.s = {};',
  24982. '']),
  24983. LinesToStr([ // $mod.$main
  24984. '$mod.Fly($mod.a);',
  24985. '$mod.Fly($mod.r);',
  24986. '$mod.Fly($mod.s);',
  24987. '']));
  24988. end;
  24989. procedure TTestModule.TestJSValue_Equal;
  24990. begin
  24991. StartProgram(false);
  24992. Add('type');
  24993. Add(' integer = longint;');
  24994. Add(' TYesNo = boolean;');
  24995. Add(' TFloat = double;');
  24996. Add(' TCaption = string;');
  24997. Add(' TChar = char;');
  24998. Add(' TMulti = JSValue;');
  24999. Add('var');
  25000. Add(' v: jsvalue;');
  25001. Add(' i: integer;');
  25002. Add(' s: TCaption;');
  25003. Add(' b: TYesNo;');
  25004. Add(' d: TFloat;');
  25005. Add(' c: char;');
  25006. Add(' m: TMulti;');
  25007. Add('begin');
  25008. Add(' b:=v=v;');
  25009. Add(' b:=v<>v;');
  25010. Add(' b:=v=1;');
  25011. Add(' b:=v<>1;');
  25012. Add(' b:=2=v;');
  25013. Add(' b:=2<>v;');
  25014. Add(' b:=v=i;');
  25015. Add(' b:=i=v;');
  25016. Add(' b:=v=nil;');
  25017. Add(' b:=nil=v;');
  25018. Add(' b:=v=false;');
  25019. Add(' b:=true=v;');
  25020. Add(' b:=v=b;');
  25021. Add(' b:=b=v;');
  25022. Add(' b:=v=s;');
  25023. Add(' b:=s=v;');
  25024. Add(' b:=v=''foo'';');
  25025. Add(' b:=''''=v;');
  25026. Add(' b:=v=d;');
  25027. Add(' b:=d=v;');
  25028. Add(' b:=v=3.4;');
  25029. Add(' b:=5.6=v;');
  25030. Add(' b:=v=c;');
  25031. Add(' b:=c=v;');
  25032. Add(' b:=m=m;');
  25033. Add(' b:=v=m;');
  25034. Add(' b:=m=v;');
  25035. ConvertProgram;
  25036. CheckSource('TestJSValue_Equal',
  25037. LinesToStr([ // statements
  25038. 'this.v = undefined;',
  25039. 'this.i = 0;',
  25040. 'this.s = "";',
  25041. 'this.b = false;',
  25042. 'this.d = 0.0;',
  25043. 'this.c = "";',
  25044. 'this.m = undefined;',
  25045. '']),
  25046. LinesToStr([ // $mod.$main
  25047. '$mod.b = $mod.v == $mod.v;',
  25048. '$mod.b = $mod.v != $mod.v;',
  25049. '$mod.b = $mod.v == 1;',
  25050. '$mod.b = $mod.v != 1;',
  25051. '$mod.b = 2 == $mod.v;',
  25052. '$mod.b = 2 != $mod.v;',
  25053. '$mod.b = $mod.v == $mod.i;',
  25054. '$mod.b = $mod.i == $mod.v;',
  25055. '$mod.b = $mod.v == null;',
  25056. '$mod.b = null == $mod.v;',
  25057. '$mod.b = $mod.v == false;',
  25058. '$mod.b = true == $mod.v;',
  25059. '$mod.b = $mod.v == $mod.b;',
  25060. '$mod.b = $mod.b == $mod.v;',
  25061. '$mod.b = $mod.v == $mod.s;',
  25062. '$mod.b = $mod.s == $mod.v;',
  25063. '$mod.b = $mod.v == "foo";',
  25064. '$mod.b = "" == $mod.v;',
  25065. '$mod.b = $mod.v == $mod.d;',
  25066. '$mod.b = $mod.d == $mod.v;',
  25067. '$mod.b = $mod.v == 3.4;',
  25068. '$mod.b = 5.6 == $mod.v;',
  25069. '$mod.b = $mod.v == $mod.c;',
  25070. '$mod.b = $mod.c == $mod.v;',
  25071. '$mod.b = $mod.m == $mod.m;',
  25072. '$mod.b = $mod.v == $mod.m;',
  25073. '$mod.b = $mod.m == $mod.v;',
  25074. '']));
  25075. end;
  25076. procedure TTestModule.TestJSValue_If;
  25077. begin
  25078. StartProgram(false);
  25079. Add([
  25080. 'var',
  25081. ' v: jsvalue;',
  25082. 'begin',
  25083. ' if v then ;',
  25084. ' while v do ;',
  25085. ' repeat until v;',
  25086. '']);
  25087. ConvertProgram;
  25088. CheckSource('TestJSValue_If',
  25089. LinesToStr([ // statements
  25090. 'this.v = undefined;',
  25091. '']),
  25092. LinesToStr([ // $mod.$main
  25093. 'if ($mod.v) ;',
  25094. 'while($mod.v){',
  25095. '};',
  25096. 'do{',
  25097. '} while(!$mod.v);',
  25098. '']));
  25099. end;
  25100. procedure TTestModule.TestJSValue_Not;
  25101. begin
  25102. StartProgram(false);
  25103. Add([
  25104. 'var',
  25105. ' v: jsvalue;',
  25106. ' b: boolean;',
  25107. 'begin',
  25108. ' b:=not v;',
  25109. ' if not v then ;',
  25110. ' while not v do ;',
  25111. ' repeat until not v;',
  25112. '']);
  25113. ConvertProgram;
  25114. CheckSource('TestJSValue_If',
  25115. LinesToStr([ // statements
  25116. 'this.v = undefined;',
  25117. 'this.b = false;',
  25118. '']),
  25119. LinesToStr([ // $mod.$main
  25120. '$mod.b=!$mod.v;',
  25121. 'if (!$mod.v) ;',
  25122. 'while(!$mod.v){',
  25123. '};',
  25124. 'do{',
  25125. '} while($mod.v);',
  25126. '']));
  25127. end;
  25128. procedure TTestModule.TestJSValue_Enum;
  25129. begin
  25130. StartProgram(false);
  25131. Add('type');
  25132. Add(' TColor = (red, blue);');
  25133. Add(' TRedBlue = TColor;');
  25134. Add('var');
  25135. Add(' v: jsvalue;');
  25136. Add(' e: TColor;');
  25137. Add('begin');
  25138. Add(' v:=e;');
  25139. Add(' v:=TColor(e);');
  25140. Add(' v:=TRedBlue(e);');
  25141. Add(' e:=TColor(v);');
  25142. Add(' e:=TRedBlue(v);');
  25143. ConvertProgram;
  25144. CheckSource('TestJSValue_Enum',
  25145. LinesToStr([ // statements
  25146. 'this.TColor = {',
  25147. ' "0": "red",',
  25148. ' red: 0,',
  25149. ' "1": "blue",',
  25150. ' blue: 1',
  25151. '};',
  25152. 'this.v = undefined;',
  25153. 'this.e = 0;',
  25154. '']),
  25155. LinesToStr([ // $mod.$main
  25156. '$mod.v = $mod.e;',
  25157. '$mod.v = $mod.e;',
  25158. '$mod.v = $mod.e;',
  25159. '$mod.e = $mod.v;',
  25160. '$mod.e = $mod.v;',
  25161. '']));
  25162. end;
  25163. procedure TTestModule.TestJSValue_ClassInstance;
  25164. begin
  25165. StartProgram(false);
  25166. Add([
  25167. 'type',
  25168. ' TObject = class',
  25169. ' end;',
  25170. ' TBirdObject = TObject;',
  25171. 'var',
  25172. ' v: jsvalue;',
  25173. ' o: TObject;',
  25174. 'begin',
  25175. ' v:=o;',
  25176. ' v:=TObject(o);',
  25177. ' v:=TBirdObject(o);',
  25178. ' o:=TObject(v);',
  25179. ' o:=TBirdObject(v);',
  25180. ' if v is TObject then ;',
  25181. '']);
  25182. ConvertProgram;
  25183. CheckSource('TestJSValue_ClassInstance',
  25184. LinesToStr([ // statements
  25185. 'rtl.createClass($mod, "TObject", null, function () {',
  25186. ' this.$init = function () {',
  25187. ' };',
  25188. ' this.$final = function () {',
  25189. ' };',
  25190. '});',
  25191. 'this.v = undefined;',
  25192. 'this.o = null;',
  25193. '']),
  25194. LinesToStr([ // $mod.$main
  25195. '$mod.v = $mod.o;',
  25196. '$mod.v = $mod.o;',
  25197. '$mod.v = $mod.o;',
  25198. '$mod.o = rtl.getObject($mod.v);',
  25199. '$mod.o = rtl.getObject($mod.v);',
  25200. 'if (rtl.isExt($mod.v, $mod.TObject, 1)) ;',
  25201. '']));
  25202. end;
  25203. procedure TTestModule.TestJSValue_ClassOf;
  25204. begin
  25205. StartProgram(false);
  25206. Add([
  25207. 'type',
  25208. ' TClass = class of TObject;',
  25209. ' TObject = class',
  25210. ' end;',
  25211. ' TBirds = class of TBird;',
  25212. ' TBird = class(TObject) end;',
  25213. 'var',
  25214. ' v: jsvalue;',
  25215. ' c: TClass;',
  25216. 'begin',
  25217. ' v:=c;',
  25218. ' v:=TObject;',
  25219. ' v:=TClass(c);',
  25220. ' v:=TBirds(c);',
  25221. ' c:=TClass(v);',
  25222. ' c:=TBirds(v);',
  25223. ' if v is TClass then ;',
  25224. '']);
  25225. ConvertProgram;
  25226. CheckSource('TestJSValue_ClassOf',
  25227. LinesToStr([ // statements
  25228. 'rtl.createClass($mod, "TObject", null, function () {',
  25229. ' this.$init = function () {',
  25230. ' };',
  25231. ' this.$final = function () {',
  25232. ' };',
  25233. '});',
  25234. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  25235. '});',
  25236. 'this.v = undefined;',
  25237. 'this.c = null;',
  25238. '']),
  25239. LinesToStr([ // $mod.$main
  25240. '$mod.v = $mod.c;',
  25241. '$mod.v = $mod.TObject;',
  25242. '$mod.v = $mod.c;',
  25243. '$mod.v = $mod.c;',
  25244. '$mod.c = rtl.getObject($mod.v);',
  25245. '$mod.c = rtl.getObject($mod.v);',
  25246. 'if (rtl.isExt($mod.v, $mod.TObject, 2)) ;',
  25247. '']));
  25248. end;
  25249. procedure TTestModule.TestJSValue_ArrayOfJSValue;
  25250. begin
  25251. StartProgram(false);
  25252. Add([
  25253. 'type',
  25254. ' integer = longint;',
  25255. ' TArray = array of JSValue;',
  25256. ' TArrgh = tarray;',
  25257. ' TArrInt = array of integer;',
  25258. 'var',
  25259. ' v: jsvalue;',
  25260. ' TheArray: tarray = (1,''2'');',
  25261. ' Arr: tarrgh;',
  25262. ' i: integer;',
  25263. ' ArrInt: tarrint;',
  25264. 'begin',
  25265. ' arr:=thearray;',
  25266. ' thearray:=arr;',
  25267. ' setlength(arr,2);',
  25268. ' setlength(thearray,3);',
  25269. ' arr[4]:=v;',
  25270. ' arr[5]:=length(thearray);',
  25271. ' arr[6]:=nil;',
  25272. ' arr[7]:=thearray[8];',
  25273. ' arr[low(arr)]:=high(thearray);',
  25274. ' arr:=arrint;',
  25275. ' arrInt:=tarrint(arr);',
  25276. ' if TheArray = nil then ;',
  25277. ' if nil = TheArray then ;',
  25278. ' if TheArray <> nil then ;',
  25279. ' if nil <> TheArray then ;',
  25280. '']);
  25281. ConvertProgram;
  25282. CheckSource('TestJSValue_ArrayOfJSValue',
  25283. LinesToStr([ // statements
  25284. 'this.v = undefined;',
  25285. 'this.TheArray = [1, "2"];',
  25286. 'this.Arr = [];',
  25287. 'this.i = 0;',
  25288. 'this.ArrInt = [];',
  25289. '']),
  25290. LinesToStr([ // $mod.$main
  25291. '$mod.Arr = $mod.TheArray;',
  25292. '$mod.TheArray = $mod.Arr;',
  25293. '$mod.Arr = rtl.arraySetLength($mod.Arr,undefined,2);',
  25294. '$mod.TheArray = rtl.arraySetLength($mod.TheArray,undefined,3);',
  25295. '$mod.Arr[4] = $mod.v;',
  25296. '$mod.Arr[5] = rtl.length($mod.TheArray);',
  25297. '$mod.Arr[6] = null;',
  25298. '$mod.Arr[7] = $mod.TheArray[8];',
  25299. '$mod.Arr[0] = rtl.length($mod.TheArray) - 1;',
  25300. '$mod.Arr = $mod.ArrInt;',
  25301. '$mod.ArrInt = $mod.Arr;',
  25302. 'if (rtl.length($mod.TheArray) === 0) ;',
  25303. 'if (rtl.length($mod.TheArray) === 0) ;',
  25304. 'if (rtl.length($mod.TheArray) > 0) ;',
  25305. 'if (rtl.length($mod.TheArray) > 0) ;',
  25306. '']));
  25307. end;
  25308. procedure TTestModule.TestJSValue_ArrayLit;
  25309. begin
  25310. StartProgram(false);
  25311. Add([
  25312. 'type',
  25313. ' TFlag = (big,small);',
  25314. ' TArray = array of JSValue;',
  25315. ' TObject = class end;',
  25316. ' TClass = class of TObject;',
  25317. 'var',
  25318. ' v: jsvalue;',
  25319. ' a: TArray;',
  25320. ' o: TObject;',
  25321. 'begin',
  25322. ' a:=[];',
  25323. ' a:=[1];',
  25324. ' a:=[1,2];',
  25325. ' a:=[big];',
  25326. ' a:=[1,big];',
  25327. ' a:=[o,nil];',
  25328. '']);
  25329. ConvertProgram;
  25330. CheckSource('TestJSValue_ArrayLit',
  25331. LinesToStr([ // statements
  25332. 'this.TFlag = {',
  25333. ' "0": "big",',
  25334. ' big: 0,',
  25335. ' "1": "small",',
  25336. ' small: 1',
  25337. '};',
  25338. 'rtl.createClass($mod, "TObject", null, function () {',
  25339. ' this.$init = function () {',
  25340. ' };',
  25341. ' this.$final = function () {',
  25342. ' };',
  25343. '});',
  25344. 'this.v = undefined;',
  25345. 'this.a = [];',
  25346. 'this.o = null;',
  25347. '']),
  25348. LinesToStr([ // $mod.$main
  25349. '$mod.a = [];',
  25350. '$mod.a = [1];',
  25351. '$mod.a = [1, 2];',
  25352. '$mod.a = [$mod.TFlag.big];',
  25353. '$mod.a = [1, $mod.TFlag.big];',
  25354. '$mod.a = [$mod.o, null];',
  25355. '']));
  25356. end;
  25357. procedure TTestModule.TestJSValue_Params;
  25358. begin
  25359. StartProgram(false);
  25360. Add('type');
  25361. Add(' integer = longint;');
  25362. Add(' TYesNo = boolean;');
  25363. Add(' TFloat = double;');
  25364. Add(' TCaption = string;');
  25365. Add(' TChar = char;');
  25366. Add('function DoIt(a: jsvalue; const b: jsvalue; var c: jsvalue; out d: jsvalue): jsvalue;');
  25367. Add('var');
  25368. Add(' l: jsvalue;');
  25369. Add('begin');
  25370. Add(' a:=a;');
  25371. Add(' l:=b;');
  25372. Add(' c:=c;');
  25373. Add(' d:=d;');
  25374. Add(' Result:=l;');
  25375. Add('end;');
  25376. Add('function DoSome(a: jsvalue; const b: jsvalue): jsvalue; begin end;');
  25377. Add('var');
  25378. Add(' v: jsvalue;');
  25379. Add(' i: integer;');
  25380. Add(' b: TYesNo;');
  25381. Add(' d: TFloat;');
  25382. Add(' s: TCaption;');
  25383. Add(' c: TChar;');
  25384. Add('begin');
  25385. Add(' v:=doit(v,v,v,v);');
  25386. Add(' i:=integer(dosome(i,i));');
  25387. Add(' b:=TYesNo(dosome(b,b));');
  25388. Add(' d:=TFloat(dosome(d,d));');
  25389. Add(' s:=TCaption(dosome(s,s));');
  25390. Add(' c:=TChar(dosome(c,c));');
  25391. ConvertProgram;
  25392. CheckSource('TestJSValue_Params',
  25393. LinesToStr([ // statements
  25394. 'this.DoIt = function (a, b, c, d) {',
  25395. ' var Result = undefined;',
  25396. ' var l = undefined;',
  25397. ' a = a;',
  25398. ' l = b;',
  25399. ' c.set(c.get());',
  25400. ' d.set(d.get());',
  25401. ' Result = l;',
  25402. ' return Result;',
  25403. '};',
  25404. 'this.DoSome = function (a, b) {',
  25405. ' var Result = undefined;',
  25406. ' return Result;',
  25407. '};',
  25408. 'this.v = undefined;',
  25409. 'this.i = 0;',
  25410. 'this.b = false;',
  25411. 'this.d = 0.0;',
  25412. 'this.s = "";',
  25413. 'this.c = "";',
  25414. '']),
  25415. LinesToStr([ // $mod.$main
  25416. '$mod.v = $mod.DoIt($mod.v, $mod.v, {',
  25417. ' p: $mod,',
  25418. ' get: function () {',
  25419. ' return this.p.v;',
  25420. ' },',
  25421. ' set: function (v) {',
  25422. ' this.p.v = v;',
  25423. ' }',
  25424. '}, {',
  25425. ' p: $mod,',
  25426. ' get: function () {',
  25427. ' return this.p.v;',
  25428. ' },',
  25429. ' set: function (v) {',
  25430. ' this.p.v = v;',
  25431. ' }',
  25432. '});',
  25433. '$mod.i = Math.floor($mod.DoSome($mod.i, $mod.i));',
  25434. '$mod.b = !($mod.DoSome($mod.b, $mod.b) == false);',
  25435. '$mod.d = rtl.getNumber($mod.DoSome($mod.d, $mod.d));',
  25436. '$mod.s = "" + $mod.DoSome($mod.s, $mod.s);',
  25437. '$mod.c = rtl.getChar($mod.DoSome($mod.c, $mod.c));',
  25438. '']));
  25439. end;
  25440. procedure TTestModule.TestJSValue_UntypedParam;
  25441. begin
  25442. StartProgram(false);
  25443. Add('function DoIt(const a; var b; out c): jsvalue;');
  25444. Add('begin');
  25445. Add(' Result:=a;');
  25446. Add(' Result:=b;');
  25447. Add(' Result:=c;');
  25448. Add(' b:=Result;');
  25449. Add(' c:=Result;');
  25450. Add('end;');
  25451. Add('var i: longint;');
  25452. Add('begin');
  25453. Add(' doit(i,i,i);');
  25454. ConvertProgram;
  25455. CheckSource('TestJSValue_UntypedParam',
  25456. LinesToStr([ // statements
  25457. 'this.DoIt = function (a, b, c) {',
  25458. ' var Result = undefined;',
  25459. ' Result = a;',
  25460. ' Result = b.get();',
  25461. ' Result = c.get();',
  25462. ' b.set(Result);',
  25463. ' c.set(Result);',
  25464. ' return Result;',
  25465. '};',
  25466. 'this.i = 0;',
  25467. '']),
  25468. LinesToStr([ // $mod.$main
  25469. '$mod.DoIt($mod.i, {',
  25470. ' p: $mod,',
  25471. ' get: function () {',
  25472. ' return this.p.i;',
  25473. ' },',
  25474. ' set: function (v) {',
  25475. ' this.p.i = v;',
  25476. ' }',
  25477. '}, {',
  25478. ' p: $mod,',
  25479. ' get: function () {',
  25480. ' return this.p.i;',
  25481. ' },',
  25482. ' set: function (v) {',
  25483. ' this.p.i = v;',
  25484. ' }',
  25485. '});',
  25486. '']));
  25487. end;
  25488. procedure TTestModule.TestJSValue_FuncResultType;
  25489. begin
  25490. StartProgram(false);
  25491. Add('type');
  25492. Add(' integer = longint;');
  25493. Add(' TJSValueArray = array of JSValue;');
  25494. Add(' TListSortCompare = function(Item1, Item2: JSValue): Integer;');
  25495. Add('procedure Sort(P: JSValue; aList: TJSValueArray; const Compare: TListSortCompare);');
  25496. Add('begin');
  25497. Add(' while Compare(P,aList[0])>0 do ;');
  25498. Add('end;');
  25499. Add('var');
  25500. Add(' Compare: TListSortCompare;');
  25501. Add(' V: JSValue;');
  25502. Add(' i: integer;');
  25503. Add('begin');
  25504. Add(' if Compare(V,V)>0 then ;');
  25505. Add(' if Compare(i,i)>1 then ;');
  25506. Add(' if Compare(nil,false)>2 then ;');
  25507. Add(' if Compare(1,true)>3 then ;');
  25508. ConvertProgram;
  25509. CheckSource('TestJSValue_UntypedParam',
  25510. LinesToStr([ // statements
  25511. 'this.Sort = function (P, aList, Compare) {',
  25512. ' while (Compare(P, aList[0]) > 0) {',
  25513. ' };',
  25514. '};',
  25515. 'this.Compare = null;',
  25516. 'this.V = undefined;',
  25517. 'this.i = 0;',
  25518. '']),
  25519. LinesToStr([ // $mod.$main
  25520. 'if ($mod.Compare($mod.V, $mod.V) > 0) ;',
  25521. 'if ($mod.Compare($mod.i, $mod.i) > 1) ;',
  25522. 'if ($mod.Compare(null, false) > 2) ;',
  25523. 'if ($mod.Compare(1, true) > 3) ;',
  25524. '']));
  25525. end;
  25526. procedure TTestModule.TestJSValue_ProcType_Assign;
  25527. begin
  25528. StartProgram(false);
  25529. Add('type');
  25530. Add(' integer = longint;');
  25531. Add(' TObject = class');
  25532. Add(' class function GetGlob: integer;');
  25533. Add(' function Getter: integer;');
  25534. Add(' end;');
  25535. Add('class function TObject.GetGlob: integer;');
  25536. Add('var v1: jsvalue;');
  25537. Add('begin');
  25538. Add(' v1:=@GetGlob;');
  25539. Add(' v1:[email protected];');
  25540. Add('end;');
  25541. Add('function TObject.Getter: integer;');
  25542. Add('var v2: jsvalue;');
  25543. Add('begin');
  25544. Add(' v2:=@Getter;');
  25545. Add(' v2:[email protected];');
  25546. Add(' v2:=@GetGlob;');
  25547. Add(' v2:[email protected];');
  25548. Add('end;');
  25549. Add('function GetIt(i: integer): integer;');
  25550. Add('var v3: jsvalue;');
  25551. Add('begin');
  25552. Add(' v3:=@GetIt;');
  25553. Add('end;');
  25554. Add('var');
  25555. Add(' V: JSValue;');
  25556. Add(' o: TObject;');
  25557. Add('begin');
  25558. Add(' v:=@GetIt;');
  25559. Add(' v:[email protected];');
  25560. Add(' v:[email protected];');
  25561. ConvertProgram;
  25562. CheckSource('TestJSValue_ProcType_Assign',
  25563. LinesToStr([ // statements
  25564. 'rtl.createClass($mod, "TObject", null, function () {',
  25565. ' this.$init = function () {',
  25566. ' };',
  25567. ' this.$final = function () {',
  25568. ' };',
  25569. ' this.GetGlob = function () {',
  25570. ' var Result = 0;',
  25571. ' var v1 = undefined;',
  25572. ' v1 = rtl.createCallback(this, "GetGlob");',
  25573. ' v1 = rtl.createCallback(this, "GetGlob");',
  25574. ' return Result;',
  25575. ' };',
  25576. ' this.Getter = function () {',
  25577. ' var Result = 0;',
  25578. ' var v2 = undefined;',
  25579. ' v2 = rtl.createCallback(this, "Getter");',
  25580. ' v2 = rtl.createCallback(this, "Getter");',
  25581. ' v2 = rtl.createCallback(this.$class, "GetGlob");',
  25582. ' v2 = rtl.createCallback(this.$class, "GetGlob");',
  25583. ' return Result;',
  25584. ' };',
  25585. '});',
  25586. 'this.GetIt = function (i) {',
  25587. ' var Result = 0;',
  25588. ' var v3 = undefined;',
  25589. ' v3 = $mod.GetIt;',
  25590. ' return Result;',
  25591. '};',
  25592. 'this.V = undefined;',
  25593. 'this.o = null;',
  25594. '']),
  25595. LinesToStr([ // $mod.$main
  25596. '$mod.V = $mod.GetIt;',
  25597. '$mod.V = rtl.createCallback($mod.o, "Getter");',
  25598. '$mod.V = rtl.createCallback($mod.o.$class, "GetGlob");',
  25599. '']));
  25600. end;
  25601. procedure TTestModule.TestJSValue_ProcType_Equal;
  25602. begin
  25603. StartProgram(false);
  25604. Add('type');
  25605. Add(' integer = longint;');
  25606. Add(' TObject = class');
  25607. Add(' class function GetGlob: integer;');
  25608. Add(' function Getter: integer;');
  25609. Add(' end;');
  25610. Add('class function TObject.GetGlob: integer;');
  25611. Add('var v1: jsvalue;');
  25612. Add('begin');
  25613. Add(' if v1=@GetGlob then;');
  25614. Add(' if [email protected] then ;');
  25615. Add('end;');
  25616. Add('function TObject.Getter: integer;');
  25617. Add('var v2: jsvalue;');
  25618. Add('begin');
  25619. Add(' if v2=@Getter then;');
  25620. Add(' if [email protected] then ;');
  25621. Add(' if v2=@GetGlob then;');
  25622. Add(' if [email protected] then;');
  25623. Add('end;');
  25624. Add('function GetIt(i: integer): integer;');
  25625. Add('var v3: jsvalue;');
  25626. Add('begin');
  25627. Add(' if v3=@GetIt then;');
  25628. Add('end;');
  25629. Add('var');
  25630. Add(' V: JSValue;');
  25631. Add(' o: TObject;');
  25632. Add('begin');
  25633. Add(' if v=@GetIt then;');
  25634. Add(' if [email protected] then;');
  25635. Add(' if [email protected] then;');
  25636. Add(' if @GetIt=v then;');
  25637. Add(' if @o.Getter=v then;');
  25638. Add(' if @o.GetGlob=v then;');
  25639. ConvertProgram;
  25640. CheckSource('TestJSValue_ProcType_Equal',
  25641. LinesToStr([ // statements
  25642. 'rtl.createClass($mod, "TObject", null, function () {',
  25643. ' this.$init = function () {',
  25644. ' };',
  25645. ' this.$final = function () {',
  25646. ' };',
  25647. ' this.GetGlob = function () {',
  25648. ' var Result = 0;',
  25649. ' var v1 = undefined;',
  25650. ' if (rtl.eqCallback(v1, rtl.createCallback(this, "GetGlob"))) ;',
  25651. ' if (rtl.eqCallback(v1, rtl.createCallback(this, "GetGlob"))) ;',
  25652. ' return Result;',
  25653. ' };',
  25654. ' this.Getter = function () {',
  25655. ' var Result = 0;',
  25656. ' var v2 = undefined;',
  25657. ' if (rtl.eqCallback(v2, rtl.createCallback(this, "Getter"))) ;',
  25658. ' if (rtl.eqCallback(v2, rtl.createCallback(this, "Getter"))) ;',
  25659. ' if (rtl.eqCallback(v2, rtl.createCallback(this.$class, "GetGlob"))) ;',
  25660. ' if (rtl.eqCallback(v2, rtl.createCallback(this.$class, "GetGlob"))) ;',
  25661. ' return Result;',
  25662. ' };',
  25663. '});',
  25664. 'this.GetIt = function (i) {',
  25665. ' var Result = 0;',
  25666. ' var v3 = undefined;',
  25667. ' if (rtl.eqCallback(v3, $mod.GetIt)) ;',
  25668. ' return Result;',
  25669. '};',
  25670. 'this.V = undefined;',
  25671. 'this.o = null;',
  25672. '']),
  25673. LinesToStr([ // $mod.$main
  25674. 'if (rtl.eqCallback($mod.V, $mod.GetIt)) ;',
  25675. 'if (rtl.eqCallback($mod.V, rtl.createCallback($mod.o, "Getter"))) ;',
  25676. 'if (rtl.eqCallback($mod.V, rtl.createCallback($mod.o.$class, "GetGlob"))) ;',
  25677. 'if (rtl.eqCallback($mod.GetIt, $mod.V)) ;',
  25678. 'if (rtl.eqCallback(rtl.createCallback($mod.o, "Getter"), $mod.V)) ;',
  25679. 'if (rtl.eqCallback(rtl.createCallback($mod.o.$class, "GetGlob"), $mod.V)) ;',
  25680. '']));
  25681. end;
  25682. procedure TTestModule.TestJSValue_ProcType_Param;
  25683. begin
  25684. StartProgram(false);
  25685. Add([
  25686. 'type',
  25687. ' variant = jsvalue;',
  25688. ' TArrVariant = array of variant;',
  25689. ' TArrVar2 = TArrVariant;',
  25690. ' TFuncInt = function: longint;',
  25691. 'function GetIt: longint;',
  25692. 'begin',
  25693. 'end;',
  25694. 'procedure DoIt(p: jsvalue; Arr: TArrVar2);',
  25695. 'var v: variant;',
  25696. 'begin',
  25697. ' v:=arr[1];',
  25698. 'end;',
  25699. 'var s: string;',
  25700. 'begin',
  25701. ' DoIt(GetIt,[]);',
  25702. ' DoIt(@GetIt,[]);',
  25703. ' DoIt(1,[s,GetIt]);',
  25704. ' DoIt(1,[s,@GetIt]);',
  25705. '']);
  25706. ConvertProgram;
  25707. CheckSource('TestJSValue_ProcType_Param',
  25708. LinesToStr([ // statements
  25709. 'this.GetIt = function () {',
  25710. ' var Result = 0;',
  25711. ' return Result;',
  25712. '};',
  25713. 'this.DoIt = function (p, Arr) {',
  25714. ' var v = undefined;',
  25715. ' v = Arr[1];',
  25716. '};',
  25717. 'this.s = "";',
  25718. '']),
  25719. LinesToStr([ // $mod.$main
  25720. '$mod.DoIt($mod.GetIt(), []);',
  25721. '$mod.DoIt($mod.GetIt, []);',
  25722. '$mod.DoIt(1, [$mod.s, $mod.GetIt()]);',
  25723. '$mod.DoIt(1, [$mod.s, $mod.GetIt]);',
  25724. '']));
  25725. end;
  25726. procedure TTestModule.TestJSValue_AssignToPointerFail;
  25727. begin
  25728. StartProgram(false);
  25729. Add([
  25730. 'var',
  25731. ' v: JSValue;',
  25732. ' p: Pointer;',
  25733. 'begin',
  25734. ' p:=v;',
  25735. '']);
  25736. SetExpectedPasResolverError('Incompatible types: got "JSValue" expected "Pointer"',
  25737. nIncompatibleTypesGotExpected);
  25738. ConvertProgram;
  25739. end;
  25740. procedure TTestModule.TestJSValue_OverloadDouble;
  25741. begin
  25742. StartProgram(false);
  25743. Add([
  25744. 'type',
  25745. ' integer = longint;',
  25746. ' tdatetime = double;',
  25747. 'procedure DoIt(d: double); begin end;',
  25748. 'procedure DoIt(v: jsvalue); begin end;',
  25749. 'var',
  25750. ' d: double;',
  25751. ' dt: tdatetime;',
  25752. ' i: integer;',
  25753. ' b: byte;',
  25754. ' shi: shortint;',
  25755. ' w: word;',
  25756. ' smi: smallint;',
  25757. ' lw: longword;',
  25758. ' li: longint;',
  25759. ' ni: nativeint;',
  25760. ' nu: nativeuint;',
  25761. 'begin',
  25762. ' DoIt(d);',
  25763. ' DoIt(dt);',
  25764. ' DoIt(i);',
  25765. ' DoIt(b);',
  25766. ' DoIt(shi);',
  25767. ' DoIt(w);',
  25768. ' DoIt(smi);',
  25769. ' DoIt(lw);',
  25770. ' DoIt(li);',
  25771. ' DoIt(ni);',
  25772. ' DoIt(nu);',
  25773. '']);
  25774. ConvertProgram;
  25775. CheckSource('TestJSValue_OverloadDouble',
  25776. LinesToStr([ // statements
  25777. 'this.DoIt = function (d) {',
  25778. '};',
  25779. 'this.DoIt$1 = function (v) {',
  25780. '};',
  25781. 'this.d = 0.0;',
  25782. 'this.dt = 0.0;',
  25783. 'this.i = 0;',
  25784. 'this.b = 0;',
  25785. 'this.shi = 0;',
  25786. 'this.w = 0;',
  25787. 'this.smi = 0;',
  25788. 'this.lw = 0;',
  25789. 'this.li = 0;',
  25790. 'this.ni = 0;',
  25791. 'this.nu = 0;',
  25792. '']),
  25793. LinesToStr([ // $mod.$main
  25794. '$mod.DoIt($mod.d);',
  25795. '$mod.DoIt($mod.dt);',
  25796. '$mod.DoIt$1($mod.i);',
  25797. '$mod.DoIt$1($mod.b);',
  25798. '$mod.DoIt$1($mod.shi);',
  25799. '$mod.DoIt$1($mod.w);',
  25800. '$mod.DoIt$1($mod.smi);',
  25801. '$mod.DoIt$1($mod.lw);',
  25802. '$mod.DoIt$1($mod.li);',
  25803. '$mod.DoIt$1($mod.ni);',
  25804. '$mod.DoIt$1($mod.nu);',
  25805. '']));
  25806. end;
  25807. procedure TTestModule.TestJSValue_OverloadNativeInt;
  25808. begin
  25809. StartProgram(false);
  25810. Add([
  25811. 'type',
  25812. ' integer = longint;',
  25813. ' int53 = nativeint;',
  25814. ' tdatetime = double;',
  25815. 'procedure DoIt(n: nativeint); begin end;',
  25816. 'procedure DoIt(v: jsvalue); begin end;',
  25817. 'var',
  25818. ' d: double;',
  25819. ' dt: tdatetime;',
  25820. ' i: integer;',
  25821. ' b: byte;',
  25822. ' shi: shortint;',
  25823. ' w: word;',
  25824. ' smi: smallint;',
  25825. ' lw: longword;',
  25826. ' li: longint;',
  25827. ' ni: nativeint;',
  25828. ' nu: nativeuint;',
  25829. 'begin',
  25830. ' DoIt(d);',
  25831. ' DoIt(dt);',
  25832. ' DoIt(i);',
  25833. ' DoIt(b);',
  25834. ' DoIt(shi);',
  25835. ' DoIt(w);',
  25836. ' DoIt(smi);',
  25837. ' DoIt(lw);',
  25838. ' DoIt(li);',
  25839. ' DoIt(ni);',
  25840. ' DoIt(nu);',
  25841. '']);
  25842. ConvertProgram;
  25843. CheckSource('TestJSValue_OverloadNativeInt',
  25844. LinesToStr([ // statements
  25845. 'this.DoIt = function (n) {',
  25846. '};',
  25847. 'this.DoIt$1 = function (v) {',
  25848. '};',
  25849. 'this.d = 0.0;',
  25850. 'this.dt = 0.0;',
  25851. 'this.i = 0;',
  25852. 'this.b = 0;',
  25853. 'this.shi = 0;',
  25854. 'this.w = 0;',
  25855. 'this.smi = 0;',
  25856. 'this.lw = 0;',
  25857. 'this.li = 0;',
  25858. 'this.ni = 0;',
  25859. 'this.nu = 0;',
  25860. '']),
  25861. LinesToStr([ // $mod.$main
  25862. '$mod.DoIt$1($mod.d);',
  25863. '$mod.DoIt$1($mod.dt);',
  25864. '$mod.DoIt($mod.i);',
  25865. '$mod.DoIt($mod.b);',
  25866. '$mod.DoIt($mod.shi);',
  25867. '$mod.DoIt($mod.w);',
  25868. '$mod.DoIt($mod.smi);',
  25869. '$mod.DoIt($mod.lw);',
  25870. '$mod.DoIt($mod.li);',
  25871. '$mod.DoIt($mod.ni);',
  25872. '$mod.DoIt($mod.nu);',
  25873. '']));
  25874. end;
  25875. procedure TTestModule.TestJSValue_OverloadWord;
  25876. begin
  25877. StartProgram(false);
  25878. Add([
  25879. 'type',
  25880. ' integer = longint;',
  25881. ' int53 = nativeint;',
  25882. ' tdatetime = double;',
  25883. 'procedure DoIt(w: word); begin end;',
  25884. 'procedure DoIt(v: jsvalue); begin end;',
  25885. 'var',
  25886. ' d: double;',
  25887. ' dt: tdatetime;',
  25888. ' i: integer;',
  25889. ' b: byte;',
  25890. ' shi: shortint;',
  25891. ' w: word;',
  25892. ' smi: smallint;',
  25893. ' lw: longword;',
  25894. ' li: longint;',
  25895. ' ni: nativeint;',
  25896. ' nu: nativeuint;',
  25897. 'begin',
  25898. ' DoIt(d);',
  25899. ' DoIt(dt);',
  25900. ' DoIt(i);',
  25901. ' DoIt(b);',
  25902. ' DoIt(shi);',
  25903. ' DoIt(w);',
  25904. ' DoIt(smi);',
  25905. ' DoIt(lw);',
  25906. ' DoIt(li);',
  25907. ' DoIt(ni);',
  25908. ' DoIt(nu);',
  25909. '']);
  25910. ConvertProgram;
  25911. CheckSource('TestJSValue_OverloadWord',
  25912. LinesToStr([ // statements
  25913. 'this.DoIt = function (w) {',
  25914. '};',
  25915. 'this.DoIt$1 = function (v) {',
  25916. '};',
  25917. 'this.d = 0.0;',
  25918. 'this.dt = 0.0;',
  25919. 'this.i = 0;',
  25920. 'this.b = 0;',
  25921. 'this.shi = 0;',
  25922. 'this.w = 0;',
  25923. 'this.smi = 0;',
  25924. 'this.lw = 0;',
  25925. 'this.li = 0;',
  25926. 'this.ni = 0;',
  25927. 'this.nu = 0;',
  25928. '']),
  25929. LinesToStr([ // $mod.$main
  25930. '$mod.DoIt$1($mod.d);',
  25931. '$mod.DoIt$1($mod.dt);',
  25932. '$mod.DoIt$1($mod.i);',
  25933. '$mod.DoIt($mod.b);',
  25934. '$mod.DoIt($mod.shi);',
  25935. '$mod.DoIt($mod.w);',
  25936. '$mod.DoIt$1($mod.smi);',
  25937. '$mod.DoIt$1($mod.lw);',
  25938. '$mod.DoIt$1($mod.li);',
  25939. '$mod.DoIt$1($mod.ni);',
  25940. '$mod.DoIt$1($mod.nu);',
  25941. '']));
  25942. end;
  25943. procedure TTestModule.TestJSValue_OverloadString;
  25944. begin
  25945. StartProgram(false);
  25946. Add([
  25947. 'type',
  25948. ' uni = string;',
  25949. ' WChar = char;',
  25950. 'procedure DoIt(s: string); begin end;',
  25951. 'procedure DoIt(v: jsvalue); begin end;',
  25952. 'var',
  25953. ' s: string;',
  25954. ' c: char;',
  25955. ' u: uni;',
  25956. 'begin',
  25957. ' DoIt(s);',
  25958. ' DoIt(c);',
  25959. ' DoIt(u);',
  25960. '']);
  25961. ConvertProgram;
  25962. CheckSource('TestJSValue_OverloadString',
  25963. LinesToStr([ // statements
  25964. 'this.DoIt = function (s) {',
  25965. '};',
  25966. 'this.DoIt$1 = function (v) {',
  25967. '};',
  25968. 'this.s = "";',
  25969. 'this.c = "";',
  25970. 'this.u = "";',
  25971. '']),
  25972. LinesToStr([ // $mod.$main
  25973. '$mod.DoIt($mod.s);',
  25974. '$mod.DoIt($mod.c);',
  25975. '$mod.DoIt($mod.u);',
  25976. '']));
  25977. end;
  25978. procedure TTestModule.TestJSValue_OverloadChar;
  25979. begin
  25980. StartProgram(false);
  25981. Add([
  25982. 'type',
  25983. ' uni = string;',
  25984. ' WChar = char;',
  25985. 'procedure DoIt(c: char); begin end;',
  25986. 'procedure DoIt(v: jsvalue); begin end;',
  25987. 'var',
  25988. ' s: string;',
  25989. ' c: char;',
  25990. ' u: uni;',
  25991. 'begin',
  25992. ' DoIt(s);',
  25993. ' DoIt(c);',
  25994. ' DoIt(u);',
  25995. '']);
  25996. ConvertProgram;
  25997. CheckSource('TestJSValue_OverloadChar',
  25998. LinesToStr([ // statements
  25999. 'this.DoIt = function (c) {',
  26000. '};',
  26001. 'this.DoIt$1 = function (v) {',
  26002. '};',
  26003. 'this.s = "";',
  26004. 'this.c = "";',
  26005. 'this.u = "";',
  26006. '']),
  26007. LinesToStr([ // $mod.$main
  26008. '$mod.DoIt$1($mod.s);',
  26009. '$mod.DoIt($mod.c);',
  26010. '$mod.DoIt$1($mod.u);',
  26011. '']));
  26012. end;
  26013. procedure TTestModule.TestJSValue_OverloadPointer;
  26014. begin
  26015. StartProgram(false);
  26016. Add([
  26017. 'type',
  26018. ' TObject = class end;',
  26019. 'procedure DoIt(p: pointer); begin end;',
  26020. 'procedure DoIt(v: jsvalue); begin end;',
  26021. 'var',
  26022. ' o: TObject;',
  26023. 'begin',
  26024. ' DoIt(o);',
  26025. '']);
  26026. ConvertProgram;
  26027. CheckSource('TestJSValue_OverloadPointer',
  26028. LinesToStr([ // statements
  26029. 'rtl.createClass($mod, "TObject", null, function () {',
  26030. ' this.$init = function () {',
  26031. ' };',
  26032. ' this.$final = function () {',
  26033. ' };',
  26034. '});',
  26035. 'this.DoIt = function (p) {',
  26036. '};',
  26037. 'this.DoIt$1 = function (v) {',
  26038. '};',
  26039. 'this.o = null;',
  26040. '']),
  26041. LinesToStr([ // $mod.$main
  26042. '$mod.DoIt($mod.o);',
  26043. '']));
  26044. end;
  26045. procedure TTestModule.TestJSValue_ForIn;
  26046. begin
  26047. StartProgram(false);
  26048. Add([
  26049. 'var',
  26050. ' v: JSValue;',
  26051. ' key: string;',
  26052. 'begin',
  26053. ' for key in v do begin',
  26054. ' if key=''abc'' then ;',
  26055. ' end;',
  26056. '']);
  26057. ConvertProgram;
  26058. CheckSource('TestJSValue_ForIn',
  26059. LinesToStr([ // statements
  26060. 'this.v = undefined;',
  26061. 'this.key = "";',
  26062. '']),
  26063. LinesToStr([ // $mod.$main
  26064. 'for ($mod.key in $mod.v) {',
  26065. ' if ($mod.key === "abc") ;',
  26066. '};',
  26067. '']));
  26068. end;
  26069. procedure TTestModule.TestRTTI_IntRange;
  26070. begin
  26071. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26072. StartProgram(false);
  26073. Add([
  26074. '{$modeswitch externalclass}',
  26075. 'type',
  26076. ' TTypeInfo = class external name ''rtl.tTypeInfo''',
  26077. ' end;',
  26078. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
  26079. ' end;',
  26080. ' TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;',
  26081. ' TColor = type TGraphicsColor;',
  26082. 'var',
  26083. ' p: TTypeInfo;',
  26084. 'begin',
  26085. ' p:=typeinfo(TGraphicsColor);',
  26086. ' p:=typeinfo(TColor);',
  26087. '']);
  26088. ConvertProgram;
  26089. CheckSource('TestRTTI_IntRange',
  26090. LinesToStr([ // statements
  26091. '$mod.$rtti.$Int("TGraphicsColor", {',
  26092. ' minvalue: -2147483648,',
  26093. ' maxvalue: 2147483647,',
  26094. ' ordtype: 4',
  26095. '});',
  26096. '$mod.$rtti.$inherited("TColor", $mod.$rtti["TGraphicsColor"], {});',
  26097. 'this.p = null;',
  26098. '']),
  26099. LinesToStr([ // $mod.$main
  26100. '$mod.p = $mod.$rtti["TGraphicsColor"];',
  26101. '$mod.p = $mod.$rtti["TColor"];',
  26102. '']));
  26103. end;
  26104. procedure TTestModule.TestRTTI_Double;
  26105. begin
  26106. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26107. StartProgram(false);
  26108. Add([
  26109. '{$modeswitch externalclass}',
  26110. 'type',
  26111. ' TTypeInfo = class external name ''rtl.tTypeInfo''',
  26112. ' end;',
  26113. ' TFloat = type double;',
  26114. 'var',
  26115. ' p: TTypeInfo;',
  26116. 'begin',
  26117. ' p:=typeinfo(double);',
  26118. ' p:=typeinfo(TFloat);',
  26119. '']);
  26120. ConvertProgram;
  26121. CheckSource('TestRTTI_Double',
  26122. LinesToStr([ // statements
  26123. '$mod.$rtti.$inherited("TFloat", rtl.double, {});',
  26124. 'this.p = null;',
  26125. '']),
  26126. LinesToStr([ // $mod.$main
  26127. '$mod.p = rtl.double;',
  26128. '$mod.p = $mod.$rtti["TFloat"];',
  26129. '']));
  26130. end;
  26131. procedure TTestModule.TestRTTI_ProcType;
  26132. begin
  26133. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26134. StartProgram(false);
  26135. Add('type');
  26136. Add(' TProcA = procedure;');
  26137. Add(' TMethodB = procedure of object;');
  26138. Add(' TProcC = procedure; varargs;');
  26139. Add(' TProcD = procedure(i: longint; const j: string; var c: char; out d: double);');
  26140. Add(' TProcE = function: nativeint;');
  26141. Add(' TProcF = function(const p: TProcA): nativeuint;');
  26142. Add('var p: pointer;');
  26143. Add('begin');
  26144. Add(' p:=typeinfo(tproca);');
  26145. ConvertProgram;
  26146. CheckSource('TestRTTI_ProcType',
  26147. LinesToStr([ // statements
  26148. '$mod.$rtti.$ProcVar("TProcA", {',
  26149. ' procsig: rtl.newTIProcSig(null)',
  26150. '});',
  26151. '$mod.$rtti.$MethodVar("TMethodB", {',
  26152. ' procsig: rtl.newTIProcSig(null),',
  26153. ' methodkind: 0',
  26154. '});',
  26155. '$mod.$rtti.$ProcVar("TProcC", {',
  26156. ' procsig: rtl.newTIProcSig(null, 2)',
  26157. '});',
  26158. '$mod.$rtti.$ProcVar("TProcD", {',
  26159. ' procsig: rtl.newTIProcSig([["i", rtl.longint], ["j", rtl.string, 2], ["c", rtl.char, 1], ["d", rtl.double, 4]])',
  26160. '});',
  26161. '$mod.$rtti.$ProcVar("TProcE", {',
  26162. ' procsig: rtl.newTIProcSig(null, rtl.nativeint)',
  26163. '});',
  26164. '$mod.$rtti.$ProcVar("TProcF", {',
  26165. ' procsig: rtl.newTIProcSig([["p", $mod.$rtti["TProcA"], 2]], rtl.nativeuint)',
  26166. '});',
  26167. 'this.p = null;',
  26168. '']),
  26169. LinesToStr([ // $mod.$main
  26170. '$mod.p = $mod.$rtti["TProcA"];',
  26171. '']));
  26172. end;
  26173. procedure TTestModule.TestRTTI_ProcType_ArgFromOtherUnit;
  26174. begin
  26175. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26176. AddModuleWithIntfImplSrc('unit2.pas',
  26177. LinesToStr([
  26178. 'type',
  26179. ' TObject = class end;'
  26180. ]),
  26181. '');
  26182. StartUnit(true);
  26183. Add('interface');
  26184. Add('uses unit2;');
  26185. Add('type');
  26186. Add(' TProcA = function(o: tobject): tobject;');
  26187. Add('implementation');
  26188. Add('type');
  26189. Add(' TProcB = function(o: tobject): tobject;');
  26190. Add('var p: Pointer;');
  26191. Add('initialization');
  26192. Add(' p:=typeinfo(tproca);');
  26193. Add(' p:=typeinfo(tprocb);');
  26194. ConvertUnit;
  26195. CheckSource('TestRTTI_ProcType_ArgFromOtherUnit',
  26196. LinesToStr([ // statements
  26197. 'var $impl = $mod.$impl;',
  26198. '$mod.$rtti.$ProcVar("TProcA", {',
  26199. ' procsig: rtl.newTIProcSig([["o", pas.unit2.$rtti["TObject"]]], pas.unit2.$rtti["TObject"])',
  26200. '});',
  26201. '']),
  26202. LinesToStr([ // this.$init
  26203. '$impl.p = $mod.$rtti["TProcA"];',
  26204. '$impl.p = $mod.$rtti["TProcB"];',
  26205. '']),
  26206. LinesToStr([ // implementation
  26207. '$mod.$rtti.$ProcVar("TProcB", {',
  26208. ' procsig: rtl.newTIProcSig([["o", pas.unit2.$rtti["TObject"]]], pas.unit2.$rtti["TObject"])',
  26209. '});',
  26210. '$impl.p = null;',
  26211. '']) );
  26212. end;
  26213. procedure TTestModule.TestRTTI_EnumAndSetType;
  26214. begin
  26215. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26216. StartProgram(false);
  26217. Add('type');
  26218. Add(' TFlag = (light,dark);');
  26219. Add(' TFlags = set of TFlag;');
  26220. Add(' TProc = function(f: TFlags): TFlag;');
  26221. Add('var p: pointer;');
  26222. Add('begin');
  26223. Add(' p:=typeinfo(tflag);');
  26224. Add(' p:=typeinfo(tflags);');
  26225. ConvertProgram;
  26226. CheckSource('TestRTTI_EnumAndType',
  26227. LinesToStr([ // statements
  26228. 'this.TFlag = {',
  26229. ' "0": "light",',
  26230. ' light: 0,',
  26231. ' "1": "dark",',
  26232. ' dark: 1',
  26233. '};',
  26234. '$mod.$rtti.$Enum("TFlag", {',
  26235. ' minvalue: 0,',
  26236. ' maxvalue: 1,',
  26237. ' ordtype: 1,',
  26238. ' enumtype: this.TFlag',
  26239. '});',
  26240. '$mod.$rtti.$Set("TFlags", {',
  26241. ' comptype: $mod.$rtti["TFlag"]',
  26242. '});',
  26243. '$mod.$rtti.$ProcVar("TProc", {',
  26244. ' procsig: rtl.newTIProcSig([["f", $mod.$rtti["TFlags"]]], $mod.$rtti["TFlag"])',
  26245. '});',
  26246. 'this.p = null;',
  26247. '']),
  26248. LinesToStr([ // $mod.$main
  26249. '$mod.p = $mod.$rtti["TFlag"];',
  26250. '$mod.p = $mod.$rtti["TFlags"];',
  26251. '']));
  26252. end;
  26253. procedure TTestModule.TestRTTI_EnumRange;
  26254. begin
  26255. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26256. StartProgram(false);
  26257. Add([
  26258. 'type',
  26259. ' TCol = (red,green,blue);',
  26260. ' TColRg = green..blue;',
  26261. ' TSetOfColRg = set of TColRg;',
  26262. 'var p: pointer;',
  26263. 'begin',
  26264. ' p:=typeinfo(tcolrg);',
  26265. ' p:=typeinfo(tsetofcolrg);',
  26266. '']);
  26267. ConvertProgram;
  26268. end;
  26269. procedure TTestModule.TestRTTI_AnonymousEnumType;
  26270. begin
  26271. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26272. StartProgram(false);
  26273. Add('type');
  26274. Add(' TFlags = set of (red, green);');
  26275. Add('var');
  26276. Add(' f: TFlags;');
  26277. Add('begin');
  26278. Add(' Include(f,red);');
  26279. ConvertProgram;
  26280. CheckSource('TestRTTI_AnonymousEnumType',
  26281. LinesToStr([ // statements
  26282. 'this.TFlags$a = {',
  26283. ' "0": "red",',
  26284. ' red: 0,',
  26285. ' "1": "green",',
  26286. ' green: 1',
  26287. '};',
  26288. '$mod.$rtti.$Enum("TFlags$a", {',
  26289. ' minvalue: 0,',
  26290. ' maxvalue: 1,',
  26291. ' ordtype: 1,',
  26292. ' enumtype: this.TFlags$a',
  26293. '});',
  26294. '$mod.$rtti.$Set("TFlags", {',
  26295. ' comptype: $mod.$rtti["TFlags$a"]',
  26296. '});',
  26297. 'this.f = {};',
  26298. '']),
  26299. LinesToStr([
  26300. '$mod.f = rtl.includeSet($mod.f, $mod.TFlags$a.red);',
  26301. '']));
  26302. end;
  26303. procedure TTestModule.TestRTTI_StaticArray;
  26304. begin
  26305. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26306. StartProgram(false);
  26307. Add('type');
  26308. Add(' TFlag = (light,dark);');
  26309. Add(' TFlagNames = array[TFlag] of string;');
  26310. Add(' TBoolNames = array[boolean] of string;');
  26311. Add(' TByteArray = array[1..32768] of byte;');
  26312. Add(' TProc = function(f: TBoolNames): TFlagNames;');
  26313. Add('var p: pointer;');
  26314. Add('begin');
  26315. Add(' p:=typeinfo(TFlagNames);');
  26316. Add(' p:=typeinfo(TBoolNames);');
  26317. ConvertProgram;
  26318. CheckSource('TestRTTI_StaticArray',
  26319. LinesToStr([ // statements
  26320. 'this.TFlag = {',
  26321. ' "0": "light",',
  26322. ' light: 0,',
  26323. ' "1": "dark",',
  26324. ' dark: 1',
  26325. '};',
  26326. '$mod.$rtti.$Enum("TFlag", {',
  26327. ' minvalue: 0,',
  26328. ' maxvalue: 1,',
  26329. ' ordtype: 1,',
  26330. ' enumtype: this.TFlag',
  26331. '});',
  26332. '$mod.$rtti.$StaticArray("TFlagNames", {',
  26333. ' dims: [2],',
  26334. ' eltype: rtl.string',
  26335. '});',
  26336. '$mod.$rtti.$StaticArray("TBoolNames", {',
  26337. ' dims: [2],',
  26338. ' eltype: rtl.string',
  26339. '});',
  26340. '$mod.$rtti.$StaticArray("TByteArray", {',
  26341. ' dims: [32768],',
  26342. ' eltype: rtl.byte',
  26343. '});',
  26344. '$mod.$rtti.$ProcVar("TProc", {',
  26345. ' procsig: rtl.newTIProcSig([["f", $mod.$rtti["TBoolNames"]]], $mod.$rtti["TFlagNames"])',
  26346. '});',
  26347. 'this.p = null;',
  26348. '']),
  26349. LinesToStr([ // $mod.$main
  26350. '$mod.p = $mod.$rtti["TFlagNames"];',
  26351. '$mod.p = $mod.$rtti["TBoolNames"];',
  26352. '']));
  26353. end;
  26354. procedure TTestModule.TestRTTI_DynArray;
  26355. begin
  26356. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26357. StartProgram(false);
  26358. Add('type');
  26359. Add(' TArrStr = array of string;');
  26360. Add(' TArr2Dim = array of tarrstr;');
  26361. Add(' TProc = function(f: TArrStr): TArr2Dim;');
  26362. Add('var p: pointer;');
  26363. Add('begin');
  26364. Add(' p:=typeinfo(tarrstr);');
  26365. Add(' p:=typeinfo(tarr2dim);');
  26366. ConvertProgram;
  26367. CheckSource('TestRTTI_DynArray',
  26368. LinesToStr([ // statements
  26369. '$mod.$rtti.$DynArray("TArrStr", {',
  26370. ' eltype: rtl.string',
  26371. '});',
  26372. '$mod.$rtti.$DynArray("TArr2Dim", {',
  26373. ' eltype: $mod.$rtti["TArrStr"]',
  26374. '});',
  26375. '$mod.$rtti.$ProcVar("TProc", {',
  26376. ' procsig: rtl.newTIProcSig([["f", $mod.$rtti["TArrStr"]]], $mod.$rtti["TArr2Dim"])',
  26377. '});',
  26378. 'this.p = null;',
  26379. '']),
  26380. LinesToStr([ // $mod.$main
  26381. '$mod.p = $mod.$rtti["TArrStr"];',
  26382. '$mod.p = $mod.$rtti["TArr2Dim"];',
  26383. '']));
  26384. end;
  26385. procedure TTestModule.TestRTTI_ArrayNestedAnonymous;
  26386. begin
  26387. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26388. StartProgram(false);
  26389. Add('type');
  26390. Add(' TArr = array of array of longint;');
  26391. Add('var a: TArr;');
  26392. Add('begin');
  26393. ConvertProgram;
  26394. CheckSource('TestRTTI_ArrayNestedAnonymous',
  26395. LinesToStr([ // statements
  26396. '$mod.$rtti.$DynArray("TArr$a", {',
  26397. ' eltype: rtl.longint',
  26398. '});',
  26399. '$mod.$rtti.$DynArray("TArr", {',
  26400. ' eltype: $mod.$rtti["TArr$a"]',
  26401. '});',
  26402. 'this.a = [];',
  26403. '']),
  26404. LinesToStr([ // $mod.$main
  26405. ]));
  26406. end;
  26407. procedure TTestModule.TestRTTI_PublishedMethodOverloadFail;
  26408. begin
  26409. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26410. StartProgram(false);
  26411. Add('type');
  26412. Add(' TObject = class');
  26413. Add(' published');
  26414. Add(' procedure Proc; virtual; abstract;');
  26415. Add(' procedure Proc(Sender: tobject); virtual; abstract;');
  26416. Add(' end;');
  26417. Add('begin');
  26418. SetExpectedPasResolverError('Duplicate identifier "Proc" at test1.pp(6,19)',
  26419. nDuplicateIdentifier);
  26420. ConvertProgram;
  26421. end;
  26422. procedure TTestModule.TestRTTI_PublishedMethodExternalFail;
  26423. begin
  26424. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26425. StartProgram(false);
  26426. Add('type');
  26427. Add(' TObject = class');
  26428. Add(' published');
  26429. Add(' procedure Proc; external name ''foo'';');
  26430. Add(' end;');
  26431. Add('begin');
  26432. SetExpectedPasResolverError(sPublishedNameMustMatchExternal,
  26433. nPublishedNameMustMatchExternal);
  26434. ConvertProgram;
  26435. end;
  26436. procedure TTestModule.TestRTTI_PublishedClassPropertyFail;
  26437. begin
  26438. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26439. StartProgram(false);
  26440. Add('type');
  26441. Add(' TObject = class');
  26442. Add(' class var FA: longint;');
  26443. Add(' published');
  26444. Add(' class property A: longint read FA;');
  26445. Add(' end;');
  26446. Add('begin');
  26447. SetExpectedPasResolverError('Invalid published property modifier "class"',
  26448. nInvalidXModifierY);
  26449. ConvertProgram;
  26450. end;
  26451. procedure TTestModule.TestRTTI_PublishedClassFieldFail;
  26452. begin
  26453. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26454. StartProgram(false);
  26455. Add('type');
  26456. Add(' TObject = class');
  26457. Add(' published');
  26458. Add(' class var FA: longint;');
  26459. Add(' end;');
  26460. Add('begin');
  26461. SetExpectedPasResolverError(sSymbolCannotBePublished,
  26462. nSymbolCannotBePublished);
  26463. ConvertProgram;
  26464. end;
  26465. procedure TTestModule.TestRTTI_PublishedFieldExternalFail;
  26466. begin
  26467. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26468. StartProgram(false);
  26469. Add('{$modeswitch externalclass}');
  26470. Add('type');
  26471. Add(' TObject = class');
  26472. Add(' published');
  26473. Add(' V: longint; external name ''foo'';');
  26474. Add(' end;');
  26475. Add('begin');
  26476. SetExpectedPasResolverError(sPublishedNameMustMatchExternal,
  26477. nPublishedNameMustMatchExternal);
  26478. ConvertProgram;
  26479. end;
  26480. procedure TTestModule.TestRTTI_Class_Field;
  26481. begin
  26482. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26483. StartProgram(false);
  26484. Add('{$modeswitch externalclass}');
  26485. Add('type');
  26486. Add(' TObject = class');
  26487. Add(' private');
  26488. Add(' FPropA: string;');
  26489. Add(' published');
  26490. Add(' VarLI: longint;');
  26491. Add(' VarC: char;');
  26492. Add(' VarS: string;');
  26493. Add(' VarD: double;');
  26494. Add(' VarB: boolean;');
  26495. Add(' VarLW: longword;');
  26496. Add(' VarSmI: smallint;');
  26497. Add(' VarW: word;');
  26498. Add(' VarShI: shortint;');
  26499. Add(' VarBy: byte;');
  26500. Add(' VarExt: longint external name ''VarExt'';');
  26501. Add(' end;');
  26502. Add('var p: pointer;');
  26503. Add(' Obj: tobject;');
  26504. Add('begin');
  26505. Add(' p:=typeinfo(tobject);');
  26506. Add(' p:=typeinfo(p);');
  26507. Add(' p:=typeinfo(obj);');
  26508. ConvertProgram;
  26509. CheckSource('TestRTTI_Class_Field',
  26510. LinesToStr([ // statements
  26511. 'rtl.createClass($mod, "TObject", null, function () {',
  26512. ' this.$init = function () {',
  26513. ' this.FPropA = "";',
  26514. ' this.VarLI = 0;',
  26515. ' this.VarC = "";',
  26516. ' this.VarS = "";',
  26517. ' this.VarD = 0.0;',
  26518. ' this.VarB = false;',
  26519. ' this.VarLW = 0;',
  26520. ' this.VarSmI = 0;',
  26521. ' this.VarW = 0;',
  26522. ' this.VarShI = 0;',
  26523. ' this.VarBy = 0;',
  26524. ' };',
  26525. ' this.$final = function () {',
  26526. ' };',
  26527. ' var $r = this.$rtti;',
  26528. ' $r.addField("VarLI", rtl.longint);',
  26529. ' $r.addField("VarC", rtl.char);',
  26530. ' $r.addField("VarS", rtl.string);',
  26531. ' $r.addField("VarD", rtl.double);',
  26532. ' $r.addField("VarB", rtl.boolean);',
  26533. ' $r.addField("VarLW", rtl.longword);',
  26534. ' $r.addField("VarSmI", rtl.smallint);',
  26535. ' $r.addField("VarW", rtl.word);',
  26536. ' $r.addField("VarShI", rtl.shortint);',
  26537. ' $r.addField("VarBy", rtl.byte);',
  26538. ' $r.addField("VarExt", rtl.longint);',
  26539. '});',
  26540. 'this.p = null;',
  26541. 'this.Obj = null;',
  26542. '']),
  26543. LinesToStr([ // $mod.$main
  26544. '$mod.p = $mod.$rtti["TObject"];',
  26545. '$mod.p = rtl.pointer;',
  26546. '$mod.p = $mod.Obj.$rtti;',
  26547. '']));
  26548. end;
  26549. procedure TTestModule.TestRTTI_Class_Method;
  26550. begin
  26551. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26552. StartProgram(false);
  26553. Add('type');
  26554. Add(' TObject = class');
  26555. Add(' private');
  26556. Add(' procedure Internal; external name ''$intern'';');
  26557. Add(' published');
  26558. Add(' procedure Click; virtual; abstract;');
  26559. Add(' procedure Notify(Sender: TObject); virtual; abstract;');
  26560. Add(' function GetNotify: boolean; external name ''GetNotify'';');
  26561. Add(' procedure Println(a,b: longint); varargs; virtual; abstract;');
  26562. Add(' end;');
  26563. Add('begin');
  26564. ConvertProgram;
  26565. CheckSource('TestRTTI_Class_Method',
  26566. LinesToStr([ // statements
  26567. 'rtl.createClass($mod, "TObject", null, function () {',
  26568. ' this.$init = function () {',
  26569. ' };',
  26570. ' this.$final = function () {',
  26571. ' };',
  26572. ' var $r = this.$rtti;',
  26573. ' $r.addMethod("Click", 0, null);',
  26574. ' $r.addMethod("Notify", 0, [["Sender", $r]]);',
  26575. ' $r.addMethod("GetNotify", 1, null, rtl.boolean,{flags: 4});',
  26576. ' $r.addMethod("Println", 0, [["a", rtl.longint], ["b", rtl.longint]], null, {',
  26577. ' flags: 2',
  26578. ' });',
  26579. '});',
  26580. '']),
  26581. LinesToStr([ // $mod.$main
  26582. '']));
  26583. end;
  26584. procedure TTestModule.TestRTTI_Class_MethodArgFlags;
  26585. begin
  26586. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26587. StartProgram(false);
  26588. Add('type');
  26589. Add(' TObject = class');
  26590. Add(' published');
  26591. Add(' procedure OpenArray(const Args: array of string); virtual; abstract;');
  26592. Add(' procedure ByRef(var Value: longint; out Item: longint); virtual; abstract;');
  26593. Add(' procedure Untyped(var Value; out Item); virtual; abstract;');
  26594. Add(' end;');
  26595. Add('begin');
  26596. ConvertProgram;
  26597. CheckSource('TestRTTI_Class_MethodOpenArray',
  26598. LinesToStr([ // statements
  26599. 'rtl.createClass($mod, "TObject", null, function () {',
  26600. ' this.$init = function () {',
  26601. ' };',
  26602. ' this.$final = function () {',
  26603. ' };',
  26604. ' var $r = this.$rtti;',
  26605. '$r.addMethod("OpenArray", 0, [["Args", rtl.string, 10]]);',
  26606. '$r.addMethod("ByRef", 0, [["Value", rtl.longint, 1], ["Item", rtl.longint, 4]]);',
  26607. '$r.addMethod("Untyped", 0, [["Value", null, 1], ["Item", null, 4]]);',
  26608. '});',
  26609. '']),
  26610. LinesToStr([ // $mod.$main
  26611. '']));
  26612. end;
  26613. procedure TTestModule.TestRTTI_Class_Property;
  26614. begin
  26615. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26616. StartProgram(false);
  26617. Add('{$modeswitch externalclass}');
  26618. Add('type');
  26619. Add(' TObject = class');
  26620. Add(' private');
  26621. Add(' FColor: longint;');
  26622. Add(' FColorStored: boolean;');
  26623. Add(' procedure SetColor(Value: longint); virtual; abstract;');
  26624. Add(' function GetColor: longint; virtual; abstract;');
  26625. Add(' function GetColorStored: boolean; virtual; abstract;');
  26626. Add(' FExtSize: longint external name ''$extSize'';');
  26627. Add(' FExtSizeStored: boolean external name ''$extSizeStored'';');
  26628. Add(' procedure SetExtSize(Value: longint); external name ''$setSize'';');
  26629. Add(' function GetExtSize: longint; external name ''$getSize'';');
  26630. Add(' function GetExtSizeStored: boolean; external name ''$getExtSizeStored'';');
  26631. Add(' published');
  26632. Add(' property ColorA: longint read FColor;');
  26633. Add(' property ColorB: longint write FColor;');
  26634. Add(' property ColorC: longint read GetColor write SetColor;');
  26635. Add(' property ColorD: longint read FColor write FColor stored FColorStored;');
  26636. Add(' property ExtSizeA: longint read FExtSize write FExtSize;');
  26637. Add(' property ExtSizeB: longint read GetExtSize write SetExtSize stored FExtSizeStored;');
  26638. Add(' property ExtSizeC: longint read FExtSize write FExtSize stored GetExtSizeStored;');
  26639. Add(' end;');
  26640. Add('begin');
  26641. ConvertProgram;
  26642. CheckSource('TestRTTI_Class_Property',
  26643. LinesToStr([ // statements
  26644. 'rtl.createClass($mod, "TObject", null, function () {',
  26645. ' this.$init = function () {',
  26646. ' this.FColor = 0;',
  26647. ' this.FColorStored = false;',
  26648. ' };',
  26649. ' this.$final = function () {',
  26650. ' };',
  26651. ' var $r = this.$rtti;',
  26652. ' $r.addProperty("ColorA", 0, rtl.longint, "FColor", "");',
  26653. ' $r.addProperty("ColorB", 0, rtl.longint, "", "FColor");',
  26654. ' $r.addProperty("ColorC", 3, rtl.longint, "GetColor", "SetColor");',
  26655. ' $r.addProperty(',
  26656. ' "ColorD",',
  26657. ' 8,',
  26658. ' rtl.longint,',
  26659. ' "FColor",',
  26660. ' "FColor",',
  26661. ' {',
  26662. ' stored: "FColorStored"',
  26663. ' }',
  26664. ' );',
  26665. ' $r.addProperty("ExtSizeA", 0, rtl.longint, "$extSize", "$extSize");',
  26666. ' $r.addProperty(',
  26667. ' "ExtSizeB",',
  26668. ' 11,',
  26669. ' rtl.longint,',
  26670. ' "$getSize",',
  26671. ' "$setSize",',
  26672. ' {',
  26673. ' stored: "$extSizeStored"',
  26674. ' }',
  26675. ' );',
  26676. ' $r.addProperty(',
  26677. ' "ExtSizeC",',
  26678. ' 12,',
  26679. ' rtl.longint,',
  26680. ' "$extSize",',
  26681. ' "$extSize",',
  26682. ' {',
  26683. ' stored: "$getExtSizeStored"',
  26684. ' }',
  26685. ' );',
  26686. '});',
  26687. '']),
  26688. LinesToStr([ // $mod.$main
  26689. '']));
  26690. end;
  26691. procedure TTestModule.TestRTTI_Class_PropertyParams;
  26692. begin
  26693. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26694. StartProgram(false);
  26695. Add('{$modeswitch externalclass}');
  26696. Add('type');
  26697. Add(' integer = longint;');
  26698. Add(' TObject = class');
  26699. Add(' private');
  26700. Add(' function GetItems(i: integer): tobject; virtual; abstract;');
  26701. Add(' procedure SetItems(i: integer; value: tobject); virtual; abstract;');
  26702. Add(' function GetValues(const i: integer; var b: boolean): char; virtual; abstract;');
  26703. Add(' procedure SetValues(const i: integer; var b: boolean; value: char); virtual; abstract;');
  26704. Add(' published');
  26705. Add(' property Items[Index: integer]: tobject read getitems write setitems;');
  26706. Add(' property Values[const keya: integer; var keyb: boolean]: char read getvalues write setvalues;');
  26707. Add(' end;');
  26708. Add('begin');
  26709. ConvertProgram;
  26710. CheckSource('TestRTTI_Class_PropertyParams',
  26711. LinesToStr([ // statements
  26712. 'rtl.createClass($mod, "TObject", null, function () {',
  26713. ' this.$init = function () {',
  26714. ' };',
  26715. ' this.$final = function () {',
  26716. ' };',
  26717. ' var $r = this.$rtti;',
  26718. ' $r.addProperty("Items", 3, $r, "GetItems", "SetItems");',
  26719. ' $r.addProperty("Values", 3, rtl.char, "GetValues", "SetValues");',
  26720. '});',
  26721. '']),
  26722. LinesToStr([ // $mod.$main
  26723. '']));
  26724. end;
  26725. procedure TTestModule.TestRTTI_Class_OtherUnit_TypeAlias;
  26726. begin
  26727. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26728. AddModuleWithIntfImplSrc('unit1.pas',
  26729. 'type TColor = -5..5;',
  26730. '');
  26731. StartProgram(true);
  26732. Add([
  26733. 'uses unit1;',
  26734. 'type',
  26735. ' TColorAlias = TColor;',
  26736. ' TColorTypeAlias = type TColor;',
  26737. ' TObject = class',
  26738. ' private',
  26739. ' fColor: TColor;',
  26740. ' fAlias: TColorAlias;',
  26741. ' fTypeAlias: TColorTypeAlias;',
  26742. ' published',
  26743. ' property Color: TColor read fcolor;',
  26744. ' property Alias: TColorAlias read falias;',
  26745. ' property TypeAlias: TColorTypeAlias read ftypealias;',
  26746. ' end;',
  26747. 'begin',
  26748. '']);
  26749. ConvertProgram;
  26750. CheckSource('TestRTTI_Class_OtherUnit_TypeAlias',
  26751. LinesToStr([ // statements
  26752. '$mod.$rtti.$inherited("TColorTypeAlias", pas.unit1.$rtti["TColor"], {});',
  26753. 'rtl.createClass($mod, "TObject", null, function () {',
  26754. ' this.$init = function () {',
  26755. ' this.fColor = 0;',
  26756. ' this.fAlias = 0;',
  26757. ' this.fTypeAlias = 0;',
  26758. ' };',
  26759. ' this.$final = function () {',
  26760. ' };',
  26761. ' var $r = this.$rtti;',
  26762. ' $r.addProperty("Color", 0, pas.unit1.$rtti["TColor"], "fColor", "");',
  26763. ' $r.addProperty("Alias", 0, pas.unit1.$rtti["TColor"], "fAlias", "");',
  26764. ' $r.addProperty("TypeAlias", 0, $mod.$rtti["TColorTypeAlias"], "fTypeAlias", "");',
  26765. '});',
  26766. '']),
  26767. LinesToStr([ // $mod.$main
  26768. '']));
  26769. end;
  26770. procedure TTestModule.TestRTTI_Class_OmitRTTI;
  26771. begin
  26772. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26773. StartProgram(false);
  26774. Add([
  26775. '{$modeswitch omitrtti}',
  26776. 'type',
  26777. ' TObject = class',
  26778. ' private',
  26779. ' FA: byte;',
  26780. ' published',
  26781. ' property A: byte read FA write FA;',
  26782. ' end;',
  26783. 'begin']);
  26784. ConvertProgram;
  26785. CheckSource('TestRTTI_Class_OmitRTTI',
  26786. LinesToStr([ // statements
  26787. 'rtl.createClass($mod, "TObject", null, function () {',
  26788. ' this.$init = function () {',
  26789. ' this.FA = 0;',
  26790. ' };',
  26791. ' this.$final = function () {',
  26792. ' };',
  26793. '});',
  26794. '']),
  26795. LinesToStr([ // $mod.$main
  26796. '']));
  26797. end;
  26798. procedure TTestModule.TestRTTI_IndexModifier;
  26799. begin
  26800. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26801. StartProgram(false);
  26802. Add([
  26803. 'type',
  26804. ' TEnum = (red, blue);',
  26805. ' TObject = class',
  26806. ' FB: boolean;',
  26807. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  26808. ' function GetBoolBool(Index: boolean): boolean; virtual; abstract;',
  26809. ' procedure SetBoolBool(Index: boolean; b: boolean); virtual; abstract;',
  26810. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  26811. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  26812. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  26813. ' published',
  26814. ' property B1: boolean index 1 read FB write SetIntBool;',
  26815. ' property B2: boolean index TEnum.blue read GetEnumBool write FB;',
  26816. ' property I1[A: String]: boolean index 2 read GetStrIntBool write SetStrIntBool;',
  26817. ' end;',
  26818. 'begin']);
  26819. ConvertProgram;
  26820. CheckSource('TestRTTI_IndexModifier',
  26821. LinesToStr([ // statements
  26822. 'this.TEnum = {',
  26823. ' "0": "red",',
  26824. ' red: 0,',
  26825. ' "1": "blue",',
  26826. ' blue: 1',
  26827. '};',
  26828. '$mod.$rtti.$Enum("TEnum", {',
  26829. ' minvalue: 0,',
  26830. ' maxvalue: 1,',
  26831. ' ordtype: 1,',
  26832. ' enumtype: this.TEnum',
  26833. '});',
  26834. 'rtl.createClass($mod, "TObject", null, function () {',
  26835. ' this.$init = function () {',
  26836. ' this.FB = false;',
  26837. ' };',
  26838. ' this.$final = function () {',
  26839. ' };',
  26840. ' var $r = this.$rtti;',
  26841. ' $r.addProperty(',
  26842. ' "B1",',
  26843. ' 18,',
  26844. ' rtl.boolean,',
  26845. ' "FB",',
  26846. ' "SetIntBool",',
  26847. ' {',
  26848. ' index: 1',
  26849. ' }',
  26850. ' );',
  26851. ' $r.addProperty(',
  26852. ' "B2",',
  26853. ' 17,',
  26854. ' rtl.boolean,',
  26855. ' "GetEnumBool",',
  26856. ' "FB",',
  26857. ' {',
  26858. ' index: $mod.TEnum.blue',
  26859. ' }',
  26860. ' );',
  26861. ' $r.addProperty(',
  26862. ' "I1",',
  26863. ' 19,',
  26864. ' rtl.boolean,',
  26865. ' "GetStrIntBool",',
  26866. ' "SetStrIntBool",',
  26867. ' {',
  26868. ' index: 2',
  26869. ' }',
  26870. ' );',
  26871. '});',
  26872. '']),
  26873. LinesToStr([ // $mod.$main
  26874. '']));
  26875. end;
  26876. procedure TTestModule.TestRTTI_StoredModifier;
  26877. begin
  26878. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26879. StartProgram(false);
  26880. Add([
  26881. 'const',
  26882. ' ConstB = true;',
  26883. 'type',
  26884. ' TObject = class',
  26885. ' private',
  26886. ' FB: boolean;',
  26887. ' function IsBStored: boolean; virtual; abstract;',
  26888. ' published',
  26889. ' property BoolA: boolean read FB stored true;',
  26890. ' property BoolB: boolean read FB stored false;',
  26891. ' property BoolC: boolean read FB stored FB;',
  26892. ' property BoolD: boolean read FB stored ConstB;',
  26893. ' property BoolE: boolean read FB stored IsBStored;',
  26894. ' end;',
  26895. 'begin']);
  26896. ConvertProgram;
  26897. CheckSource('TestRTTI_StoredModifier',
  26898. LinesToStr([ // statements
  26899. 'this.ConstB = true;',
  26900. 'rtl.createClass($mod, "TObject", null, function () {',
  26901. ' this.$init = function () {',
  26902. ' this.FB = false;',
  26903. ' };',
  26904. ' this.$final = function () {',
  26905. ' };',
  26906. ' var $r = this.$rtti;',
  26907. ' $r.addProperty("BoolA", 0, rtl.boolean, "FB", "");',
  26908. ' $r.addProperty("BoolB", 4, rtl.boolean, "FB", "");',
  26909. ' $r.addProperty(',
  26910. ' "BoolC",',
  26911. ' 8,',
  26912. ' rtl.boolean,',
  26913. ' "FB",',
  26914. ' "",',
  26915. ' {',
  26916. ' stored: "FB"',
  26917. ' }',
  26918. ' );',
  26919. ' $r.addProperty("BoolD", 0, rtl.boolean, "FB", "");',
  26920. ' $r.addProperty(',
  26921. ' "BoolE",',
  26922. ' 12,',
  26923. ' rtl.boolean,',
  26924. ' "FB",',
  26925. ' "",',
  26926. ' {',
  26927. ' stored: "IsBStored"',
  26928. ' }',
  26929. ' );',
  26930. '});',
  26931. '']),
  26932. LinesToStr([ // $mod.$main
  26933. '']));
  26934. end;
  26935. procedure TTestModule.TestRTTI_DefaultValue;
  26936. begin
  26937. Converter.Options:=Converter.Options-[coNoTypeInfo];
  26938. StartProgram(false);
  26939. Add([
  26940. 'type',
  26941. ' TEnum = (red, blue);',
  26942. 'const',
  26943. ' CB = true or false;',
  26944. ' CI = 1+2;',
  26945. 'type',
  26946. ' TObject = class',
  26947. ' FB: boolean;',
  26948. ' FI: longint;',
  26949. ' FE: TEnum;',
  26950. ' published',
  26951. ' property B1: boolean read FB default true;',
  26952. ' property B2: boolean read FB default CB;',
  26953. ' property B3: boolean read FB default test1.cb;',
  26954. ' property I1: longint read FI default 2;',
  26955. ' property I2: longint read FI default CI;',
  26956. ' property E1: TEnum read FE default red;',
  26957. ' property E2: TEnum read FE default TEnum.blue;',
  26958. ' end;',
  26959. 'begin']);
  26960. ConvertProgram;
  26961. CheckSource('TestRTTI_DefaultValue',
  26962. LinesToStr([ // statements
  26963. 'this.TEnum = {',
  26964. ' "0": "red",',
  26965. ' red: 0,',
  26966. ' "1": "blue",',
  26967. ' blue: 1',
  26968. '};',
  26969. '$mod.$rtti.$Enum("TEnum", {',
  26970. ' minvalue: 0,',
  26971. ' maxvalue: 1,',
  26972. ' ordtype: 1,',
  26973. ' enumtype: this.TEnum',
  26974. '});',
  26975. 'this.CB = true || false;',
  26976. 'this.CI = 1 + 2;',
  26977. 'rtl.createClass($mod, "TObject", null, function () {',
  26978. ' this.$init = function () {',
  26979. ' this.FB = false;',
  26980. ' this.FI = 0;',
  26981. ' this.FE = 0;',
  26982. ' };',
  26983. ' this.$final = function () {',
  26984. ' };',
  26985. ' var $r = this.$rtti;',
  26986. ' $r.addProperty(',
  26987. ' "B1",',
  26988. ' 0,',
  26989. ' rtl.boolean,',
  26990. ' "FB",',
  26991. ' "",',
  26992. ' {',
  26993. ' Default: true',
  26994. ' }',
  26995. ' );',
  26996. ' $r.addProperty(',
  26997. ' "B2",',
  26998. ' 0,',
  26999. ' rtl.boolean,',
  27000. ' "FB",',
  27001. ' "",',
  27002. ' {',
  27003. ' Default: true',
  27004. ' }',
  27005. ' );',
  27006. ' $r.addProperty(',
  27007. ' "B3",',
  27008. ' 0,',
  27009. ' rtl.boolean,',
  27010. ' "FB",',
  27011. ' "",',
  27012. ' {',
  27013. ' Default: true',
  27014. ' }',
  27015. ' );',
  27016. ' $r.addProperty(',
  27017. ' "I1",',
  27018. ' 0,',
  27019. ' rtl.longint,',
  27020. ' "FI",',
  27021. ' "",',
  27022. ' {',
  27023. ' Default: 2',
  27024. ' }',
  27025. ' );',
  27026. ' $r.addProperty(',
  27027. ' "I2",',
  27028. ' 0,',
  27029. ' rtl.longint,',
  27030. ' "FI",',
  27031. ' "",',
  27032. ' {',
  27033. ' Default: 3',
  27034. ' }',
  27035. ' );',
  27036. ' $r.addProperty(',
  27037. ' "E1",',
  27038. ' 0,',
  27039. ' $mod.$rtti["TEnum"],',
  27040. ' "FE",',
  27041. ' "",',
  27042. ' {',
  27043. ' Default: $mod.TEnum.red',
  27044. ' }',
  27045. ' );',
  27046. ' $r.addProperty(',
  27047. ' "E2",',
  27048. ' 0,',
  27049. ' $mod.$rtti["TEnum"],',
  27050. ' "FE",',
  27051. ' "",',
  27052. ' {',
  27053. ' Default: $mod.TEnum.blue',
  27054. ' }',
  27055. ' );',
  27056. '});',
  27057. '']),
  27058. LinesToStr([ // $mod.$main
  27059. '']));
  27060. end;
  27061. procedure TTestModule.TestRTTI_DefaultValueSet;
  27062. begin
  27063. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27064. StartProgram(false);
  27065. Add([
  27066. 'type',
  27067. ' TEnum = (red, blue);',
  27068. ' TSet = set of TEnum;',
  27069. 'const',
  27070. ' CSet = [red,blue];',
  27071. 'type',
  27072. ' TObject = class',
  27073. ' FSet: TSet;',
  27074. ' published',
  27075. ' property Set1: TSet read FSet default [];',
  27076. ' property Set2: TSet read FSet default [red];',
  27077. ' property Set3: TSet read FSet default [red,blue];',
  27078. ' property Set4: TSet read FSet default CSet;',
  27079. ' end;',
  27080. 'begin']);
  27081. ConvertProgram;
  27082. CheckSource('TestRTTI_DefaultValueSet',
  27083. LinesToStr([ // statements
  27084. 'this.TEnum = {',
  27085. ' "0": "red",',
  27086. ' red: 0,',
  27087. ' "1": "blue",',
  27088. ' blue: 1',
  27089. '};',
  27090. '$mod.$rtti.$Enum("TEnum", {',
  27091. ' minvalue: 0,',
  27092. ' maxvalue: 1,',
  27093. ' ordtype: 1,',
  27094. ' enumtype: this.TEnum',
  27095. '});',
  27096. '$mod.$rtti.$Set("TSet", {',
  27097. ' comptype: $mod.$rtti["TEnum"]',
  27098. '});',
  27099. 'this.CSet = rtl.createSet($mod.TEnum.red, $mod.TEnum.blue);',
  27100. 'rtl.createClass($mod, "TObject", null, function () {',
  27101. ' this.$init = function () {',
  27102. ' this.FSet = {};',
  27103. ' };',
  27104. ' this.$final = function () {',
  27105. ' this.FSet = undefined;',
  27106. ' };',
  27107. ' var $r = this.$rtti;',
  27108. ' $r.addProperty(',
  27109. ' "Set1",',
  27110. ' 0,',
  27111. ' $mod.$rtti["TSet"],',
  27112. ' "FSet",',
  27113. ' "",',
  27114. ' {',
  27115. ' Default: {}',
  27116. ' }',
  27117. ' );',
  27118. ' $r.addProperty(',
  27119. ' "Set2",',
  27120. ' 0,',
  27121. ' $mod.$rtti["TSet"],',
  27122. ' "FSet",',
  27123. ' "",',
  27124. ' {',
  27125. ' Default: rtl.createSet($mod.TEnum.red)',
  27126. ' }',
  27127. ' );',
  27128. ' $r.addProperty(',
  27129. ' "Set3",',
  27130. ' 0,',
  27131. ' $mod.$rtti["TSet"],',
  27132. ' "FSet",',
  27133. ' "",',
  27134. ' {',
  27135. ' Default: rtl.createSet($mod.TEnum.red, $mod.TEnum.blue)',
  27136. ' }',
  27137. ' );',
  27138. ' $r.addProperty(',
  27139. ' "Set4",',
  27140. ' 0,',
  27141. ' $mod.$rtti["TSet"],',
  27142. ' "FSet",',
  27143. ' "",',
  27144. ' {',
  27145. ' Default: $mod.CSet',
  27146. ' }',
  27147. ' );',
  27148. '});',
  27149. '']),
  27150. LinesToStr([ // $mod.$main
  27151. '']));
  27152. end;
  27153. procedure TTestModule.TestRTTI_DefaultValueRangeType;
  27154. begin
  27155. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27156. StartProgram(false);
  27157. Add([
  27158. 'type',
  27159. ' TRg = -1..1;',
  27160. 'const',
  27161. ' l = low(TRg);',
  27162. ' h = high(TRg);',
  27163. 'type',
  27164. ' TObject = class',
  27165. ' FV: TRg;',
  27166. ' published',
  27167. ' property V1: TRg read FV default -1;',
  27168. ' end;',
  27169. 'begin']);
  27170. ConvertProgram;
  27171. CheckSource('TestRTTI_DefaultValueRangeType',
  27172. LinesToStr([ // statements
  27173. '$mod.$rtti.$Int("TRg", {',
  27174. ' minvalue: -1,',
  27175. ' maxvalue: 1,',
  27176. ' ordtype: 0',
  27177. '});',
  27178. 'this.l = -1;',
  27179. 'this.h = 1;',
  27180. 'rtl.createClass($mod, "TObject", null, function () {',
  27181. ' this.$init = function () {',
  27182. ' this.FV = 0;',
  27183. ' };',
  27184. ' this.$final = function () {',
  27185. ' };',
  27186. ' var $r = this.$rtti;',
  27187. ' $r.addProperty(',
  27188. ' "V1",',
  27189. ' 0,',
  27190. ' $mod.$rtti["TRg"],',
  27191. ' "FV",',
  27192. ' "",',
  27193. ' {',
  27194. ' Default: -1',
  27195. ' }',
  27196. ' );',
  27197. '});',
  27198. '']),
  27199. LinesToStr([ // $mod.$main
  27200. '']));
  27201. end;
  27202. procedure TTestModule.TestRTTI_DefaultValueInherit;
  27203. begin
  27204. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27205. StartProgram(false);
  27206. Add([
  27207. 'type',
  27208. ' TObject = class',
  27209. ' FA, FB: byte;',
  27210. ' property A: byte read FA default 1;',
  27211. ' property B: byte read FB default 2;',
  27212. ' end;',
  27213. ' TBird = class',
  27214. ' published',
  27215. ' property A;',
  27216. ' property B nodefault;',
  27217. ' end;',
  27218. 'begin']);
  27219. ConvertProgram;
  27220. CheckSource('TestRTTI_DefaultValueInherit',
  27221. LinesToStr([ // statements
  27222. 'rtl.createClass($mod, "TObject", null, function () {',
  27223. ' this.$init = function () {',
  27224. ' this.FA = 0;',
  27225. ' this.FB = 0;',
  27226. ' };',
  27227. ' this.$final = function () {',
  27228. ' };',
  27229. '});',
  27230. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  27231. ' var $r = this.$rtti;',
  27232. ' $r.addProperty(',
  27233. ' "A",',
  27234. ' 0,',
  27235. ' rtl.byte,',
  27236. ' "FA",',
  27237. ' "",',
  27238. ' {',
  27239. ' Default: 1',
  27240. ' }',
  27241. ' );',
  27242. ' $r.addProperty("B", 0, rtl.byte, "FB", "");',
  27243. '});',
  27244. '']),
  27245. LinesToStr([ // $mod.$main
  27246. '']));
  27247. end;
  27248. procedure TTestModule.TestRTTI_OverrideMethod;
  27249. begin
  27250. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27251. StartProgram(false);
  27252. Add('type');
  27253. Add(' TObject = class');
  27254. Add(' published');
  27255. Add(' procedure DoIt; virtual; abstract;');
  27256. Add(' end;');
  27257. Add(' TSky = class');
  27258. Add(' published');
  27259. Add(' procedure DoIt; override;');
  27260. Add(' end;');
  27261. Add('procedure TSky.DoIt; begin end;');
  27262. Add('begin');
  27263. ConvertProgram;
  27264. CheckSource('TestRTTI_OverrideMethod',
  27265. LinesToStr([ // statements
  27266. 'rtl.createClass($mod, "TObject", null, function () {',
  27267. ' this.$init = function () {',
  27268. ' };',
  27269. ' this.$final = function () {',
  27270. ' };',
  27271. ' var $r = this.$rtti;',
  27272. ' $r.addMethod("DoIt", 0, null);',
  27273. '});',
  27274. 'rtl.createClass($mod, "TSky", $mod.TObject, function () {',
  27275. ' this.DoIt = function () {',
  27276. ' };',
  27277. '});',
  27278. '']),
  27279. LinesToStr([ // $mod.$main
  27280. '']));
  27281. end;
  27282. procedure TTestModule.TestRTTI_OverloadProperty;
  27283. begin
  27284. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27285. StartProgram(false);
  27286. Add('type');
  27287. Add(' TObject = class');
  27288. Add(' protected');
  27289. Add(' FFlag: longint;');
  27290. Add(' published');
  27291. Add(' property Flag: longint read fflag;');
  27292. Add(' end;');
  27293. Add(' TSky = class');
  27294. Add(' published');
  27295. Add(' property FLAG: longint write fflag;');
  27296. Add(' end;');
  27297. Add('begin');
  27298. ConvertProgram;
  27299. CheckSource('TestRTTI_OverrideMethod',
  27300. LinesToStr([ // statements
  27301. 'rtl.createClass($mod, "TObject", null, function () {',
  27302. ' this.$init = function () {',
  27303. ' this.FFlag = 0;',
  27304. ' };',
  27305. ' this.$final = function () {',
  27306. ' };',
  27307. ' var $r = this.$rtti;',
  27308. ' $r.addProperty("Flag", 0, rtl.longint, "FFlag", "");',
  27309. '});',
  27310. 'rtl.createClass($mod, "TSky", $mod.TObject, function () {',
  27311. ' var $r = this.$rtti;',
  27312. ' $r.addProperty("Flag", 0, rtl.longint, "", "FFlag");',
  27313. '});',
  27314. '']),
  27315. LinesToStr([ // $mod.$main
  27316. '']));
  27317. end;
  27318. procedure TTestModule.TestRTTI_ClassForward;
  27319. begin
  27320. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27321. StartProgram(false);
  27322. Add('type');
  27323. Add(' TObject = class end;');
  27324. Add(' tbridge = class;');
  27325. Add(' TProc = function: tbridge;');
  27326. Add(' TOger = class');
  27327. Add(' published');
  27328. Add(' FBridge: tbridge;');
  27329. Add(' procedure SetBridge(Value: tbridge); virtual; abstract;');
  27330. Add(' property Bridge: tbridge read fbridge write setbridge;');
  27331. Add(' end;');
  27332. Add(' TBridge = class');
  27333. Add(' FOger: toger;');
  27334. Add(' end;');
  27335. Add('var p: Pointer;');
  27336. Add(' b: tbridge;');
  27337. Add('begin');
  27338. Add(' p:=typeinfo(tbridge);');
  27339. Add(' p:=typeinfo(b);');
  27340. ConvertProgram;
  27341. CheckSource('TestRTTI_ClassForward',
  27342. LinesToStr([ // statements
  27343. 'rtl.createClass($mod, "TObject", null, function () {',
  27344. ' this.$init = function () {',
  27345. ' };',
  27346. ' this.$final = function () {',
  27347. ' };',
  27348. '});',
  27349. '$mod.$rtti.$Class("TBridge");',
  27350. '$mod.$rtti.$ProcVar("TProc", {',
  27351. ' procsig: rtl.newTIProcSig(null, $mod.$rtti["TBridge"])',
  27352. '});',
  27353. 'rtl.createClass($mod, "TOger", $mod.TObject, function () {',
  27354. ' this.$init = function () {',
  27355. ' $mod.TObject.$init.call(this);',
  27356. ' this.FBridge = null;',
  27357. ' };',
  27358. ' this.$final = function () {',
  27359. ' this.FBridge = undefined;',
  27360. ' $mod.TObject.$final.call(this);',
  27361. ' };',
  27362. ' var $r = this.$rtti;',
  27363. ' $r.addField("FBridge", $mod.$rtti["TBridge"]);',
  27364. ' $r.addMethod("SetBridge", 0, [["Value", $mod.$rtti["TBridge"]]]);',
  27365. ' $r.addProperty("Bridge", 2, $mod.$rtti["TBridge"], "FBridge", "SetBridge");',
  27366. '});',
  27367. 'rtl.createClass($mod, "TBridge", $mod.TObject, function () {',
  27368. ' this.$init = function () {',
  27369. ' $mod.TObject.$init.call(this);',
  27370. ' this.FOger = null;',
  27371. ' };',
  27372. ' this.$final = function () {',
  27373. ' this.FOger = undefined;',
  27374. ' $mod.TObject.$final.call(this);',
  27375. ' };',
  27376. '});',
  27377. 'this.p = null;',
  27378. 'this.b = null;',
  27379. '']),
  27380. LinesToStr([ // $mod.$main
  27381. '$mod.p = $mod.$rtti["TBridge"];',
  27382. '$mod.p = $mod.b.$rtti;',
  27383. '']));
  27384. end;
  27385. procedure TTestModule.TestRTTI_ClassOf;
  27386. begin
  27387. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27388. StartProgram(false);
  27389. Add('type');
  27390. Add(' TClass = class of tobject;');
  27391. Add(' TProcA = function: TClass;');
  27392. Add(' TObject = class');
  27393. Add(' published');
  27394. Add(' C: tclass;');
  27395. Add(' end;');
  27396. Add(' tfox = class;');
  27397. Add(' TBird = class end;');
  27398. Add(' TBirds = class of tbird;');
  27399. Add(' TFox = class end;');
  27400. Add(' TFoxes = class of tfox;');
  27401. Add(' TCows = class of TCow;');
  27402. Add(' TCow = class;');
  27403. Add(' TCow = class end;');
  27404. Add('begin');
  27405. ConvertProgram;
  27406. CheckSource('TestRTTI_ClassOf',
  27407. LinesToStr([ // statements
  27408. '$mod.$rtti.$Class("TObject");',
  27409. '$mod.$rtti.$ClassRef("TClass", {',
  27410. ' instancetype: $mod.$rtti["TObject"]',
  27411. '});',
  27412. '$mod.$rtti.$ProcVar("TProcA", {',
  27413. ' procsig: rtl.newTIProcSig(null, $mod.$rtti["TClass"])',
  27414. '});',
  27415. 'rtl.createClass($mod, "TObject", null, function () {',
  27416. ' this.$init = function () {',
  27417. ' this.C = null;',
  27418. ' };',
  27419. ' this.$final = function () {',
  27420. ' this.C = undefined;',
  27421. ' };',
  27422. ' var $r = this.$rtti;',
  27423. ' $r.addField("C", $mod.$rtti["TClass"]);',
  27424. '});',
  27425. '$mod.$rtti.$Class("TFox");',
  27426. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  27427. '});',
  27428. '$mod.$rtti.$ClassRef("TBirds", {',
  27429. ' instancetype: $mod.$rtti["TBird"]',
  27430. '});',
  27431. 'rtl.createClass($mod, "TFox", $mod.TObject, function () {',
  27432. '});',
  27433. '$mod.$rtti.$ClassRef("TFoxes", {',
  27434. ' instancetype: $mod.$rtti["TFox"]',
  27435. '});',
  27436. '$mod.$rtti.$Class("TCow");',
  27437. '$mod.$rtti.$ClassRef("TCows", {',
  27438. ' instancetype: $mod.$rtti["TCow"]',
  27439. '});',
  27440. 'rtl.createClass($mod, "TCow", $mod.TObject, function () {',
  27441. '});',
  27442. '']),
  27443. LinesToStr([ // $mod.$main
  27444. '']));
  27445. end;
  27446. procedure TTestModule.TestRTTI_Record;
  27447. begin
  27448. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27449. StartProgram(false);
  27450. Add('type');
  27451. Add(' integer = longint;');
  27452. Add(' TPoint = record');
  27453. Add(' x,y: integer;');
  27454. Add(' end;');
  27455. Add('var p: pointer;');
  27456. Add(' r: tpoint;');
  27457. Add('begin');
  27458. Add(' p:=typeinfo(tpoint);');
  27459. Add(' p:=typeinfo(r);');
  27460. Add(' p:=typeinfo(r.x);');
  27461. ConvertProgram;
  27462. CheckSource('TestRTTI_Record',
  27463. LinesToStr([ // statements
  27464. 'rtl.recNewT($mod, "TPoint", function () {',
  27465. ' this.x = 0;',
  27466. ' this.y = 0;',
  27467. ' this.$eq = function (b) {',
  27468. ' return (this.x === b.x) && (this.y === b.y);',
  27469. ' };',
  27470. ' this.$assign = function (s) {',
  27471. ' this.x = s.x;',
  27472. ' this.y = s.y;',
  27473. ' return this;',
  27474. ' };',
  27475. ' var $r = $mod.$rtti.$Record("TPoint", {});',
  27476. ' $r.addField("x", rtl.longint);',
  27477. ' $r.addField("y", rtl.longint);',
  27478. '});',
  27479. 'this.p = null;',
  27480. 'this.r = $mod.TPoint.$new();',
  27481. '']),
  27482. LinesToStr([ // $mod.$main
  27483. '$mod.p = $mod.$rtti["TPoint"];',
  27484. '$mod.p = $mod.$rtti["TPoint"];',
  27485. '$mod.p = rtl.longint;',
  27486. '']));
  27487. end;
  27488. procedure TTestModule.TestRTTI_RecordAnonymousArray;
  27489. begin
  27490. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27491. StartProgram(false);
  27492. Add('type');
  27493. Add(' TFloatRec = record');
  27494. Add(' d: array of char;');
  27495. // Add(' i: array of array of longint;');
  27496. Add(' end;');
  27497. Add('var p: pointer;');
  27498. Add(' r: tfloatrec;');
  27499. Add('begin');
  27500. Add(' p:=typeinfo(tfloatrec);');
  27501. Add(' p:=typeinfo(r);');
  27502. Add(' p:=typeinfo(r.d);');
  27503. ConvertProgram;
  27504. CheckSource('TestRTTI_Record',
  27505. LinesToStr([ // statements
  27506. 'rtl.recNewT($mod, "TFloatRec", function () {',
  27507. ' this.d = [];',
  27508. ' this.$eq = function (b) {',
  27509. ' return this.d === b.d;',
  27510. ' };',
  27511. ' this.$assign = function (s) {',
  27512. ' this.d = s.d;',
  27513. ' return this;',
  27514. ' };',
  27515. ' $mod.$rtti.$DynArray("TFloatRec.d$a", {',
  27516. ' eltype: rtl.char',
  27517. ' });',
  27518. ' var $r = $mod.$rtti.$Record("TFloatRec", {});',
  27519. ' $r.addField("d", $mod.$rtti["TFloatRec.d$a"]);',
  27520. '});',
  27521. 'this.p = null;',
  27522. 'this.r = $mod.TFloatRec.$new();',
  27523. '']),
  27524. LinesToStr([ // $mod.$main
  27525. '$mod.p = $mod.$rtti["TFloatRec"];',
  27526. '$mod.p = $mod.$rtti["TFloatRec"];',
  27527. '$mod.p = $mod.$rtti["TFloatRec.d$a"];',
  27528. '']));
  27529. end;
  27530. procedure TTestModule.TestRTTI_LocalTypes;
  27531. begin
  27532. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27533. StartProgram(false);
  27534. Add([
  27535. 'procedure DoIt;',
  27536. 'type',
  27537. ' integer = longint;',
  27538. ' TPoint = record',
  27539. ' x,y: integer;',
  27540. ' end;',
  27541. 'var p: TPoint;',
  27542. 'begin',
  27543. 'end;',
  27544. 'begin']);
  27545. ConvertProgram;
  27546. CheckSource('TestRTTI_LocalTypes',
  27547. LinesToStr([ // statements
  27548. 'var TPoint = rtl.recNewT(null, "", function () {',
  27549. ' this.x = 0;',
  27550. ' this.y = 0;',
  27551. ' this.$eq = function (b) {',
  27552. ' return (this.x === b.x) && (this.y === b.y);',
  27553. ' };',
  27554. ' this.$assign = function (s) {',
  27555. ' this.x = s.x;',
  27556. ' this.y = s.y;',
  27557. ' return this;',
  27558. ' };',
  27559. '});',
  27560. 'this.DoIt = function () {',
  27561. ' var p = TPoint.$new();',
  27562. '};',
  27563. '']),
  27564. LinesToStr([ // $mod.$main
  27565. '']));
  27566. end;
  27567. procedure TTestModule.TestRTTI_TypeInfo_BaseTypes;
  27568. begin
  27569. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27570. StartProgram(false);
  27571. Add([
  27572. 'type',
  27573. ' TCaption = string;',
  27574. ' TYesNo = boolean;',
  27575. ' TLetter = char;',
  27576. ' TFloat = double;',
  27577. ' TPtr = pointer;',
  27578. ' TShortInt = shortint;',
  27579. ' TByte = byte;',
  27580. ' TSmallInt = smallint;',
  27581. ' TWord = word;',
  27582. ' TInt32 = longint;',
  27583. ' TDWord = longword;',
  27584. ' TValue = jsvalue;',
  27585. 'var p: TPtr;',
  27586. 'begin',
  27587. ' p:=typeinfo(string);',
  27588. ' p:=typeinfo(tcaption);',
  27589. ' p:=typeinfo(boolean);',
  27590. ' p:=typeinfo(tyesno);',
  27591. ' p:=typeinfo(char);',
  27592. ' p:=typeinfo(tletter);',
  27593. ' p:=typeinfo(double);',
  27594. ' p:=typeinfo(tfloat);',
  27595. ' p:=typeinfo(pointer);',
  27596. ' p:=typeinfo(tptr);',
  27597. ' p:=typeinfo(shortint);',
  27598. ' p:=typeinfo(tshortint);',
  27599. ' p:=typeinfo(byte);',
  27600. ' p:=typeinfo(tbyte);',
  27601. ' p:=typeinfo(smallint);',
  27602. ' p:=typeinfo(tsmallint);',
  27603. ' p:=typeinfo(word);',
  27604. ' p:=typeinfo(tword);',
  27605. ' p:=typeinfo(longword);',
  27606. ' p:=typeinfo(tdword);',
  27607. ' p:=typeinfo(jsvalue);',
  27608. ' p:=typeinfo(tvalue);',
  27609. '']);
  27610. ConvertProgram;
  27611. CheckSource('TestRTTI_TypeInfo_BaseTypes',
  27612. LinesToStr([ // statements
  27613. 'this.p = null;',
  27614. '']),
  27615. LinesToStr([ // $mod.$main
  27616. '$mod.p = rtl.string;',
  27617. '$mod.p = rtl.string;',
  27618. '$mod.p = rtl.boolean;',
  27619. '$mod.p = rtl.boolean;',
  27620. '$mod.p = rtl.char;',
  27621. '$mod.p = rtl.char;',
  27622. '$mod.p = rtl.double;',
  27623. '$mod.p = rtl.double;',
  27624. '$mod.p = rtl.pointer;',
  27625. '$mod.p = rtl.pointer;',
  27626. '$mod.p = rtl.shortint;',
  27627. '$mod.p = rtl.shortint;',
  27628. '$mod.p = rtl.byte;',
  27629. '$mod.p = rtl.byte;',
  27630. '$mod.p = rtl.smallint;',
  27631. '$mod.p = rtl.smallint;',
  27632. '$mod.p = rtl.word;',
  27633. '$mod.p = rtl.word;',
  27634. '$mod.p = rtl.longword;',
  27635. '$mod.p = rtl.longword;',
  27636. '$mod.p = rtl.jsvalue;',
  27637. '$mod.p = rtl.jsvalue;',
  27638. '']));
  27639. end;
  27640. procedure TTestModule.TestRTTI_TypeInfo_Type_BaseTypes;
  27641. begin
  27642. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27643. StartProgram(false);
  27644. Add([
  27645. 'type',
  27646. ' TCaption = type string;',
  27647. ' TYesNo = type boolean;',
  27648. ' TLetter = type char;',
  27649. ' TFloat = type double;',
  27650. ' TPtr = type pointer;',
  27651. ' TShortInt = type shortint;',
  27652. ' TByte = type byte;',
  27653. ' TSmallInt = type smallint;',
  27654. ' TWord = type word;',
  27655. ' TInt32 = type longint;',
  27656. ' TDWord = type longword;',
  27657. ' TValue = type jsvalue;',
  27658. ' TAliasValue = type TValue;',
  27659. 'var',
  27660. ' p: TPtr;',
  27661. ' a: TAliasValue;',
  27662. 'begin',
  27663. ' p:=typeinfo(tcaption);',
  27664. ' p:=typeinfo(tyesno);',
  27665. ' p:=typeinfo(tletter);',
  27666. ' p:=typeinfo(tfloat);',
  27667. ' p:=typeinfo(tptr);',
  27668. ' p:=typeinfo(tshortint);',
  27669. ' p:=typeinfo(tbyte);',
  27670. ' p:=typeinfo(tsmallint);',
  27671. ' p:=typeinfo(tword);',
  27672. ' p:=typeinfo(tdword);',
  27673. ' p:=typeinfo(tvalue);',
  27674. ' p:=typeinfo(taliasvalue);',
  27675. ' p:=typeinfo(a);',
  27676. '']);
  27677. ConvertProgram;
  27678. CheckSource('TestRTTI_TypeInfo_Type_BaseTypes',
  27679. LinesToStr([ // statements
  27680. '$mod.$rtti.$inherited("TCaption", rtl.string, {});',
  27681. '$mod.$rtti.$inherited("TYesNo", rtl.boolean, {});',
  27682. '$mod.$rtti.$inherited("TLetter", rtl.char, {});',
  27683. '$mod.$rtti.$inherited("TFloat", rtl.double, {});',
  27684. '$mod.$rtti.$inherited("TPtr", rtl.pointer, {});',
  27685. '$mod.$rtti.$inherited("TShortInt", rtl.shortint, {});',
  27686. '$mod.$rtti.$inherited("TByte", rtl.byte, {});',
  27687. '$mod.$rtti.$inherited("TSmallInt", rtl.smallint, {});',
  27688. '$mod.$rtti.$inherited("TWord", rtl.word, {});',
  27689. '$mod.$rtti.$inherited("TInt32", rtl.longint, {});',
  27690. '$mod.$rtti.$inherited("TDWord", rtl.longword, {});',
  27691. '$mod.$rtti.$inherited("TValue", rtl.jsvalue, {});',
  27692. '$mod.$rtti.$inherited("TAliasValue", $mod.$rtti["TValue"], {});',
  27693. 'this.p = null;',
  27694. 'this.a = undefined;',
  27695. '']),
  27696. LinesToStr([ // $mod.$main
  27697. '$mod.p = $mod.$rtti["TCaption"];',
  27698. '$mod.p = $mod.$rtti["TYesNo"];',
  27699. '$mod.p = $mod.$rtti["TLetter"];',
  27700. '$mod.p = $mod.$rtti["TFloat"];',
  27701. '$mod.p = $mod.$rtti["TPtr"];',
  27702. '$mod.p = $mod.$rtti["TShortInt"];',
  27703. '$mod.p = $mod.$rtti["TByte"];',
  27704. '$mod.p = $mod.$rtti["TSmallInt"];',
  27705. '$mod.p = $mod.$rtti["TWord"];',
  27706. '$mod.p = $mod.$rtti["TDWord"];',
  27707. '$mod.p = $mod.$rtti["TValue"];',
  27708. '$mod.p = $mod.$rtti["TAliasValue"];',
  27709. '$mod.p = $mod.$rtti["TAliasValue"];',
  27710. '']));
  27711. end;
  27712. procedure TTestModule.TestRTTI_TypeInfo_LocalFail;
  27713. begin
  27714. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27715. StartProgram(false);
  27716. Add('procedure DoIt;');
  27717. Add('type');
  27718. Add(' integer = longint;');
  27719. Add(' TPoint = record');
  27720. Add(' x,y: integer;');
  27721. Add(' end;');
  27722. Add('var p: pointer;');
  27723. Add('begin');
  27724. Add(' p:=typeinfo(tpoint);');
  27725. Add('end;');
  27726. Add('begin');
  27727. SetExpectedPasResolverError(sSymbolCannotBePublished,nSymbolCannotBePublished);
  27728. ConvertProgram;
  27729. end;
  27730. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses1;
  27731. begin
  27732. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27733. StartProgram(false);
  27734. Add([
  27735. '{$modeswitch externalclass}',
  27736. 'type',
  27737. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  27738. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo) end;',
  27739. ' TFlag = (up,down);',
  27740. ' TTypeInfoEnum = class external name ''rtl.tTypeInfoEnum''(TTypeInfoInteger) end;',
  27741. ' TFlags = set of TFlag;',
  27742. ' TTypeInfoSet = class external name ''rtl.tTypeInfoSet''(TTypeInfo) end;',
  27743. 'var',
  27744. ' ti: TTypeInfo;',
  27745. ' tiInt: TTypeInfoInteger;',
  27746. ' tiEnum: TTypeInfoEnum;',
  27747. ' tiSet: TTypeInfoSet;',
  27748. 'begin',
  27749. ' ti:=typeinfo(string);',
  27750. ' ti:=typeinfo(boolean);',
  27751. ' ti:=typeinfo(char);',
  27752. ' ti:=typeinfo(double);',
  27753. ' tiInt:=typeinfo(shortint);',
  27754. ' tiInt:=typeinfo(byte);',
  27755. ' tiInt:=typeinfo(smallint);',
  27756. ' tiInt:=typeinfo(word);',
  27757. ' tiInt:=typeinfo(longint);',
  27758. ' tiInt:=typeinfo(longword);',
  27759. ' ti:=typeinfo(jsvalue);',
  27760. ' tiEnum:=typeinfo(tflag);',
  27761. ' tiSet:=typeinfo(tflags);']);
  27762. ConvertProgram;
  27763. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses1',
  27764. LinesToStr([ // statements
  27765. 'this.TFlag = {',
  27766. ' "0": "up",',
  27767. ' up: 0,',
  27768. ' "1": "down",',
  27769. ' down: 1',
  27770. '};',
  27771. '$mod.$rtti.$Enum("TFlag", {',
  27772. ' minvalue: 0,',
  27773. ' maxvalue: 1,',
  27774. ' ordtype: 1,',
  27775. ' enumtype: this.TFlag',
  27776. '});',
  27777. '$mod.$rtti.$Set("TFlags", {',
  27778. ' comptype: $mod.$rtti["TFlag"]',
  27779. '});',
  27780. 'this.ti = null;',
  27781. 'this.tiInt = null;',
  27782. 'this.tiEnum = null;',
  27783. 'this.tiSet = null;',
  27784. '']),
  27785. LinesToStr([ // $mod.$main
  27786. '$mod.ti = rtl.string;',
  27787. '$mod.ti = rtl.boolean;',
  27788. '$mod.ti = rtl.char;',
  27789. '$mod.ti = rtl.double;',
  27790. '$mod.tiInt = rtl.shortint;',
  27791. '$mod.tiInt = rtl.byte;',
  27792. '$mod.tiInt = rtl.smallint;',
  27793. '$mod.tiInt = rtl.word;',
  27794. '$mod.tiInt = rtl.longint;',
  27795. '$mod.tiInt = rtl.longword;',
  27796. '$mod.ti = rtl.jsvalue;',
  27797. '$mod.tiEnum = $mod.$rtti["TFlag"];',
  27798. '$mod.tiSet = $mod.$rtti["TFlags"];',
  27799. '']));
  27800. end;
  27801. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses2;
  27802. begin
  27803. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27804. StartProgram(false);
  27805. Add('{$modeswitch externalclass}');
  27806. Add('type');
  27807. Add(' TTypeInfo = class external name ''rtl.tTypeInfo'' end;');
  27808. Add(' TStaticArr = array[boolean] of string;');
  27809. Add(' TTypeInfoStaticArray = class external name ''rtl.tTypeInfoStaticArray''(TTypeInfo) end;');
  27810. Add(' TDynArr = array of string;');
  27811. Add(' TTypeInfoDynArray = class external name ''rtl.tTypeInfoDynArray''(TTypeInfo) end;');
  27812. Add(' TProc = procedure;');
  27813. Add(' TTypeInfoProcVar = class external name ''rtl.tTypeInfoProcVar''(TTypeInfo) end;');
  27814. Add(' TMethod = procedure of object;');
  27815. Add(' TTypeInfoMethodVar = class external name ''rtl.tTypeInfoMethodVar''(TTypeInfoProcVar) end;');
  27816. Add('var');
  27817. Add(' StaticArray: TStaticArr;');
  27818. Add(' tiStaticArray: TTypeInfoStaticArray;');
  27819. Add(' DynArray: TDynArr;');
  27820. Add(' tiDynArray: TTypeInfoDynArray;');
  27821. Add(' ProcVar: TProc;');
  27822. Add(' tiProcVar: TTypeInfoProcVar;');
  27823. Add(' MethodVar: TMethod;');
  27824. Add(' tiMethodVar: TTypeInfoMethodVar;');
  27825. Add('begin');
  27826. Add(' tiStaticArray:=typeinfo(StaticArray);');
  27827. Add(' tiStaticArray:=typeinfo(TStaticArr);');
  27828. Add(' tiDynArray:=typeinfo(DynArray);');
  27829. Add(' tiDynArray:=typeinfo(TDynArr);');
  27830. Add(' tiProcVar:=typeinfo(ProcVar);');
  27831. Add(' tiProcVar:=typeinfo(TProc);');
  27832. Add(' tiMethodVar:=typeinfo(MethodVar);');
  27833. Add(' tiMethodVar:=typeinfo(TMethod);');
  27834. ConvertProgram;
  27835. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses2',
  27836. LinesToStr([ // statements
  27837. ' $mod.$rtti.$StaticArray("TStaticArr", {',
  27838. ' dims: [2],',
  27839. ' eltype: rtl.string',
  27840. '});',
  27841. '$mod.$rtti.$DynArray("TDynArr", {',
  27842. ' eltype: rtl.string',
  27843. '});',
  27844. '$mod.$rtti.$ProcVar("TProc", {',
  27845. ' procsig: rtl.newTIProcSig(null)',
  27846. '});',
  27847. '$mod.$rtti.$MethodVar("TMethod", {',
  27848. ' procsig: rtl.newTIProcSig(null),',
  27849. ' methodkind: 0',
  27850. '});',
  27851. 'this.StaticArray = rtl.arraySetLength(null,"",2);',
  27852. 'this.tiStaticArray = null;',
  27853. 'this.DynArray = [];',
  27854. 'this.tiDynArray = null;',
  27855. 'this.ProcVar = null;',
  27856. 'this.tiProcVar = null;',
  27857. 'this.MethodVar = null;',
  27858. 'this.tiMethodVar = null;',
  27859. '']),
  27860. LinesToStr([ // $mod.$main
  27861. '$mod.tiStaticArray = $mod.$rtti["TStaticArr"];',
  27862. '$mod.tiStaticArray = $mod.$rtti["TStaticArr"];',
  27863. '$mod.tiDynArray = $mod.$rtti["TDynArr"];',
  27864. '$mod.tiDynArray = $mod.$rtti["TDynArr"];',
  27865. '$mod.tiProcVar = $mod.$rtti["TProc"];',
  27866. '$mod.tiProcVar = $mod.$rtti["TProc"];',
  27867. '$mod.tiMethodVar = $mod.$rtti["TMethod"];',
  27868. '$mod.tiMethodVar = $mod.$rtti["TMethod"];',
  27869. '']));
  27870. end;
  27871. procedure TTestModule.TestRTTI_TypeInfo_ExtTypeInfoClasses3;
  27872. begin
  27873. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27874. StartProgram(false);
  27875. Add('{$modeswitch externalclass}');
  27876. Add('type');
  27877. Add(' TTypeInfo = class external name ''rtl.tTypeInfo'' end;');
  27878. Add(' TRec = record end;');
  27879. Add(' TTypeInfoRecord = class external name ''rtl.tTypeInfoRecord''(TTypeInfo) end;');
  27880. // ToDo: ^PRec
  27881. Add(' TObject = class end;');
  27882. Add(' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;');
  27883. Add(' TClass = class of tobject;');
  27884. Add(' TTypeInfoClassRef = class external name ''rtl.tTypeInfoClassRef''(TTypeInfo) end;');
  27885. Add(' TTypeInfoPointer = class external name ''rtl.tTypeInfoPointer''(TTypeInfo) end;');
  27886. Add('var');
  27887. Add(' Rec: trec;');
  27888. Add(' tiRecord: ttypeinforecord;');
  27889. Add(' Obj: tobject;');
  27890. Add(' tiClass: ttypeinfoclass;');
  27891. Add(' aClass: tclass;');
  27892. Add(' tiClassRef: ttypeinfoclassref;');
  27893. // ToDo: ^PRec
  27894. Add(' tiPointer: ttypeinfopointer;');
  27895. Add('begin');
  27896. Add(' tirecord:=typeinfo(trec);');
  27897. Add(' tirecord:=typeinfo(trec);');
  27898. Add(' ticlass:=typeinfo(obj);');
  27899. Add(' ticlass:=typeinfo(tobject);');
  27900. Add(' ticlass:=typeinfo(aclass);');
  27901. Add(' ticlassref:=typeinfo(tclass);');
  27902. ConvertProgram;
  27903. CheckSource('TestRTTI_TypeInfo_ExtTypeInfoClasses3',
  27904. LinesToStr([ // statements
  27905. 'rtl.recNewT($mod, "TRec", function () {',
  27906. ' this.$eq = function (b) {',
  27907. ' return true;',
  27908. ' };',
  27909. ' this.$assign = function (s) {',
  27910. ' return this;',
  27911. ' };',
  27912. ' $mod.$rtti.$Record("TRec", {});',
  27913. '});',
  27914. 'rtl.createClass($mod, "TObject", null, function () {',
  27915. ' this.$init = function () {',
  27916. ' };',
  27917. ' this.$final = function () {',
  27918. ' };',
  27919. '});',
  27920. '$mod.$rtti.$ClassRef("TClass", {',
  27921. ' instancetype: $mod.$rtti["TObject"]',
  27922. '});',
  27923. 'this.Rec = $mod.TRec.$new();',
  27924. 'this.tiRecord = null;',
  27925. 'this.Obj = null;',
  27926. 'this.tiClass = null;',
  27927. 'this.aClass = null;',
  27928. 'this.tiClassRef = null;',
  27929. 'this.tiPointer = null;',
  27930. '']),
  27931. LinesToStr([ // $mod.$main
  27932. '$mod.tiRecord = $mod.$rtti["TRec"];',
  27933. '$mod.tiRecord = $mod.$rtti["TRec"];',
  27934. '$mod.tiClass = $mod.Obj.$rtti;',
  27935. '$mod.tiClass = $mod.$rtti["TObject"];',
  27936. '$mod.tiClass = $mod.aClass.$rtti;',
  27937. '$mod.tiClassRef = $mod.$rtti["TClass"];',
  27938. '']));
  27939. end;
  27940. procedure TTestModule.TestRTTI_TypeInfo_FunctionClassType;
  27941. begin
  27942. Converter.Options:=Converter.Options-[coNoTypeInfo];
  27943. StartProgram(false);
  27944. Add([
  27945. '{$modeswitch externalclass}',
  27946. 'type',
  27947. ' TClass = class of tobject;',
  27948. ' TObject = class',
  27949. ' function MyClass: TClass;',
  27950. ' class function ClassType: TClass;',
  27951. ' end;',
  27952. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  27953. ' TTypeInfoClass = class external name ''rtl.tTypeInfoClass''(TTypeInfo) end;',
  27954. 'function TObject.MyClass: TClass;',
  27955. 'var t: TTypeInfoClass;',
  27956. 'begin',
  27957. ' t:=TypeInfo(Self);',
  27958. ' t:=TypeInfo(Result);',
  27959. ' t:=TypeInfo(TObject);',
  27960. 'end;',
  27961. 'class function TObject.ClassType: TClass;',
  27962. 'var t: TTypeInfoClass;',
  27963. 'begin',
  27964. ' t:=TypeInfo(Self);',
  27965. ' t:=TypeInfo(Result);',
  27966. 'end;',
  27967. 'var',
  27968. ' Obj: TObject;',
  27969. ' t: TTypeInfoClass;',
  27970. 'begin',
  27971. ' t:=TypeInfo(TObject.ClassType);',
  27972. ' t:=TypeInfo(Obj.ClassType);',
  27973. ' t:=TypeInfo(Obj.MyClass);',
  27974. '']);
  27975. ConvertProgram;
  27976. CheckSource('TestRTTI_TypeInfo_FunctionClassType',
  27977. LinesToStr([ // statements
  27978. '$mod.$rtti.$Class("TObject");',
  27979. '$mod.$rtti.$ClassRef("TClass", {',
  27980. ' instancetype: $mod.$rtti["TObject"]',
  27981. '});',
  27982. 'rtl.createClass($mod, "TObject", null, function () {',
  27983. ' this.$init = function () {',
  27984. ' };',
  27985. ' this.$final = function () {',
  27986. ' };',
  27987. ' this.MyClass = function () {',
  27988. ' var Result = null;',
  27989. ' var t = null;',
  27990. ' t = this.$rtti;',
  27991. ' t = Result.$rtti;',
  27992. ' t = $mod.$rtti["TObject"];',
  27993. ' return Result;',
  27994. ' };',
  27995. ' this.ClassType = function () {',
  27996. ' var Result = null;',
  27997. ' var t = null;',
  27998. ' t = this.$rtti;',
  27999. ' t = Result.$rtti;',
  28000. ' return Result;',
  28001. ' };',
  28002. '});',
  28003. 'this.Obj = null;',
  28004. 'this.t = null;',
  28005. '']),
  28006. LinesToStr([ // $mod.$main
  28007. '$mod.t = $mod.TObject.ClassType().$rtti;',
  28008. '$mod.t = $mod.Obj.$class.ClassType().$rtti;',
  28009. '$mod.t = $mod.Obj.MyClass().$rtti;',
  28010. '']));
  28011. end;
  28012. procedure TTestModule.TestRTTI_TypeInfo_MixedUnits_PointerAndClass;
  28013. begin
  28014. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28015. AddModuleWithIntfImplSrc('typinfo.pas',
  28016. LinesToStr([
  28017. '{$modeswitch externalclass}',
  28018. 'type',
  28019. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28020. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo) end;',
  28021. '']),
  28022. '');
  28023. AddModuleWithIntfImplSrc('unit2.pas',
  28024. LinesToStr([
  28025. 'uses typinfo;',
  28026. 'type PTypeInfo = TTypeInfo;', // delphi compatibility code
  28027. 'procedure DoPtr(p: PTypeInfo);',
  28028. 'procedure DoInfo(t: TTypeInfo);',
  28029. 'procedure DoInt(t: TTypeInfoInteger);',
  28030. '']),
  28031. LinesToStr([
  28032. 'procedure DoPtr(p: PTypeInfo);',
  28033. 'begin end;',
  28034. 'procedure DoInfo(t: TTypeInfo);',
  28035. 'begin end;',
  28036. 'procedure DoInt(t: TTypeInfoInteger);',
  28037. 'begin end;',
  28038. '']));
  28039. StartUnit(true);
  28040. Add([
  28041. 'interface',
  28042. 'uses unit2;', // does not use unit typinfo
  28043. 'implementation',
  28044. 'var',
  28045. ' i: byte;',
  28046. ' p: pointer;',
  28047. ' t: PTypeInfo;',
  28048. 'initialization',
  28049. ' p:=typeinfo(i);',
  28050. ' t:=typeinfo(i);',
  28051. ' if p=t then ;',
  28052. ' if p=typeinfo(i) then ;',
  28053. ' if typeinfo(i)=p then ;',
  28054. ' if t=typeinfo(i) then ;',
  28055. ' if typeinfo(i)=t then ;',
  28056. ' DoPtr(p);',
  28057. ' DoPtr(t);',
  28058. ' DoPtr(typeinfo(i));',
  28059. ' DoInfo(p);',
  28060. ' DoInfo(t);',
  28061. ' DoInfo(typeinfo(i));',
  28062. ' DoInt(typeinfo(i));',
  28063. '']);
  28064. ConvertUnit;
  28065. CheckSource('TestRTTI_TypeInfo_MixedUnits_PointerAndClass',
  28066. LinesToStr([ // statements
  28067. 'var $impl = $mod.$impl;',
  28068. '']),
  28069. LinesToStr([ // this.$init
  28070. '$impl.p = rtl.byte;',
  28071. '$impl.t = rtl.byte;',
  28072. 'if ($impl.p === $impl.t) ;',
  28073. 'if ($impl.p === rtl.byte) ;',
  28074. 'if (rtl.byte === $impl.p) ;',
  28075. 'if ($impl.t === rtl.byte) ;',
  28076. 'if (rtl.byte === $impl.t) ;',
  28077. 'pas.unit2.DoPtr($impl.p);',
  28078. 'pas.unit2.DoPtr($impl.t);',
  28079. 'pas.unit2.DoPtr(rtl.byte);',
  28080. 'pas.unit2.DoInfo($impl.p);',
  28081. 'pas.unit2.DoInfo($impl.t);',
  28082. 'pas.unit2.DoInfo(rtl.byte);',
  28083. 'pas.unit2.DoInt(rtl.byte);',
  28084. '']),
  28085. LinesToStr([ // implementation
  28086. '$impl.i = 0;',
  28087. '$impl.p = null;',
  28088. '$impl.t = null;',
  28089. '']) );
  28090. end;
  28091. procedure TTestModule.TestRTTI_Interface_Corba;
  28092. begin
  28093. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28094. StartProgram(false);
  28095. Add([
  28096. '{$interfaces corba}',
  28097. '{$modeswitch externalclass}',
  28098. 'type',
  28099. ' IUnknown = interface',
  28100. ' end;',
  28101. ' IBird = interface',
  28102. ' function GetItem: longint;',
  28103. ' procedure SetItem(Value: longint);',
  28104. ' property Item: longint read GetItem write SetItem;',
  28105. ' end;',
  28106. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28107. ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
  28108. 'procedure DoIt(t: TTypeInfoInterface); begin end;',
  28109. 'var',
  28110. ' i: IBird;',
  28111. ' t: TTypeInfoInterface;',
  28112. 'begin',
  28113. ' t:=TypeInfo(IBird);',
  28114. ' t:=TypeInfo(i);',
  28115. ' DoIt(t);',
  28116. ' DoIt(TypeInfo(IBird));',
  28117. '']);
  28118. ConvertProgram;
  28119. CheckSource('TestRTTI_Interface_Corba',
  28120. LinesToStr([ // statements
  28121. 'rtl.createInterface(',
  28122. ' $mod,',
  28123. ' "IUnknown",',
  28124. ' "{B92D5841-758A-322B-B800-000000000000}",',
  28125. ' [],',
  28126. ' null,',
  28127. ' function () {',
  28128. ' }',
  28129. ');',
  28130. 'rtl.createInterface(',
  28131. ' $mod,',
  28132. ' "IBird",',
  28133. ' "{D32D5841-6264-3AE3-A2C9-B91CE922C9B9}",',
  28134. ' ["GetItem", "SetItem"],',
  28135. ' null,',
  28136. ' function () {',
  28137. ' var $r = this.$rtti;',
  28138. ' $r.addMethod("GetItem", 1, null, rtl.longint);',
  28139. ' $r.addMethod("SetItem", 0, [["Value", rtl.longint]]);',
  28140. ' $r.addProperty("Item", 3, rtl.longint, "GetItem", "SetItem");',
  28141. ' }',
  28142. ');',
  28143. 'this.DoIt = function (t) {',
  28144. '}; ',
  28145. 'this.i = null;',
  28146. 'this.t = null;',
  28147. '']),
  28148. LinesToStr([ // $mod.$main
  28149. '$mod.t = $mod.$rtti["IBird"];',
  28150. '$mod.t = $mod.i.$rtti;',
  28151. '$mod.DoIt($mod.t);',
  28152. '$mod.DoIt($mod.$rtti["IBird"]);',
  28153. '']));
  28154. end;
  28155. procedure TTestModule.TestRTTI_Interface_COM;
  28156. begin
  28157. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28158. StartProgram(false);
  28159. Add([
  28160. '{$interfaces com}',
  28161. '{$modeswitch externalclass}',
  28162. 'type',
  28163. ' TGuid = record end;',
  28164. ' integer = longint;',
  28165. ' IUnknown = interface',
  28166. ' function QueryInterface(const iid: TGuid; out obj): Integer;',
  28167. ' function _AddRef: Integer;',
  28168. ' function _Release: Integer;',
  28169. ' end;',
  28170. ' IBird = interface',
  28171. ' function GetItem: longint;',
  28172. ' procedure SetItem(Value: longint);',
  28173. ' property Item: longint read GetItem write SetItem;',
  28174. ' end;',
  28175. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28176. ' TTypeInfoInterface = class external name ''rtl.tTypeInfoInterface''(TTypeInfo) end;',
  28177. 'var',
  28178. ' i: IBird;',
  28179. ' t: TTypeInfoInterface;',
  28180. 'begin',
  28181. ' t:=TypeInfo(IBird);',
  28182. ' t:=TypeInfo(i);',
  28183. '']);
  28184. ConvertProgram;
  28185. CheckSource('TestRTTI_Interface_COM',
  28186. LinesToStr([ // statements
  28187. 'rtl.recNewT($mod, "TGuid", function () {',
  28188. ' this.$eq = function (b) {',
  28189. ' return true;',
  28190. ' };',
  28191. ' this.$assign = function (s) {',
  28192. ' return this;',
  28193. ' };',
  28194. ' $mod.$rtti.$Record("TGuid", {});',
  28195. '});',
  28196. 'rtl.createInterface(',
  28197. ' $mod,',
  28198. ' "IUnknown",',
  28199. ' "{D7ADB00D-1A9B-3EDC-B123-730E661DDFA9}",',
  28200. ' ["QueryInterface", "_AddRef", "_Release"],',
  28201. ' null,',
  28202. ' function () {',
  28203. ' this.$kind = "com";',
  28204. ' var $r = this.$rtti;',
  28205. ' $r.addMethod("QueryInterface", 1, [["iid", $mod.$rtti["TGuid"], 2], ["obj", null, 4]], rtl.longint);',
  28206. ' $r.addMethod("_AddRef", 1, null, rtl.longint);',
  28207. ' $r.addMethod("_Release", 1, null, rtl.longint);',
  28208. ' }',
  28209. ');',
  28210. 'rtl.createInterface(',
  28211. ' $mod,',
  28212. ' "IBird",',
  28213. ' "{9CC77572-0E45-3594-9A88-9E8D865C9E0A}",',
  28214. ' ["GetItem", "SetItem"],',
  28215. ' $mod.IUnknown,',
  28216. ' function () {',
  28217. ' var $r = this.$rtti;',
  28218. ' $r.addMethod("GetItem", 1, null, rtl.longint);',
  28219. ' $r.addMethod("SetItem", 0, [["Value", rtl.longint]]);',
  28220. ' $r.addProperty("Item", 3, rtl.longint, "GetItem", "SetItem");',
  28221. ' }',
  28222. ');',
  28223. 'this.i = null;',
  28224. 'this.t = null;',
  28225. '']),
  28226. LinesToStr([ // $mod.$main
  28227. '$mod.t = $mod.$rtti["IBird"];',
  28228. '$mod.t = $mod.i.$rtti;',
  28229. '']));
  28230. end;
  28231. procedure TTestModule.TestRTTI_ClassHelper;
  28232. begin
  28233. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28234. StartProgram(false);
  28235. Add([
  28236. '{$interfaces com}',
  28237. '{$modeswitch externalclass}',
  28238. 'type',
  28239. ' TObject = class',
  28240. ' end;',
  28241. ' THelper = class helper for TObject',
  28242. ' published',
  28243. ' function GetItem: longint;',
  28244. ' property Item: longint read GetItem;',
  28245. ' end;',
  28246. ' TTypeInfo = class external name ''rtl.tTypeInfo'' end;',
  28247. ' TTypeInfoHelper = class external name ''rtl.tTypeInfoHelper''(TTypeInfo) end;',
  28248. 'function THelper.GetItem: longint;',
  28249. 'begin',
  28250. 'end;',
  28251. 'var',
  28252. ' t: TTypeInfoHelper;',
  28253. 'begin',
  28254. ' t:=TypeInfo(THelper);',
  28255. '']);
  28256. ConvertProgram;
  28257. CheckSource('TestRTTI_ClassHelper',
  28258. LinesToStr([ // statements
  28259. 'rtl.createClass($mod, "TObject", null, function () {',
  28260. ' this.$init = function () {',
  28261. ' };',
  28262. ' this.$final = function () {',
  28263. ' };',
  28264. '});',
  28265. 'rtl.createHelper($mod, "THelper", null, function () {',
  28266. ' this.GetItem = function () {',
  28267. ' var Result = 0;',
  28268. ' return Result;',
  28269. ' };',
  28270. ' var $r = this.$rtti;',
  28271. ' $r.addMethod("GetItem", 1, null, rtl.longint);',
  28272. ' $r.addProperty("Item", 1, rtl.longint, "GetItem", "");',
  28273. '});',
  28274. 'this.t = null;',
  28275. '']),
  28276. LinesToStr([ // $mod.$main
  28277. '$mod.t = $mod.$rtti["THelper"];',
  28278. '']));
  28279. end;
  28280. procedure TTestModule.TestResourcestringProgram;
  28281. begin
  28282. StartProgram(false);
  28283. Add([
  28284. 'const Bar = ''bar'';',
  28285. 'resourcestring',
  28286. ' Red = ''red'';',
  28287. ' Foobar = ''fOo''+bar;',
  28288. 'var s: string;',
  28289. ' c: char;',
  28290. 'begin',
  28291. ' s:=red;',
  28292. ' s:=test1.red;',
  28293. ' c:=red[1];',
  28294. ' c:=test1.red[2];',
  28295. ' if red=foobar then ;',
  28296. ' if red[3]=red[4] then ;']);
  28297. ConvertProgram;
  28298. CheckSource('TestResourcestringProgram',
  28299. LinesToStr([ // statements
  28300. 'this.Bar = "bar";',
  28301. 'this.s = "";',
  28302. 'this.c = "";',
  28303. '$mod.$resourcestrings = {',
  28304. ' Red: {',
  28305. ' org: "red"',
  28306. ' },',
  28307. ' Foobar: {',
  28308. ' org: "fOobar"',
  28309. ' }',
  28310. '};',
  28311. '']),
  28312. LinesToStr([ // $mod.$main
  28313. '$mod.s = rtl.getResStr(pas.program, "Red");',
  28314. '$mod.s = rtl.getResStr(pas.program, "Red");',
  28315. '$mod.c = rtl.getResStr(pas.program, "Red").charAt(0);',
  28316. '$mod.c = rtl.getResStr(pas.program, "Red").charAt(1);',
  28317. 'if (rtl.getResStr(pas.program, "Red") === rtl.getResStr(pas.program, "Foobar")) ;',
  28318. 'if (rtl.getResStr(pas.program, "Red").charAt(2) === rtl.getResStr(pas.program, "Red").charAt(3)) ;',
  28319. '']));
  28320. end;
  28321. procedure TTestModule.TestResourcestringUnit;
  28322. begin
  28323. StartUnit(false);
  28324. Add([
  28325. 'interface',
  28326. 'const Red = ''rEd'';',
  28327. 'resourcestring',
  28328. ' Blue = ''blue'';',
  28329. ' NotRed = ''not''+Red;',
  28330. 'var s: string;',
  28331. 'implementation',
  28332. 'resourcestring',
  28333. ' ImplGreen = ''green'';',
  28334. 'initialization',
  28335. ' s:=blue+ImplGreen;',
  28336. ' s:=test1.blue+test1.implgreen;',
  28337. ' s:=blue[1]+implgreen[2];']);
  28338. ConvertUnit;
  28339. CheckSource('TestResourcestringUnit',
  28340. LinesToStr([ // statements
  28341. 'this.Red = "rEd";',
  28342. 'this.s = "";',
  28343. '$mod.$resourcestrings = {',
  28344. ' Blue: {',
  28345. ' org: "blue"',
  28346. ' },',
  28347. ' NotRed: {',
  28348. ' org: "notrEd"',
  28349. ' },',
  28350. ' ImplGreen: {',
  28351. ' org: "green"',
  28352. ' }',
  28353. '};',
  28354. '']),
  28355. LinesToStr([ // $mod.$main
  28356. '$mod.s = rtl.getResStr(pas.Test1, "Blue") + rtl.getResStr(pas.Test1, "ImplGreen");',
  28357. '$mod.s = rtl.getResStr(pas.Test1, "Blue") + rtl.getResStr(pas.Test1, "ImplGreen");',
  28358. '$mod.s = rtl.getResStr(pas.Test1, "Blue").charAt(0) + rtl.getResStr(pas.Test1, "ImplGreen").charAt(1);',
  28359. '']));
  28360. end;
  28361. procedure TTestModule.TestResourcestringImplementation;
  28362. begin
  28363. StartUnit(false);
  28364. Add([
  28365. 'interface',
  28366. 'implementation',
  28367. 'resourcestring',
  28368. ' ImplRed = ''red'';']);
  28369. ConvertUnit;
  28370. CheckSource('TestResourcestringImplementation',
  28371. LinesToStr([ // intf statements
  28372. 'var $impl = $mod.$impl;']),
  28373. LinesToStr([ // $mod.$init
  28374. '']),
  28375. LinesToStr([ // impl statements
  28376. '$mod.$resourcestrings = {',
  28377. ' ImplRed: {',
  28378. ' org: "red"',
  28379. ' }',
  28380. '};',
  28381. '']));
  28382. end;
  28383. procedure TTestModule.TestAttributes_Members;
  28384. begin
  28385. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28386. StartProgram(false);
  28387. Add([
  28388. '{$modeswitch PrefixedAttributes}',
  28389. 'type',
  28390. ' TObject = class',
  28391. ' constructor Create;',
  28392. ' end;',
  28393. ' TCustomAttribute = class',
  28394. ' constructor Create(Id: word);',
  28395. ' end;',
  28396. ' [Missing]',
  28397. ' TBird = class',
  28398. ' published',
  28399. ' [Tcustom]',
  28400. ' FField: word;',
  28401. ' [tcustom(14)]',
  28402. ' property Size: word read FField;',
  28403. ' [Tcustom(15)]',
  28404. ' procedure Fly; virtual; abstract;',
  28405. ' end;',
  28406. ' TRec = record',
  28407. ' [Tcustom,tcustom(14)]',
  28408. ' Size: word;',
  28409. ' end;',
  28410. 'constructor TObject.Create; begin end;',
  28411. 'constructor TCustomAttribute.Create(Id: word); begin end;',
  28412. 'begin',
  28413. '']);
  28414. ConvertProgram;
  28415. CheckSource('TestAttributes_Members',
  28416. LinesToStr([ // statements
  28417. 'rtl.createClass($mod, "TObject", null, function () {',
  28418. ' this.$init = function () {',
  28419. ' };',
  28420. ' this.$final = function () {',
  28421. ' };',
  28422. ' this.Create = function () {',
  28423. ' return this;',
  28424. ' };',
  28425. '});',
  28426. 'rtl.createClass($mod, "TCustomAttribute", $mod.TObject, function () {',
  28427. ' this.Create$1 = function (Id) {',
  28428. ' return this;',
  28429. ' };',
  28430. '});',
  28431. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  28432. ' this.$init = function () {',
  28433. ' $mod.TObject.$init.call(this);',
  28434. ' this.FField = 0;',
  28435. ' };',
  28436. ' var $r = this.$rtti;',
  28437. ' $r.addField("FField", rtl.word, {',
  28438. ' attr: [$mod.TCustomAttribute, "Create"]',
  28439. ' });',
  28440. ' $r.addProperty(',
  28441. ' "Size",',
  28442. ' 0,',
  28443. ' rtl.word,',
  28444. ' "FField",',
  28445. ' "",',
  28446. ' {',
  28447. ' attr: [$mod.TCustomAttribute, "Create$1", [14]]',
  28448. ' }',
  28449. ' );',
  28450. ' $r.addMethod("Fly", 0, null, null, {',
  28451. ' attr: [$mod.TCustomAttribute, "Create$1", [15]]',
  28452. ' });',
  28453. '});',
  28454. 'rtl.recNewT($mod, "TRec", function () {',
  28455. ' this.Size = 0;',
  28456. ' this.$eq = function (b) {',
  28457. ' return this.Size === b.Size;',
  28458. ' };',
  28459. ' this.$assign = function (s) {',
  28460. ' this.Size = s.Size;',
  28461. ' return this;',
  28462. ' };',
  28463. ' var $r = $mod.$rtti.$Record("TRec", {});',
  28464. ' $r.addField("Size", rtl.word, {',
  28465. ' attr: [',
  28466. ' $mod.TCustomAttribute,',
  28467. ' "Create",',
  28468. ' $mod.TCustomAttribute,',
  28469. ' "Create$1",',
  28470. ' [14]',
  28471. ' ]',
  28472. ' });',
  28473. '});',
  28474. '']),
  28475. LinesToStr([ // $mod.$main
  28476. '']));
  28477. end;
  28478. procedure TTestModule.TestAttributes_Types;
  28479. begin
  28480. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28481. StartProgram(false);
  28482. Add([
  28483. '{$modeswitch PrefixedAttributes}',
  28484. 'type',
  28485. ' TObject = class',
  28486. ' constructor Create(Id: word);',
  28487. ' end;',
  28488. ' TCustomAttribute = class',
  28489. ' end;',
  28490. ' [TCustom(1)]',
  28491. ' TMyClass = class',
  28492. ' end;',
  28493. ' [TCustom(2)]',
  28494. ' TRec = record',
  28495. ' end;',
  28496. ' [TCustom(3)]',
  28497. ' TInt = type word;',
  28498. 'constructor TObject.Create(Id: word);',
  28499. 'begin',
  28500. 'end;',
  28501. 'var p: pointer;',
  28502. 'begin',
  28503. ' p:=typeinfo(TMyClass);',
  28504. ' p:=typeinfo(TRec);',
  28505. ' p:=typeinfo(TInt);',
  28506. '']);
  28507. ConvertProgram;
  28508. CheckSource('TestAttributes_Types',
  28509. LinesToStr([ // statements
  28510. 'rtl.createClass($mod, "TObject", null, function () {',
  28511. ' this.$init = function () {',
  28512. ' };',
  28513. ' this.$final = function () {',
  28514. ' };',
  28515. ' this.Create = function (Id) {',
  28516. ' return this;',
  28517. ' };',
  28518. '});',
  28519. 'rtl.createClass($mod, "TCustomAttribute", $mod.TObject, function () {',
  28520. '});',
  28521. 'rtl.createClass($mod, "TMyClass", $mod.TObject, function () {',
  28522. ' var $r = this.$rtti;',
  28523. ' $r.attr = [$mod.TCustomAttribute, "Create", [1]];',
  28524. '});',
  28525. 'rtl.recNewT($mod, "TRec", function () {',
  28526. ' this.$eq = function (b) {',
  28527. ' return true;',
  28528. ' };',
  28529. ' this.$assign = function (s) {',
  28530. ' return this;',
  28531. ' };',
  28532. ' $mod.$rtti.$Record("TRec", {',
  28533. ' attr: [$mod.TCustomAttribute, "Create", [2]]',
  28534. ' });',
  28535. '});',
  28536. '$mod.$rtti.$inherited("TInt", rtl.word, {',
  28537. ' attr: [$mod.TCustomAttribute, "Create", [3]]',
  28538. '});',
  28539. 'this.p = null;',
  28540. '']),
  28541. LinesToStr([ // $mod.$main
  28542. '$mod.p = $mod.$rtti["TMyClass"];',
  28543. '$mod.p = $mod.$rtti["TRec"];',
  28544. '$mod.p = $mod.$rtti["TInt"];',
  28545. '']));
  28546. end;
  28547. procedure TTestModule.TestAttributes_HelperConstructor_Fail;
  28548. begin
  28549. Converter.Options:=Converter.Options-[coNoTypeInfo];
  28550. StartProgram(false);
  28551. Add([
  28552. '{$modeswitch PrefixedAttributes}',
  28553. 'type',
  28554. ' TObject = class',
  28555. ' constructor Create;',
  28556. ' end;',
  28557. ' TCustomAttribute = class',
  28558. ' end;',
  28559. ' THelper = class helper for TCustomAttribute',
  28560. ' constructor Create(Id: word);',
  28561. ' end;',
  28562. ' [TCustom(3)]',
  28563. ' TMyInt = word;',
  28564. 'constructor TObject.Create; begin end;',
  28565. 'constructor THelper.Create(Id: word); begin end;',
  28566. 'begin',
  28567. ' if typeinfo(TMyInt)=nil then ;']);
  28568. //SetExpectedConverterError('aaa',123);
  28569. ConvertProgram;
  28570. end;
  28571. procedure TTestModule.TestAssert;
  28572. begin
  28573. StartProgram(false);
  28574. Add([
  28575. 'procedure DoIt;',
  28576. 'var',
  28577. ' b: boolean;',
  28578. ' s: string;',
  28579. 'begin',
  28580. ' {$Assertions on}',
  28581. ' Assert(b);',
  28582. 'end;',
  28583. 'begin',
  28584. ' DoIt;',
  28585. '']);
  28586. ConvertProgram;
  28587. CheckSource('TestAssert',
  28588. LinesToStr([ // statements
  28589. 'this.DoIt = function () {',
  28590. ' var b = false;',
  28591. ' var s = "";',
  28592. ' if (!b) throw "assert failed";',
  28593. '};',
  28594. '']),
  28595. LinesToStr([ // $mod.$main
  28596. '$mod.DoIt();',
  28597. '']));
  28598. end;
  28599. procedure TTestModule.TestAssert_SysUtils;
  28600. begin
  28601. AddModuleWithIntfImplSrc('SysUtils.pas',
  28602. LinesToStr([
  28603. 'type',
  28604. ' TObject = class',
  28605. ' constructor Create;',
  28606. ' end;',
  28607. ' EAssertionFailed = class',
  28608. ' constructor Create(s: string);',
  28609. ' end;',
  28610. '']),
  28611. LinesToStr([
  28612. 'constructor TObject.Create;',
  28613. 'begin end;',
  28614. 'constructor EAssertionFailed.Create(s: string);',
  28615. 'begin end;',
  28616. '']) );
  28617. StartProgram(true);
  28618. Add([
  28619. 'uses sysutils;',
  28620. 'procedure DoIt;',
  28621. 'var',
  28622. ' b: boolean;',
  28623. ' s: string;',
  28624. 'begin',
  28625. ' {$Assertions on}',
  28626. ' Assert(b);',
  28627. ' Assert(b,''msg'');',
  28628. 'end;',
  28629. 'begin',
  28630. ' DoIt;',
  28631. '']);
  28632. ConvertProgram;
  28633. CheckSource('TestAssert_SysUtils',
  28634. LinesToStr([ // statements
  28635. 'this.DoIt = function () {',
  28636. ' var b = false;',
  28637. ' var s = "";',
  28638. ' if (!b) throw pas.SysUtils.EAssertionFailed.$create("Create");',
  28639. ' if (!b) throw pas.SysUtils.EAssertionFailed.$create("Create$1", ["msg"]);',
  28640. '};',
  28641. '']),
  28642. LinesToStr([ // $mod.$main
  28643. '$mod.DoIt();',
  28644. '']));
  28645. end;
  28646. procedure TTestModule.TestObjectChecks;
  28647. begin
  28648. Scanner.CurrentBoolSwitches:=Scanner.CurrentBoolSwitches+[bsObjectChecks];
  28649. StartProgram(false);
  28650. Add([
  28651. 'type',
  28652. ' TObject = class',
  28653. ' procedure DoIt;',
  28654. ' end;',
  28655. ' TClass = class of tobject;',
  28656. ' TBird = class',
  28657. ' end;',
  28658. ' TBirdClass = class of TBird;',
  28659. 'var',
  28660. ' o : TObject;',
  28661. ' c: TClass;',
  28662. ' b: TBird;',
  28663. ' bc: TBirdClass;',
  28664. 'procedure TObject.DoIt;',
  28665. 'begin',
  28666. ' b:=TBird(o);',
  28667. 'end;',
  28668. 'begin',
  28669. ' o.DoIt;',
  28670. ' b:=TBird(o);',
  28671. ' bc:=TBirdClass(c);',
  28672. '']);
  28673. ConvertProgram;
  28674. CheckSource('TestCheckMethodCall',
  28675. LinesToStr([ // statements
  28676. 'rtl.createClass($mod, "TObject", null, function () {',
  28677. ' this.$init = function () {',
  28678. ' };',
  28679. ' this.$final = function () {',
  28680. ' };',
  28681. ' this.DoIt = function () {',
  28682. ' rtl.checkMethodCall(this,$mod.TObject);',
  28683. ' $mod.b = rtl.asExt($mod.o, $mod.TBird, 1);',
  28684. ' };',
  28685. '});',
  28686. 'rtl.createClass($mod, "TBird", $mod.TObject, function () {',
  28687. '});',
  28688. 'this.o = null;',
  28689. 'this.c = null;',
  28690. 'this.b = null;',
  28691. 'this.bc = null;',
  28692. '']),
  28693. LinesToStr([ // $mod.$main
  28694. '$mod.o.DoIt();',
  28695. '$mod.b = rtl.asExt($mod.o,$mod.TBird, 1);',
  28696. '$mod.bc = rtl.asExt($mod.c, $mod.TBird, 2);',
  28697. '']));
  28698. end;
  28699. procedure TTestModule.TestOverflowChecks_Int;
  28700. begin
  28701. Scanner.CurrentBoolSwitches:=Scanner.CurrentBoolSwitches+[bsOverflowChecks];
  28702. StartProgram(false);
  28703. Add([
  28704. 'procedure DoIt;',
  28705. 'var',
  28706. ' b: byte;',
  28707. ' n: nativeint;',
  28708. ' u: nativeuint;',
  28709. ' c: currency;',
  28710. 'begin',
  28711. ' n:=n+n;',
  28712. ' n:=n-n;',
  28713. ' n:=n+b;',
  28714. ' n:=b-n;',
  28715. ' n:=n*n;',
  28716. ' n:=n*u;',
  28717. ' c:=c+b;',
  28718. ' c:=b+c;',
  28719. ' c:=c*b;',
  28720. ' c:=b*c;',
  28721. 'end;',
  28722. 'begin',
  28723. '']);
  28724. ConvertProgram;
  28725. CheckSource('TestOverflowChecks_Int',
  28726. LinesToStr([ // statements
  28727. 'this.DoIt = function () {',
  28728. ' var b = 0;',
  28729. ' var n = 0;',
  28730. ' var u = 0;',
  28731. ' var c = 0;',
  28732. ' n = rtl.oc(n + n);',
  28733. ' n = rtl.oc(n - n);',
  28734. ' n = rtl.oc(n + b);',
  28735. ' n = rtl.oc(b - n);',
  28736. ' n = rtl.oc(n * n);',
  28737. ' n = rtl.oc(n * u);',
  28738. ' c = rtl.oc(c + (b * 10000));',
  28739. ' c = rtl.oc((b * 10000) + c);',
  28740. ' c = rtl.oc(c * b);',
  28741. ' c = rtl.oc(b * c);',
  28742. '};',
  28743. '']),
  28744. LinesToStr([ // $mod.$main
  28745. '']));
  28746. end;
  28747. procedure TTestModule.TestRangeChecks_AssignInt;
  28748. begin
  28749. Scanner.Options:=Scanner.Options+[po_CAssignments];
  28750. StartProgram(false);
  28751. Add([
  28752. '{$R+}',
  28753. 'var',
  28754. ' b: byte = 2;',
  28755. ' w: word = 3;',
  28756. 'procedure DoIt(p: byte);',
  28757. 'begin',
  28758. ' b:=w;',
  28759. ' b+=w;',
  28760. ' b:=1;',
  28761. 'end;',
  28762. '{$R-}',
  28763. 'procedure DoSome;',
  28764. 'begin',
  28765. ' DoIt(w);',
  28766. ' b:=w;',
  28767. ' b:=2;',
  28768. 'end;',
  28769. 'begin',
  28770. '{$R+}',
  28771. '']);
  28772. ConvertProgram;
  28773. CheckSource('TestRangeChecks_AssignInt',
  28774. LinesToStr([ // statements
  28775. 'this.b = 2;',
  28776. 'this.w = 3;',
  28777. 'this.DoIt = function (p) {',
  28778. ' rtl.rc(p, 0, 255);',
  28779. ' $mod.b = rtl.rc($mod.w,0,255);',
  28780. ' rtl.rc($mod.b += $mod.w, 0, 255);',
  28781. ' $mod.b = 1;',
  28782. '};',
  28783. 'this.DoSome = function () {',
  28784. ' $mod.DoIt($mod.w);',
  28785. ' $mod.b = $mod.w;',
  28786. ' $mod.b = 2;',
  28787. '};',
  28788. '']),
  28789. LinesToStr([ // $mod.$main
  28790. '']));
  28791. end;
  28792. procedure TTestModule.TestRangeChecks_AssignIntRange;
  28793. begin
  28794. Scanner.Options:=Scanner.Options+[po_CAssignments];
  28795. StartProgram(false);
  28796. Add([
  28797. '{$R+}',
  28798. 'type Ten = 1..10;',
  28799. 'var',
  28800. ' b: Ten = 2;',
  28801. ' w: Ten = 3;',
  28802. 'procedure DoIt(p: Ten);',
  28803. 'begin',
  28804. ' b:=w;',
  28805. ' b+=w;',
  28806. ' b:=1;',
  28807. 'end;',
  28808. '{$R-}',
  28809. 'procedure DoSome;',
  28810. 'begin',
  28811. ' DoIt(w);',
  28812. ' b:=w;',
  28813. ' b:=2;',
  28814. 'end;',
  28815. 'begin',
  28816. '{$R+}',
  28817. '']);
  28818. ConvertProgram;
  28819. CheckSource('TestRangeChecks_AssignIntRange',
  28820. LinesToStr([ // statements
  28821. 'this.b = 2;',
  28822. 'this.w = 3;',
  28823. 'this.DoIt = function (p) {',
  28824. ' rtl.rc(p, 1, 10);',
  28825. ' $mod.b = rtl.rc($mod.w, 1, 10);',
  28826. ' rtl.rc($mod.b += $mod.w, 1, 10);',
  28827. ' $mod.b = 1;',
  28828. '};',
  28829. 'this.DoSome = function () {',
  28830. ' $mod.DoIt($mod.w);',
  28831. ' $mod.b = $mod.w;',
  28832. ' $mod.b = 2;',
  28833. '};',
  28834. '']),
  28835. LinesToStr([ // $mod.$main
  28836. '']));
  28837. end;
  28838. procedure TTestModule.TestRangeChecks_AssignEnum;
  28839. begin
  28840. StartProgram(false);
  28841. Add([
  28842. '{$R+}',
  28843. 'type TEnum = (red,green);',
  28844. 'var',
  28845. ' e: TEnum = red;',
  28846. 'procedure DoIt(p: TEnum);',
  28847. 'begin',
  28848. ' e:=p;',
  28849. ' p:=TEnum(0);',
  28850. ' p:=succ(e);',
  28851. 'end;',
  28852. '{$R-}',
  28853. 'procedure DoSome;',
  28854. 'begin',
  28855. ' DoIt(e);',
  28856. ' e:=TEnum(1);',
  28857. ' e:=pred(e);',
  28858. 'end;',
  28859. 'begin',
  28860. '{$R+}',
  28861. '']);
  28862. ConvertProgram;
  28863. CheckSource('TestRangeChecks_AssignEnum',
  28864. LinesToStr([ // statements
  28865. 'this.TEnum = {',
  28866. ' "0": "red",',
  28867. ' red: 0,',
  28868. ' "1": "green",',
  28869. ' green: 1',
  28870. '};',
  28871. 'this.e = $mod.TEnum.red;',
  28872. 'this.DoIt = function (p) {',
  28873. ' rtl.rc(p, 0, 1);',
  28874. ' $mod.e = rtl.rc(p, 0, 1);',
  28875. ' p = 0;',
  28876. ' p = rtl.rc($mod.e + 1, 0, 1);',
  28877. '};',
  28878. 'this.DoSome = function () {',
  28879. ' $mod.DoIt($mod.e);',
  28880. ' $mod.e = 1;',
  28881. ' $mod.e = $mod.e - 1;',
  28882. '};',
  28883. '']),
  28884. LinesToStr([ // $mod.$main
  28885. '']));
  28886. end;
  28887. procedure TTestModule.TestRangeChecks_AssignEnumRange;
  28888. begin
  28889. StartProgram(false);
  28890. Add([
  28891. '{$R+}',
  28892. 'type',
  28893. ' TEnum = (red,green);',
  28894. ' TEnumRg = red..green;',
  28895. 'var',
  28896. ' e: TEnumRg = red;',
  28897. 'procedure DoIt(p: TEnumRg);',
  28898. 'begin',
  28899. ' e:=p;',
  28900. ' p:=TEnumRg(0);',
  28901. ' p:=succ(e);',
  28902. 'end;',
  28903. '{$R-}',
  28904. 'procedure DoSome;',
  28905. 'begin',
  28906. ' DoIt(e);',
  28907. ' e:=TEnum(1);',
  28908. ' e:=pred(e);',
  28909. 'end;',
  28910. 'begin',
  28911. '{$R+}',
  28912. '']);
  28913. ConvertProgram;
  28914. CheckSource('TestRangeChecks_AssignEnumRange',
  28915. LinesToStr([ // statements
  28916. 'this.TEnum = {',
  28917. ' "0": "red",',
  28918. ' red: 0,',
  28919. ' "1": "green",',
  28920. ' green: 1',
  28921. '};',
  28922. 'this.e = $mod.TEnum.red;',
  28923. 'this.DoIt = function (p) {',
  28924. ' rtl.rc(p, 0, 1);',
  28925. ' $mod.e = rtl.rc(p, 0, 1);',
  28926. ' p = 0;',
  28927. ' p = rtl.rc($mod.e + 1, 0, 1);',
  28928. '};',
  28929. 'this.DoSome = function () {',
  28930. ' $mod.DoIt($mod.e);',
  28931. ' $mod.e = 1;',
  28932. ' $mod.e = $mod.e - 1;',
  28933. '};',
  28934. '']),
  28935. LinesToStr([ // $mod.$main
  28936. '']));
  28937. end;
  28938. procedure TTestModule.TestRangeChecks_AssignChar;
  28939. begin
  28940. StartProgram(false);
  28941. Add([
  28942. '{$R+}',
  28943. 'type',
  28944. ' TLetter = char;',
  28945. 'var',
  28946. ' b: TLetter = ''2'';',
  28947. ' w: TLetter = ''3'';',
  28948. 'procedure DoIt(p: TLetter);',
  28949. 'begin',
  28950. ' b:=w;',
  28951. ' b:=''1'';',
  28952. 'end;',
  28953. '{$R-}',
  28954. 'procedure DoSome;',
  28955. 'begin',
  28956. ' DoIt(w);',
  28957. ' b:=w;',
  28958. ' b:=''2'';',
  28959. 'end;',
  28960. 'begin',
  28961. '{$R+}',
  28962. '']);
  28963. ConvertProgram;
  28964. CheckSource('TestRangeChecks_AssignChar',
  28965. LinesToStr([ // statements
  28966. 'this.b = "2";',
  28967. 'this.w = "3";',
  28968. 'this.DoIt = function (p) {',
  28969. ' rtl.rcc(p, 0, 65535);',
  28970. ' $mod.b = rtl.rcc($mod.w, 0, 65535);',
  28971. ' $mod.b = "1";',
  28972. '};',
  28973. 'this.DoSome = function () {',
  28974. ' $mod.DoIt($mod.w);',
  28975. ' $mod.b = $mod.w;',
  28976. ' $mod.b = "2";',
  28977. '};',
  28978. '']),
  28979. LinesToStr([ // $mod.$main
  28980. '']));
  28981. end;
  28982. procedure TTestModule.TestRangeChecks_AssignCharRange;
  28983. begin
  28984. StartProgram(false);
  28985. Add([
  28986. '{$R+}',
  28987. 'type TDigit = ''0''..''9'';',
  28988. 'var',
  28989. ' b: TDigit = ''2'';',
  28990. ' w: TDigit = ''3'';',
  28991. 'procedure DoIt(p: TDigit);',
  28992. 'begin',
  28993. ' b:=w;',
  28994. ' b:=''1'';',
  28995. 'end;',
  28996. '{$R-}',
  28997. 'procedure DoSome;',
  28998. 'begin',
  28999. ' DoIt(w);',
  29000. ' b:=w;',
  29001. ' b:=''2'';',
  29002. 'end;',
  29003. 'begin',
  29004. '{$R+}',
  29005. '']);
  29006. ConvertProgram;
  29007. CheckSource('TestRangeChecks_AssignCharRange',
  29008. LinesToStr([ // statements
  29009. 'this.b = "2";',
  29010. 'this.w = "3";',
  29011. 'this.DoIt = function (p) {',
  29012. ' rtl.rcc(p, 48, 57);',
  29013. ' $mod.b = rtl.rcc($mod.w, 48, 57);',
  29014. ' $mod.b = "1";',
  29015. '};',
  29016. 'this.DoSome = function () {',
  29017. ' $mod.DoIt($mod.w);',
  29018. ' $mod.b = $mod.w;',
  29019. ' $mod.b = "2";',
  29020. '};',
  29021. '']),
  29022. LinesToStr([ // $mod.$main
  29023. '']));
  29024. end;
  29025. procedure TTestModule.TestRangeChecks_ArrayIndex;
  29026. begin
  29027. StartProgram(false);
  29028. Add([
  29029. '{$R+}',
  29030. 'type',
  29031. ' Ten = 1..10;',
  29032. ' TArr = array of Ten;',
  29033. ' TArrArr = array of TArr;',
  29034. ' TArrByte = array[byte] of Ten;',
  29035. ' TArrChar = array[''0''..''9''] of Ten;',
  29036. ' TArrByteChar = array[byte,''0''..''9''] of Ten;',
  29037. ' TObject = class',
  29038. ' A: TArr;',
  29039. ' end;',
  29040. 'procedure DoIt;',
  29041. 'var',
  29042. ' Arr: TArr;',
  29043. ' ArrArr: TArrArr;',
  29044. ' ArrByte: TArrByte;',
  29045. ' ArrChar: TArrChar;',
  29046. ' ArrByteChar: TArrByteChar;',
  29047. ' i: Ten;',
  29048. ' c: char;',
  29049. ' o: tobject;',
  29050. 'begin',
  29051. ' i:=Arr[1];',
  29052. ' i:=ArrByteChar[1,''2''];',
  29053. ' Arr[1]:=Arr[1];',
  29054. ' Arr[i]:=Arr[i];',
  29055. ' ArrByte[3]:=ArrByte[3];',
  29056. ' ArrByte[i]:=ArrByte[i];',
  29057. ' ArrChar[''5'']:=ArrChar[''5''];',
  29058. ' ArrChar[c]:=ArrChar[c];',
  29059. ' ArrByteChar[7,''7'']:=ArrByteChar[7,''7''];',
  29060. ' ArrByteChar[i,c]:=ArrByteChar[i,c];',
  29061. ' o.a[i]:=o.a[i];',
  29062. 'end;',
  29063. 'begin',
  29064. '']);
  29065. ConvertProgram;
  29066. CheckSource('TestRangeChecks_ArrayIndex',
  29067. LinesToStr([ // statements
  29068. 'rtl.createClass($mod, "TObject", null, function () {',
  29069. ' this.$init = function () {',
  29070. ' this.A = [];',
  29071. ' };',
  29072. ' this.$final = function () {',
  29073. ' this.A = undefined;',
  29074. ' };',
  29075. '});',
  29076. 'this.DoIt = function () {',
  29077. ' var Arr = [];',
  29078. ' var ArrArr = [];',
  29079. ' var ArrByte = rtl.arraySetLength(null, 0, 256);',
  29080. ' var ArrChar = rtl.arraySetLength(null, 0, 10);',
  29081. ' var ArrByteChar = rtl.arraySetLength(null, 0, 256, 10);',
  29082. ' var i = 0;',
  29083. ' var c = "";',
  29084. ' var o = null;',
  29085. ' i = rtl.rc(Arr[1], 1, 10);',
  29086. ' i = rtl.rc(ArrByteChar[1][2], 1, 10);',
  29087. ' Arr[1] = rtl.rc(Arr[1], 1, 10);',
  29088. ' rtl.rcArrW(Arr, i, rtl.rcArrR(Arr, i));',
  29089. ' ArrByte[3] = rtl.rc(ArrByte[3], 1, 10);',
  29090. ' rtl.rcArrW(ArrByte, i, rtl.rcArrR(ArrByte, i));',
  29091. ' ArrChar[5] = rtl.rc(ArrChar[5], 1, 10);',
  29092. ' rtl.rcArrW(ArrChar, c.charCodeAt() - 48, rtl.rcArrR(ArrChar, c.charCodeAt() - 48));',
  29093. ' ArrByteChar[7][7] = rtl.rc(ArrByteChar[7][7], 1, 10);',
  29094. ' rtl.rcArrW(ArrByteChar, i, c.charCodeAt() - 48, rtl.rcArrR(ArrByteChar, i, c.charCodeAt() - 48));',
  29095. ' rtl.rcArrW(o.A, i, rtl.rcArrR(o.A, i));',
  29096. '};',
  29097. '']),
  29098. LinesToStr([ // $mod.$main
  29099. '']));
  29100. end;
  29101. procedure TTestModule.TestRangeChecks_ArrayOfRecIndex;
  29102. begin
  29103. StartProgram(false);
  29104. Add([
  29105. '{$R+}',
  29106. 'type',
  29107. ' Ten = 1..10;',
  29108. ' TRec = record x: Ten end;',
  29109. ' TArr = array of TRec;',
  29110. ' TArrArr = array of TArr;',
  29111. ' TObject = class',
  29112. ' A: TArr;',
  29113. ' end;',
  29114. 'procedure DoIt;',
  29115. 'var',
  29116. ' Arr: TArr;',
  29117. ' ArrArr: TArrArr;',
  29118. ' i: Ten;',
  29119. ' o: tobject;',
  29120. 'begin',
  29121. ' Arr[1]:=Arr[1];',
  29122. ' Arr[i]:=Arr[i+1];',
  29123. ' o.a[i]:=o.a[i+2];',
  29124. 'end;',
  29125. 'begin',
  29126. '']);
  29127. ConvertProgram;
  29128. CheckSource('TestRangeChecks_ArrayOfRecIndex',
  29129. LinesToStr([ // statements
  29130. 'rtl.recNewT($mod, "TRec", function () {',
  29131. ' this.x = 0;',
  29132. ' this.$eq = function (b) {',
  29133. ' return this.x === b.x;',
  29134. ' };',
  29135. ' this.$assign = function (s) {',
  29136. ' this.x = s.x;',
  29137. ' return this;',
  29138. ' };',
  29139. '});',
  29140. 'rtl.createClass($mod, "TObject", null, function () {',
  29141. ' this.$init = function () {',
  29142. ' this.A = [];',
  29143. ' };',
  29144. ' this.$final = function () {',
  29145. ' this.A = undefined;',
  29146. ' };',
  29147. '});',
  29148. 'this.DoIt = function () {',
  29149. ' var Arr = [];',
  29150. ' var ArrArr = [];',
  29151. ' var i = 0;',
  29152. ' var o = null;',
  29153. ' Arr[1].$assign(Arr[1]);',
  29154. ' rtl.rcArrR(Arr, i).$assign(rtl.rcArrR(Arr, i + 1));',
  29155. ' rtl.rcArrR(o.A, i).$assign(rtl.rcArrR(o.A, i + 2));',
  29156. '};',
  29157. '']),
  29158. LinesToStr([ // $mod.$main
  29159. '']));
  29160. end;
  29161. procedure TTestModule.TestRangeChecks_StringIndex;
  29162. begin
  29163. StartProgram(false);
  29164. Add([
  29165. 'type',
  29166. ' TObject = class',
  29167. ' S: string;',
  29168. ' end;',
  29169. '{$R+}',
  29170. 'procedure DoIt(var h: string);',
  29171. 'var',
  29172. ' s: string;',
  29173. ' i: longint;',
  29174. ' c: char;',
  29175. ' o: tobject;',
  29176. 'begin',
  29177. ' c:=s[1];',
  29178. ' s[i]:=s[i];',
  29179. ' h[i]:=h[i];',
  29180. ' c:=o.s[i];',
  29181. ' o.s[i]:=c;',
  29182. 'end;',
  29183. 'begin',
  29184. '']);
  29185. ConvertProgram;
  29186. CheckSource('TestRangeChecks_StringIndex',
  29187. LinesToStr([ // statements
  29188. 'rtl.createClass($mod, "TObject", null, function () {',
  29189. ' this.$init = function () {',
  29190. ' this.S = "";',
  29191. ' };',
  29192. ' this.$final = function () {',
  29193. ' };',
  29194. '});',
  29195. 'this.DoIt = function (h) {',
  29196. ' var s = "";',
  29197. ' var i = 0;',
  29198. ' var c = "";',
  29199. ' var o = null;',
  29200. ' c = rtl.rcc(rtl.rcCharAt(s, 0), 0, 65535);',
  29201. ' s = rtl.rcSetCharAt(s, i - 1, rtl.rcCharAt(s, i - 1));',
  29202. ' h.set(rtl.rcSetCharAt(h.get(), i - 1, rtl.rcCharAt(h.get(), i - 1)));',
  29203. ' c = rtl.rcc(rtl.rcCharAt(o.S, i - 1), 0, 65535);',
  29204. ' o.S = rtl.rcSetCharAt(o.S, i - 1, c);',
  29205. '};',
  29206. '']),
  29207. LinesToStr([ // $mod.$main
  29208. '']));
  29209. end;
  29210. procedure TTestModule.TestRangeChecks_TypecastInt;
  29211. begin
  29212. StartProgram(false);
  29213. Add([
  29214. '{$R+}',
  29215. 'var',
  29216. ' i: nativeint;',
  29217. ' b: byte;',
  29218. ' sh: shortint;',
  29219. ' w: word;',
  29220. ' sm: smallint;',
  29221. ' lw: longword;',
  29222. ' li: longint;',
  29223. 'begin',
  29224. ' b:=12+byte(i);',
  29225. ' sh:=12+shortint(i);',
  29226. ' w:=12+word(i);',
  29227. ' sm:=12+smallint(i);',
  29228. ' lw:=12+longword(i);',
  29229. ' li:=12+longint(i);',
  29230. '']);
  29231. ConvertProgram;
  29232. CheckSource('TestRangeChecks_TypecastInt',
  29233. LinesToStr([
  29234. 'this.i = 0;',
  29235. 'this.b = 0;',
  29236. 'this.sh = 0;',
  29237. 'this.w = 0;',
  29238. 'this.sm = 0;',
  29239. 'this.lw = 0;',
  29240. 'this.li = 0;',
  29241. '']),
  29242. LinesToStr([
  29243. '$mod.b = rtl.rc(12 + rtl.rc($mod.i, 0, 255), 0, 255);',
  29244. '$mod.sh = rtl.rc(12 + rtl.rc($mod.i, -128, 127), -128, 127);',
  29245. '$mod.w = rtl.rc(12 + rtl.rc($mod.i, 0, 65535), 0, 65535);',
  29246. '$mod.sm = rtl.rc(12 + rtl.rc($mod.i, -32768, 32767), -32768, 32767);',
  29247. '$mod.lw = rtl.rc(12 + rtl.rc($mod.i, 0, 4294967295), 0, 4294967295);',
  29248. '$mod.li = rtl.rc(12 + rtl.rc($mod.i, -2147483648, 2147483647), -2147483648, 2147483647);',
  29249. '']));
  29250. end;
  29251. procedure TTestModule.TestRangeChecks_TypeHelperInt;
  29252. begin
  29253. Scanner.Options:=Scanner.Options+[po_CAssignments];
  29254. StartProgram(false);
  29255. Add([
  29256. '{$modeswitch typehelpers}',
  29257. '{$R+}',
  29258. 'type',
  29259. ' TObject = class',
  29260. ' FSize: byte;',
  29261. ' property Size: byte read FSize;',
  29262. ' end;',
  29263. ' THelper = type helper for byte',
  29264. ' procedure SetIt(w: word);',
  29265. ' end;',
  29266. 'procedure THelper.SetIt(w: word);',
  29267. 'begin',
  29268. ' Self:=w;',
  29269. 'end;',
  29270. 'function GetIt: byte;',
  29271. 'begin',
  29272. ' Result.SetIt(2);',
  29273. 'end;',
  29274. 'var',
  29275. ' b: byte = 3;',
  29276. ' o: TObject;',
  29277. 'begin',
  29278. ' b.SetIt(14);',
  29279. ' with b do SetIt(15);',
  29280. ' o.Size.SetIt(16);',
  29281. '']);
  29282. ConvertProgram;
  29283. CheckSource('TestRangeChecks_AssignInt',
  29284. LinesToStr([ // statements
  29285. 'rtl.createClass($mod, "TObject", null, function () {',
  29286. ' this.$init = function () {',
  29287. ' this.FSize = 0;',
  29288. ' };',
  29289. ' this.$final = function () {',
  29290. ' };',
  29291. '});',
  29292. 'rtl.createHelper($mod, "THelper", null, function () {',
  29293. ' this.SetIt = function (w) {',
  29294. ' rtl.rc(w, 0, 65535);',
  29295. ' this.set(w);',
  29296. ' };',
  29297. '});',
  29298. 'this.GetIt = function () {',
  29299. ' var Result = 0;',
  29300. ' $mod.THelper.SetIt.call({',
  29301. ' get: function () {',
  29302. ' return Result;',
  29303. ' },',
  29304. ' set: function (v) {',
  29305. ' rtl.rc(v, 0, 255);',
  29306. ' Result = v;',
  29307. ' }',
  29308. ' }, 2);',
  29309. ' return Result;',
  29310. '};',
  29311. 'this.b = 3;',
  29312. 'this.o = null;',
  29313. '']),
  29314. LinesToStr([ // $mod.$main
  29315. '$mod.THelper.SetIt.call({',
  29316. ' p: $mod,',
  29317. ' get: function () {',
  29318. ' return this.p.b;',
  29319. ' },',
  29320. ' set: function (v) {',
  29321. ' rtl.rc(v, 0, 255);',
  29322. ' this.p.b = v;',
  29323. ' }',
  29324. '}, 14);',
  29325. 'var $with1 = $mod.b;',
  29326. '$mod.THelper.SetIt.call({',
  29327. ' get: function () {',
  29328. ' return $with1;',
  29329. ' },',
  29330. ' set: function (v) {',
  29331. ' rtl.rc(v, 0, 255);',
  29332. ' $with1 = v;',
  29333. ' }',
  29334. '}, 15);',
  29335. '$mod.THelper.SetIt.call({',
  29336. ' p: $mod.o,',
  29337. ' get: function () {',
  29338. ' return this.p.FSize;',
  29339. ' },',
  29340. ' set: function (v) {',
  29341. ' rtl.rc(v, 0, 255);',
  29342. ' this.p.FSize = v;',
  29343. ' }',
  29344. '}, 16);',
  29345. '']));
  29346. end;
  29347. Initialization
  29348. RegisterTests([TTestModule]);
  29349. end.