2
0

tcmodules.pas 250 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2014 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, fppas2js,
  20. pastree, PScanner, PasResolver, PParser, jstree, jswriter, jsbase;
  21. const
  22. po_pas2js = [po_asmwhole,po_resolvestandardtypes];
  23. type
  24. { TTestPasParser }
  25. TTestPasParser = Class(TPasParser)
  26. end;
  27. TOnFindUnit = function(const aUnitName: String): TPasModule of object;
  28. { TTestEnginePasResolver }
  29. TTestEnginePasResolver = class(TPas2JsResolver)
  30. private
  31. FFilename: string;
  32. FModule: TPasModule;
  33. FOnFindUnit: TOnFindUnit;
  34. FParser: TTestPasParser;
  35. FResolver: TStreamResolver;
  36. FScanner: TPascalScanner;
  37. FSource: string;
  38. procedure SetModule(AValue: TPasModule);
  39. public
  40. destructor Destroy; override;
  41. function FindModule(const AName: String): TPasModule; override;
  42. property OnFindUnit: TOnFindUnit read FOnFindUnit write FOnFindUnit;
  43. property Filename: string read FFilename write FFilename;
  44. property Resolver: TStreamResolver read FResolver write FResolver;
  45. property Scanner: TPascalScanner read FScanner write FScanner;
  46. property Parser: TTestPasParser read FParser write FParser;
  47. property Source: string read FSource write FSource;
  48. property Module: TPasModule read FModule write SetModule;
  49. end;
  50. { TCustomTestModule }
  51. TCustomTestModule = Class(TTestCase)
  52. private
  53. FConverter: TPasToJSConverter;
  54. FEngine: TTestEnginePasResolver;
  55. FExpectedErrorClass: ExceptClass;
  56. FExpectedErrorMsg: string;
  57. FExpectedErrorNumber: integer;
  58. FFilename: string;
  59. FFileResolver: TStreamResolver;
  60. FJSInitBody: TJSFunctionBody;
  61. FJSInterfaceUses: TJSArrayLiteral;
  62. FJSModule: TJSSourceElements;
  63. FJSModuleSrc: TJSSourceElements;
  64. FJSSource: TStringList;
  65. FModule: TPasModule;
  66. FJSModuleCallArgs: TJSArguments;
  67. FModules: TObjectList;// list of TTestEnginePasResolver
  68. FParser: TTestPasParser;
  69. FPasProgram: TPasProgram;
  70. FJSRegModuleCall: TJSCallExpression;
  71. FScanner: TPascalScanner;
  72. FSkipTests: boolean;
  73. FSource: TStringList;
  74. FFirstPasStatement: TPasImplBlock;
  75. function GetModuleCount: integer;
  76. function GetModules(Index: integer): TTestEnginePasResolver;
  77. function OnPasResolverFindUnit(const aUnitName: String): TPasModule;
  78. protected
  79. procedure SetUp; override;
  80. procedure TearDown; override;
  81. Procedure Add(Line: string); virtual;
  82. Procedure StartParsing; virtual;
  83. procedure ParseModule; virtual;
  84. procedure ParseProgram; virtual;
  85. procedure ParseUnit; virtual;
  86. protected
  87. function FindModuleWithFilename(aFilename: string): TTestEnginePasResolver; virtual;
  88. function AddModule(aFilename: string): TTestEnginePasResolver; virtual;
  89. function AddModuleWithSrc(aFilename, Src: string): TTestEnginePasResolver; virtual;
  90. function AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  91. ImplementationSrc: string): TTestEnginePasResolver; virtual;
  92. procedure AddSystemUnit; virtual;
  93. procedure StartProgram(NeedSystemUnit: boolean); virtual;
  94. procedure StartUnit(NeedSystemUnit: boolean); virtual;
  95. Procedure ConvertModule; virtual;
  96. Procedure ConvertProgram; virtual;
  97. Procedure ConvertUnit; virtual;
  98. procedure CheckDottedIdentifier(Msg: string; El: TJSElement; DottedName: string);
  99. function GetDottedIdentifier(El: TJSElement): string;
  100. procedure CheckSource(Msg,Statements, InitStatements: string); virtual;
  101. procedure CheckDiff(Msg, Expected, Actual: string); virtual;
  102. procedure SetExpectedPasResolverError(Msg: string; MsgNumber: integer);
  103. procedure SetExpectedConverterError(Msg: string; MsgNumber: integer);
  104. function IsErrorExpected(E: Exception): boolean;
  105. procedure HandleScannerError(E: EScannerError);
  106. procedure HandleParserError(E: EParserError);
  107. procedure HandlePasResolveError(E: EPasResolve);
  108. procedure HandlePas2JSError(E: EPas2JS);
  109. procedure HandleException(E: Exception);
  110. procedure RaiseException(E: Exception);
  111. procedure WriteSources(const aFilename: string; aRow, aCol: integer);
  112. property PasProgram: TPasProgram Read FPasProgram;
  113. property Modules[Index: integer]: TTestEnginePasResolver read GetModules;
  114. property ModuleCount: integer read GetModuleCount;
  115. property Engine: TTestEnginePasResolver read FEngine;
  116. property Filename: string read FFilename;
  117. Property Module: TPasModule Read FModule;
  118. property FirstPasStatement: TPasImplBlock read FFirstPasStatement;
  119. property Converter: TPasToJSConverter read FConverter;
  120. property JSSource: TStringList read FJSSource;
  121. property JSModule: TJSSourceElements read FJSModule;
  122. property JSRegModuleCall: TJSCallExpression read FJSRegModuleCall;
  123. property JSModuleCallArgs: TJSArguments read FJSModuleCallArgs;
  124. property JSInterfaceUses: TJSArrayLiteral read FJSInterfaceUses;
  125. property JSModuleSrc: TJSSourceElements read FJSModuleSrc;
  126. property JSInitBody: TJSFunctionBody read FJSInitBody;
  127. property ExpectedErrorClass: ExceptClass read FExpectedErrorClass write FExpectedErrorClass;
  128. property ExpectedErrorMsg: string read FExpectedErrorMsg write FExpectedErrorMsg;
  129. property ExpectedErrorNumber: integer read FExpectedErrorNumber write FExpectedErrorNumber;
  130. property SkipTests: boolean read FSkipTests write FSkipTests;
  131. public
  132. property Source: TStringList read FSource;
  133. property FileResolver: TStreamResolver read FFileResolver;
  134. property Scanner: TPascalScanner read FScanner;
  135. property Parser: TTestPasParser read FParser;
  136. end;
  137. { TTestModule }
  138. TTestModule = class(TCustomTestModule)
  139. Published
  140. // modules
  141. Procedure TestEmptyProgram;
  142. Procedure TestEmptyProgramUseStrict;
  143. Procedure TestEmptyUnit;
  144. Procedure TestEmptyUnitUseStrict;
  145. // vars/const
  146. Procedure TestVarInt;
  147. Procedure TestVarBaseTypes;
  148. Procedure TestConstBaseTypes;
  149. Procedure TestUnitImplVars;
  150. Procedure TestUnitImplConsts;
  151. Procedure TestUnitImplRecord;
  152. Procedure TestRenameJSNameConflict;
  153. Procedure TestLocalConst;
  154. Procedure TestVarExternal;
  155. Procedure TestVarExternalOtherUnit;
  156. // strings
  157. Procedure TestCharConst;
  158. Procedure TestChar_Compare;
  159. Procedure TestChar_Ord;
  160. Procedure TestChar_Chr;
  161. Procedure TestStringConst;
  162. Procedure TestString_Length;
  163. Procedure TestString_Compare;
  164. Procedure TestString_SetLength;
  165. Procedure TestString_CharAt;
  166. Procedure TestStr;
  167. Procedure TestAnsiStringFail;
  168. // alias types
  169. Procedure TestAliasTypeRef;
  170. Procedure TestTypeCast_BaseTypes;
  171. Procedure TestTypeCast_AliasBaseTypes;
  172. // functions
  173. Procedure TestEmptyProc;
  174. Procedure TestProcOneParam;
  175. Procedure TestFunctionWithoutParams;
  176. Procedure TestProcedureWithoutParams;
  177. Procedure TestPrgProcVar;
  178. Procedure TestProcTwoArgs;
  179. Procedure TestProc_DefaultValue;
  180. Procedure TestUnitProcVar;
  181. Procedure TestImplProc;
  182. Procedure TestFunctionResult;
  183. Procedure TestNestedProc;
  184. Procedure TestForwardProc;
  185. Procedure TestNestedForwardProc;
  186. Procedure TestAssignFunctionResult;
  187. Procedure TestFunctionResultInCondition;
  188. Procedure TestExit;
  189. Procedure TestBreak;
  190. Procedure TestContinue;
  191. Procedure TestProcedureExternal;
  192. Procedure TestProcedureExternalOtherUnit;
  193. Procedure TestProcedureAsm;
  194. Procedure TestProcedureAssembler;
  195. Procedure TestProcedure_VarParam;
  196. Procedure TestProcedureOverload;
  197. Procedure TestProcedureOverloadForward;
  198. Procedure TestProcedureOverloadUnit;
  199. Procedure TestProcedureOverloadNested;
  200. Procedure TestProc_Varargs;
  201. // enums, sets
  202. Procedure TestEnumName;
  203. Procedure TestEnumNumber;
  204. Procedure TestEnumFunctions;
  205. Procedure TestSet;
  206. Procedure TestSetOperators;
  207. Procedure TestSetFunctions;
  208. Procedure TestSet_PassAsArgClone;
  209. Procedure TestEnum_AsParams;
  210. Procedure TestSet_AsParams;
  211. Procedure TestSet_Property;
  212. // statements
  213. Procedure TestNestBegin;
  214. Procedure TestIncDec;
  215. Procedure TestAssignments;
  216. Procedure TestArithmeticOperators1;
  217. Procedure TestLogicalOperators;
  218. Procedure TestBitwiseOperators;
  219. Procedure TestFunctionInt;
  220. Procedure TestFunctionString;
  221. Procedure TestForLoop;
  222. Procedure TestForLoopInFunction;
  223. Procedure TestForLoop_ReadVarAfter;
  224. Procedure TestForLoop_Nested;
  225. Procedure TestRepeatUntil;
  226. Procedure TestAsmBlock;
  227. Procedure TestTryFinally;
  228. Procedure TestTryExcept;
  229. Procedure TestCaseOf;
  230. Procedure TestCaseOf_UseSwitch;
  231. Procedure TestCaseOfNoElse;
  232. Procedure TestCaseOfNoElse_UseSwitch;
  233. Procedure TestCaseOfRange;
  234. // arrays
  235. Procedure TestArray_Dynamic;
  236. Procedure TestArray_Dynamic_Nil;
  237. Procedure TestArray_DynMultiDimensional;
  238. Procedure TestArrayOfRecord;
  239. Procedure TestArray_AsParams;
  240. Procedure TestArrayElement_AsParams;
  241. Procedure TestArrayElementFromFuncResult_AsParams;
  242. Procedure TestArrayEnumTypeRange;
  243. Procedure TestArray_SetLengthProperty;
  244. Procedure TestArray_OpenArrayOfString;
  245. // ToDo: const array
  246. // ToDo: SetLength(array of static array)
  247. // record
  248. Procedure TestRecord_Var;
  249. Procedure TestWithRecordDo;
  250. Procedure TestRecord_Assign;
  251. Procedure TestRecord_PassAsArgClone;
  252. Procedure TestRecord_AsParams;
  253. Procedure TestRecordElement_AsParams;
  254. Procedure TestRecordElementFromFuncResult_AsParams;
  255. Procedure TestRecordElementFromWith_AsParams;
  256. Procedure TestRecord_Equal;
  257. // ToDo: const record
  258. // classes
  259. Procedure TestClass_TObjectDefaultConstructor;
  260. Procedure TestClass_TObjectConstructorWithParams;
  261. Procedure TestClass_Var;
  262. Procedure TestClass_Method;
  263. Procedure TestClass_Inheritance;
  264. Procedure TestClass_AbstractMethod;
  265. Procedure TestClass_CallInherited_NoParams;
  266. Procedure TestClass_CallInherited_WithParams;
  267. Procedure TestClasS_CallInheritedConstructor;
  268. Procedure TestClass_ClassVar;
  269. Procedure TestClass_CallClassMethod;
  270. Procedure TestClass_Property;
  271. Procedure TestClass_Property_ClassMethod;
  272. Procedure TestClass_Property_Index;
  273. Procedure TestClass_PropertyOfTypeArray;
  274. Procedure TestClass_PropertyDefault;
  275. Procedure TestClass_PropertyOverride;
  276. Procedure TestClass_Assigned;
  277. Procedure TestClass_WithClassDoCreate;
  278. Procedure TestClass_WithClassInstDoProperty;
  279. Procedure TestClass_WithClassInstDoPropertyWithParams;
  280. Procedure TestClass_WithClassInstDoFunc;
  281. Procedure TestClass_TypeCast;
  282. Procedure TestClass_TypeCastUntypedParam;
  283. Procedure TestClass_Overloads;
  284. Procedure TestClass_OverloadsAncestor;
  285. Procedure TestClass_OverloadConstructor;
  286. Procedure TestClass_ReintroducedVar;
  287. Procedure TestClass_RaiseDescendant;
  288. Procedure TestClass_ExternalMethod;
  289. Procedure TestClass_ExternalVirtualNameMismatchFail;
  290. Procedure TestClass_ExternalOverrideFail;
  291. Procedure TestClass_ExternalVar;
  292. // class of
  293. Procedure TestClassOf_Create;
  294. Procedure TestClassOf_Call;
  295. Procedure TestClassOf_Assign;
  296. Procedure TestClassOf_Is;
  297. Procedure TestClassOf_Compare;
  298. Procedure TestClassOf_ClassVar;
  299. Procedure TestClassOf_ClassMethod;
  300. Procedure TestClassOf_ClassProperty;
  301. Procedure TestClassOf_ClassMethodSelf;
  302. Procedure TestClassOf_TypeCast;
  303. Procedure TestClassOf_ImplicitFunctionCall;
  304. // external class
  305. Procedure TestExternalClass_Var;
  306. // ToDo TestExternalClass_Const
  307. Procedure TestExternalClass_DuplicateVarFail;
  308. Procedure TestExternalClass_Method;
  309. Procedure TestExternalClass_NonExternalOverride;
  310. Procedure TestExternalClass_Property;
  311. Procedure TestExternalClass_ClassProperty;
  312. Procedure TestExternalClass_ClassOf;
  313. Procedure TestExternalClass_ClassOtherUnit;
  314. Procedure TestExternalClass_Is;
  315. Procedure TestExternalClass_As;
  316. Procedure TestExternalClass_DestructorFail;
  317. Procedure TestExternalClass_New;
  318. Procedure TestExternalClass_ClassOf_New;
  319. Procedure TestExternalClass_FuncClassOf_New;
  320. Procedure TestExternalClass_LocalConstSameName;
  321. Procedure TestExternalClass_ReintroduceOverload;
  322. Procedure TestExternalClass_Inherited;
  323. Procedure TestExternalClass_NewInstance;
  324. Procedure TestExternalClass_NewInstance_NonVirtualFail;
  325. Procedure TestExternalClass_NewInstance_FirstParamNotString_Fail;
  326. Procedure TestExternalClass_NewInstance_SecondParamTyped_Fail;
  327. Procedure TestExternalClass_TypeCastToRootClass;
  328. // proc types
  329. Procedure TestProcType;
  330. Procedure TestProcType_FunctionFPC;
  331. Procedure TestProcType_FunctionDelphi;
  332. Procedure TestProcType_AsParam;
  333. Procedure TestProcType_MethodFPC;
  334. Procedure TestProcType_MethodDelphi;
  335. Procedure TestProcType_PropertyFPC;
  336. Procedure TestProcType_PropertyDelphi;
  337. Procedure TestProcType_WithClassInstDoPropertyFPC;
  338. // jsvalue
  339. Procedure TestJSValue_AssignToJSValue;
  340. Procedure TestJSValue_TypeCastToBaseType;
  341. Procedure TestJSValue_Enum;
  342. Procedure TestJSValue_ClassInstance;
  343. Procedure TestJSValue_ClassOf;
  344. Procedure TestJSValue_ArrayOfJSValue;
  345. Procedure TestJSValue_Params;
  346. Procedure TestJSValue_UntypedParam;
  347. Procedure TestJSValue_FuncType;
  348. end;
  349. function LinesToStr(Args: array of const): string;
  350. function ExtractFileUnitName(aFilename: string): string;
  351. function JSToStr(El: TJSElement): string;
  352. implementation
  353. function LinesToStr(Args: array of const): string;
  354. var
  355. s: String;
  356. i: Integer;
  357. begin
  358. s:='';
  359. for i:=Low(Args) to High(Args) do
  360. case Args[i].VType of
  361. vtChar: s += Args[i].VChar+LineEnding;
  362. vtString: s += Args[i].VString^+LineEnding;
  363. vtPChar: s += Args[i].VPChar+LineEnding;
  364. vtWideChar: s += AnsiString(Args[i].VWideChar)+LineEnding;
  365. vtPWideChar: s += AnsiString(Args[i].VPWideChar)+LineEnding;
  366. vtAnsiString: s += AnsiString(Args[i].VAnsiString)+LineEnding;
  367. vtWidestring: s += AnsiString(WideString(Args[i].VWideString))+LineEnding;
  368. vtUnicodeString:s += AnsiString(UnicodeString(Args[i].VUnicodeString))+LineEnding;
  369. end;
  370. Result:=s;
  371. end;
  372. function ExtractFileUnitName(aFilename: string): string;
  373. var
  374. p: Integer;
  375. begin
  376. Result:=ExtractFileName(aFilename);
  377. if Result='' then exit;
  378. for p:=length(Result) downto 1 do
  379. case Result[p] of
  380. '/','\': exit;
  381. '.':
  382. begin
  383. Delete(Result,p,length(Result));
  384. exit;
  385. end;
  386. end;
  387. end;
  388. function JSToStr(El: TJSElement): string;
  389. var
  390. aWriter: TBufferWriter;
  391. aJSWriter: TJSWriter;
  392. begin
  393. aWriter:=TBufferWriter.Create(1000);
  394. try
  395. aJSWriter:=TJSWriter.Create(aWriter);
  396. aJSWriter.IndentSize:=2;
  397. aJSWriter.WriteJS(El);
  398. Result:=aWriter.AsAnsistring;
  399. finally
  400. aWriter.Free;
  401. end;
  402. end;
  403. { TTestEnginePasResolver }
  404. procedure TTestEnginePasResolver.SetModule(AValue: TPasModule);
  405. begin
  406. if FModule=AValue then Exit;
  407. if Module<>nil then
  408. Module.Release;
  409. FModule:=AValue;
  410. if Module<>nil then
  411. Module.AddRef;
  412. end;
  413. destructor TTestEnginePasResolver.Destroy;
  414. begin
  415. FreeAndNil(FResolver);
  416. Module:=nil;
  417. FreeAndNil(FParser);
  418. FreeAndNil(FScanner);
  419. FreeAndNil(FResolver);
  420. inherited Destroy;
  421. end;
  422. function TTestEnginePasResolver.FindModule(const AName: String): TPasModule;
  423. begin
  424. Result:=nil;
  425. if Assigned(OnFindUnit) then
  426. Result:=OnFindUnit(AName);
  427. end;
  428. { TCustomTestModule }
  429. function TCustomTestModule.GetModuleCount: integer;
  430. begin
  431. Result:=FModules.Count;
  432. end;
  433. function TCustomTestModule.GetModules(Index: integer
  434. ): TTestEnginePasResolver;
  435. begin
  436. Result:=TTestEnginePasResolver(FModules[Index]);
  437. end;
  438. function TCustomTestModule.OnPasResolverFindUnit(const aUnitName: String
  439. ): TPasModule;
  440. var
  441. i: Integer;
  442. CurEngine: TTestEnginePasResolver;
  443. CurUnitName: String;
  444. begin
  445. //writeln('TTestModule.OnPasResolverFindUnit START Unit="',aUnitName,'"');
  446. Result:=nil;
  447. for i:=0 to ModuleCount-1 do
  448. begin
  449. CurEngine:=Modules[i];
  450. CurUnitName:=ExtractFileUnitName(CurEngine.Filename);
  451. //writeln('TTestModule.OnPasResolverFindUnit Checking ',i,'/',ModuleCount,' ',CurEngine.Filename,' ',CurUnitName);
  452. if CompareText(aUnitName,CurUnitName)=0 then
  453. begin
  454. Result:=CurEngine.Module;
  455. if Result<>nil then exit;
  456. //writeln('TTestModule.OnPasResolverFindUnit PARSING unit "',CurEngine.Filename,'"');
  457. FileResolver.FindSourceFile(aUnitName);
  458. CurEngine.Resolver:=TStreamResolver.Create;
  459. CurEngine.Resolver.OwnsStreams:=True;
  460. //writeln('TTestResolver.OnPasResolverFindUnit SOURCE=',CurEngine.Source);
  461. CurEngine.Resolver.AddStream(CurEngine.FileName,TStringStream.Create(CurEngine.Source));
  462. CurEngine.Scanner:=TPascalScanner.Create(CurEngine.Resolver);
  463. CurEngine.Parser:=TTestPasParser.Create(CurEngine.Scanner,CurEngine.Resolver,CurEngine);
  464. CurEngine.Parser.Options:=CurEngine.Parser.Options+po_pas2js;
  465. if CompareText(CurUnitName,'System')=0 then
  466. CurEngine.Parser.ImplicitUses.Clear;
  467. CurEngine.Scanner.OpenFile(CurEngine.Filename);
  468. try
  469. CurEngine.Parser.NextToken;
  470. CurEngine.Parser.ParseUnit(CurEngine.FModule);
  471. except
  472. on E: EParserError do
  473. HandleParserError(E);
  474. on E: EPasResolve do
  475. HandlePasResolveError(E);
  476. on E: Exception do
  477. HandleException(E);
  478. end;
  479. //writeln('TTestModule.OnPasResolverFindUnit END ',CurUnitName);
  480. Result:=CurEngine.Module;
  481. exit;
  482. end;
  483. end;
  484. writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"');
  485. Fail('can''t find unit "'+aUnitName+'"');
  486. end;
  487. procedure TCustomTestModule.SetUp;
  488. begin
  489. inherited SetUp;
  490. FSkipTests:=false;
  491. FSource:=TStringList.Create;
  492. FModules:=TObjectList.Create(true);
  493. FFilename:='test1.pp';
  494. FFileResolver:=TStreamResolver.Create;
  495. FFileResolver.OwnsStreams:=True;
  496. FScanner:=TPascalScanner.Create(FFileResolver);
  497. FEngine:=AddModule(Filename);
  498. FParser:=TTestPasParser.Create(FScanner,FFileResolver,FEngine);
  499. Parser.Options:=Parser.Options+po_pas2js;
  500. FModule:=Nil;
  501. FConverter:=TPasToJSConverter.Create;
  502. FConverter.UseLowerCase:=false;
  503. FExpectedErrorClass:=nil;
  504. end;
  505. procedure TCustomTestModule.TearDown;
  506. begin
  507. FSkipTests:=false;
  508. FJSModule:=nil;
  509. FJSRegModuleCall:=nil;
  510. FJSModuleCallArgs:=nil;
  511. FJSInterfaceUses:=nil;
  512. FJSModuleSrc:=nil;
  513. FJSInitBody:=nil;
  514. FreeAndNil(FJSSource);
  515. FreeAndNil(FJSModule);
  516. FreeAndNil(FConverter);
  517. Engine.Clear;
  518. if Assigned(FModule) then
  519. begin
  520. FModule.Release;
  521. FModule:=nil;
  522. end;
  523. FreeAndNil(FSource);
  524. FreeAndNil(FParser);
  525. FreeAndNil(FScanner);
  526. FreeAndNil(FFileResolver);
  527. if FModules<>nil then
  528. begin
  529. FreeAndNil(FModules);
  530. FEngine:=nil;
  531. end;
  532. inherited TearDown;
  533. end;
  534. procedure TCustomTestModule.Add(Line: string);
  535. begin
  536. Source.Add(Line);
  537. end;
  538. procedure TCustomTestModule.StartParsing;
  539. var
  540. Src: String;
  541. begin
  542. Src:=Source.Text;
  543. FEngine.Source:=Src;
  544. FileResolver.AddStream(FileName,TStringStream.Create(Src));
  545. Scanner.OpenFile(FileName);
  546. Writeln('// Test : ',Self.TestName);
  547. Writeln(Src);
  548. end;
  549. procedure TCustomTestModule.ParseModule;
  550. begin
  551. if SkipTests then exit;
  552. FFirstPasStatement:=nil;
  553. try
  554. StartParsing;
  555. Parser.ParseMain(FModule);
  556. except
  557. on E: EParserError do
  558. HandleParserError(E);
  559. on E: EPasResolve do
  560. HandlePasResolveError(E);
  561. on E: EPas2JS do
  562. HandlePas2JSError(E);
  563. on E: Exception do
  564. HandleException(E);
  565. end;
  566. if SkipTests then exit;
  567. AssertNotNull('Module resulted in Module',FModule);
  568. AssertEquals('modulename',lowercase(ChangeFileExt(FFileName,'')),lowercase(Module.Name));
  569. TAssert.AssertSame('Has resolver',Engine,Parser.Engine);
  570. end;
  571. procedure TCustomTestModule.ParseProgram;
  572. begin
  573. if SkipTests then exit;
  574. ParseModule;
  575. if SkipTests then exit;
  576. AssertEquals('Has program',TPasProgram,Module.ClassType);
  577. FPasProgram:=TPasProgram(Module);
  578. AssertNotNull('Has program section',PasProgram.ProgramSection);
  579. AssertNotNull('Has initialization section',PasProgram.InitializationSection);
  580. if (PasProgram.InitializationSection.Elements.Count>0) then
  581. if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
  582. FFirstPasStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
  583. end;
  584. procedure TCustomTestModule.ParseUnit;
  585. begin
  586. if SkipTests then exit;
  587. ParseModule;
  588. if SkipTests then exit;
  589. AssertEquals('Has unit (TPasModule)',TPasModule,Module.ClassType);
  590. AssertNotNull('Has interface section',Module.InterfaceSection);
  591. AssertNotNull('Has implementation section',Module.ImplementationSection);
  592. if (Module.InitializationSection<>nil)
  593. and (Module.InitializationSection.Elements.Count>0)
  594. and (TObject(Module.InitializationSection.Elements[0]) is TPasImplBlock) then
  595. FFirstPasStatement:=TPasImplBlock(Module.InitializationSection.Elements[0]);
  596. end;
  597. function TCustomTestModule.FindModuleWithFilename(aFilename: string
  598. ): TTestEnginePasResolver;
  599. var
  600. i: Integer;
  601. begin
  602. for i:=0 to ModuleCount-1 do
  603. if CompareText(Modules[i].Filename,aFilename)=0 then
  604. exit(Modules[i]);
  605. Result:=nil;
  606. end;
  607. function TCustomTestModule.AddModule(aFilename: string
  608. ): TTestEnginePasResolver;
  609. begin
  610. //writeln('TTestModuleConverter.AddModule ',aFilename);
  611. if FindModuleWithFilename(aFilename)<>nil then
  612. Fail('TTestModuleConverter.AddModule: file "'+aFilename+'" already exists');
  613. Result:=TTestEnginePasResolver.Create;
  614. Result.Filename:=aFilename;
  615. Result.AddObjFPCBuiltInIdentifiers([btChar,btString,btLongint,btInt64,btBoolean,btDouble]);
  616. Result.OnFindUnit:=@OnPasResolverFindUnit;
  617. FModules.Add(Result);
  618. end;
  619. function TCustomTestModule.AddModuleWithSrc(aFilename, Src: string
  620. ): TTestEnginePasResolver;
  621. begin
  622. Result:=AddModule(aFilename);
  623. Result.Source:=Src;
  624. end;
  625. function TCustomTestModule.AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  626. ImplementationSrc: string): TTestEnginePasResolver;
  627. var
  628. Src: String;
  629. begin
  630. Src:='unit '+ExtractFileUnitName(aFilename)+';'+LineEnding;
  631. Src+=LineEnding;
  632. Src+='interface'+LineEnding;
  633. Src+=LineEnding;
  634. Src+=InterfaceSrc;
  635. Src+='implementation'+LineEnding;
  636. Src+=LineEnding;
  637. Src+=ImplementationSrc;
  638. Src+='end.'+LineEnding;
  639. Result:=AddModuleWithSrc(aFilename,Src);
  640. end;
  641. procedure TCustomTestModule.AddSystemUnit;
  642. begin
  643. AddModuleWithIntfImplSrc('system.pp',
  644. // interface
  645. LinesToStr([
  646. 'type',
  647. ' integer=longint;',
  648. 'var',
  649. ' ExitCode: Longint;',
  650. ''
  651. // implementation
  652. ]),LinesToStr([
  653. ''
  654. ]));
  655. end;
  656. procedure TCustomTestModule.StartProgram(NeedSystemUnit: boolean);
  657. begin
  658. if NeedSystemUnit then
  659. AddSystemUnit
  660. else
  661. Parser.ImplicitUses.Clear;
  662. Add('program test1;');
  663. Add('');
  664. end;
  665. procedure TCustomTestModule.StartUnit(NeedSystemUnit: boolean);
  666. begin
  667. if NeedSystemUnit then
  668. AddSystemUnit
  669. else
  670. Parser.ImplicitUses.Clear;
  671. Add('unit Test1;');
  672. Add('');
  673. end;
  674. procedure TCustomTestModule.ConvertModule;
  675. var
  676. ModuleNameExpr: TJSLiteral;
  677. FunDecl, InitFunction: TJSFunctionDeclarationStatement;
  678. FunDef: TJSFuncDef;
  679. InitAssign: TJSSimpleAssignStatement;
  680. FunBody: TJSFunctionBody;
  681. InitName: String;
  682. begin
  683. if SkipTests then exit;
  684. try
  685. FJSModule:=FConverter.ConvertPasElement(Module,Engine) as TJSSourceElements;
  686. except
  687. on E: EScannerError do
  688. HandleScannerError(E);
  689. on E: EParserError do
  690. HandleParserError(E);
  691. on E: EPasResolve do
  692. HandlePasResolveError(E);
  693. on E: EPas2JS do
  694. HandlePas2JSError(E);
  695. on E: Exception do
  696. HandleException(E);
  697. end;
  698. if SkipTests then exit;
  699. if ExpectedErrorClass<>nil then
  700. Fail('Missing '+ExpectedErrorClass.ClassName+' error {'+ExpectedErrorMsg+'} ('+IntToStr(ExpectedErrorNumber)+')');
  701. FJSSource:=TStringList.Create;
  702. FJSSource.Text:=JSToStr(JSModule);
  703. {$IFDEF VerbosePas2JS}
  704. writeln('TTestModule.ConvertModule JS:');
  705. write(FJSSource.Text);
  706. {$ENDIF}
  707. // rtl.module(...
  708. AssertEquals('jsmodule has one statement - the call',1,JSModule.Statements.Count);
  709. AssertNotNull('register module call',JSModule.Statements.Nodes[0].Node);
  710. AssertEquals('register module call',TJSCallExpression,JSModule.Statements.Nodes[0].Node.ClassType);
  711. FJSRegModuleCall:=JSModule.Statements.Nodes[0].Node as TJSCallExpression;
  712. AssertNotNull('register module rtl.module expr',JSRegModuleCall.Expr);
  713. AssertNotNull('register module rtl.module args',JSRegModuleCall.Args);
  714. AssertEquals('rtl.module args',TJSArguments,JSRegModuleCall.Args.ClassType);
  715. FJSModuleCallArgs:=JSRegModuleCall.Args as TJSArguments;
  716. AssertEquals('rtl.module args.count',3,JSModuleCallArgs.Elements.Count);
  717. // parameter 'unitname'
  718. AssertNotNull('module name param',JSModuleCallArgs.Elements.Elements[0].Expr);
  719. ModuleNameExpr:=JSModuleCallArgs.Elements.Elements[0].Expr as TJSLiteral;
  720. AssertEquals('module name param is string',ord(jstString),ord(ModuleNameExpr.Value.ValueType));
  721. if Module is TPasProgram then
  722. AssertEquals('module name','program',String(ModuleNameExpr.Value.AsString))
  723. else
  724. AssertEquals('module name',Module.Name,String(ModuleNameExpr.Value.AsString));
  725. // main uses section
  726. AssertNotNull('interface uses section',JSModuleCallArgs.Elements.Elements[1].Expr);
  727. AssertEquals('interface uses section type',TJSArrayLiteral,JSModuleCallArgs.Elements.Elements[1].Expr.ClassType);
  728. FJSInterfaceUses:=JSModuleCallArgs.Elements.Elements[1].Expr as TJSArrayLiteral;
  729. // function()
  730. AssertNotNull('module function',JSModuleCallArgs.Elements.Elements[2].Expr);
  731. AssertEquals('module function type',TJSFunctionDeclarationStatement,JSModuleCallArgs.Elements.Elements[2].Expr.ClassType);
  732. FunDecl:=JSModuleCallArgs.Elements.Elements[2].Expr as TJSFunctionDeclarationStatement;
  733. AssertNotNull('module function def',FunDecl.AFunction);
  734. FunDef:=FunDecl.AFunction as TJSFuncDef;
  735. AssertEquals('module function name','',String(FunDef.Name));
  736. AssertNotNull('module function body',FunDef.Body);
  737. FunBody:=FunDef.Body as TJSFunctionBody;
  738. FJSModuleSrc:=FunBody.A as TJSSourceElements;
  739. // init this.$main - the last statement
  740. if Module is TPasProgram then
  741. begin
  742. InitName:='$main';
  743. AssertEquals('this.'+InitName+' function 1',true,JSModuleSrc.Statements.Count>0);
  744. end
  745. else
  746. InitName:='$init';
  747. FJSInitBody:=nil;
  748. if JSModuleSrc.Statements.Count>0 then
  749. begin
  750. InitAssign:=JSModuleSrc.Statements.Nodes[JSModuleSrc.Statements.Count-1].Node as TJSSimpleAssignStatement;
  751. if GetDottedIdentifier(InitAssign.LHS)='this.'+InitName then
  752. begin
  753. InitFunction:=InitAssign.Expr as TJSFunctionDeclarationStatement;
  754. FJSInitBody:=InitFunction.AFunction.Body as TJSFunctionBody;
  755. end
  756. else if Module is TPasProgram then
  757. CheckDottedIdentifier('init function',InitAssign.LHS,'this.'+InitName);
  758. end;
  759. end;
  760. procedure TCustomTestModule.ConvertProgram;
  761. begin
  762. Add('end.');
  763. ParseProgram;
  764. ConvertModule;
  765. end;
  766. procedure TCustomTestModule.ConvertUnit;
  767. begin
  768. Add('end.');
  769. ParseUnit;
  770. ConvertModule;
  771. end;
  772. procedure TCustomTestModule.CheckDottedIdentifier(Msg: string; El: TJSElement;
  773. DottedName: string);
  774. begin
  775. if DottedName='' then
  776. begin
  777. AssertNull(Msg,El);
  778. end
  779. else
  780. begin
  781. AssertNotNull(Msg,El);
  782. AssertEquals(Msg,DottedName,GetDottedIdentifier(El));
  783. end;
  784. end;
  785. function TCustomTestModule.GetDottedIdentifier(El: TJSElement): string;
  786. begin
  787. if El=nil then
  788. Result:=''
  789. else if El is TJSPrimaryExpressionIdent then
  790. Result:=String(TJSPrimaryExpressionIdent(El).Name)
  791. else if El is TJSDotMemberExpression then
  792. Result:=GetDottedIdentifier(TJSDotMemberExpression(El).MExpr)+'.'+String(TJSDotMemberExpression(El).Name)
  793. else
  794. AssertEquals('GetDottedIdentifier',TJSPrimaryExpressionIdent,El.ClassType);
  795. end;
  796. procedure TCustomTestModule.CheckSource(Msg, Statements, InitStatements: string);
  797. var
  798. ActualSrc, ExpectedSrc, InitName: String;
  799. begin
  800. ActualSrc:=JSToStr(JSModuleSrc);
  801. ExpectedSrc:=Statements;
  802. if Module is TPasProgram then
  803. InitName:='$main'
  804. else
  805. InitName:='$init';
  806. if (Module is TPasProgram) or (InitStatements<>'') then
  807. ExpectedSrc:=ExpectedSrc+LineEnding
  808. +'this.'+InitName+' = function () {'+LineEnding
  809. +InitStatements
  810. +'};'+LineEnding;
  811. //writeln('TTestModule.CheckSource InitStatements="',InitStatements,'"');
  812. CheckDiff(Msg,ExpectedSrc,ActualSrc);
  813. end;
  814. procedure TCustomTestModule.CheckDiff(Msg, Expected, Actual: string);
  815. // search diff, ignore changes in spaces
  816. const
  817. SpaceChars = [#9,#10,#13,' '];
  818. var
  819. ExpectedP, ActualP: PChar;
  820. function FindLineEnd(p: PChar): PChar;
  821. begin
  822. Result:=p;
  823. while not (Result^ in [#0,#10,#13]) do inc(Result);
  824. end;
  825. function FindLineStart(p, MinP: PChar): PChar;
  826. begin
  827. while (p>MinP) and not (p[-1] in [#10,#13]) do dec(p);
  828. Result:=p;
  829. end;
  830. procedure DiffFound;
  831. var
  832. ActLineStartP, ActLineEndP, p, StartPos: PChar;
  833. ExpLine, ActLine: String;
  834. i: Integer;
  835. begin
  836. writeln('Diff found "',Msg,'". Lines:');
  837. // write correct lines
  838. p:=PChar(Expected);
  839. repeat
  840. StartPos:=p;
  841. while not (p^ in [#0,#10,#13]) do inc(p);
  842. ExpLine:=copy(Expected,StartPos-PChar(Expected)+1,p-StartPos);
  843. if p^ in [#10,#13] then begin
  844. if (p[1] in [#10,#13]) and (p^<>p[1]) then
  845. inc(p,2)
  846. else
  847. inc(p);
  848. end;
  849. if p<=ExpectedP then begin
  850. writeln('= ',ExpLine);
  851. end else begin
  852. // diff line
  853. // write actual line
  854. ActLineStartP:=FindLineStart(ActualP,PChar(Actual));
  855. ActLineEndP:=FindLineEnd(ActualP);
  856. ActLine:=copy(Actual,ActLineStartP-PChar(Actual)+1,ActLineEndP-ActLineStartP);
  857. writeln('- ',ActLine);
  858. // write expected line
  859. writeln('+ ',ExpLine);
  860. // write empty line with pointer ^
  861. for i:=1 to 2+ExpectedP-StartPos do write(' ');
  862. writeln('^');
  863. AssertEquals(Msg,ExpLine,ActLine);
  864. break;
  865. end;
  866. until p^=#0;
  867. raise Exception.Create('diff found, but lines are the same, internal error');
  868. end;
  869. var
  870. IsSpaceNeeded: Boolean;
  871. LastChar: Char;
  872. begin
  873. if Expected='' then Expected:=' ';
  874. if Actual='' then Actual:=' ';
  875. ExpectedP:=PChar(Expected);
  876. ActualP:=PChar(Actual);
  877. repeat
  878. //writeln('TTestModule.CheckDiff Exp="',ExpectedP^,'" Act="',ActualP^,'"');
  879. case ExpectedP^ of
  880. #0:
  881. begin
  882. // check that rest of Actual has only spaces
  883. while ActualP^ in SpaceChars do inc(ActualP);
  884. if ActualP^<>#0 then
  885. DiffFound;
  886. exit;
  887. end;
  888. ' ',#9,#10,#13:
  889. begin
  890. // skip space in Expected
  891. IsSpaceNeeded:=false;
  892. if ExpectedP>PChar(Expected) then
  893. LastChar:=ExpectedP[-1]
  894. else
  895. LastChar:=#0;
  896. while ExpectedP^ in SpaceChars do inc(ExpectedP);
  897. if (LastChar in ['a'..'z','A'..'Z','0'..'9','_','$'])
  898. and (ExpectedP^ in ['a'..'z','A'..'Z','0'..'9','_','$']) then
  899. IsSpaceNeeded:=true;
  900. if IsSpaceNeeded and (not (ActualP^ in SpaceChars)) then
  901. DiffFound;
  902. while ActualP^ in SpaceChars do inc(ActualP);
  903. end;
  904. else
  905. while ActualP^ in SpaceChars do inc(ActualP);
  906. if ExpectedP^<>ActualP^ then
  907. DiffFound;
  908. inc(ExpectedP);
  909. inc(ActualP);
  910. end;
  911. until false;
  912. end;
  913. procedure TCustomTestModule.SetExpectedPasResolverError(Msg: string;
  914. MsgNumber: integer);
  915. begin
  916. ExpectedErrorClass:=EPasResolve;
  917. ExpectedErrorMsg:=Msg;
  918. ExpectedErrorNumber:=MsgNumber;
  919. end;
  920. procedure TCustomTestModule.SetExpectedConverterError(Msg: string;
  921. MsgNumber: integer);
  922. begin
  923. ExpectedErrorClass:=EPas2JS;
  924. ExpectedErrorMsg:=Msg;
  925. ExpectedErrorNumber:=MsgNumber;
  926. end;
  927. function TCustomTestModule.IsErrorExpected(E: Exception): boolean;
  928. var
  929. MsgNumber: Integer;
  930. begin
  931. Result:=false;
  932. if (ExpectedErrorClass=nil) or (ExpectedErrorClass<>E.ClassType) then exit;
  933. if E is EPas2JS then
  934. MsgNumber:=EPas2JS(E).MsgNumber
  935. else if E is EPasResolve then
  936. MsgNumber:=EPasResolve(E).MsgNumber
  937. else
  938. MsgNumber:=0;
  939. Result:=(MsgNumber=ExpectedErrorNumber) and (E.Message=ExpectedErrorMsg);
  940. if Result then
  941. SkipTests:=true;
  942. end;
  943. procedure TCustomTestModule.HandleScannerError(E: EScannerError);
  944. begin
  945. if IsErrorExpected(E) then exit;
  946. WriteSources(Scanner.CurFilename,Scanner.CurRow,Scanner.CurColumn);
  947. writeln('ERROR: TCustomTestModule.HandleScannerError '+E.ClassName+':'+E.Message
  948. +' '+Scanner.CurFilename
  949. +'('+IntToStr(Scanner.CurRow)+','+IntToStr(Scanner.CurColumn)+')');
  950. RaiseException(E);
  951. end;
  952. procedure TCustomTestModule.HandleParserError(E: EParserError);
  953. begin
  954. if IsErrorExpected(E) then exit;
  955. WriteSources(E.Filename,E.Row,E.Column);
  956. writeln('ERROR: TCustomTestModule.HandleParserError '+E.ClassName+':'+E.Message
  957. +' '+E.Filename+'('+IntToStr(E.Row)+','+IntToStr(E.Column)+')'
  958. +' Line="'+Scanner.CurLine+'"'
  959. );
  960. RaiseException(E);
  961. end;
  962. procedure TCustomTestModule.HandlePasResolveError(E: EPasResolve);
  963. var
  964. Row, Col: integer;
  965. begin
  966. if IsErrorExpected(E) then exit;
  967. Engine.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,Row,Col);
  968. WriteSources(E.PasElement.SourceFilename,Row,Col);
  969. writeln('ERROR: TCustomTestModule.HandlePasResolveError '+E.ClassName+':'+E.Message
  970. +' '+E.PasElement.SourceFilename
  971. +'('+IntToStr(Row)+','+IntToStr(Col)+')');
  972. RaiseException(E);
  973. end;
  974. procedure TCustomTestModule.HandlePas2JSError(E: EPas2JS);
  975. var
  976. Row, Col: integer;
  977. begin
  978. if IsErrorExpected(E) then exit;
  979. Engine.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,Row,Col);
  980. WriteSources(E.PasElement.SourceFilename,Row,Col);
  981. writeln('ERROR: TCustomTestModule.HandlePas2JSError '+E.ClassName+':'+E.Message
  982. +' '+E.PasElement.SourceFilename
  983. +'('+IntToStr(Row)+','+IntToStr(Col)+')');
  984. RaiseException(E);
  985. end;
  986. procedure TCustomTestModule.HandleException(E: Exception);
  987. begin
  988. if IsErrorExpected(E) then exit;
  989. WriteSources('',0,0);
  990. writeln('ERROR: TCustomTestModule.HandleException '+E.ClassName+':'+E.Message);
  991. RaiseException(E);
  992. end;
  993. procedure TCustomTestModule.RaiseException(E: Exception);
  994. var
  995. MsgNumber: Integer;
  996. begin
  997. if ExpectedErrorClass<>nil then begin
  998. if FExpectedErrorClass=E.ClassType then begin
  999. if E is EPas2JS then
  1000. MsgNumber:=EPas2JS(E).MsgNumber
  1001. else if E is EPasResolve then
  1002. MsgNumber:=EPasResolve(E).MsgNumber
  1003. else
  1004. MsgNumber:=0;
  1005. AssertEquals('Expected error message ('+IntToStr(ExpectedErrorNumber)+')','{'+ExpectedErrorMsg+'}','{'+E.Message+'}');
  1006. AssertEquals('Expected {'+ExpectedErrorMsg+'}, but got msg {'+E.Message+'} number',
  1007. ExpectedErrorNumber,MsgNumber);
  1008. end else begin
  1009. AssertEquals('Wrong exception class',ExpectedErrorClass.ClassName,E.ClassName);
  1010. end;
  1011. end;
  1012. Fail(E.Message);
  1013. end;
  1014. procedure TCustomTestModule.WriteSources(const aFilename: string; aRow,
  1015. aCol: integer);
  1016. var
  1017. IsSrc: Boolean;
  1018. i, j: Integer;
  1019. SrcLines: TStringList;
  1020. Line: string;
  1021. aModule: TTestEnginePasResolver;
  1022. begin
  1023. for i:=0 to ModuleCount-1 do
  1024. begin
  1025. aModule:=Modules[i];
  1026. SrcLines:=TStringList.Create;
  1027. try
  1028. SrcLines.Text:=aModule.Source;
  1029. IsSrc:=ExtractFilename(aModule.Filename)=ExtractFileName(aFilename);
  1030. writeln('Testcode:-File="',aModule.Filename,'"----------------------------------:');
  1031. for j:=1 to SrcLines.Count do
  1032. begin
  1033. Line:=SrcLines[j-1];
  1034. if IsSrc and (j=aRow) then
  1035. begin
  1036. write('*');
  1037. Line:=LeftStr(Line,aCol-1)+'|'+copy(Line,aCol,length(Line));
  1038. end;
  1039. writeln(Format('%:4d: ',[j]),Line);
  1040. end;
  1041. finally
  1042. SrcLines.Free;
  1043. end;
  1044. end;
  1045. end;
  1046. { TTestModule }
  1047. procedure TTestModule.TestEmptyProgram;
  1048. begin
  1049. StartProgram(false);
  1050. Add('begin');
  1051. ConvertProgram;
  1052. CheckSource('TestEmptyProgram','','');
  1053. end;
  1054. procedure TTestModule.TestEmptyProgramUseStrict;
  1055. begin
  1056. Converter.Options:=Converter.Options+[coUseStrict];
  1057. StartProgram(false);
  1058. Add('begin');
  1059. ConvertProgram;
  1060. CheckSource('TestEmptyProgramUseStrict','"use strict";','');
  1061. end;
  1062. procedure TTestModule.TestEmptyUnit;
  1063. begin
  1064. StartUnit(false);
  1065. Add('interface');
  1066. Add('implementation');
  1067. ConvertUnit;
  1068. CheckSource('TestEmptyUnit',
  1069. LinesToStr([
  1070. 'var $impl = {',
  1071. '};',
  1072. 'this.$impl = $impl;'
  1073. ]),
  1074. '');
  1075. end;
  1076. procedure TTestModule.TestEmptyUnitUseStrict;
  1077. begin
  1078. Converter.Options:=Converter.Options+[coUseStrict];
  1079. StartUnit(false);
  1080. Add('interface');
  1081. Add('implementation');
  1082. ConvertUnit;
  1083. CheckSource('TestEmptyUnitUseStrict',
  1084. LinesToStr([
  1085. '"use strict";',
  1086. 'var $impl = {',
  1087. '};',
  1088. 'this.$impl = $impl;'
  1089. ]),
  1090. '');
  1091. end;
  1092. procedure TTestModule.TestVarInt;
  1093. begin
  1094. StartProgram(false);
  1095. Add('var MyI: longint;');
  1096. Add('begin');
  1097. ConvertProgram;
  1098. CheckSource('TestVarInt','this.MyI=0;','');
  1099. end;
  1100. procedure TTestModule.TestVarBaseTypes;
  1101. begin
  1102. StartProgram(false);
  1103. Add('var');
  1104. Add(' i: longint;');
  1105. Add(' s: string;');
  1106. Add(' c: char;');
  1107. Add(' b: boolean;');
  1108. Add(' d: double;');
  1109. Add(' i2: longint = 3;');
  1110. Add(' s2: string = ''foo'';');
  1111. Add(' c2: char = ''4'';');
  1112. Add(' b2: boolean = true;');
  1113. Add(' d2: double = 5.6;');
  1114. Add(' i3: longint = $707;');
  1115. Add(' i4: int64 = 4503599627370495;');
  1116. Add(' i5: int64 = -4503599627370496;');
  1117. Add(' i6: int64 = $fffffffffffff;');
  1118. Add(' i7: int64 = -$10000000000000;');
  1119. Add('begin');
  1120. ConvertProgram;
  1121. CheckSource('TestVarBaseTypes',
  1122. LinesToStr([
  1123. 'this.i=0;',
  1124. 'this.s="";',
  1125. 'this.c="";',
  1126. 'this.b=false;',
  1127. 'this.d=0.0;',
  1128. 'this.i2=3;',
  1129. 'this.s2="foo";',
  1130. 'this.c2="4";',
  1131. 'this.b2=true;',
  1132. 'this.d2=5.6;',
  1133. 'this.i3=0x707;',
  1134. 'this.i4= 4503599627370495;',
  1135. 'this.i5= -4503599627370496;',
  1136. 'this.i6= 0xfffffffffffff;',
  1137. 'this.i7=-0x10000000000000;'
  1138. ]),
  1139. '');
  1140. end;
  1141. procedure TTestModule.TestConstBaseTypes;
  1142. begin
  1143. StartProgram(false);
  1144. Add('const');
  1145. Add(' i: longint = 3;');
  1146. Add(' s: string = ''foo'';');
  1147. Add(' c: char = ''4'';');
  1148. Add(' b: boolean = true;');
  1149. Add(' d: double = 5.6;');
  1150. Add('begin');
  1151. ConvertProgram;
  1152. CheckSource('TestVarBaseTypes',
  1153. LinesToStr([
  1154. 'this.i=3;',
  1155. 'this.s="foo";',
  1156. 'this.c="4";',
  1157. 'this.b=true;',
  1158. 'this.d=5.6;'
  1159. ]),
  1160. '');
  1161. end;
  1162. procedure TTestModule.TestAliasTypeRef;
  1163. begin
  1164. StartProgram(false);
  1165. Add('type');
  1166. Add(' a=longint;');
  1167. Add(' b=a;');
  1168. Add('var');
  1169. Add(' c: A;');
  1170. Add(' d: B;');
  1171. Add('begin');
  1172. ConvertProgram;
  1173. CheckSource('TestAliasTypeRef',
  1174. LinesToStr([ // statements
  1175. 'this.c = 0;',
  1176. 'this.d = 0;'
  1177. ]),
  1178. LinesToStr([ // this.$main
  1179. ''
  1180. ]));
  1181. end;
  1182. procedure TTestModule.TestTypeCast_BaseTypes;
  1183. begin
  1184. StartProgram(false);
  1185. Add('var');
  1186. Add(' i: longint;');
  1187. Add(' b: boolean;');
  1188. Add(' d: double;');
  1189. Add(' s: string;');
  1190. Add(' c: char;');
  1191. Add('begin');
  1192. Add(' i:=longint(i);');
  1193. Add(' i:=longint(b);');
  1194. Add(' b:=boolean(b);');
  1195. Add(' b:=boolean(i);');
  1196. Add(' d:=double(d);');
  1197. Add(' d:=double(i);');
  1198. Add(' s:=string(s);');
  1199. Add(' s:=string(c);');
  1200. Add(' c:=char(c);');
  1201. ConvertProgram;
  1202. CheckSource('TestAliasTypeRef',
  1203. LinesToStr([ // statements
  1204. 'this.i = 0;',
  1205. 'this.b = false;',
  1206. 'this.d = 0.0;',
  1207. 'this.s = "";',
  1208. 'this.c = "";',
  1209. '']),
  1210. LinesToStr([ // this.$main
  1211. 'this.i = this.i;',
  1212. 'this.i = (this.b ? 1 : 0);',
  1213. 'this.b = this.b;',
  1214. 'this.b = this.i != 0;',
  1215. 'this.d = this.d;',
  1216. 'this.d = this.i;',
  1217. 'this.s = this.s;',
  1218. 'this.s = this.c;',
  1219. 'this.c = this.c;',
  1220. '']));
  1221. end;
  1222. procedure TTestModule.TestTypeCast_AliasBaseTypes;
  1223. begin
  1224. StartProgram(false);
  1225. Add('type');
  1226. Add(' integer = longint;');
  1227. Add(' TYesNo = boolean;');
  1228. Add(' TFloat = double;');
  1229. Add(' TCaption = string;');
  1230. Add(' TChar = char;');
  1231. Add('var');
  1232. Add(' i: integer;');
  1233. Add(' b: TYesNo;');
  1234. Add(' d: TFloat;');
  1235. Add(' s: TCaption;');
  1236. Add(' c: TChar;');
  1237. Add('begin');
  1238. Add(' i:=integer(i);');
  1239. Add(' i:=integer(b);');
  1240. Add(' b:=TYesNo(b);');
  1241. Add(' b:=TYesNo(i);');
  1242. Add(' d:=TFloat(d);');
  1243. Add(' d:=TFloat(i);');
  1244. Add(' s:=TCaption(s);');
  1245. Add(' s:=TCaption(c);');
  1246. Add(' c:=TChar(c);');
  1247. ConvertProgram;
  1248. CheckSource('TestAliasTypeRef',
  1249. LinesToStr([ // statements
  1250. 'this.i = 0;',
  1251. 'this.b = false;',
  1252. 'this.d = 0.0;',
  1253. 'this.s = "";',
  1254. 'this.c = "";',
  1255. '']),
  1256. LinesToStr([ // this.$main
  1257. 'this.i = this.i;',
  1258. 'this.i = (this.b ? 1 : 0);',
  1259. 'this.b = this.b;',
  1260. 'this.b = this.i != 0;',
  1261. 'this.d = this.d;',
  1262. 'this.d = this.i;',
  1263. 'this.s = this.s;',
  1264. 'this.s = this.c;',
  1265. 'this.c = this.c;',
  1266. '']));
  1267. end;
  1268. procedure TTestModule.TestEmptyProc;
  1269. begin
  1270. StartProgram(false);
  1271. Add('procedure Test;');
  1272. Add('begin');
  1273. Add('end;');
  1274. Add('begin');
  1275. ConvertProgram;
  1276. CheckSource('TestEmptyProc',
  1277. LinesToStr([ // statements
  1278. 'this.Test = function () {',
  1279. '};'
  1280. ]),
  1281. LinesToStr([ // this.$main
  1282. ''
  1283. ]));
  1284. end;
  1285. procedure TTestModule.TestProcOneParam;
  1286. begin
  1287. StartProgram(false);
  1288. Add('procedure ProcA(i: longint);');
  1289. Add('begin');
  1290. Add('end;');
  1291. Add('begin');
  1292. Add(' PROCA(3);');
  1293. ConvertProgram;
  1294. CheckSource('TestProcOneParam',
  1295. LinesToStr([ // statements
  1296. 'this.ProcA = function (i) {',
  1297. '};'
  1298. ]),
  1299. LinesToStr([ // this.$main
  1300. 'this.ProcA(3);'
  1301. ]));
  1302. end;
  1303. procedure TTestModule.TestFunctionWithoutParams;
  1304. begin
  1305. StartProgram(false);
  1306. Add('function FuncA: longint;');
  1307. Add('begin');
  1308. Add('end;');
  1309. Add('var i: longint;');
  1310. Add('begin');
  1311. Add(' I:=FUNCA();');
  1312. Add(' I:=FUNCA;');
  1313. Add(' FUNCA();');
  1314. Add(' FUNCA;');
  1315. ConvertProgram;
  1316. CheckSource('TestProcWithoutParams',
  1317. LinesToStr([ // statements
  1318. 'this.FuncA = function () {',
  1319. ' var Result = 0;',
  1320. ' return Result;',
  1321. '};',
  1322. 'this.i=0;'
  1323. ]),
  1324. LinesToStr([ // this.$main
  1325. 'this.i=this.FuncA();',
  1326. 'this.i=this.FuncA();',
  1327. 'this.FuncA();',
  1328. 'this.FuncA();'
  1329. ]));
  1330. end;
  1331. procedure TTestModule.TestProcedureWithoutParams;
  1332. begin
  1333. StartProgram(false);
  1334. Add('procedure ProcA;');
  1335. Add('begin');
  1336. Add('end;');
  1337. Add('begin');
  1338. Add(' PROCA();');
  1339. Add(' PROCA;');
  1340. ConvertProgram;
  1341. CheckSource('TestProcWithoutParams',
  1342. LinesToStr([ // statements
  1343. 'this.ProcA = function () {',
  1344. '};'
  1345. ]),
  1346. LinesToStr([ // this.$main
  1347. 'this.ProcA();',
  1348. 'this.ProcA();'
  1349. ]));
  1350. end;
  1351. procedure TTestModule.TestIncDec;
  1352. begin
  1353. StartProgram(false);
  1354. Add('var');
  1355. Add(' Bar: longint;');
  1356. Add('begin');
  1357. Add(' inc(bar);');
  1358. Add(' inc(bar,2);');
  1359. Add(' dec(bar);');
  1360. Add(' dec(bar,3);');
  1361. ConvertProgram;
  1362. CheckSource('TestIncDec',
  1363. LinesToStr([ // statements
  1364. 'this.Bar = 0;'
  1365. ]),
  1366. LinesToStr([ // this.$main
  1367. 'this.Bar+=1;',
  1368. 'this.Bar+=2;',
  1369. 'this.Bar-=1;',
  1370. 'this.Bar-=3;'
  1371. ]));
  1372. end;
  1373. procedure TTestModule.TestAssignments;
  1374. begin
  1375. StartProgram(false);
  1376. Parser.Options:=Parser.Options+[po_cassignments];
  1377. Add('var');
  1378. Add(' Bar:longint;');
  1379. Add('begin');
  1380. Add(' bar:=3;');
  1381. Add(' bar+=4;');
  1382. Add(' bar-=5;');
  1383. Add(' bar*=6;');
  1384. ConvertProgram;
  1385. CheckSource('TestAssignments',
  1386. LinesToStr([ // statements
  1387. 'this.Bar = 0;'
  1388. ]),
  1389. LinesToStr([ // this.$main
  1390. 'this.Bar=3;',
  1391. 'this.Bar+=4;',
  1392. 'this.Bar-=5;',
  1393. 'this.Bar*=6;'
  1394. ]));
  1395. end;
  1396. procedure TTestModule.TestArithmeticOperators1;
  1397. begin
  1398. StartProgram(false);
  1399. Add('var');
  1400. Add(' vA,vB,vC:longint;');
  1401. Add('begin');
  1402. Add(' va:=1;');
  1403. Add(' vb:=va+va;');
  1404. Add(' vb:=va div vb;');
  1405. Add(' vb:=va mod vb;');
  1406. Add(' vb:=va+va*vb+va div vb;');
  1407. Add(' vc:=-va;');
  1408. Add(' va:=va-vb;');
  1409. Add(' vb:=va;');
  1410. Add(' if va<vb then vc:=va else vc:=vb;');
  1411. ConvertProgram;
  1412. CheckSource('TestArithmeticOperators1',
  1413. LinesToStr([ // statements
  1414. 'this.vA = 0;',
  1415. 'this.vB = 0;',
  1416. 'this.vC = 0;'
  1417. ]),
  1418. LinesToStr([ // this.$main
  1419. 'this.vA = 1;',
  1420. 'this.vB = this.vA + this.vA;',
  1421. 'this.vB = Math.floor(this.vA / this.vB);',
  1422. 'this.vB = this.vA % this.vB;',
  1423. 'this.vB = (this.vA + (this.vA * this.vB)) + Math.floor(this.vA / this.vB);',
  1424. 'this.vC = -this.vA;',
  1425. 'this.vA = this.vA - this.vB;',
  1426. 'this.vB = this.vA;',
  1427. 'if (this.vA < this.vB){ this.vC = this.vA } else this.vC = this.vB;'
  1428. ]));
  1429. end;
  1430. procedure TTestModule.TestLogicalOperators;
  1431. begin
  1432. StartProgram(false);
  1433. Add('var');
  1434. Add(' vA,vB,vC:boolean;');
  1435. Add('begin');
  1436. Add(' va:=vb and vc;');
  1437. Add(' va:=vb or vc;');
  1438. Add(' va:=true and vc;');
  1439. Add(' va:=(vb and vc) or (va and vb);');
  1440. Add(' va:=not vb;');
  1441. ConvertProgram;
  1442. CheckSource('TestLogicalOperators',
  1443. LinesToStr([ // statements
  1444. 'this.vA = false;',
  1445. 'this.vB = false;',
  1446. 'this.vC = false;'
  1447. ]),
  1448. LinesToStr([ // this.$main
  1449. 'this.vA = this.vB && this.vC;',
  1450. 'this.vA = this.vB || this.vC;',
  1451. 'this.vA = true && this.vC;',
  1452. 'this.vA = (this.vB && this.vC) || (this.vA && this.vB);',
  1453. 'this.vA = !this.vB;'
  1454. ]));
  1455. end;
  1456. procedure TTestModule.TestBitwiseOperators;
  1457. begin
  1458. StartProgram(false);
  1459. Add('var');
  1460. Add(' vA,vB,vC:longint;');
  1461. Add('begin');
  1462. Add(' va:=vb and vc;');
  1463. Add(' va:=vb or vc;');
  1464. Add(' va:=vb xor vc;');
  1465. Add(' va:=vb shl vc;');
  1466. Add(' va:=vb shr vc;');
  1467. Add(' va:=3 and vc;');
  1468. Add(' va:=(vb and vc) or (va and vb);');
  1469. Add(' va:=not vb;');
  1470. ConvertProgram;
  1471. CheckSource('TestBitwiseOperators',
  1472. LinesToStr([ // statements
  1473. 'this.vA = 0;',
  1474. 'this.vB = 0;',
  1475. 'this.vC = 0;'
  1476. ]),
  1477. LinesToStr([ // this.$main
  1478. 'this.vA = this.vB & this.vC;',
  1479. 'this.vA = this.vB | this.vC;',
  1480. 'this.vA = this.vB ^ this.vC;',
  1481. 'this.vA = this.vB << this.vC;',
  1482. 'this.vA = this.vB >>> this.vC;',
  1483. 'this.vA = 3 & this.vC;',
  1484. 'this.vA = (this.vB & this.vC) | (this.vA & this.vB);',
  1485. 'this.vA = ~this.vB;'
  1486. ]));
  1487. end;
  1488. procedure TTestModule.TestPrgProcVar;
  1489. begin
  1490. StartProgram(false);
  1491. Add('procedure Proc1;');
  1492. Add('type');
  1493. Add(' t1=longint;');
  1494. Add('var');
  1495. Add(' vA:t1;');
  1496. Add('begin');
  1497. Add('end;');
  1498. Add('begin');
  1499. ConvertProgram;
  1500. CheckSource('TestPrgProcVar',
  1501. LinesToStr([ // statements
  1502. 'this.Proc1 = function () {',
  1503. ' var vA=0;',
  1504. '};'
  1505. ]),
  1506. LinesToStr([ // this.$main
  1507. ''
  1508. ]));
  1509. end;
  1510. procedure TTestModule.TestUnitProcVar;
  1511. begin
  1512. StartUnit(false);
  1513. Add('interface');
  1514. Add('');
  1515. Add('type tA=string; // unit scope');
  1516. Add('procedure Proc1;');
  1517. Add('');
  1518. Add('implementation');
  1519. Add('');
  1520. Add('procedure Proc1;');
  1521. Add('type tA=longint; // local proc scope');
  1522. Add('var v1:tA; // using local tA');
  1523. Add('begin');
  1524. Add('end;');
  1525. Add('var v2:tA; // using interface tA');
  1526. ConvertUnit;
  1527. CheckSource('TestUnitProcVar',
  1528. LinesToStr([ // statements
  1529. 'var $impl = {',
  1530. '};',
  1531. 'this.$impl = $impl;',
  1532. 'this.Proc1 = function () {',
  1533. ' var v1 = 0;',
  1534. '};',
  1535. '$impl.v2 = "";'
  1536. ]),
  1537. '' // this.$init
  1538. );
  1539. end;
  1540. procedure TTestModule.TestImplProc;
  1541. begin
  1542. StartUnit(false);
  1543. Add('interface');
  1544. Add('');
  1545. Add('procedure Proc1;');
  1546. Add('');
  1547. Add('implementation');
  1548. Add('');
  1549. Add('procedure Proc1; begin end;');
  1550. Add('procedure Proc2; begin end;');
  1551. Add('initialization');
  1552. Add(' Proc1;');
  1553. Add(' Proc2;');
  1554. ConvertUnit;
  1555. CheckSource('TestImplProc',
  1556. LinesToStr([ // statements
  1557. 'var $impl = {',
  1558. '};',
  1559. 'this.$impl = $impl;',
  1560. 'this.Proc1 = function () {',
  1561. '};',
  1562. '$impl.Proc2 = function () {',
  1563. '};',
  1564. '']),
  1565. LinesToStr([ // this.$init
  1566. 'this.Proc1();',
  1567. '$impl.Proc2();',
  1568. '']));
  1569. end;
  1570. procedure TTestModule.TestFunctionResult;
  1571. begin
  1572. StartProgram(false);
  1573. Add('function Func1: longint;');
  1574. Add('begin');
  1575. Add(' Result:=3;');
  1576. Add('end;');
  1577. Add('begin');
  1578. ConvertProgram;
  1579. CheckSource('TestFunctionResult',
  1580. LinesToStr([ // statements
  1581. 'this.Func1 = function () {',
  1582. ' var Result = 0;',
  1583. ' Result = 3;',
  1584. ' return Result;',
  1585. '};'
  1586. ]),
  1587. '');
  1588. end;
  1589. procedure TTestModule.TestNestedProc;
  1590. begin
  1591. StartProgram(false);
  1592. Add('function DoIt(pA,pD: longint): longint;');
  1593. Add('var');
  1594. Add(' vB: longint;');
  1595. Add(' vC: longint;');
  1596. Add(' function Nesty(pA: longint): longint; ');
  1597. Add(' var vB: longint;');
  1598. Add(' begin');
  1599. Add(' Result:=pa+vb+vc+pd;');
  1600. Add(' end;');
  1601. Add('begin');
  1602. Add(' Result:=pa+vb+vc;');
  1603. Add('end;');
  1604. Add('begin');
  1605. ConvertProgram;
  1606. CheckSource('TestNestedProc',
  1607. LinesToStr([ // statements
  1608. 'this.DoIt = function (pA, pD) {',
  1609. ' var Result = 0;',
  1610. ' var vB = 0;',
  1611. ' var vC = 0;',
  1612. ' function Nesty(pA) {',
  1613. ' var Result = 0;',
  1614. ' var vB = 0;',
  1615. ' Result = ((pA + vB) + vC) + pD;',
  1616. ' return Result;',
  1617. ' };',
  1618. ' Result = (pA + vB) + vC;',
  1619. ' return Result;',
  1620. '};'
  1621. ]),
  1622. '');
  1623. end;
  1624. procedure TTestModule.TestForwardProc;
  1625. begin
  1626. StartProgram(false);
  1627. Add('procedure FuncA(Bar: longint); forward;');
  1628. Add('procedure FuncB(Bar: longint);');
  1629. Add('begin');
  1630. Add(' funca(bar);');
  1631. Add('end;');
  1632. Add('procedure funca(bar: longint);');
  1633. Add('begin');
  1634. Add(' if bar=3 then ;');
  1635. Add('end;');
  1636. Add('begin');
  1637. Add(' funca(4);');
  1638. Add(' funcb(5);');
  1639. ConvertProgram;
  1640. CheckSource('TestForwardProc',
  1641. LinesToStr([ // statements'
  1642. 'this.FuncB = function (Bar) {',
  1643. ' this.FuncA(Bar);',
  1644. '};',
  1645. 'this.FuncA = function (Bar) {',
  1646. ' if (Bar == 3);',
  1647. '};'
  1648. ]),
  1649. LinesToStr([
  1650. 'this.FuncA(4);',
  1651. 'this.FuncB(5);'
  1652. ])
  1653. );
  1654. end;
  1655. procedure TTestModule.TestNestedForwardProc;
  1656. begin
  1657. StartProgram(false);
  1658. Add('procedure FuncA;');
  1659. Add(' procedure FuncB(i: longint); forward;');
  1660. Add(' procedure FuncC(i: longint);');
  1661. Add(' begin');
  1662. Add(' funcb(i);');
  1663. Add(' end;');
  1664. Add(' procedure FuncB(i: longint);');
  1665. Add(' begin');
  1666. Add(' if i=3 then ;');
  1667. Add(' end;');
  1668. Add('begin');
  1669. Add(' funcc(4)');
  1670. Add('end;');
  1671. Add('begin');
  1672. Add(' funca;');
  1673. ConvertProgram;
  1674. CheckSource('TestNestedForwardProc',
  1675. LinesToStr([ // statements'
  1676. 'this.FuncA = function () {',
  1677. ' function FuncC(i) {',
  1678. ' FuncB(i);',
  1679. ' };',
  1680. ' function FuncB(i) {',
  1681. ' if (i == 3);',
  1682. ' };',
  1683. ' FuncC(4);',
  1684. '};'
  1685. ]),
  1686. LinesToStr([
  1687. 'this.FuncA();'
  1688. ])
  1689. );
  1690. end;
  1691. procedure TTestModule.TestAssignFunctionResult;
  1692. begin
  1693. StartProgram(false);
  1694. Add('function Func1: longint;');
  1695. Add('begin');
  1696. Add('end;');
  1697. Add('var i: longint;');
  1698. Add('begin');
  1699. Add(' i:=func1();');
  1700. Add(' i:=func1()+func1();');
  1701. ConvertProgram;
  1702. CheckSource('TestAssignFunctionResult',
  1703. LinesToStr([ // statements
  1704. 'this.Func1 = function () {',
  1705. ' var Result = 0;',
  1706. ' return Result;',
  1707. '};',
  1708. 'this.i = 0;'
  1709. ]),
  1710. LinesToStr([
  1711. 'this.i = this.Func1();',
  1712. 'this.i = this.Func1() + this.Func1();'
  1713. ]));
  1714. end;
  1715. procedure TTestModule.TestFunctionResultInCondition;
  1716. begin
  1717. StartProgram(false);
  1718. Add('function Func1: longint;');
  1719. Add('begin');
  1720. Add('end;');
  1721. Add('function Func2: boolean;');
  1722. Add('begin');
  1723. Add('end;');
  1724. Add('var i: longint;');
  1725. Add('begin');
  1726. Add(' if func2 then ;');
  1727. Add(' if i=func1() then ;');
  1728. Add(' if i=func1 then ;');
  1729. ConvertProgram;
  1730. CheckSource('TestFunctionResultInCondition',
  1731. LinesToStr([ // statements
  1732. 'this.Func1 = function () {',
  1733. ' var Result = 0;',
  1734. ' return Result;',
  1735. '};',
  1736. 'this.Func2 = function () {',
  1737. ' var Result = false;',
  1738. ' return Result;',
  1739. '};',
  1740. 'this.i = 0;'
  1741. ]),
  1742. LinesToStr([
  1743. 'if (this.Func2());',
  1744. 'if (this.i == this.Func1());',
  1745. 'if (this.i == this.Func1());'
  1746. ]));
  1747. end;
  1748. procedure TTestModule.TestExit;
  1749. begin
  1750. StartProgram(false);
  1751. Add('procedure ProcA;');
  1752. Add('begin');
  1753. Add(' exit;');
  1754. Add('end;');
  1755. Add('function FuncB: longint;');
  1756. Add('begin');
  1757. Add(' exit;');
  1758. Add(' exit(3);');
  1759. Add('end;');
  1760. Add('function FuncC: string;');
  1761. Add('begin');
  1762. Add(' exit;');
  1763. Add(' exit(''a'');');
  1764. Add(' exit(''abc'');');
  1765. Add('end;');
  1766. Add('begin');
  1767. ConvertProgram;
  1768. CheckSource('TestExit',
  1769. LinesToStr([ // statements
  1770. 'this.ProcA = function () {',
  1771. ' return;',
  1772. '};',
  1773. 'this.FuncB = function () {',
  1774. ' var Result = 0;',
  1775. ' return Result;',
  1776. ' return 3;',
  1777. ' return Result;',
  1778. '};',
  1779. 'this.FuncC = function () {',
  1780. ' var Result = "";',
  1781. ' return Result;',
  1782. ' return "a";',
  1783. ' return "abc";',
  1784. ' return Result;',
  1785. '};'
  1786. ]),
  1787. '');
  1788. end;
  1789. procedure TTestModule.TestBreak;
  1790. begin
  1791. StartProgram(false);
  1792. Add('var i: longint;');
  1793. Add('begin');
  1794. Add(' repeat');
  1795. Add(' break;');
  1796. Add(' until true;');
  1797. Add(' while true do');
  1798. Add(' break;');
  1799. Add(' for i:=1 to 2 do');
  1800. Add(' break;');
  1801. ConvertProgram;
  1802. CheckSource('TestBreak',
  1803. LinesToStr([ // statements
  1804. 'this.i = 0;'
  1805. ]),
  1806. LinesToStr([
  1807. 'do {',
  1808. ' break;',
  1809. '} while (!true);',
  1810. 'while (true) break;',
  1811. 'var $loopend1 = 2;',
  1812. 'for (this.i = 1; this.i <= $loopend1; this.i++) break;',
  1813. 'if (this.i > $loopend1) this.i--;'
  1814. ]));
  1815. end;
  1816. procedure TTestModule.TestContinue;
  1817. begin
  1818. StartProgram(false);
  1819. Add('var i: longint;');
  1820. Add('begin');
  1821. Add(' repeat');
  1822. Add(' continue;');
  1823. Add(' until true;');
  1824. Add(' while true do');
  1825. Add(' continue;');
  1826. Add(' for i:=1 to 2 do');
  1827. Add(' continue;');
  1828. ConvertProgram;
  1829. CheckSource('TestContinue',
  1830. LinesToStr([ // statements
  1831. 'this.i = 0;'
  1832. ]),
  1833. LinesToStr([
  1834. 'do {',
  1835. ' continue;',
  1836. '} while (!true);',
  1837. 'while (true) continue;',
  1838. 'var $loopend1 = 2;',
  1839. 'for (this.i = 1; this.i <= $loopend1; this.i++) continue;',
  1840. 'if (this.i > $loopend1) this.i--;'
  1841. ]));
  1842. end;
  1843. procedure TTestModule.TestProcedureExternal;
  1844. begin
  1845. StartProgram(false);
  1846. Add('procedure Foo; external name ''console.log'';');
  1847. Add('function Bar: longint; external name ''get.item'';');
  1848. Add('function Bla(s: string): longint; external name ''apply.something'';');
  1849. Add('var');
  1850. Add(' i: longint;');
  1851. Add('begin');
  1852. Add(' Foo;');
  1853. Add(' i:=Bar;');
  1854. Add(' i:=Bla(''abc'');');
  1855. ConvertProgram;
  1856. CheckSource('TestProcedureExternal',
  1857. LinesToStr([ // statements
  1858. 'this.i = 0;'
  1859. ]),
  1860. LinesToStr([
  1861. 'console.log();',
  1862. 'this.i = get.item();',
  1863. 'this.i = apply.something("abc");'
  1864. ]));
  1865. end;
  1866. procedure TTestModule.TestProcedureExternalOtherUnit;
  1867. begin
  1868. AddModuleWithIntfImplSrc('unit2.pas',
  1869. LinesToStr([
  1870. 'procedure Now; external name ''Date.now'';',
  1871. 'procedure DoIt;'
  1872. ]),
  1873. 'procedure doit; begin end;');
  1874. StartUnit(true);
  1875. Add('interface');
  1876. Add('uses unit2;');
  1877. Add('implementation');
  1878. Add('begin');
  1879. Add(' now;');
  1880. Add(' now();');
  1881. Add(' uNit2.now;');
  1882. Add(' uNit2.now();');
  1883. Add(' test1.now;');
  1884. Add(' test1.now();');
  1885. Add(' doit;');
  1886. Add(' uNit2.doit;');
  1887. Add(' test1.doit;');
  1888. ConvertUnit;
  1889. CheckSource('TestProcedureExternalOtherUnit',
  1890. LinesToStr([
  1891. 'var $impl = {',
  1892. '};',
  1893. 'this.$impl = $impl;'
  1894. ]),
  1895. LinesToStr([
  1896. 'Date.now();',
  1897. 'Date.now();',
  1898. 'Date.now();',
  1899. 'Date.now();',
  1900. 'Date.now();',
  1901. 'Date.now();',
  1902. 'pas.unit2.DoIt();',
  1903. 'pas.unit2.DoIt();',
  1904. 'pas.unit2.DoIt();'
  1905. ]));
  1906. end;
  1907. procedure TTestModule.TestProcedureAsm;
  1908. begin
  1909. StartProgram(false);
  1910. Add('function DoIt: longint;');
  1911. Add('begin;');
  1912. Add(' asm');
  1913. Add(' { a:{ b:{}, c:[]}, d:''1'' };');
  1914. Add(' end;');
  1915. Add('end;');
  1916. Add('begin');
  1917. ConvertProgram;
  1918. CheckSource('TestProcedureAsm',
  1919. LinesToStr([ // statements
  1920. 'this.DoIt = function () {',
  1921. ' var Result = 0;',
  1922. ' { a:{ b:{}, c:[]}, d:''1'' };',
  1923. ' return Result;',
  1924. '};'
  1925. ]),
  1926. LinesToStr([
  1927. ''
  1928. ]));
  1929. end;
  1930. procedure TTestModule.TestProcedureAssembler;
  1931. begin
  1932. StartProgram(false);
  1933. Add('function DoIt: longint; assembler;');
  1934. Add('asm');
  1935. Add('{ a:{ b:{}, c:[]}, d:''1'' };');
  1936. Add('end;');
  1937. Add('begin');
  1938. ConvertProgram;
  1939. CheckSource('TestProcedureAssembler',
  1940. LinesToStr([ // statements
  1941. 'this.DoIt = function () {',
  1942. ' { a:{ b:{}, c:[]}, d:''1'' };',
  1943. '};'
  1944. ]),
  1945. LinesToStr([
  1946. ''
  1947. ]));
  1948. end;
  1949. procedure TTestModule.TestProcedure_VarParam;
  1950. begin
  1951. StartProgram(false);
  1952. Add('type integer = longint;');
  1953. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  1954. Add('var vJ: integer;');
  1955. Add('begin');
  1956. Add(' vg:=vg+1;');
  1957. Add(' vj:=vh+2;');
  1958. Add(' vi:=vi+3;');
  1959. Add(' doit(vg,vg,vg);');
  1960. Add(' doit(vh,vh,vj);');
  1961. Add(' doit(vi,vi,vi);');
  1962. Add(' doit(vj,vj,vj);');
  1963. Add('end;');
  1964. Add('var i: integer;');
  1965. Add('begin');
  1966. Add(' doit(i,i,i);');
  1967. ConvertProgram;
  1968. CheckSource('TestProcedure_VarParam',
  1969. LinesToStr([ // statements
  1970. 'this.DoIt = function (vG,vH,vI) {',
  1971. ' var vJ = 0;',
  1972. ' vG = vG + 1;',
  1973. ' vJ = vH + 2;',
  1974. ' vI.set(vI.get()+3);',
  1975. ' this.DoIt(vG, vG, {',
  1976. ' get: function () {',
  1977. ' return vG;',
  1978. ' },',
  1979. ' set: function (v) {',
  1980. ' vG = v;',
  1981. ' }',
  1982. ' });',
  1983. ' this.DoIt(vH, vH, {',
  1984. ' get: function () {',
  1985. ' return vJ;',
  1986. ' },',
  1987. ' set: function (v) {',
  1988. ' vJ = v;',
  1989. ' }',
  1990. ' });',
  1991. ' this.DoIt(vI.get(), vI.get(), vI);',
  1992. ' this.DoIt(vJ, vJ, {',
  1993. ' get: function () {',
  1994. ' return vJ;',
  1995. ' },',
  1996. ' set: function (v) {',
  1997. ' vJ = v;',
  1998. ' }',
  1999. ' });',
  2000. '};',
  2001. 'this.i = 0;'
  2002. ]),
  2003. LinesToStr([
  2004. 'this.DoIt(this.i,this.i,{',
  2005. ' p: this,',
  2006. ' get: function () {',
  2007. ' return this.p.i;',
  2008. ' },',
  2009. ' set: function (v) {',
  2010. ' this.p.i = v;',
  2011. ' }',
  2012. '});'
  2013. ]));
  2014. end;
  2015. procedure TTestModule.TestProcedureOverload;
  2016. begin
  2017. StartProgram(false);
  2018. Add('procedure DoIt(vI: longint); begin end;');
  2019. Add('procedure DoIt(vI, vJ: longint); begin end;');
  2020. Add('procedure DoIt(vD: double); begin end;');
  2021. Add('begin');
  2022. Add(' DoIt(1);');
  2023. Add(' DoIt(2,3);');
  2024. Add(' DoIt(4.5);');
  2025. ConvertProgram;
  2026. CheckSource('TestProcedureOverload',
  2027. LinesToStr([ // statements
  2028. 'this.DoIt = function (vI) {',
  2029. '};',
  2030. 'this.DoIt$1 = function (vI, vJ) {',
  2031. '};',
  2032. 'this.DoIt$2 = function (vD) {',
  2033. '};',
  2034. '']),
  2035. LinesToStr([
  2036. 'this.DoIt(1);',
  2037. 'this.DoIt$1(2, 3);',
  2038. 'this.DoIt$2(4.5);',
  2039. '']));
  2040. end;
  2041. procedure TTestModule.TestProcedureOverloadForward;
  2042. begin
  2043. StartProgram(false);
  2044. Add('procedure DoIt(vI: longint); forward;');
  2045. Add('procedure DoIt(vI, vJ: longint); begin end;');
  2046. Add('procedure doit(vi: longint); begin end;');
  2047. Add('begin');
  2048. Add(' doit(1);');
  2049. Add(' doit(2,3);');
  2050. ConvertProgram;
  2051. CheckSource('TestProcedureOverloadForward',
  2052. LinesToStr([ // statements
  2053. 'this.DoIt$1 = function (vI, vJ) {',
  2054. '};',
  2055. 'this.DoIt = function (vI) {',
  2056. '};',
  2057. '']),
  2058. LinesToStr([
  2059. 'this.DoIt(1);',
  2060. 'this.DoIt$1(2, 3);',
  2061. '']));
  2062. end;
  2063. procedure TTestModule.TestProcedureOverloadUnit;
  2064. begin
  2065. StartUnit(false);
  2066. Add('interface');
  2067. Add('procedure DoIt(vI: longint);');
  2068. Add('procedure DoIt(vI, vJ: longint);');
  2069. Add('implementation');
  2070. Add('procedure DoIt(vI, vJ, vK, vL, vM: longint); forward;');
  2071. Add('procedure DoIt(vI, vJ, vK: longint); begin end;');
  2072. Add('procedure DoIt(vi: longint); begin end;');
  2073. Add('procedure DoIt(vI, vJ, vK, vL: longint); begin end;');
  2074. Add('procedure DoIt(vi, vj: longint); begin end;');
  2075. Add('procedure DoIt(vi, vj, vk, vl, vm: longint); begin end;');
  2076. Add('begin');
  2077. Add(' doit(1);');
  2078. Add(' doit(2,3);');
  2079. Add(' doit(4,5,6);');
  2080. Add(' doit(7,8,9,10);');
  2081. Add(' doit(11,12,13,14,15);');
  2082. ConvertUnit;
  2083. CheckSource('TestProcedureOverloadUnit',
  2084. LinesToStr([ // statements
  2085. 'var $impl = {',
  2086. '};',
  2087. 'this.$impl = $impl;',
  2088. 'this.DoIt = function (vI) {',
  2089. '};',
  2090. 'this.DoIt$1 = function (vI, vJ) {',
  2091. '};',
  2092. '$impl.DoIt$3 = function (vI, vJ, vK) {',
  2093. '};',
  2094. '$impl.DoIt$4 = function (vI, vJ, vK, vL) {',
  2095. '};',
  2096. '$impl.DoIt$2 = function (vI, vJ, vK, vL, vM) {',
  2097. '};',
  2098. '']),
  2099. LinesToStr([
  2100. 'this.DoIt(1);',
  2101. 'this.DoIt$1(2, 3);',
  2102. '$impl.DoIt$3(4,5,6);',
  2103. '$impl.DoIt$4(7,8,9,10);',
  2104. '$impl.DoIt$2(11,12,13,14,15);',
  2105. '']));
  2106. end;
  2107. procedure TTestModule.TestProcedureOverloadNested;
  2108. begin
  2109. StartProgram(false);
  2110. Add('procedure DoIt(vA: longint); forward;');
  2111. Add('procedure DoIt(vB, vC: longint);');
  2112. Add('begin // 2 param overload');
  2113. Add(' doit(1);');
  2114. Add(' doit(1,2);');
  2115. Add('end;');
  2116. Add('procedure doit(vA: longint);');
  2117. Add(' procedure DoIt(vA, vB, vC: longint); forward;');
  2118. Add(' procedure DoIt(vA, vB, vC, vD: longint);');
  2119. Add(' begin // 4 param overload');
  2120. Add(' doit(1);');
  2121. Add(' doit(1,2);');
  2122. Add(' doit(1,2,3);');
  2123. Add(' doit(1,2,3,4);');
  2124. Add(' end;');
  2125. Add(' procedure doit(vA, vB, vC: longint);');
  2126. Add(' procedure DoIt(vA, vB, vC, vD, vE: longint); forward;');
  2127. Add(' procedure DoIt(vA, vB, vC, vD, vE, vF: longint);');
  2128. Add(' begin // 6 param overload');
  2129. Add(' doit(1);');
  2130. Add(' doit(1,2);');
  2131. Add(' doit(1,2,3);');
  2132. Add(' doit(1,2,3,4);');
  2133. Add(' doit(1,2,3,4,5);');
  2134. Add(' doit(1,2,3,4,5,6);');
  2135. Add(' end;');
  2136. Add(' procedure doit(vA, vB, vC, vD, vE: longint);');
  2137. Add(' begin // 5 param overload');
  2138. Add(' doit(1);');
  2139. Add(' doit(1,2);');
  2140. Add(' doit(1,2,3);');
  2141. Add(' doit(1,2,3,4);');
  2142. Add(' doit(1,2,3,4,5);');
  2143. Add(' doit(1,2,3,4,5,6);');
  2144. Add(' end;');
  2145. Add(' begin // 3 param overload');
  2146. Add(' doit(1);');
  2147. Add(' doit(1,2);');
  2148. Add(' doit(1,2,3);');
  2149. Add(' doit(1,2,3,4);');
  2150. Add(' doit(1,2,3,4,5);');
  2151. Add(' doit(1,2,3,4,5,6);');
  2152. Add(' end;');
  2153. Add('begin // 1 param overload');
  2154. Add(' doit(1);');
  2155. Add(' doit(1,2);');
  2156. Add(' doit(1,2,3);');
  2157. Add(' doit(1,2,3,4);');
  2158. Add('end;');
  2159. Add('begin // main');
  2160. Add(' doit(1);');
  2161. Add(' doit(1,2);');
  2162. ConvertProgram;
  2163. CheckSource('TestProcedureOverloadNested',
  2164. LinesToStr([ // statements
  2165. 'this.DoIt$1 = function (vB, vC) {',
  2166. ' this.DoIt(1);',
  2167. ' this.DoIt$1(1, 2);',
  2168. '};',
  2169. 'this.DoIt = function (vA) {',
  2170. ' function DoIt$3(vA, vB, vC, vD) {',
  2171. ' this.DoIt(1);',
  2172. ' this.DoIt$1(1, 2);',
  2173. ' DoIt$2(1, 2, 3);',
  2174. ' DoIt$3(1, 2, 3, 4);',
  2175. ' };',
  2176. ' function DoIt$2(vA, vB, vC) {',
  2177. ' function DoIt$5(vA, vB, vC, vD, vE, vF) {',
  2178. ' this.DoIt(1);',
  2179. ' this.DoIt$1(1, 2);',
  2180. ' DoIt$2(1, 2, 3);',
  2181. ' DoIt$3(1, 2, 3, 4);',
  2182. ' DoIt$4(1, 2, 3, 4, 5);',
  2183. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  2184. ' };',
  2185. ' function DoIt$4(vA, vB, vC, vD, vE) {',
  2186. ' this.DoIt(1);',
  2187. ' this.DoIt$1(1, 2);',
  2188. ' DoIt$2(1, 2, 3);',
  2189. ' DoIt$3(1, 2, 3, 4);',
  2190. ' DoIt$4(1, 2, 3, 4, 5);',
  2191. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  2192. ' };',
  2193. ' this.DoIt(1);',
  2194. ' this.DoIt$1(1, 2);',
  2195. ' DoIt$2(1, 2, 3);',
  2196. ' DoIt$3(1, 2, 3, 4);',
  2197. ' DoIt$4(1, 2, 3, 4, 5);',
  2198. ' DoIt$5(1, 2, 3, 4, 5, 6);',
  2199. ' };',
  2200. ' this.DoIt(1);',
  2201. ' this.DoIt$1(1, 2);',
  2202. ' DoIt$2(1, 2, 3);',
  2203. ' DoIt$3(1, 2, 3, 4);',
  2204. '};',
  2205. '']),
  2206. LinesToStr([
  2207. 'this.DoIt(1);',
  2208. 'this.DoIt$1(1, 2);',
  2209. '']));
  2210. end;
  2211. procedure TTestModule.TestProc_Varargs;
  2212. begin
  2213. StartProgram(false);
  2214. Add('procedure ProcA(i:longint); varargs; external name ''ProcA'';');
  2215. Add('procedure ProcB; varargs; external name ''ProcB'';');
  2216. Add('procedure ProcC(i: longint = 17); varargs; external name ''ProcC'';');
  2217. Add('function GetIt: longint; begin end;');
  2218. Add('begin');
  2219. Add(' ProcA(1);');
  2220. Add(' ProcA(1,2);');
  2221. Add(' ProcA(1,2.0);');
  2222. Add(' ProcA(1,2,3);');
  2223. Add(' ProcA(1,''2'');');
  2224. Add(' ProcA(2,'''');');
  2225. Add(' ProcA(3,false);');
  2226. Add(' ProcB;');
  2227. Add(' ProcB();');
  2228. Add(' ProcB(4);');
  2229. Add(' ProcB(''foo'');');
  2230. Add(' ProcC;');
  2231. Add(' ProcC();');
  2232. Add(' ProcC(4);');
  2233. Add(' ProcC(5,''foo'');');
  2234. Add(' ProcB(GetIt);');
  2235. Add(' ProcB(GetIt());');
  2236. Add(' ProcB(GetIt,GetIt());');
  2237. ConvertProgram;
  2238. CheckSource('TestProc_Varargs',
  2239. LinesToStr([ // statements
  2240. 'this.GetIt = function () {',
  2241. ' var Result = 0;',
  2242. ' return Result;',
  2243. '};',
  2244. '']),
  2245. LinesToStr([
  2246. 'ProcA(1);',
  2247. 'ProcA(1, 2);',
  2248. 'ProcA(1, 2.0);',
  2249. 'ProcA(1, 2, 3);',
  2250. 'ProcA(1, "2");',
  2251. 'ProcA(2, "");',
  2252. 'ProcA(3, false);',
  2253. 'ProcB();',
  2254. 'ProcB();',
  2255. 'ProcB(4);',
  2256. 'ProcB("foo");',
  2257. 'ProcC(17);',
  2258. 'ProcC(17);',
  2259. 'ProcC(4);',
  2260. 'ProcC(5, "foo");',
  2261. 'ProcB(this.GetIt());',
  2262. 'ProcB(this.GetIt());',
  2263. 'ProcB(this.GetIt(), this.GetIt());',
  2264. '']));
  2265. end;
  2266. procedure TTestModule.TestEnumName;
  2267. begin
  2268. StartProgram(false);
  2269. Add('type TMyEnum = (Red, Green, Blue);');
  2270. Add('var e: TMyEnum;');
  2271. Add('var f: TMyEnum = Blue;');
  2272. Add('begin');
  2273. Add(' e:=green;');
  2274. ConvertProgram;
  2275. CheckSource('TestEnumName',
  2276. LinesToStr([ // statements
  2277. 'this.TMyEnum = {',
  2278. ' "0":"Red",',
  2279. ' Red:0,',
  2280. ' "1":"Green",',
  2281. ' Green:1,',
  2282. ' "2":"Blue",',
  2283. ' Blue:2',
  2284. ' };',
  2285. 'this.e = 0;',
  2286. 'this.f = this.TMyEnum.Blue;'
  2287. ]),
  2288. LinesToStr([
  2289. 'this.e=this.TMyEnum.Green;'
  2290. ]));
  2291. end;
  2292. procedure TTestModule.TestEnumNumber;
  2293. begin
  2294. Converter.Options:=Converter.Options+[coEnumNumbers];
  2295. StartProgram(false);
  2296. Add('type TMyEnum = (Red, Green);');
  2297. Add('var');
  2298. Add(' e: TMyEnum;');
  2299. Add(' f: TMyEnum = Green;');
  2300. Add('begin');
  2301. Add(' e:=green;');
  2302. ConvertProgram;
  2303. CheckSource('TestEnumNumber',
  2304. LinesToStr([ // statements
  2305. 'this.TMyEnum = {',
  2306. ' "0":"Red",',
  2307. ' Red:0,',
  2308. ' "1":"Green",',
  2309. ' Green:1',
  2310. ' };',
  2311. 'this.e = 0;',
  2312. 'this.f = 1;'
  2313. ]),
  2314. LinesToStr([
  2315. 'this.e=1;'
  2316. ]));
  2317. end;
  2318. procedure TTestModule.TestEnumFunctions;
  2319. begin
  2320. StartProgram(false);
  2321. Add('type TMyEnum = (Red, Green);');
  2322. Add('var');
  2323. Add(' e: TMyEnum;');
  2324. Add(' i: longint;');
  2325. Add(' s: string;');
  2326. Add('begin');
  2327. Add(' i:=ord(red);');
  2328. Add(' i:=ord(green);');
  2329. Add(' i:=ord(e);');
  2330. Add(' e:=low(tmyenum);');
  2331. Add(' e:=low(e);');
  2332. Add(' e:=high(tmyenum);');
  2333. Add(' e:=high(e);');
  2334. Add(' e:=pred(green);');
  2335. Add(' e:=pred(e);');
  2336. Add(' e:=succ(red);');
  2337. Add(' e:=succ(e);');
  2338. Add(' e:=tmyenum(1);');
  2339. Add(' e:=tmyenum(i);');
  2340. Add(' s:=str(e);');
  2341. Add(' str(e,s)');
  2342. Add(' s:=str(e:3);');
  2343. ConvertProgram;
  2344. CheckSource('TestEnumNumber',
  2345. LinesToStr([ // statements
  2346. 'this.TMyEnum = {',
  2347. ' "0":"Red",',
  2348. ' Red:0,',
  2349. ' "1":"Green",',
  2350. ' Green:1',
  2351. ' };',
  2352. 'this.e = 0;',
  2353. 'this.i = 0;',
  2354. 'this.s = "";'
  2355. ]),
  2356. LinesToStr([
  2357. 'this.i=this.TMyEnum.Red;',
  2358. 'this.i=this.TMyEnum.Green;',
  2359. 'this.i=this.e;',
  2360. 'this.e=this.TMyEnum.Red;',
  2361. 'this.e=this.TMyEnum.Red;',
  2362. 'this.e=this.TMyEnum.Green;',
  2363. 'this.e=this.TMyEnum.Green;',
  2364. 'this.e=this.TMyEnum.Green-1;',
  2365. 'this.e=this.e-1;',
  2366. 'this.e=this.TMyEnum.Red+1;',
  2367. 'this.e=this.e+1;',
  2368. 'this.e=1;',
  2369. 'this.e=this.i;',
  2370. 'this.s = this.TMyEnum[this.e];',
  2371. 'this.s = this.TMyEnum[this.e];',
  2372. 'this.s = rtl.spaceLeft(this.TMyEnum[this.e], 3);',
  2373. '']));
  2374. end;
  2375. procedure TTestModule.TestSet;
  2376. begin
  2377. StartProgram(false);
  2378. Add('type');
  2379. Add(' TColor = (Red, Green, Blue);');
  2380. Add(' TColors = set of TColor;');
  2381. Add('var');
  2382. Add(' c: TColor;');
  2383. Add(' s: TColors;');
  2384. Add(' t: TColors = [];');
  2385. Add(' u: TColors = [Red];');
  2386. Add('begin');
  2387. Add(' s:=[];');
  2388. Add(' s:=[Green];');
  2389. Add(' s:=[Green,Blue];');
  2390. Add(' s:=[Red..Blue];');
  2391. Add(' s:=[Red,Green..Blue];');
  2392. Add(' s:=[Red,c];');
  2393. Add(' s:=t;');
  2394. ConvertProgram;
  2395. CheckSource('TestEnumName',
  2396. LinesToStr([ // statements
  2397. 'this.TColor = {',
  2398. ' "0":"Red",',
  2399. ' Red:0,',
  2400. ' "1":"Green",',
  2401. ' Green:1,',
  2402. ' "2":"Blue",',
  2403. ' Blue:2',
  2404. ' };',
  2405. 'this.c = 0;',
  2406. 'this.s = {};',
  2407. 'this.t = {};',
  2408. 'this.u = rtl.createSet(this.TColor.Red);'
  2409. ]),
  2410. LinesToStr([
  2411. 'this.s={};',
  2412. 'this.s=rtl.createSet(this.TColor.Green);',
  2413. 'this.s=rtl.createSet(this.TColor.Green,this.TColor.Blue);',
  2414. 'this.s=rtl.createSet(null,this.TColor.Red,this.TColor.Blue);',
  2415. 'this.s=rtl.createSet(this.TColor.Red,null,this.TColor.Green,this.TColor.Blue);',
  2416. 'this.s=rtl.createSet(this.TColor.Red,this.c);',
  2417. 'this.s=rtl.refSet(this.t);',
  2418. '']));
  2419. end;
  2420. procedure TTestModule.TestSetOperators;
  2421. begin
  2422. StartProgram(false);
  2423. Add('type');
  2424. Add(' TColor = (Red, Green, Blue);');
  2425. Add(' TColors = set of tcolor;');
  2426. Add('var');
  2427. Add(' vC: TColor;');
  2428. Add(' vS: TColors;');
  2429. Add(' vT: TColors;');
  2430. Add(' vU: TColors;');
  2431. Add(' B: boolean;');
  2432. Add('begin');
  2433. Add(' include(vs,green);');
  2434. Add(' exclude(vs,vc);');
  2435. Add(' vs:=vt+vu;');
  2436. Add(' vs:=vt+[red];');
  2437. Add(' vs:=[red]+vt;');
  2438. Add(' vs:=[red]+[green];');
  2439. Add(' vs:=vt-vu;');
  2440. Add(' vs:=vt-[red];');
  2441. Add(' vs:=[red]-vt;');
  2442. Add(' vs:=[red]-[green];');
  2443. Add(' vs:=vt*vu;');
  2444. Add(' vs:=vt*[red];');
  2445. Add(' vs:=[red]*vt;');
  2446. Add(' vs:=[red]*[green];');
  2447. Add(' vs:=vt><vu;');
  2448. Add(' vs:=vt><[red];');
  2449. Add(' vs:=[red]><vt;');
  2450. Add(' vs:=[red]><[green];');
  2451. Add(' b:=vt=vu;');
  2452. Add(' b:=vt=[red];');
  2453. Add(' b:=[red]=vt;');
  2454. Add(' b:=[red]=[green];');
  2455. Add(' b:=vt<>vu;');
  2456. Add(' b:=vt<>[red];');
  2457. Add(' b:=[red]<>vt;');
  2458. Add(' b:=[red]<>[green];');
  2459. Add(' b:=vt<=vu;');
  2460. Add(' b:=vt<=[red];');
  2461. Add(' b:=[red]<=vt;');
  2462. Add(' b:=[red]<=[green];');
  2463. Add(' b:=vt>=vu;');
  2464. Add(' b:=vt>=[red];');
  2465. Add(' b:=[red]>=vt;');
  2466. Add(' b:=[red]>=[green];');
  2467. Add(' b:=Red in vt;');
  2468. Add(' b:=vc in vt;');
  2469. Add(' b:=Green in [Red..Blue];');
  2470. Add(' b:=vc in [Red..Blue];');
  2471. ConvertProgram;
  2472. CheckSource('TestEnumName',
  2473. LinesToStr([ // statements
  2474. 'this.TColor = {',
  2475. ' "0":"Red",',
  2476. ' Red:0,',
  2477. ' "1":"Green",',
  2478. ' Green:1,',
  2479. ' "2":"Blue",',
  2480. ' Blue:2',
  2481. ' };',
  2482. 'this.vC = 0;',
  2483. 'this.vS = {};',
  2484. 'this.vT = {};',
  2485. 'this.vU = {};',
  2486. 'this.B = false;'
  2487. ]),
  2488. LinesToStr([
  2489. 'this.vS = rtl.includeSet(this.vS,this.TColor.Green);',
  2490. 'this.vS = rtl.excludeSet(this.vS,this.vC);',
  2491. 'this.vS = rtl.unionSet(this.vT, this.vU);',
  2492. 'this.vS = rtl.unionSet(this.vT, rtl.createSet(this.TColor.Red));',
  2493. 'this.vS = rtl.unionSet(rtl.createSet(this.TColor.Red), this.vT);',
  2494. 'this.vS = rtl.unionSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2495. 'this.vS = rtl.diffSet(this.vT, this.vU);',
  2496. 'this.vS = rtl.diffSet(this.vT, rtl.createSet(this.TColor.Red));',
  2497. 'this.vS = rtl.diffSet(rtl.createSet(this.TColor.Red), this.vT);',
  2498. 'this.vS = rtl.diffSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2499. 'this.vS = rtl.intersectSet(this.vT, this.vU);',
  2500. 'this.vS = rtl.intersectSet(this.vT, rtl.createSet(this.TColor.Red));',
  2501. 'this.vS = rtl.intersectSet(rtl.createSet(this.TColor.Red), this.vT);',
  2502. 'this.vS = rtl.intersectSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2503. 'this.vS = rtl.symDiffSet(this.vT, this.vU);',
  2504. 'this.vS = rtl.symDiffSet(this.vT, rtl.createSet(this.TColor.Red));',
  2505. 'this.vS = rtl.symDiffSet(rtl.createSet(this.TColor.Red), this.vT);',
  2506. 'this.vS = rtl.symDiffSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2507. 'this.B = rtl.eqSet(this.vT, this.vU);',
  2508. 'this.B = rtl.eqSet(this.vT, rtl.createSet(this.TColor.Red));',
  2509. 'this.B = rtl.eqSet(rtl.createSet(this.TColor.Red), this.vT);',
  2510. 'this.B = rtl.eqSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2511. 'this.B = rtl.neSet(this.vT, this.vU);',
  2512. 'this.B = rtl.neSet(this.vT, rtl.createSet(this.TColor.Red));',
  2513. 'this.B = rtl.neSet(rtl.createSet(this.TColor.Red), this.vT);',
  2514. 'this.B = rtl.neSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2515. 'this.B = rtl.leSet(this.vT, this.vU);',
  2516. 'this.B = rtl.leSet(this.vT, rtl.createSet(this.TColor.Red));',
  2517. 'this.B = rtl.leSet(rtl.createSet(this.TColor.Red), this.vT);',
  2518. 'this.B = rtl.leSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2519. 'this.B = rtl.geSet(this.vT, this.vU);',
  2520. 'this.B = rtl.geSet(this.vT, rtl.createSet(this.TColor.Red));',
  2521. 'this.B = rtl.geSet(rtl.createSet(this.TColor.Red), this.vT);',
  2522. 'this.B = rtl.geSet(rtl.createSet(this.TColor.Red), rtl.createSet(this.TColor.Green));',
  2523. 'this.B = this.vT[this.TColor.Red];',
  2524. 'this.B = this.vT[this.vC];',
  2525. 'this.B = rtl.createSet(null, this.TColor.Red, this.TColor.Blue)[this.TColor.Green];',
  2526. 'this.B = rtl.createSet(null, this.TColor.Red, this.TColor.Blue)[this.vC];',
  2527. '']));
  2528. end;
  2529. procedure TTestModule.TestSetFunctions;
  2530. begin
  2531. StartProgram(false);
  2532. Add('type');
  2533. Add(' TMyEnum = (Red, Green);');
  2534. Add(' TMyEnums = set of TMyEnum;');
  2535. Add('var');
  2536. Add(' e: TMyEnum;');
  2537. Add(' s: TMyEnums;');
  2538. Add('begin');
  2539. Add(' e:=Low(TMyEnums);');
  2540. Add(' e:=Low(s);');
  2541. Add(' e:=High(TMyEnums);');
  2542. Add(' e:=High(s);');
  2543. ConvertProgram;
  2544. CheckSource('TestSetFunctions',
  2545. LinesToStr([ // statements
  2546. 'this.TMyEnum = {',
  2547. ' "0":"Red",',
  2548. ' Red:0,',
  2549. ' "1":"Green",',
  2550. ' Green:1',
  2551. ' };',
  2552. 'this.e = 0;',
  2553. 'this.s = {};'
  2554. ]),
  2555. LinesToStr([
  2556. 'this.e=this.TMyEnum.Red;',
  2557. 'this.e=this.TMyEnum.Red;',
  2558. 'this.e=this.TMyEnum.Green;',
  2559. 'this.e=this.TMyEnum.Green;',
  2560. '']));
  2561. end;
  2562. procedure TTestModule.TestSet_PassAsArgClone;
  2563. begin
  2564. StartProgram(false);
  2565. Add('type');
  2566. Add(' TMyEnum = (Red, Green);');
  2567. Add(' TMyEnums = set of TMyEnum;');
  2568. Add('procedure DoDefault(s: tmyenums); begin end;');
  2569. Add('procedure DoConst(const s: tmyenums); begin end;');
  2570. Add('var');
  2571. Add(' aSet: tmyenums;');
  2572. Add('begin');
  2573. Add(' dodefault(aset);');
  2574. Add(' doconst(aset);');
  2575. ConvertProgram;
  2576. CheckSource('TestSetFunctions',
  2577. LinesToStr([ // statements
  2578. 'this.TMyEnum = {',
  2579. ' "0":"Red",',
  2580. ' Red:0,',
  2581. ' "1":"Green",',
  2582. ' Green:1',
  2583. ' };',
  2584. 'this.DoDefault = function (s) {',
  2585. '};',
  2586. 'this.DoConst = function (s) {',
  2587. '};',
  2588. 'this.aSet = {};'
  2589. ]),
  2590. LinesToStr([
  2591. 'this.DoDefault(rtl.refSet(this.aSet));',
  2592. 'this.DoConst(this.aSet);',
  2593. '']));
  2594. end;
  2595. procedure TTestModule.TestEnum_AsParams;
  2596. begin
  2597. StartProgram(false);
  2598. Add('type TEnum = (Red,Blue);');
  2599. Add('procedure DoIt(vG: TEnum; const vH: TEnum; var vI: TEnum);');
  2600. Add('var vJ: TEnum;');
  2601. Add('begin');
  2602. Add(' vg:=vg;');
  2603. Add(' vj:=vh;');
  2604. Add(' vi:=vi;');
  2605. Add(' doit(vg,vg,vg);');
  2606. Add(' doit(vh,vh,vj);');
  2607. Add(' doit(vi,vi,vi);');
  2608. Add(' doit(vj,vj,vj);');
  2609. Add('end;');
  2610. Add('var i: TEnum;');
  2611. Add('begin');
  2612. Add(' doit(i,i,i);');
  2613. ConvertProgram;
  2614. CheckSource('TestEnum_AsParams',
  2615. LinesToStr([ // statements
  2616. 'this.TEnum = {',
  2617. ' "0": "Red",',
  2618. ' Red: 0,',
  2619. ' "1": "Blue",',
  2620. ' Blue: 1',
  2621. '};',
  2622. 'this.DoIt = function (vG,vH,vI) {',
  2623. ' var vJ = 0;',
  2624. ' vG = vG;',
  2625. ' vJ = vH;',
  2626. ' vI.set(vI.get());',
  2627. ' this.DoIt(vG, vG, {',
  2628. ' get: function () {',
  2629. ' return vG;',
  2630. ' },',
  2631. ' set: function (v) {',
  2632. ' vG = v;',
  2633. ' }',
  2634. ' });',
  2635. ' this.DoIt(vH, vH, {',
  2636. ' get: function () {',
  2637. ' return vJ;',
  2638. ' },',
  2639. ' set: function (v) {',
  2640. ' vJ = v;',
  2641. ' }',
  2642. ' });',
  2643. ' this.DoIt(vI.get(), vI.get(), vI);',
  2644. ' this.DoIt(vJ, vJ, {',
  2645. ' get: function () {',
  2646. ' return vJ;',
  2647. ' },',
  2648. ' set: function (v) {',
  2649. ' vJ = v;',
  2650. ' }',
  2651. ' });',
  2652. '};',
  2653. 'this.i = 0;'
  2654. ]),
  2655. LinesToStr([
  2656. 'this.DoIt(this.i,this.i,{',
  2657. ' p: this,',
  2658. ' get: function () {',
  2659. ' return this.p.i;',
  2660. ' },',
  2661. ' set: function (v) {',
  2662. ' this.p.i = v;',
  2663. ' }',
  2664. '});'
  2665. ]));
  2666. end;
  2667. procedure TTestModule.TestSet_AsParams;
  2668. begin
  2669. StartProgram(false);
  2670. Add('type TEnum = (Red,Blue);');
  2671. Add('type TEnums = set of TEnum;');
  2672. Add('procedure DoIt(vG: TEnums; const vH: TEnums; var vI: TEnums);');
  2673. Add('var vJ: TEnums;');
  2674. Add('begin');
  2675. Add(' vg:=vg;');
  2676. Add(' vj:=vh;');
  2677. Add(' vi:=vi;');
  2678. Add(' doit(vg,vg,vg);');
  2679. Add(' doit(vh,vh,vj);');
  2680. Add(' doit(vi,vi,vi);');
  2681. Add(' doit(vj,vj,vj);');
  2682. Add('end;');
  2683. Add('var i: TEnums;');
  2684. Add('begin');
  2685. Add(' doit(i,i,i);');
  2686. ConvertProgram;
  2687. CheckSource('TestSet_AsParams',
  2688. LinesToStr([ // statements
  2689. 'this.TEnum = {',
  2690. ' "0": "Red",',
  2691. ' Red: 0,',
  2692. ' "1": "Blue",',
  2693. ' Blue: 1',
  2694. '};',
  2695. 'this.DoIt = function (vG,vH,vI) {',
  2696. ' var vJ = {};',
  2697. ' vG = rtl.refSet(vG);',
  2698. ' vJ = rtl.refSet(vH);',
  2699. ' vI.set(rtl.refSet(vI.get()));',
  2700. ' this.DoIt(rtl.refSet(vG), vG, {',
  2701. ' get: function () {',
  2702. ' return vG;',
  2703. ' },',
  2704. ' set: function (v) {',
  2705. ' vG = v;',
  2706. ' }',
  2707. ' });',
  2708. ' this.DoIt(rtl.refSet(vH), vH, {',
  2709. ' get: function () {',
  2710. ' return vJ;',
  2711. ' },',
  2712. ' set: function (v) {',
  2713. ' vJ = v;',
  2714. ' }',
  2715. ' });',
  2716. ' this.DoIt(rtl.refSet(vI.get()), vI.get(), vI);',
  2717. ' this.DoIt(rtl.refSet(vJ), vJ, {',
  2718. ' get: function () {',
  2719. ' return vJ;',
  2720. ' },',
  2721. ' set: function (v) {',
  2722. ' vJ = v;',
  2723. ' }',
  2724. ' });',
  2725. '};',
  2726. 'this.i = {};'
  2727. ]),
  2728. LinesToStr([
  2729. 'this.DoIt(rtl.refSet(this.i),this.i,{',
  2730. ' p: this,',
  2731. ' get: function () {',
  2732. ' return this.p.i;',
  2733. ' },',
  2734. ' set: function (v) {',
  2735. ' this.p.i = v;',
  2736. ' }',
  2737. '});'
  2738. ]));
  2739. end;
  2740. procedure TTestModule.TestSet_Property;
  2741. begin
  2742. StartProgram(false);
  2743. Add('type');
  2744. Add(' TEnum = (Red,Blue);');
  2745. Add(' TEnums = set of TEnum;');
  2746. Add(' TObject = class');
  2747. Add(' function GetColors: TEnums; external name ''GetColors'';');
  2748. Add(' procedure SetColors(const Value: TEnums); external name ''SetColors'';');
  2749. Add(' property Colors: TEnums read GetColors write SetColors;');
  2750. Add(' end;');
  2751. Add('procedure DoIt(i: TEnums; const j: TEnums; var k: TEnums; out l: TEnums);');
  2752. Add('begin end;');
  2753. Add('var Obj: TObject;');
  2754. Add('begin');
  2755. Add(' Include(Obj.Colors,Red);');
  2756. Add(' Exclude(Obj.Colors,Red);');
  2757. //Add(' DoIt(Obj.Colors,Obj.Colors,Obj.Colors,Obj.Colors);');
  2758. ConvertProgram;
  2759. CheckSource('TestSet_Property',
  2760. LinesToStr([ // statements
  2761. 'this.TEnum = {',
  2762. ' "0": "Red",',
  2763. ' Red: 0,',
  2764. ' "1": "Blue",',
  2765. ' Blue: 1',
  2766. '};',
  2767. 'rtl.createClass(this, "TObject", null, function () {',
  2768. ' this.$init = function () {',
  2769. ' };',
  2770. ' this.$final = function () {',
  2771. ' };',
  2772. '});',
  2773. 'this.DoIt = function (i, j, k, l) {',
  2774. '};',
  2775. 'this.Obj = null;',
  2776. '']),
  2777. LinesToStr([
  2778. 'this.Obj.SetColors(rtl.includeSet(this.Obj.GetColors(), this.TEnum.Red));',
  2779. 'this.Obj.SetColors(rtl.excludeSet(this.Obj.GetColors(), this.TEnum.Red));',
  2780. '']));
  2781. end;
  2782. procedure TTestModule.TestNestBegin;
  2783. begin
  2784. StartProgram(false);
  2785. Add('begin');
  2786. Add(' begin');
  2787. Add(' begin');
  2788. Add(' end;');
  2789. Add(' begin');
  2790. Add(' if true then ;');
  2791. Add(' end;');
  2792. Add(' end;');
  2793. ConvertProgram;
  2794. CheckSource('TestNestBegin',
  2795. '',
  2796. 'if (true) ;');
  2797. end;
  2798. procedure TTestModule.TestUnitImplVars;
  2799. begin
  2800. StartUnit(false);
  2801. Add('interface');
  2802. Add('implementation');
  2803. Add('var');
  2804. Add(' V1:longint;');
  2805. Add(' V2:longint = 3;');
  2806. Add(' V3:string = ''abc'';');
  2807. ConvertUnit;
  2808. CheckSource('TestUnitImplVars',
  2809. LinesToStr([ // statements
  2810. 'var $impl = {',
  2811. '};',
  2812. 'this.$impl = $impl;',
  2813. '$impl.V1 = 0;',
  2814. '$impl.V2 = 3;',
  2815. '$impl.V3 = "abc";'
  2816. ]),
  2817. '');
  2818. end;
  2819. procedure TTestModule.TestUnitImplConsts;
  2820. begin
  2821. StartUnit(false);
  2822. Add('interface');
  2823. Add('implementation');
  2824. Add('const');
  2825. Add(' v1 = 3;');
  2826. Add(' v2:longint = 4;');
  2827. Add(' v3:string = ''abc'';');
  2828. ConvertUnit;
  2829. CheckSource('TestUnitImplConsts',
  2830. LinesToStr([ // statements
  2831. 'var $impl = {',
  2832. '};',
  2833. 'this.$impl = $impl;',
  2834. '$impl.v1 = 3;',
  2835. '$impl.v2 = 4;',
  2836. '$impl.v3 = "abc";'
  2837. ]),
  2838. '');
  2839. end;
  2840. procedure TTestModule.TestUnitImplRecord;
  2841. begin
  2842. StartUnit(false);
  2843. Add('interface');
  2844. Add('implementation');
  2845. Add('type');
  2846. Add(' TMyRecord = record');
  2847. Add(' i: longint;');
  2848. Add(' end;');
  2849. Add('var aRec: TMyRecord;');
  2850. Add('initialization');
  2851. Add(' arec.i:=3;');
  2852. ConvertUnit;
  2853. CheckSource('TestUnitImplRecord',
  2854. LinesToStr([ // statements
  2855. 'var $impl = {',
  2856. '};',
  2857. 'this.$impl = $impl;',
  2858. '$impl.TMyRecord = function (s) {',
  2859. ' if (s) {',
  2860. ' this.i = s.i;',
  2861. ' } else {',
  2862. ' this.i = 0;',
  2863. ' };',
  2864. ' this.$equal = function (b) {',
  2865. ' return this.i == b.i;',
  2866. ' };',
  2867. '};',
  2868. '$impl.aRec = new $impl.TMyRecord();'
  2869. ]),
  2870. '$impl.aRec.i = 3;'
  2871. );
  2872. end;
  2873. procedure TTestModule.TestRenameJSNameConflict;
  2874. begin
  2875. StartProgram(false);
  2876. Add('var apply: longint;');
  2877. Add('var bind: longint;');
  2878. Add('var call: longint;');
  2879. Add('begin');
  2880. ConvertProgram;
  2881. CheckSource('TestRenameJSNameConflict',
  2882. LinesToStr([ // statements
  2883. 'this.Apply = 0;',
  2884. 'this.Bind = 0;',
  2885. 'this.Call = 0;'
  2886. ]),
  2887. LinesToStr([ // this.$main
  2888. ''
  2889. ]));
  2890. end;
  2891. procedure TTestModule.TestLocalConst;
  2892. begin
  2893. StartProgram(false);
  2894. Add('procedure DoIt;');
  2895. Add('const');
  2896. Add(' cA: longint = 1;');
  2897. Add(' cB = 2;');
  2898. Add(' procedure Sub;');
  2899. Add(' const');
  2900. Add(' csA = 3;');
  2901. Add(' cB: double = 4;');
  2902. Add(' begin');
  2903. Add(' cb:=cb+csa;');
  2904. Add(' ca:=ca+csa+5;');
  2905. Add(' end;');
  2906. Add('begin');
  2907. Add(' ca:=ca+cb+6;');
  2908. Add('end;');
  2909. Add('begin');
  2910. ConvertProgram;
  2911. CheckSource('TestLocalConst',
  2912. LinesToStr([
  2913. 'var cA = 1;',
  2914. 'var cB = 2;',
  2915. 'var csA = 3;',
  2916. 'var cB$1 = 4;',
  2917. 'this.DoIt = function () {',
  2918. ' function Sub() {',
  2919. ' cB$1 = cB$1 + csA;',
  2920. ' cA = (cA + csA) + 5;',
  2921. ' };',
  2922. ' cA = (cA + cB) + 6;',
  2923. '};'
  2924. ]),
  2925. LinesToStr([
  2926. ]));
  2927. end;
  2928. procedure TTestModule.TestVarExternal;
  2929. begin
  2930. StartProgram(false);
  2931. Add('var');
  2932. Add(' NaN: double; external name ''Global.NaN'';');
  2933. Add(' d: double;');
  2934. Add('begin');
  2935. Add(' d:=NaN;');
  2936. ConvertProgram;
  2937. CheckSource('TestVarExternal',
  2938. LinesToStr([
  2939. 'this.d = 0.0;'
  2940. ]),
  2941. LinesToStr([
  2942. 'this.d = Global.NaN;'
  2943. ]));
  2944. end;
  2945. procedure TTestModule.TestVarExternalOtherUnit;
  2946. begin
  2947. AddModuleWithIntfImplSrc('unit2.pas',
  2948. LinesToStr([
  2949. 'var NaN: double; external name ''Global.NaN'';',
  2950. 'var iV: longint;'
  2951. ]),
  2952. '');
  2953. StartUnit(true);
  2954. Add('interface');
  2955. Add('uses unit2;');
  2956. Add('implementation');
  2957. Add('var');
  2958. Add(' d: double;');
  2959. Add(' i: longint;');
  2960. Add('begin');
  2961. Add(' d:=nan;');
  2962. Add(' d:=uNit2.nan;');
  2963. Add(' d:=test1.nan;');
  2964. Add(' i:=iv;');
  2965. Add(' i:=uNit2.iv;');
  2966. Add(' i:=test1.iv;');
  2967. ConvertUnit;
  2968. CheckSource('TestVarExternalOtherUnit',
  2969. LinesToStr([
  2970. 'var $impl = {',
  2971. '};',
  2972. 'this.$impl = $impl;',
  2973. '$impl.d = 0.0;',
  2974. '$impl.i = 0;',
  2975. '']),
  2976. LinesToStr([
  2977. '$impl.d = Global.NaN;',
  2978. '$impl.d = Global.NaN;',
  2979. '$impl.d = Global.NaN;',
  2980. '$impl.i = pas.unit2.iV;',
  2981. '$impl.i = pas.unit2.iV;',
  2982. '$impl.i = pas.unit2.iV;',
  2983. '']));
  2984. end;
  2985. procedure TTestModule.TestCharConst;
  2986. begin
  2987. StartProgram(false);
  2988. Add('const');
  2989. Add(' c: char = ''1'';');
  2990. Add('begin');
  2991. Add(' c:=#0;');
  2992. Add(' c:=#1;');
  2993. Add(' c:=#9;');
  2994. Add(' c:=#10;');
  2995. Add(' c:=#13;');
  2996. Add(' c:=#31;');
  2997. Add(' c:=#32;');
  2998. Add(' c:=#$A;');
  2999. Add(' c:=#$0A;');
  3000. Add(' c:=#$b;');
  3001. Add(' c:=#$0b;');
  3002. Add(' c:=^A;');
  3003. Add(' c:=''"'';');
  3004. ConvertProgram;
  3005. CheckSource('TestCharConst',
  3006. LinesToStr([
  3007. 'this.c="1";'
  3008. ]),
  3009. LinesToStr([
  3010. 'this.c="\x00";',
  3011. 'this.c="\x01";',
  3012. 'this.c="\t";',
  3013. 'this.c="\n";',
  3014. 'this.c="\r";',
  3015. 'this.c="\x1F";',
  3016. 'this.c=" ";',
  3017. 'this.c="\n";',
  3018. 'this.c="\n";',
  3019. 'this.c="\x0B";',
  3020. 'this.c="\x0B";',
  3021. 'this.c="\x01";',
  3022. 'this.c=''"'';'
  3023. ]));
  3024. end;
  3025. procedure TTestModule.TestChar_Compare;
  3026. begin
  3027. StartProgram(false);
  3028. Add('var');
  3029. Add(' c: char;');
  3030. Add(' b: boolean;');
  3031. Add('begin');
  3032. Add(' b:=c=''1'';');
  3033. Add(' b:=''2''=c;');
  3034. Add(' b:=''3''=''4'';');
  3035. Add(' b:=c<>''5'';');
  3036. Add(' b:=''6''<>c;');
  3037. Add(' b:=c>''7'';');
  3038. Add(' b:=''8''>c;');
  3039. Add(' b:=c>=''9'';');
  3040. Add(' b:=''A''>=c;');
  3041. Add(' b:=c<''B'';');
  3042. Add(' b:=''C''<c;');
  3043. Add(' b:=c<=''D'';');
  3044. Add(' b:=''E''<=c;');
  3045. ConvertProgram;
  3046. CheckSource('TestChar_Compare',
  3047. LinesToStr([
  3048. 'this.c="";',
  3049. 'this.b = false;'
  3050. ]),
  3051. LinesToStr([
  3052. 'this.b = this.c == "1";',
  3053. 'this.b = "2" == this.c;',
  3054. 'this.b = "3" == "4";',
  3055. 'this.b = this.c != "5";',
  3056. 'this.b = "6" != this.c;',
  3057. 'this.b = this.c > "7";',
  3058. 'this.b = "8" > this.c;',
  3059. 'this.b = this.c >= "9";',
  3060. 'this.b = "A" >= this.c;',
  3061. 'this.b = this.c < "B";',
  3062. 'this.b = "C" < this.c;',
  3063. 'this.b = this.c <= "D";',
  3064. 'this.b = "E" <= this.c;',
  3065. '']));
  3066. end;
  3067. procedure TTestModule.TestChar_Ord;
  3068. begin
  3069. StartProgram(false);
  3070. Add('var');
  3071. Add(' c: char;');
  3072. Add(' i: longint;');
  3073. Add('begin');
  3074. Add(' i:=ord(c);');
  3075. ConvertProgram;
  3076. CheckSource('TestChar_Ord',
  3077. LinesToStr([
  3078. 'this.c = "";',
  3079. 'this.i = 0;'
  3080. ]),
  3081. LinesToStr([
  3082. 'this.i = this.c.charCodeAt();',
  3083. '']));
  3084. end;
  3085. procedure TTestModule.TestChar_Chr;
  3086. begin
  3087. StartProgram(false);
  3088. Add('var');
  3089. Add(' c: char;');
  3090. Add(' i: longint;');
  3091. Add('begin');
  3092. Add(' c:=chr(i);');
  3093. ConvertProgram;
  3094. CheckSource('TestChar_Chr',
  3095. LinesToStr([
  3096. 'this.c = "";',
  3097. 'this.i = 0;'
  3098. ]),
  3099. LinesToStr([
  3100. 'this.c = String.fromCharCode(this.i);',
  3101. '']));
  3102. end;
  3103. procedure TTestModule.TestStringConst;
  3104. begin
  3105. StartProgram(false);
  3106. Add('var');
  3107. Add(' s: string = ''abc'';');
  3108. Add('begin');
  3109. Add(' s:='''';');
  3110. Add(' s:=#13#10;');
  3111. Add(' s:=#9''foo'';');
  3112. Add(' s:=#$A9;');
  3113. Add(' s:=''foo''#13''bar'';');
  3114. Add(' s:=''"'';');
  3115. Add(' s:=''"''''"'';');
  3116. ConvertProgram;
  3117. CheckSource('TestStringConst',
  3118. LinesToStr([
  3119. 'this.s="abc";'
  3120. ]),
  3121. LinesToStr([
  3122. 'this.s="";',
  3123. 'this.s="\r\n";',
  3124. 'this.s="\tfoo";',
  3125. 'this.s="©";',
  3126. 'this.s="foo\rbar";',
  3127. 'this.s=''"'';',
  3128. 'this.s=''"\''"'';'
  3129. ]));
  3130. end;
  3131. procedure TTestModule.TestString_Length;
  3132. begin
  3133. StartProgram(false);
  3134. Add('const c = ''foo'';');
  3135. Add('var');
  3136. Add(' s: string;');
  3137. Add(' i: longint;');
  3138. Add('begin');
  3139. Add(' i:=length(s);');
  3140. Add(' i:=length(s+s);');
  3141. Add(' i:=length(''abc'');');
  3142. Add(' i:=length(c);');
  3143. ConvertProgram;
  3144. CheckSource('TestString_Length',
  3145. LinesToStr([
  3146. 'this.c = "foo";',
  3147. 'this.s = "";',
  3148. 'this.i = 0;',
  3149. '']),
  3150. LinesToStr([
  3151. 'this.i = this.s.length;',
  3152. 'this.i = (this.s+this.s).length;',
  3153. 'this.i = "abc".length;',
  3154. 'this.i = this.c.length;',
  3155. '']));
  3156. end;
  3157. procedure TTestModule.TestString_Compare;
  3158. begin
  3159. StartProgram(false);
  3160. Add('var');
  3161. Add(' s, t: string;');
  3162. Add(' b: boolean;');
  3163. Add('begin');
  3164. Add(' b:=s=t;');
  3165. Add(' b:=s<>t;');
  3166. Add(' b:=s>t;');
  3167. Add(' b:=s>=t;');
  3168. Add(' b:=s<t;');
  3169. Add(' b:=s<=t;');
  3170. ConvertProgram;
  3171. CheckSource('TestString_Compare',
  3172. LinesToStr([ // statements
  3173. 'this.s = "";',
  3174. 'this.t = "";',
  3175. 'this.b =false;'
  3176. ]),
  3177. LinesToStr([ // this.$main
  3178. 'this.b = this.s == this.t;',
  3179. 'this.b = this.s != this.t;',
  3180. 'this.b = this.s > this.t;',
  3181. 'this.b = this.s >= this.t;',
  3182. 'this.b = this.s < this.t;',
  3183. 'this.b = this.s <= this.t;',
  3184. '']));
  3185. end;
  3186. procedure TTestModule.TestString_SetLength;
  3187. begin
  3188. StartProgram(false);
  3189. Add('var s: string;');
  3190. Add('begin');
  3191. Add(' SetLength(s,3);');
  3192. ConvertProgram;
  3193. CheckSource('TestString_SetLength',
  3194. LinesToStr([ // statements
  3195. 'this.s = "";'
  3196. ]),
  3197. LinesToStr([ // this.$main
  3198. 'this.s.length = 3;'
  3199. ]));
  3200. end;
  3201. procedure TTestModule.TestString_CharAt;
  3202. begin
  3203. StartProgram(false);
  3204. Add('var');
  3205. Add(' s: string;');
  3206. Add(' c: char;');
  3207. Add(' b: boolean;');
  3208. Add('begin');
  3209. Add(' b:= s[1] = c;');
  3210. Add(' b:= c = s[1];');
  3211. Add(' b:= c <> s[1];');
  3212. Add(' b:= c > s[1];');
  3213. Add(' b:= c >= s[1];');
  3214. Add(' b:= c < s[1];');
  3215. Add(' b:= c <= s[1];');
  3216. Add(' s[1] := c;');
  3217. ConvertProgram;
  3218. CheckSource('TestString_CharAt',
  3219. LinesToStr([ // statements
  3220. 'this.s = "";',
  3221. 'this.c = "";',
  3222. 'this.b = false;'
  3223. ]),
  3224. LinesToStr([ // this.$main
  3225. 'this.b = this.s.charAt(1-1) == this.c;',
  3226. 'this.b = this.c == this.s.charAt(1 - 1);',
  3227. 'this.b = this.c != this.s.charAt(1 - 1);',
  3228. 'this.b = this.c > this.s.charAt(1 - 1);',
  3229. 'this.b = this.c >= this.s.charAt(1 - 1);',
  3230. 'this.b = this.c < this.s.charAt(1 - 1);',
  3231. 'this.b = this.c <= this.s.charAt(1 - 1);',
  3232. 'this.s = rtl.setCharAt(this.s, 1, this.c);',
  3233. '']));
  3234. end;
  3235. procedure TTestModule.TestStr;
  3236. begin
  3237. StartProgram(false);
  3238. Add('var');
  3239. Add(' b: boolean;');
  3240. Add(' i: longint;');
  3241. Add(' d: double;');
  3242. Add(' s: string;');
  3243. Add('begin');
  3244. Add(' str(b,s);');
  3245. Add(' str(i,s);');
  3246. Add(' str(d,s);');
  3247. Add(' str(i:3,s);');
  3248. Add(' str(d:3:2,s);');
  3249. Add(' s:=str(b);');
  3250. Add(' s:=str(i);');
  3251. Add(' s:=str(d);');
  3252. Add(' s:=str(i,i);');
  3253. Add(' s:=str(i:3);');
  3254. Add(' s:=str(d:3:2);');
  3255. Add(' s:=str(i:4,i);');
  3256. Add(' s:=str(i,i:5);');
  3257. Add(' s:=str(i:4,i:5);');
  3258. Add(' s:=str(s,s);');
  3259. Add(' s:=str(s,''foo'');');
  3260. ConvertProgram;
  3261. CheckSource('TestStr',
  3262. LinesToStr([ // statements
  3263. 'this.b = false;',
  3264. 'this.i = 0;',
  3265. 'this.d = 0.0;',
  3266. 'this.s = "";',
  3267. '']),
  3268. LinesToStr([ // this.$main
  3269. 'this.s = ""+this.b;',
  3270. 'this.s = ""+this.i;',
  3271. 'this.s = ""+this.d;',
  3272. 'this.s = rtl.spaceLeft(""+this.i,3);',
  3273. 'this.s = rtl.spaceLeft(this.d.toFixed(2),3);',
  3274. 'this.s = ""+this.b;',
  3275. 'this.s = ""+this.i;',
  3276. 'this.s = ""+this.d;',
  3277. 'this.s = (""+this.i)+this.i;',
  3278. 'this.s = rtl.spaceLeft(""+this.i,3);',
  3279. 'this.s = rtl.spaceLeft(this.d.toFixed(2),3);',
  3280. 'this.s = rtl.spaceLeft("" + this.i, 4) + this.i;',
  3281. 'this.s = ("" + this.i) + rtl.spaceLeft("" + this.i, 5);',
  3282. 'this.s = rtl.spaceLeft("" + this.i, 4) + rtl.spaceLeft("" + this.i, 5);',
  3283. 'this.s = this.s + this.s;',
  3284. 'this.s = this.s + "foo";',
  3285. '']));
  3286. end;
  3287. procedure TTestModule.TestAnsiStringFail;
  3288. begin
  3289. StartProgram(false);
  3290. Add('var s: AnsiString');
  3291. Add('begin');
  3292. SetExpectedPasResolverError('foo',123);
  3293. end;
  3294. procedure TTestModule.TestProcTwoArgs;
  3295. begin
  3296. StartProgram(false);
  3297. Add('procedure Test(a,b: longint);');
  3298. Add('begin');
  3299. Add('end;');
  3300. Add('begin');
  3301. ConvertProgram;
  3302. CheckSource('TestProcTwoArgs',
  3303. LinesToStr([ // statements
  3304. 'this.Test = function (a,b) {',
  3305. '};'
  3306. ]),
  3307. LinesToStr([ // this.$main
  3308. ''
  3309. ]));
  3310. end;
  3311. procedure TTestModule.TestProc_DefaultValue;
  3312. begin
  3313. StartProgram(false);
  3314. Add('procedure p1(i: longint = 1);');
  3315. Add('begin');
  3316. Add('end;');
  3317. Add('procedure p2(i: longint = 1; c: char = ''a'');');
  3318. Add('begin');
  3319. Add('end;');
  3320. Add('procedure p3(d: double = 1.0; b: boolean = false; s: string = ''abc'');');
  3321. Add('begin');
  3322. Add('end;');
  3323. Add('begin');
  3324. Add(' p1;');
  3325. Add(' p1();');
  3326. Add(' p1(11);');
  3327. Add(' p2;');
  3328. Add(' p2();');
  3329. Add(' p2(12);');
  3330. Add(' p2(13,''b'');');
  3331. Add(' p3();');
  3332. ConvertProgram;
  3333. CheckSource('TestProc_DefaultValue',
  3334. LinesToStr([ // statements
  3335. 'this.p1 = function (i) {',
  3336. '};',
  3337. 'this.p2 = function (i,c) {',
  3338. '};',
  3339. 'this.p3 = function (d,b,s) {',
  3340. '};'
  3341. ]),
  3342. LinesToStr([ // this.$main
  3343. ' this.p1(1);',
  3344. ' this.p1(1);',
  3345. ' this.p1(11);',
  3346. ' this.p2(1,"a");',
  3347. ' this.p2(1,"a");',
  3348. ' this.p2(12,"a");',
  3349. ' this.p2(13,"b");',
  3350. ' this.p3(1.0,false,"abc");'
  3351. ]));
  3352. end;
  3353. procedure TTestModule.TestFunctionInt;
  3354. begin
  3355. StartProgram(false);
  3356. Add('function MyTest(Bar: longint): longint;');
  3357. Add('begin');
  3358. Add(' Result:=2*bar');
  3359. Add('end;');
  3360. Add('begin');
  3361. ConvertProgram;
  3362. CheckSource('TestFunctionInt',
  3363. LinesToStr([ // statements
  3364. 'this.MyTest = function (Bar) {',
  3365. ' var Result = 0;',
  3366. ' Result = 2*Bar;',
  3367. ' return Result;',
  3368. '};'
  3369. ]),
  3370. LinesToStr([ // this.$main
  3371. ''
  3372. ]));
  3373. end;
  3374. procedure TTestModule.TestFunctionString;
  3375. begin
  3376. StartProgram(false);
  3377. Add('function Test(Bar: string): string;');
  3378. Add('begin');
  3379. Add(' Result:=bar+BAR');
  3380. Add('end;');
  3381. Add('begin');
  3382. ConvertProgram;
  3383. CheckSource('TestFunctionString',
  3384. LinesToStr([ // statements
  3385. 'this.Test = function (Bar) {',
  3386. ' var Result = "";',
  3387. ' Result = Bar+Bar;',
  3388. ' return Result;',
  3389. '};'
  3390. ]),
  3391. LinesToStr([ // this.$main
  3392. ''
  3393. ]));
  3394. end;
  3395. procedure TTestModule.TestForLoop;
  3396. begin
  3397. StartProgram(false);
  3398. Add('var');
  3399. Add(' vI, vJ, vN: longint;');
  3400. Add('begin');
  3401. Add(' VJ:=0;');
  3402. Add(' VN:=3;');
  3403. Add(' for VI:=1 to VN do');
  3404. Add(' begin');
  3405. Add(' VJ:=VJ+VI;');
  3406. Add(' end;');
  3407. ConvertProgram;
  3408. CheckSource('TestForLoop',
  3409. LinesToStr([ // statements
  3410. 'this.vI = 0;',
  3411. 'this.vJ = 0;',
  3412. 'this.vN = 0;'
  3413. ]),
  3414. LinesToStr([ // this.$main
  3415. ' this.vJ = 0;',
  3416. ' this.vN = 3;',
  3417. ' var $loopend1 = this.vN;',
  3418. ' for (this.vI = 1; this.vI <= $loopend1; this.vI++) {',
  3419. ' this.vJ = this.vJ + this.vI;',
  3420. ' };',
  3421. ' if (this.vI > $loopend1) this.vI--;'
  3422. ]));
  3423. end;
  3424. procedure TTestModule.TestForLoopInFunction;
  3425. begin
  3426. StartProgram(false);
  3427. Add('function SumNumbers(Count: longint): longint;');
  3428. Add('var');
  3429. Add(' vI, vJ: longint;');
  3430. Add('begin');
  3431. Add(' vj:=0;');
  3432. Add(' for vi:=1 to count do');
  3433. Add(' begin');
  3434. Add(' vj:=vj+vi;');
  3435. Add(' end;');
  3436. Add('end;');
  3437. Add('begin');
  3438. Add(' sumnumbers(3);');
  3439. ConvertProgram;
  3440. CheckSource('TestForLoopInFunction',
  3441. LinesToStr([ // statements
  3442. 'this.SumNumbers = function (Count) {',
  3443. ' var Result = 0;',
  3444. ' var vI = 0;',
  3445. ' var vJ = 0;',
  3446. ' vJ = 0;',
  3447. ' var $loopend1 = Count;',
  3448. ' for (vI = 1; vI <= $loopend1; vI++) {',
  3449. ' vJ = vJ + vI;',
  3450. ' };',
  3451. ' return Result;',
  3452. '};'
  3453. ]),
  3454. LinesToStr([ // this.$main
  3455. ' this.SumNumbers(3);'
  3456. ]));
  3457. end;
  3458. procedure TTestModule.TestForLoop_ReadVarAfter;
  3459. begin
  3460. StartProgram(false);
  3461. Add('var');
  3462. Add(' vI: longint;');
  3463. Add('begin');
  3464. Add(' for vi:=1 to 2 do ;');
  3465. Add(' if vi=3 then ;');
  3466. ConvertProgram;
  3467. CheckSource('TestForLoop',
  3468. LinesToStr([ // statements
  3469. 'this.vI = 0;'
  3470. ]),
  3471. LinesToStr([ // this.$main
  3472. ' var $loopend1 = 2;',
  3473. ' for (this.vI = 1; this.vI <= $loopend1; this.vI++);',
  3474. ' if(this.vI>$loopend1)this.vI--;',
  3475. ' if (this.vI==3) ;'
  3476. ]));
  3477. end;
  3478. procedure TTestModule.TestForLoop_Nested;
  3479. begin
  3480. StartProgram(false);
  3481. Add('function SumNumbers(Count: longint): longint;');
  3482. Add('var');
  3483. Add(' vI, vJ, vK: longint;');
  3484. Add('begin');
  3485. Add(' VK:=0;');
  3486. Add(' for VI:=1 to count do');
  3487. Add(' begin');
  3488. Add(' for vj:=1 to vi do');
  3489. Add(' begin');
  3490. Add(' vk:=VK+VI;');
  3491. Add(' end;');
  3492. Add(' end;');
  3493. Add('end;');
  3494. Add('begin');
  3495. Add(' sumnumbers(3);');
  3496. ConvertProgram;
  3497. CheckSource('TestForLoopInFunction',
  3498. LinesToStr([ // statements
  3499. 'this.SumNumbers = function (Count) {',
  3500. ' var Result = 0;',
  3501. ' var vI = 0;',
  3502. ' var vJ = 0;',
  3503. ' var vK = 0;',
  3504. ' vK = 0;',
  3505. ' var $loopend1 = Count;',
  3506. ' for (vI = 1; vI <= $loopend1; vI++) {',
  3507. ' var $loopend2 = vI;',
  3508. ' for (vJ = 1; vJ <= $loopend2; vJ++) {',
  3509. ' vK = vK + vI;',
  3510. ' };',
  3511. ' };',
  3512. ' return Result;',
  3513. '};'
  3514. ]),
  3515. LinesToStr([ // this.$main
  3516. ' this.SumNumbers(3);'
  3517. ]));
  3518. end;
  3519. procedure TTestModule.TestRepeatUntil;
  3520. begin
  3521. StartProgram(false);
  3522. Add('var');
  3523. Add(' vI, vJ, vN: longint;');
  3524. Add('begin');
  3525. Add(' vn:=3;');
  3526. Add(' vj:=0;');
  3527. Add(' VI:=0;');
  3528. Add(' repeat');
  3529. Add(' VI:=vi+1;');
  3530. Add(' vj:=VJ+vI;');
  3531. Add(' until vi>=vn');
  3532. ConvertProgram;
  3533. CheckSource('TestRepeatUntil',
  3534. LinesToStr([ // statements
  3535. 'this.vI = 0;',
  3536. 'this.vJ = 0;',
  3537. 'this.vN = 0;'
  3538. ]),
  3539. LinesToStr([ // this.$main
  3540. ' this.vN = 3;',
  3541. ' this.vJ = 0;',
  3542. ' this.vI = 0;',
  3543. ' do{',
  3544. ' this.vI = this.vI + 1;',
  3545. ' this.vJ = this.vJ + this.vI;',
  3546. ' }while(!(this.vI>=this.vN));'
  3547. ]));
  3548. end;
  3549. procedure TTestModule.TestAsmBlock;
  3550. begin
  3551. StartProgram(false);
  3552. Add('var');
  3553. Add(' vI: longint;');
  3554. Add('begin');
  3555. Add(' vi:=1;');
  3556. Add(' asm');
  3557. Add(' if (vI==1) {');
  3558. Add(' vI=2;');
  3559. Add(' }');
  3560. Add(' if (vI==2){ vI=3; }');
  3561. Add(' end;');
  3562. Add(' VI:=4;');
  3563. ConvertProgram;
  3564. CheckSource('TestAsmBlock',
  3565. LinesToStr([ // statements
  3566. 'this.vI = 0;'
  3567. ]),
  3568. LinesToStr([ // this.$main
  3569. 'this.vI = 1;',
  3570. 'if (vI==1) {',
  3571. ' vI=2;',
  3572. '}',
  3573. 'if (vI==2){ vI=3; }',
  3574. ';',
  3575. 'this.vI = 4;'
  3576. ]));
  3577. end;
  3578. procedure TTestModule.TestTryFinally;
  3579. begin
  3580. StartProgram(false);
  3581. Add('var i: longint;');
  3582. Add('begin');
  3583. Add(' try');
  3584. Add(' i:=0; i:=2 div i;');
  3585. Add(' finally');
  3586. Add(' i:=3');
  3587. Add(' end;');
  3588. ConvertProgram;
  3589. CheckSource('TestTryFinally',
  3590. LinesToStr([ // statements
  3591. 'this.i = 0;'
  3592. ]),
  3593. LinesToStr([ // this.$main
  3594. 'try {',
  3595. ' this.i = 0;',
  3596. ' this.i = Math.floor(2 / this.i);',
  3597. '} finally {',
  3598. ' this.i = 3;',
  3599. '};'
  3600. ]));
  3601. end;
  3602. procedure TTestModule.TestTryExcept;
  3603. begin
  3604. StartProgram(false);
  3605. Add('type');
  3606. Add(' TObject = class end;');
  3607. Add(' Exception = class Msg: string; end;');
  3608. Add(' EInvalidCast = class(Exception) end;');
  3609. Add('var vI: longint;');
  3610. Add('begin');
  3611. Add(' try');
  3612. Add(' vi:=1;');
  3613. Add(' except');
  3614. Add(' vi:=2');
  3615. Add(' end;');
  3616. Add(' try');
  3617. Add(' vi:=3;');
  3618. Add(' except');
  3619. Add(' raise;');
  3620. Add(' end;');
  3621. Add(' try');
  3622. Add(' VI:=4;');
  3623. Add(' except');
  3624. Add(' on einvalidcast do');
  3625. Add(' raise;');
  3626. Add(' on E: exception do');
  3627. Add(' if e.msg='''' then');
  3628. Add(' raise e;');
  3629. Add(' else');
  3630. Add(' vi:=5');
  3631. Add(' end;');
  3632. Add(' try');
  3633. Add(' VI:=6;');
  3634. Add(' except');
  3635. Add(' on einvalidcast do ;');
  3636. Add(' end;');
  3637. ConvertProgram;
  3638. CheckSource('TestTryExcept',
  3639. LinesToStr([ // statements
  3640. 'rtl.createClass(this, "TObject", null, function () {',
  3641. ' this.$init = function () {',
  3642. ' };',
  3643. ' this.$final = function () {',
  3644. ' };',
  3645. '});',
  3646. 'rtl.createClass(this, "Exception", this.TObject, function () {',
  3647. ' this.$init = function () {',
  3648. ' pas.program.TObject.$init.call(this);',
  3649. ' this.Msg = "";',
  3650. ' };',
  3651. '});',
  3652. 'rtl.createClass(this, "EInvalidCast", this.Exception, function () {',
  3653. '});',
  3654. 'this.vI = 0;'
  3655. ]),
  3656. LinesToStr([ // this.$main
  3657. 'try {',
  3658. ' this.vI = 1;',
  3659. '} catch {',
  3660. ' this.vI = 2;',
  3661. '};',
  3662. 'try {',
  3663. ' this.vI = 3;',
  3664. '} catch ($e) {',
  3665. ' throw $e;',
  3666. '};',
  3667. 'try {',
  3668. ' this.vI = 4;',
  3669. '} catch ($e) {',
  3670. ' if (this.EInvalidCast.isPrototypeOf($e)){',
  3671. ' throw $e',
  3672. ' } else if (this.Exception.isPrototypeOf($e)) {',
  3673. ' var E = $e;',
  3674. ' if (E.Msg == "") throw E;',
  3675. ' } else {',
  3676. ' this.vI = 5;',
  3677. ' }',
  3678. '};',
  3679. 'try {',
  3680. ' this.vI = 6;',
  3681. '} catch ($e) {',
  3682. ' if (this.EInvalidCast.isPrototypeOf($e)){' ,
  3683. ' } else throw $e',
  3684. '};',
  3685. '']));
  3686. end;
  3687. procedure TTestModule.TestCaseOf;
  3688. begin
  3689. StartProgram(false);
  3690. Add('var vI: longint;');
  3691. Add('begin');
  3692. Add(' case vi of');
  3693. Add(' 1: ;');
  3694. Add(' 2: vi:=3;');
  3695. Add(' else');
  3696. Add(' VI:=4');
  3697. Add(' end;');
  3698. ConvertProgram;
  3699. CheckSource('TestCaseOf',
  3700. LinesToStr([ // statements
  3701. 'this.vI = 0;'
  3702. ]),
  3703. LinesToStr([ // this.$main
  3704. 'var $tmp1 = this.vI;',
  3705. 'if ($tmp1 == 1) {} else if ($tmp1 == 2){ this.vI = 3 }else {',
  3706. ' this.vI = 4;',
  3707. '};'
  3708. ]));
  3709. end;
  3710. procedure TTestModule.TestCaseOf_UseSwitch;
  3711. begin
  3712. StartProgram(false);
  3713. Converter.UseSwitchStatement:=true;
  3714. Add('var Vi: longint;');
  3715. Add('begin');
  3716. Add(' case vi of');
  3717. Add(' 1: ;');
  3718. Add(' 2: VI:=3;');
  3719. Add(' else');
  3720. Add(' vi:=4');
  3721. Add(' end;');
  3722. ConvertProgram;
  3723. CheckSource('TestCaseOf_UseSwitch',
  3724. LinesToStr([ // statements
  3725. 'this.Vi = 0;'
  3726. ]),
  3727. LinesToStr([ // this.$main
  3728. 'switch (this.Vi) {',
  3729. 'case 1:',
  3730. ' break;',
  3731. 'case 2:',
  3732. ' this.Vi = 3;',
  3733. ' break;',
  3734. 'default:',
  3735. ' this.Vi = 4;',
  3736. '};'
  3737. ]));
  3738. end;
  3739. procedure TTestModule.TestCaseOfNoElse;
  3740. begin
  3741. StartProgram(false);
  3742. Add('var Vi: longint;');
  3743. Add('begin');
  3744. Add(' case vi of');
  3745. Add(' 1: begin vi:=2; VI:=3; end;');
  3746. Add(' end;');
  3747. ConvertProgram;
  3748. CheckSource('TestCaseOfNoElse',
  3749. LinesToStr([ // statements
  3750. 'this.Vi = 0;'
  3751. ]),
  3752. LinesToStr([ // this.$main
  3753. 'var $tmp1 = this.Vi;',
  3754. 'if ($tmp1 == 1) {',
  3755. ' this.Vi = 2;',
  3756. ' this.Vi = 3;',
  3757. '};'
  3758. ]));
  3759. end;
  3760. procedure TTestModule.TestCaseOfNoElse_UseSwitch;
  3761. begin
  3762. StartProgram(false);
  3763. Converter.UseSwitchStatement:=true;
  3764. Add('var vI: longint;');
  3765. Add('begin');
  3766. Add(' case vi of');
  3767. Add(' 1: begin VI:=2; vi:=3; end;');
  3768. Add(' end;');
  3769. ConvertProgram;
  3770. CheckSource('TestCaseOfNoElse_UseSwitch',
  3771. LinesToStr([ // statements
  3772. 'this.vI = 0;'
  3773. ]),
  3774. LinesToStr([ // this.$main
  3775. 'switch (this.vI) {',
  3776. 'case 1:',
  3777. ' this.vI = 2;',
  3778. ' this.vI = 3;',
  3779. ' break;',
  3780. '};'
  3781. ]));
  3782. end;
  3783. procedure TTestModule.TestCaseOfRange;
  3784. begin
  3785. StartProgram(false);
  3786. Add('var vI: longint;');
  3787. Add('begin');
  3788. Add(' case vi of');
  3789. Add(' 1..3: vi:=14;');
  3790. Add(' 4,5: vi:=16;');
  3791. Add(' 6..7,9..10: ;');
  3792. Add(' else ;');
  3793. Add(' end;');
  3794. ConvertProgram;
  3795. CheckSource('TestCaseOfRange',
  3796. LinesToStr([ // statements
  3797. 'this.vI = 0;'
  3798. ]),
  3799. LinesToStr([ // this.$main
  3800. 'var $tmp1 = this.vI;',
  3801. 'if (($tmp1 >= 1) && ($tmp1 <= 3)){',
  3802. ' this.vI = 14',
  3803. '} else if (($tmp1 == 4) || ($tmp1 == 5)){',
  3804. ' this.vI = 16',
  3805. '} else if ((($tmp1 >= 6) && ($tmp1 <= 7)) || (($tmp1 >= 9) && ($tmp1 <= 10))) ;'
  3806. ]));
  3807. end;
  3808. procedure TTestModule.TestArray_Dynamic;
  3809. begin
  3810. StartProgram(false);
  3811. Add('type');
  3812. Add(' TArrayInt = array of longint;');
  3813. Add('var');
  3814. Add(' Arr: TArrayInt;');
  3815. Add(' i: longint;');
  3816. Add(' b: boolean;');
  3817. Add('begin');
  3818. Add(' SetLength(arr,3);');
  3819. Add(' arr[0]:=4;');
  3820. Add(' arr[1]:=length(arr)+arr[0];');
  3821. Add(' arr[i]:=5;');
  3822. Add(' arr[arr[i]]:=arr[6];');
  3823. Add(' i:=low(arr);');
  3824. Add(' i:=high(arr);');
  3825. Add(' b:=Assigned(arr);');
  3826. ConvertProgram;
  3827. CheckSource('TestArray_Dynamic',
  3828. LinesToStr([ // statements
  3829. 'this.Arr = [];',
  3830. 'this.i = 0;',
  3831. 'this.b = false;'
  3832. ]),
  3833. LinesToStr([ // this.$main
  3834. 'this.Arr = rtl.arraySetLength(this.Arr,3,0);',
  3835. 'this.Arr[0] = 4;',
  3836. 'this.Arr[1] = this.Arr.length + this.Arr[0];',
  3837. 'this.Arr[this.i] = 5;',
  3838. 'this.Arr[this.Arr[this.i]] = this.Arr[6];',
  3839. 'this.i = 0;',
  3840. 'this.i = this.Arr.length - 1;',
  3841. 'this.b = this.Arr.length > 0;',
  3842. '']));
  3843. end;
  3844. procedure TTestModule.TestArray_Dynamic_Nil;
  3845. begin
  3846. StartProgram(false);
  3847. Add('type');
  3848. Add(' TArrayInt = array of longint;');
  3849. Add('var');
  3850. Add(' Arr: TArrayInt;');
  3851. Add('procedure DoIt(const i: TArrayInt; j: TArrayInt); begin end;');
  3852. Add('begin');
  3853. Add(' arr:=nil;');
  3854. Add(' if arr=nil then;');
  3855. Add(' if nil=arr then;');
  3856. Add(' DoIt(nil,nil);');
  3857. ConvertProgram;
  3858. CheckSource('TestArray_Dynamic',
  3859. LinesToStr([ // statements
  3860. 'this.Arr = [];',
  3861. 'this.DoIt = function(i,j){',
  3862. '};'
  3863. ]),
  3864. LinesToStr([ // this.$main
  3865. 'this.Arr = [];',
  3866. 'if (this.Arr.length == 0);',
  3867. 'if (0 == this.Arr.length);',
  3868. 'this.DoIt([],[]);',
  3869. '']));
  3870. end;
  3871. procedure TTestModule.TestArray_DynMultiDimensional;
  3872. begin
  3873. StartProgram(false);
  3874. Add('type');
  3875. Add(' TArrayInt = array of longint;');
  3876. Add(' TArrayArrayInt = array of TArrayInt;');
  3877. Add('var');
  3878. Add(' Arr: TArrayInt;');
  3879. Add(' Arr2: TArrayArrayInt;');
  3880. Add(' i: longint;');
  3881. Add('begin');
  3882. Add(' arr2:=nil;');
  3883. Add(' if arr2=nil then;');
  3884. Add(' if nil=arr2 then;');
  3885. Add(' i:=low(arr2);');
  3886. Add(' i:=low(arr2[1]);');
  3887. Add(' i:=high(arr2);');
  3888. Add(' i:=high(arr2[2]);');
  3889. Add(' arr2[3]:=arr;');
  3890. Add(' arr2[4][5]:=i;');
  3891. Add(' i:=arr2[6][7];');
  3892. Add(' arr2[8,9]:=i;');
  3893. Add(' i:=arr2[10,11];');
  3894. Add(' SetLength(arr2,14);');
  3895. Add(' SetLength(arr2[15],16);');
  3896. ConvertProgram;
  3897. CheckSource('TestArray_Dynamic',
  3898. LinesToStr([ // statements
  3899. 'this.Arr = [];',
  3900. 'this.Arr2 = [];',
  3901. 'this.i = 0;'
  3902. ]),
  3903. LinesToStr([ // this.$main
  3904. 'this.Arr2 = [];',
  3905. 'if (this.Arr2.length == 0);',
  3906. 'if (0 == this.Arr2.length);',
  3907. 'this.i = 0;',
  3908. 'this.i = 0;',
  3909. 'this.i = this.Arr2.length-1;',
  3910. 'this.i = this.Arr2[2].length-1;',
  3911. 'this.Arr2[3] = this.Arr;',
  3912. 'this.Arr2[4][5] = this.i;',
  3913. 'this.i = this.Arr2[6][7];',
  3914. 'this.Arr2[8][9] = this.i;',
  3915. 'this.i = this.Arr2[10][11];',
  3916. 'this.Arr2 = rtl.arraySetLength(this.Arr2, 14, []);',
  3917. 'this.Arr2[15] = rtl.arraySetLength(this.Arr2[15], 16, 0);',
  3918. '']));
  3919. end;
  3920. procedure TTestModule.TestArrayOfRecord;
  3921. begin
  3922. StartProgram(false);
  3923. Add('type');
  3924. Add(' TRec = record');
  3925. Add(' Int: longint;');
  3926. Add(' end;');
  3927. Add(' TArrayRec = array of TRec;');
  3928. Add('var');
  3929. Add(' Arr: TArrayRec;');
  3930. Add(' r: TRec;');
  3931. Add(' i: longint;');
  3932. Add('begin');
  3933. Add(' SetLength(arr,3);');
  3934. Add(' arr[0].int:=4;');
  3935. Add(' arr[1].int:=length(arr)+arr[2].int;');
  3936. Add(' arr[arr[i].int].int:=arr[5].int;');
  3937. Add(' arr[7]:=r;');
  3938. Add(' r:=arr[8];');
  3939. Add(' i:=low(arr);');
  3940. Add(' i:=high(arr);');
  3941. ConvertProgram;
  3942. CheckSource('TestArrayOfRecord',
  3943. LinesToStr([ // statements
  3944. 'this.TRec = function (s) {',
  3945. ' if (s) {',
  3946. ' this.Int = s.Int;',
  3947. ' } else {',
  3948. ' this.Int = 0;',
  3949. ' };',
  3950. ' this.$equal = function (b) {',
  3951. ' return this.Int == b.Int;',
  3952. ' };',
  3953. '};',
  3954. 'this.Arr = [];',
  3955. 'this.r = new this.TRec();',
  3956. 'this.i = 0;'
  3957. ]),
  3958. LinesToStr([ // this.$main
  3959. 'this.Arr = rtl.arraySetLength(this.Arr,3, this.TRec);',
  3960. 'this.Arr[0].Int = 4;',
  3961. 'this.Arr[1].Int = this.Arr.length+this.Arr[2].Int;',
  3962. 'this.Arr[this.Arr[this.i].Int].Int = this.Arr[5].Int;',
  3963. 'this.Arr[7] = new this.TRec(this.r);',
  3964. 'this.r = new this.TRec(this.Arr[8]);',
  3965. 'this.i = 0;',
  3966. 'this.i = this.Arr.length-1;',
  3967. '']));
  3968. end;
  3969. procedure TTestModule.TestArray_AsParams;
  3970. begin
  3971. StartProgram(false);
  3972. Add('type integer = longint;');
  3973. Add('type TArrInt = array of integer;');
  3974. Add('procedure DoIt(vG: TArrInt; const vH: TArrInt; var vI: TArrInt);');
  3975. Add('var vJ: TArrInt;');
  3976. Add('begin');
  3977. Add(' vg:=vg;');
  3978. Add(' vj:=vh;');
  3979. Add(' vi:=vi;');
  3980. Add(' doit(vg,vg,vg);');
  3981. Add(' doit(vh,vh,vj);');
  3982. Add(' doit(vi,vi,vi);');
  3983. Add(' doit(vj,vj,vj);');
  3984. Add('end;');
  3985. Add('var i: TArrInt;');
  3986. Add('begin');
  3987. Add(' doit(i,i,i);');
  3988. ConvertProgram;
  3989. CheckSource('TestArray_AsParams',
  3990. LinesToStr([ // statements
  3991. 'this.DoIt = function (vG,vH,vI) {',
  3992. ' var vJ = [];',
  3993. ' vG = vG;',
  3994. ' vJ = vH;',
  3995. ' vI.set(vI.get());',
  3996. ' this.DoIt(vG, vG, {',
  3997. ' get: function () {',
  3998. ' return vG;',
  3999. ' },',
  4000. ' set: function (v) {',
  4001. ' vG = v;',
  4002. ' }',
  4003. ' });',
  4004. ' this.DoIt(vH, vH, {',
  4005. ' get: function () {',
  4006. ' return vJ;',
  4007. ' },',
  4008. ' set: function (v) {',
  4009. ' vJ = v;',
  4010. ' }',
  4011. ' });',
  4012. ' this.DoIt(vI.get(), vI.get(), vI);',
  4013. ' this.DoIt(vJ, vJ, {',
  4014. ' get: function () {',
  4015. ' return vJ;',
  4016. ' },',
  4017. ' set: function (v) {',
  4018. ' vJ = v;',
  4019. ' }',
  4020. ' });',
  4021. '};',
  4022. 'this.i = [];'
  4023. ]),
  4024. LinesToStr([
  4025. 'this.DoIt(this.i,this.i,{',
  4026. ' p: this,',
  4027. ' get: function () {',
  4028. ' return this.p.i;',
  4029. ' },',
  4030. ' set: function (v) {',
  4031. ' this.p.i = v;',
  4032. ' }',
  4033. '});'
  4034. ]));
  4035. end;
  4036. procedure TTestModule.TestArrayElement_AsParams;
  4037. begin
  4038. StartProgram(false);
  4039. Add('type integer = longint;');
  4040. Add('type TArrayInt = array of integer;');
  4041. Add('procedure DoIt(vG: Integer; const vH: Integer; var vI: Integer);');
  4042. Add('var vJ: tarrayint;');
  4043. Add('begin');
  4044. Add(' vi:=vi;');
  4045. Add(' doit(vi,vi,vi);');
  4046. Add(' doit(vj[1+1],vj[1+2],vj[1+3]);');
  4047. Add('end;');
  4048. Add('var a: TArrayInt;');
  4049. Add('begin');
  4050. Add(' doit(a[1+4],a[1+5],a[1+6]);');
  4051. ConvertProgram;
  4052. CheckSource('TestArrayElement_AsParams',
  4053. LinesToStr([ // statements
  4054. 'this.DoIt = function (vG,vH,vI) {',
  4055. ' var vJ = [];',
  4056. ' vI.set(vI.get());',
  4057. ' this.DoIt(vI.get(), vI.get(), vI);',
  4058. ' this.DoIt(vJ[1+1], vJ[1+2], {',
  4059. ' a:1+3,',
  4060. ' p:vJ,',
  4061. ' get: function () {',
  4062. ' return this.p[this.a];',
  4063. ' },',
  4064. ' set: function (v) {',
  4065. ' this.p[this.a] = v;',
  4066. ' }',
  4067. ' });',
  4068. '};',
  4069. 'this.a = [];'
  4070. ]),
  4071. LinesToStr([
  4072. 'this.DoIt(this.a[1+4],this.a[1+5],{',
  4073. ' a: 1+6,',
  4074. ' p: this.a,',
  4075. ' get: function () {',
  4076. ' return this.p[this.a];',
  4077. ' },',
  4078. ' set: function (v) {',
  4079. ' this.p[this.a] = v;',
  4080. ' }',
  4081. '});'
  4082. ]));
  4083. end;
  4084. procedure TTestModule.TestArrayElementFromFuncResult_AsParams;
  4085. begin
  4086. StartProgram(false);
  4087. Add('type Integer = longint;');
  4088. Add('type TArrayInt = array of integer;');
  4089. Add('function GetArr(vB: integer = 0): tarrayint;');
  4090. Add('begin');
  4091. Add('end;');
  4092. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  4093. Add('begin');
  4094. Add('end;');
  4095. Add('begin');
  4096. Add(' doit(getarr[1+1],getarr[1+2],getarr[1+3]);');
  4097. Add(' doit(getarr()[2+1],getarr()[2+2],getarr()[2+3]);');
  4098. Add(' doit(getarr(7)[3+1],getarr(8)[3+2],getarr(9)[3+3]);');
  4099. ConvertProgram;
  4100. CheckSource('TestArrayElementFromFuncResult_AsParams',
  4101. LinesToStr([ // statements
  4102. 'this.GetArr = function (vB) {',
  4103. ' var Result = [];',
  4104. ' return Result;',
  4105. '};',
  4106. 'this.DoIt = function (vG,vH,vI) {',
  4107. '};'
  4108. ]),
  4109. LinesToStr([
  4110. 'this.DoIt(this.GetArr(0)[1+1],this.GetArr(0)[1+2],{',
  4111. ' a: 1+3,',
  4112. ' p: this.GetArr(0),',
  4113. ' get: function () {',
  4114. ' return this.p[this.a];',
  4115. ' },',
  4116. ' set: function (v) {',
  4117. ' this.p[this.a] = v;',
  4118. ' }',
  4119. '});',
  4120. 'this.DoIt(this.GetArr(0)[2+1],this.GetArr(0)[2+2],{',
  4121. ' a: 2+3,',
  4122. ' p: this.GetArr(0),',
  4123. ' get: function () {',
  4124. ' return this.p[this.a];',
  4125. ' },',
  4126. ' set: function (v) {',
  4127. ' this.p[this.a] = v;',
  4128. ' }',
  4129. '});',
  4130. 'this.DoIt(this.GetArr(7)[3+1],this.GetArr(8)[3+2],{',
  4131. ' a: 3+3,',
  4132. ' p: this.GetArr(9),',
  4133. ' get: function () {',
  4134. ' return this.p[this.a];',
  4135. ' },',
  4136. ' set: function (v) {',
  4137. ' this.p[this.a] = v;',
  4138. ' }',
  4139. '});',
  4140. '']));
  4141. end;
  4142. procedure TTestModule.TestArrayEnumTypeRange;
  4143. begin
  4144. StartProgram(false);
  4145. Add('type');
  4146. Add(' TEnum = (red,blue);');
  4147. Add(' TEnumArray = array[TEnum] of longint;');
  4148. Add('var');
  4149. Add(' e: TEnum;');
  4150. Add(' i: longint;');
  4151. Add(' a: TEnumArray;');
  4152. Add(' numbers: TEnumArray = (1,2);');
  4153. Add(' names: array[TEnum] of string = (''red'',''blue'');');
  4154. Add('begin');
  4155. Add(' e:=low(a);');
  4156. Add(' e:=high(a);');
  4157. Add(' i:=a[red]+length(a);');
  4158. Add(' a[e]:=a[e];');
  4159. ConvertProgram;
  4160. CheckSource('TestArrayEnumTypeRange',
  4161. LinesToStr([ // statements
  4162. ' this.TEnum = {',
  4163. ' "0": "red",',
  4164. ' red: 0,',
  4165. ' "1": "blue",',
  4166. ' blue: 1',
  4167. '};',
  4168. 'this.e = 0;',
  4169. 'this.i = 0;',
  4170. 'this.a = rtl.arrayNewMultiDim([2],0);',
  4171. 'this.numbers = [1, 2];',
  4172. 'this.names = ["red", "blue"];',
  4173. '']),
  4174. LinesToStr([ // this.$main
  4175. 'this.e = this.TEnum.red;',
  4176. 'this.e = this.TEnum.blue;',
  4177. 'this.i = this.a[this.TEnum.red]+2;',
  4178. 'this.a[this.e] = this.a[this.e];',
  4179. '']));
  4180. end;
  4181. procedure TTestModule.TestArray_SetLengthProperty;
  4182. begin
  4183. StartProgram(false);
  4184. Add('type');
  4185. Add(' TArrInt = array of longint;');
  4186. Add(' TObject = class');
  4187. Add(' function GetColors: TArrInt; external name ''GetColors'';');
  4188. Add(' procedure SetColors(const Value: TArrInt); external name ''SetColors'';');
  4189. Add(' property Colors: TArrInt read GetColors write SetColors;');
  4190. Add(' end;');
  4191. Add('var Obj: TObject;');
  4192. Add('begin');
  4193. Add(' SetLength(Obj.Colors,2);');
  4194. ConvertProgram;
  4195. CheckSource('TestArray_SetLengthProperty',
  4196. LinesToStr([ // statements
  4197. 'rtl.createClass(this, "TObject", null, function () {',
  4198. ' this.$init = function () {',
  4199. ' };',
  4200. ' this.$final = function () {',
  4201. ' };',
  4202. '});',
  4203. 'this.Obj = null;',
  4204. '']),
  4205. LinesToStr([
  4206. 'this.Obj.SetColors(rtl.arraySetLength(this.Obj.GetColors(), 2, 0));',
  4207. '']));
  4208. end;
  4209. procedure TTestModule.TestArray_OpenArrayOfString;
  4210. begin
  4211. StartProgram(false);
  4212. Add('procedure DoIt(const a: array of String);');
  4213. Add('var');
  4214. Add(' i: longint;');
  4215. Add(' s: string;');
  4216. Add('begin');
  4217. Add(' for i:=low(a) to high(a) do s:=a[length(a)-i-1];');
  4218. Add('end;');
  4219. Add('var s: string;');
  4220. Add('begin');
  4221. Add(' DoIt([]);');
  4222. Add(' DoIt([s,''foo'','''',s+s]);');
  4223. ConvertProgram;
  4224. CheckSource('TestArray_OpenArrayOfString',
  4225. LinesToStr([ // statements
  4226. 'this.DoIt = function (a) {',
  4227. ' var i = 0;',
  4228. ' var s = "";',
  4229. ' var $loopend1 = a.length - 1;',
  4230. ' for (i = 0; i <= $loopend1; i++) s = a[(a.length - i) - 1];',
  4231. '};',
  4232. 'this.s = "";',
  4233. '']),
  4234. LinesToStr([
  4235. 'this.DoIt([]);',
  4236. 'this.DoIt([this.s, "foo", "", this.s + this.s]);',
  4237. '']));
  4238. end;
  4239. procedure TTestModule.TestRecord_Var;
  4240. begin
  4241. StartProgram(false);
  4242. Add('type');
  4243. Add(' TRecA = record');
  4244. Add(' Bold: longint;');
  4245. Add(' end;');
  4246. Add('var Rec: TRecA;');
  4247. Add('begin');
  4248. Add(' rec.bold:=123');
  4249. ConvertProgram;
  4250. CheckSource('TestRecord_Var',
  4251. LinesToStr([ // statements
  4252. 'this.TRecA = function (s) {',
  4253. ' if (s) {',
  4254. ' this.Bold = s.Bold;',
  4255. ' } else {',
  4256. ' this.Bold = 0;',
  4257. ' };',
  4258. ' this.$equal = function (b) {',
  4259. ' return this.Bold == b.Bold;',
  4260. ' };',
  4261. '};',
  4262. 'this.Rec = new this.TRecA();'
  4263. ]),
  4264. LinesToStr([ // this.$main
  4265. 'this.Rec.Bold = 123;'
  4266. ]));
  4267. end;
  4268. procedure TTestModule.TestWithRecordDo;
  4269. begin
  4270. StartProgram(false);
  4271. Add('type');
  4272. Add(' TRec = record');
  4273. Add(' vI: longint;');
  4274. Add(' end;');
  4275. Add('var');
  4276. Add(' Int: longint;');
  4277. Add(' r: TRec;');
  4278. Add('begin');
  4279. Add(' with r do');
  4280. Add(' int:=vi;');
  4281. Add(' with r do begin');
  4282. Add(' int:=vi;');
  4283. Add(' vi:=int;');
  4284. Add(' end;');
  4285. ConvertProgram;
  4286. CheckSource('TestWithRecordDo',
  4287. LinesToStr([ // statements
  4288. 'this.TRec = function (s) {',
  4289. ' if (s) {',
  4290. ' this.vI = s.vI;',
  4291. ' } else {',
  4292. ' this.vI = 0;',
  4293. ' };',
  4294. ' this.$equal = function (b) {',
  4295. ' return this.vI == b.vI;',
  4296. ' };',
  4297. '};',
  4298. 'this.Int = 0;',
  4299. 'this.r = new this.TRec();'
  4300. ]),
  4301. LinesToStr([ // this.$main
  4302. 'var $with1 = this.r;',
  4303. 'this.Int = $with1.vI;',
  4304. 'var $with2 = this.r;',
  4305. 'this.Int = $with2.vI;',
  4306. '$with2.vI = this.Int;'
  4307. ]));
  4308. end;
  4309. procedure TTestModule.TestRecord_Assign;
  4310. begin
  4311. StartProgram(false);
  4312. Add('type');
  4313. Add(' TEnum = (red,green);');
  4314. Add(' TEnums = set of TEnum;');
  4315. Add(' TSmallRec = record');
  4316. Add(' N: longint;');
  4317. Add(' end;');
  4318. Add(' TBigRec = record');
  4319. Add(' Int: longint;');
  4320. Add(' D: double;');
  4321. Add(' Arr: array of longint;');
  4322. Add(' Small: TSmallRec;');
  4323. Add(' Enums: TEnums;');
  4324. Add(' end;');
  4325. Add('var');
  4326. Add(' r, s: TBigRec;');
  4327. Add('begin');
  4328. Add(' r:=s;');
  4329. ConvertProgram;
  4330. CheckSource('TestRecord_Assign',
  4331. LinesToStr([ // statements
  4332. 'this.TEnum = {',
  4333. ' "0": "red",',
  4334. ' red: 0,',
  4335. ' "1": "green",',
  4336. ' green: 1',
  4337. '};',
  4338. 'this.TSmallRec = function (s) {',
  4339. ' if(s){',
  4340. ' this.N = s.N;',
  4341. ' } else {',
  4342. ' this.N = 0;',
  4343. ' };',
  4344. ' this.$equal = function (b) {',
  4345. ' return this.N == b.N;',
  4346. ' };',
  4347. '};',
  4348. 'this.TBigRec = function (s) {',
  4349. ' if(s){',
  4350. ' this.Int = s.Int;',
  4351. ' this.D = s.D;',
  4352. ' this.Arr = s.Arr;',
  4353. ' this.Small = new pas.program.TSmallRec(s.Small);',
  4354. ' this.Enums = rtl.refSet(s.Enums);',
  4355. ' } else {',
  4356. ' this.Int = 0;',
  4357. ' this.D = 0.0;',
  4358. ' this.Arr = [];',
  4359. ' this.Small = new pas.program.TSmallRec();',
  4360. ' this.Enums = {};',
  4361. ' };',
  4362. ' this.$equal = function (b) {',
  4363. ' return (this.Int == b.Int) && ((this.D == b.D) && ((this.Arr == b.Arr)',
  4364. ' && (this.Small.$equal(b.Small) && rtl.eqSet(this.Enums, b.Enums))));',
  4365. ' };',
  4366. '};',
  4367. 'this.r = new this.TBigRec();',
  4368. 'this.s = new this.TBigRec();'
  4369. ]),
  4370. LinesToStr([ // this.$main
  4371. 'this.r = new this.TBigRec(this.s);',
  4372. '']));
  4373. end;
  4374. procedure TTestModule.TestRecord_PassAsArgClone;
  4375. begin
  4376. StartProgram(false);
  4377. Add('type');
  4378. Add(' TRecA = record');
  4379. Add(' Bold: longint;');
  4380. Add(' end;');
  4381. Add('procedure DoDefault(r: treca); begin end;');
  4382. Add('procedure DoConst(const r: treca); begin end;');
  4383. Add('var Rec: treca;');
  4384. Add('begin');
  4385. Add(' dodefault(rec);');
  4386. Add(' doconst(rec);');
  4387. ConvertProgram;
  4388. CheckSource('TestRecord_PassAsArgClone',
  4389. LinesToStr([ // statements
  4390. 'this.TRecA = function (s) {',
  4391. ' if (s) {',
  4392. ' this.Bold = s.Bold;',
  4393. ' } else {',
  4394. ' this.Bold = 0;',
  4395. ' };',
  4396. ' this.$equal = function (b) {',
  4397. ' return this.Bold == b.Bold;',
  4398. ' };',
  4399. '};',
  4400. 'this.DoDefault = function (r) {',
  4401. '};',
  4402. 'this.DoConst = function (r) {',
  4403. '};',
  4404. 'this.Rec = new this.TRecA();'
  4405. ]),
  4406. LinesToStr([ // this.$main
  4407. 'this.DoDefault(new this.TRecA(this.Rec));',
  4408. 'this.DoConst(this.Rec);',
  4409. '']));
  4410. end;
  4411. procedure TTestModule.TestRecord_AsParams;
  4412. begin
  4413. StartProgram(false);
  4414. Add('type');
  4415. Add(' integer = longint;');
  4416. Add(' TRecord = record');
  4417. Add(' i: integer;');
  4418. Add(' end;');
  4419. Add('procedure DoIt(vG: TRecord; const vH: TRecord; var vI: TRecord);');
  4420. Add('var vJ: TRecord;');
  4421. Add('begin');
  4422. Add(' vg:=vg;');
  4423. Add(' vj:=vh;');
  4424. Add(' vi:=vi;');
  4425. Add(' doit(vg,vg,vg);');
  4426. Add(' doit(vh,vh,vj);');
  4427. Add(' doit(vi,vi,vi);');
  4428. Add(' doit(vj,vj,vj);');
  4429. Add('end;');
  4430. Add('var i: TRecord;');
  4431. Add('begin');
  4432. Add(' doit(i,i,i);');
  4433. ConvertProgram;
  4434. CheckSource('TestRecord_AsParams',
  4435. LinesToStr([ // statements
  4436. 'this.TRecord = function (s) {',
  4437. ' if (s) {',
  4438. ' this.i = s.i;',
  4439. ' } else {',
  4440. ' this.i = 0;',
  4441. ' };',
  4442. ' this.$equal = function (b) {',
  4443. ' return this.i == b.i;',
  4444. ' };',
  4445. '};',
  4446. 'this.DoIt = function (vG,vH,vI) {',
  4447. ' var vJ = new this.TRecord();',
  4448. ' vG = new this.TRecord(vG);',
  4449. ' vJ = new this.TRecord(vH);',
  4450. ' vI.set(new this.TRecord(vI.get()));',
  4451. ' this.DoIt(new this.TRecord(vG), vG, {',
  4452. ' get: function () {',
  4453. ' return vG;',
  4454. ' },',
  4455. ' set: function (v) {',
  4456. ' vG = v;',
  4457. ' }',
  4458. ' });',
  4459. ' this.DoIt(new this.TRecord(vH), vH, {',
  4460. ' get: function () {',
  4461. ' return vJ;',
  4462. ' },',
  4463. ' set: function (v) {',
  4464. ' vJ = v;',
  4465. ' }',
  4466. ' });',
  4467. ' this.DoIt(new this.TRecord(vI.get()), vI.get(), vI);',
  4468. ' this.DoIt(new this.TRecord(vJ), vJ, {',
  4469. ' get: function () {',
  4470. ' return vJ;',
  4471. ' },',
  4472. ' set: function (v) {',
  4473. ' vJ = v;',
  4474. ' }',
  4475. ' });',
  4476. '};',
  4477. 'this.i = new this.TRecord();'
  4478. ]),
  4479. LinesToStr([
  4480. 'this.DoIt(new this.TRecord(this.i),this.i,{',
  4481. ' p: this,',
  4482. ' get: function () {',
  4483. ' return this.p.i;',
  4484. ' },',
  4485. ' set: function (v) {',
  4486. ' this.p.i = v;',
  4487. ' }',
  4488. '});'
  4489. ]));
  4490. end;
  4491. procedure TTestModule.TestRecordElement_AsParams;
  4492. begin
  4493. StartProgram(false);
  4494. Add('type');
  4495. Add(' integer = longint;');
  4496. Add(' TRecord = record');
  4497. Add(' i: integer;');
  4498. Add(' end;');
  4499. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  4500. Add('var vJ: TRecord;');
  4501. Add('begin');
  4502. Add(' doit(vj.i,vj.i,vj.i);');
  4503. Add('end;');
  4504. Add('var r: TRecord;');
  4505. Add('begin');
  4506. Add(' doit(r.i,r.i,r.i);');
  4507. ConvertProgram;
  4508. CheckSource('TestRecordElement_AsParams',
  4509. LinesToStr([ // statements
  4510. 'this.TRecord = function (s) {',
  4511. ' if (s) {',
  4512. ' this.i = s.i;',
  4513. ' } else {',
  4514. ' this.i = 0;',
  4515. ' };',
  4516. ' this.$equal = function (b) {',
  4517. ' return this.i == b.i;',
  4518. ' };',
  4519. '};',
  4520. 'this.DoIt = function (vG,vH,vI) {',
  4521. ' var vJ = new this.TRecord();',
  4522. ' this.DoIt(vJ.i, vJ.i, {',
  4523. ' p: vJ,',
  4524. ' get: function () {',
  4525. ' return this.p.i;',
  4526. ' },',
  4527. ' set: function (v) {',
  4528. ' this.p.i = v;',
  4529. ' }',
  4530. ' });',
  4531. '};',
  4532. 'this.r = new this.TRecord();'
  4533. ]),
  4534. LinesToStr([
  4535. 'this.DoIt(this.r.i,this.r.i,{',
  4536. ' p: this.r,',
  4537. ' get: function () {',
  4538. ' return this.p.i;',
  4539. ' },',
  4540. ' set: function (v) {',
  4541. ' this.p.i = v;',
  4542. ' }',
  4543. '});'
  4544. ]));
  4545. end;
  4546. procedure TTestModule.TestRecordElementFromFuncResult_AsParams;
  4547. begin
  4548. StartProgram(false);
  4549. Add('type');
  4550. Add(' integer = longint;');
  4551. Add(' TRecord = record');
  4552. Add(' i: integer;');
  4553. Add(' end;');
  4554. Add('function GetRec(vB: integer = 0): TRecord;');
  4555. Add('begin');
  4556. Add('end;');
  4557. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  4558. Add('begin');
  4559. Add('end;');
  4560. Add('begin');
  4561. Add(' doit(getrec.i,getrec.i,getrec.i);');
  4562. Add(' doit(getrec().i,getrec().i,getrec().i);');
  4563. Add(' doit(getrec(1).i,getrec(2).i,getrec(3).i);');
  4564. ConvertProgram;
  4565. CheckSource('TestRecordElementFromFuncResult_AsParams',
  4566. LinesToStr([ // statements
  4567. 'this.TRecord = function (s) {',
  4568. ' if (s) {',
  4569. ' this.i = s.i;',
  4570. ' } else {',
  4571. ' this.i = 0;',
  4572. ' };',
  4573. ' this.$equal = function (b) {',
  4574. ' return this.i == b.i;',
  4575. ' };',
  4576. '};',
  4577. 'this.GetRec = function (vB) {',
  4578. ' var Result = new this.TRecord();',
  4579. ' return Result;',
  4580. '};',
  4581. 'this.DoIt = function (vG,vH,vI) {',
  4582. '};'
  4583. ]),
  4584. LinesToStr([
  4585. 'this.DoIt(this.GetRec(0).i,this.GetRec(0).i,{',
  4586. ' p: this.GetRec(0),',
  4587. ' get: function () {',
  4588. ' return this.p.i;',
  4589. ' },',
  4590. ' set: function (v) {',
  4591. ' this.p.i = v;',
  4592. ' }',
  4593. '});',
  4594. 'this.DoIt(this.GetRec(0).i,this.GetRec(0).i,{',
  4595. ' p: this.GetRec(0),',
  4596. ' get: function () {',
  4597. ' return this.p.i;',
  4598. ' },',
  4599. ' set: function (v) {',
  4600. ' this.p.i = v;',
  4601. ' }',
  4602. '});',
  4603. 'this.DoIt(this.GetRec(1).i,this.GetRec(2).i,{',
  4604. ' p: this.GetRec(3),',
  4605. ' get: function () {',
  4606. ' return this.p.i;',
  4607. ' },',
  4608. ' set: function (v) {',
  4609. ' this.p.i = v;',
  4610. ' }',
  4611. '});',
  4612. '']));
  4613. end;
  4614. procedure TTestModule.TestRecordElementFromWith_AsParams;
  4615. begin
  4616. StartProgram(false);
  4617. Add('type');
  4618. Add(' integer = longint;');
  4619. Add(' TRecord = record');
  4620. Add(' i: integer;');
  4621. Add(' end;');
  4622. Add('procedure DoIt(vG: integer; const vH: integer; var vI: integer);');
  4623. Add('begin');
  4624. Add('end;');
  4625. Add('var r: trecord;');
  4626. Add('begin');
  4627. Add(' with r do ');
  4628. Add(' doit(i,i,i);');
  4629. ConvertProgram;
  4630. CheckSource('TestRecordElementFromWith_AsParams',
  4631. LinesToStr([ // statements
  4632. 'this.TRecord = function (s) {',
  4633. ' if (s) {',
  4634. ' this.i = s.i;',
  4635. ' } else {',
  4636. ' this.i = 0;',
  4637. ' };',
  4638. ' this.$equal = function (b) {',
  4639. ' return this.i == b.i;',
  4640. ' };',
  4641. '};',
  4642. 'this.DoIt = function (vG,vH,vI) {',
  4643. '};',
  4644. 'this.r = new this.TRecord();'
  4645. ]),
  4646. LinesToStr([
  4647. 'var $with1 = this.r;',
  4648. 'this.DoIt($with1.i,$with1.i,{',
  4649. ' p: $with1,',
  4650. ' get: function () {',
  4651. ' return this.p.i;',
  4652. ' },',
  4653. ' set: function (v) {',
  4654. ' this.p.i = v;',
  4655. ' }',
  4656. '});',
  4657. '']));
  4658. end;
  4659. procedure TTestModule.TestRecord_Equal;
  4660. begin
  4661. StartProgram(false);
  4662. Add('type');
  4663. Add(' integer = longint;');
  4664. Add(' TFlag = (red,blue);');
  4665. Add(' TFlags = set of TFlag;');
  4666. Add(' TProc = procedure;');
  4667. Add(' TRecord = record');
  4668. Add(' i: integer;');
  4669. Add(' Event: TProc;');
  4670. Add(' f: TFlags;');
  4671. Add(' end;');
  4672. Add(' TNested = record');
  4673. Add(' r: TRecord;');
  4674. Add(' end;');
  4675. Add('var');
  4676. Add(' b: boolean;');
  4677. Add(' r,s: trecord;');
  4678. Add('begin');
  4679. Add(' b:=r=s;');
  4680. Add(' b:=r<>s;');
  4681. ConvertProgram;
  4682. CheckSource('TestRecord_Equal',
  4683. LinesToStr([ // statements
  4684. 'this.TFlag = {',
  4685. ' "0": "red",',
  4686. ' red: 0,',
  4687. ' "1": "blue",',
  4688. ' blue: 1',
  4689. '};',
  4690. 'this.TRecord = function (s) {',
  4691. ' if (s) {',
  4692. ' this.i = s.i;',
  4693. ' this.Event = s.Event;',
  4694. ' this.f = rtl.refSet(s.f);',
  4695. ' } else {',
  4696. ' this.i = 0;',
  4697. ' this.Event = null;',
  4698. ' this.f = {};',
  4699. ' };',
  4700. ' this.$equal = function (b) {',
  4701. ' return (this.i == b.i) && (rtl.eqCallback(this.Event, b.Event) && rtl.eqSet(this.f, b.f));',
  4702. ' };',
  4703. '};',
  4704. 'this.TNested = function (s) {',
  4705. ' if (s) {',
  4706. ' this.r = new pas.program.TRecord(s.r);',
  4707. ' } else {',
  4708. ' this.r = new pas.program.TRecord();',
  4709. ' };',
  4710. ' this.$equal = function (b) {',
  4711. ' return this.r.$equal(b.r);',
  4712. ' };',
  4713. '};',
  4714. 'this.b = false;',
  4715. 'this.r = new this.TRecord();',
  4716. 'this.s = new this.TRecord();'
  4717. ]),
  4718. LinesToStr([
  4719. 'this.b = this.r.$equal(this.s);',
  4720. 'this.b = !this.r.$equal(this.s);',
  4721. '']));
  4722. end;
  4723. procedure TTestModule.TestClass_TObjectDefaultConstructor;
  4724. begin
  4725. StartProgram(false);
  4726. Add('type');
  4727. Add(' TObject = class');
  4728. Add(' public');
  4729. Add(' constructor Create;');
  4730. Add(' destructor Destroy;');
  4731. Add(' end;');
  4732. Add('constructor tobject.create;');
  4733. Add('begin end;');
  4734. Add('destructor tobject.destroy;');
  4735. Add('begin end;');
  4736. Add('var Obj: tobject;');
  4737. Add('begin');
  4738. Add(' obj:=tobject.create;');
  4739. Add(' obj.destroy;');
  4740. ConvertProgram;
  4741. CheckSource('TestClass_TObjectDefaultConstructor',
  4742. LinesToStr([ // statements
  4743. 'rtl.createClass(this,"TObject",null,function(){',
  4744. ' this.$init = function () {',
  4745. ' };',
  4746. ' this.$final = function () {',
  4747. ' };',
  4748. ' this.Create = function(){',
  4749. ' };',
  4750. ' this.Destroy = function(){',
  4751. ' };',
  4752. '});',
  4753. 'this.Obj = null;'
  4754. ]),
  4755. LinesToStr([ // this.$main
  4756. 'this.Obj = this.TObject.$create("Create");',
  4757. 'this.Obj.$destroy("Destroy");',
  4758. '']));
  4759. end;
  4760. procedure TTestModule.TestClass_TObjectConstructorWithParams;
  4761. begin
  4762. StartProgram(false);
  4763. Add('type');
  4764. Add(' TObject = class');
  4765. Add(' public');
  4766. Add(' constructor Create(Par: longint);');
  4767. Add(' end;');
  4768. Add('constructor tobject.create(par: longint);');
  4769. Add('begin end;');
  4770. Add('var Obj: tobject;');
  4771. Add('begin');
  4772. Add(' obj:=tobject.create(3);');
  4773. ConvertProgram;
  4774. CheckSource('TestClass_TObjectConstructorWithParams',
  4775. LinesToStr([ // statements
  4776. 'rtl.createClass(this,"TObject",null,function(){',
  4777. ' this.$init = function () {',
  4778. ' };',
  4779. ' this.$final = function () {',
  4780. ' };',
  4781. ' this.Create = function(Par){',
  4782. ' };',
  4783. '});',
  4784. 'this.Obj = null;'
  4785. ]),
  4786. LinesToStr([ // this.$main
  4787. 'this.Obj = this.TObject.$create("Create",[3]);'
  4788. ]));
  4789. end;
  4790. procedure TTestModule.TestClass_Var;
  4791. begin
  4792. StartProgram(false);
  4793. Add('type');
  4794. Add(' TObject = class');
  4795. Add(' public');
  4796. Add(' vI: longint;');
  4797. Add(' constructor Create(Par: longint);');
  4798. Add(' end;');
  4799. Add('constructor tobject.create(par: longint);');
  4800. Add('begin');
  4801. Add(' vi:=par+3');
  4802. Add('end;');
  4803. Add('var Obj: tobject;');
  4804. Add('begin');
  4805. Add(' obj:=tobject.create(4);');
  4806. Add(' obj.vi:=obj.VI+5;');
  4807. ConvertProgram;
  4808. CheckSource('TestClass_Var',
  4809. LinesToStr([ // statements
  4810. 'rtl.createClass(this,"TObject",null,function(){',
  4811. ' this.$init = function () {',
  4812. ' this.vI = 0;',
  4813. ' };',
  4814. ' this.$final = function () {',
  4815. ' };',
  4816. ' this.Create = function(Par){',
  4817. ' this.vI = Par+3;',
  4818. ' };',
  4819. '});',
  4820. 'this.Obj = null;'
  4821. ]),
  4822. LinesToStr([ // this.$main
  4823. 'this.Obj = this.TObject.$create("Create",[4]);',
  4824. 'this.Obj.vI = this.Obj.vI + 5;'
  4825. ]));
  4826. end;
  4827. procedure TTestModule.TestClass_Method;
  4828. begin
  4829. StartProgram(false);
  4830. Add('type');
  4831. Add(' TObject = class');
  4832. Add(' public');
  4833. Add(' vI: longint;');
  4834. Add(' Sub: TObject;');
  4835. Add(' constructor Create;');
  4836. Add(' function GetIt(Par: longint): tobject;');
  4837. Add(' end;');
  4838. Add('constructor tobject.create; begin end;');
  4839. Add('function tobject.getit(par: longint): tobject;');
  4840. Add('begin');
  4841. Add(' Self.vi:=par+3;');
  4842. Add(' Result:=self.sub;');
  4843. Add('end;');
  4844. Add('var Obj: tobject;');
  4845. Add('begin');
  4846. Add(' obj:=tobject.create;');
  4847. Add(' obj.getit(4);');
  4848. Add(' obj.sub.sub:=nil;');
  4849. Add(' obj.sub.getit(5);');
  4850. Add(' obj.sub.getit(6).SUB:=nil;');
  4851. Add(' obj.sub.getit(7).GETIT(8);');
  4852. Add(' obj.sub.getit(9).SuB.getit(10);');
  4853. ConvertProgram;
  4854. CheckSource('TestClass_Method',
  4855. LinesToStr([ // statements
  4856. 'rtl.createClass(this,"TObject",null,function(){',
  4857. ' this.$init = function () {',
  4858. ' this.vI = 0;',
  4859. ' this.Sub = null;',
  4860. ' };',
  4861. ' this.$final = function () {',
  4862. ' this.Sub = undefined;',
  4863. ' };',
  4864. ' this.Create = function(){',
  4865. ' };',
  4866. ' this.GetIt = function(Par){',
  4867. ' var Result = null;',
  4868. ' this.vI = Par + 3;',
  4869. ' Result = this.Sub;',
  4870. ' return Result;',
  4871. ' };',
  4872. '});',
  4873. 'this.Obj = null;'
  4874. ]),
  4875. LinesToStr([ // this.$main
  4876. 'this.Obj = this.TObject.$create("Create");',
  4877. 'this.Obj.GetIt(4);',
  4878. 'this.Obj.Sub.Sub=null;',
  4879. 'this.Obj.Sub.GetIt(5);',
  4880. 'this.Obj.Sub.GetIt(6).Sub=null;',
  4881. 'this.Obj.Sub.GetIt(7).GetIt(8);',
  4882. 'this.Obj.Sub.GetIt(9).Sub.GetIt(10);'
  4883. ]));
  4884. end;
  4885. procedure TTestModule.TestClass_Inheritance;
  4886. begin
  4887. StartProgram(false);
  4888. Add('type');
  4889. Add(' TObject = class');
  4890. Add(' public');
  4891. Add(' constructor Create;');
  4892. Add(' end;');
  4893. Add(' TClassA = class');
  4894. Add(' end;');
  4895. Add(' TClassB = class(TObject)');
  4896. Add(' procedure ProcB;');
  4897. Add(' end;');
  4898. Add('constructor tobject.create; begin end;');
  4899. Add('procedure tclassb.procb; begin end;');
  4900. Add('var');
  4901. Add(' oO: TObject;');
  4902. Add(' oA: TClassA;');
  4903. Add(' oB: TClassB;');
  4904. Add('begin');
  4905. Add(' oO:=tobject.Create;');
  4906. Add(' oA:=tclassa.Create;');
  4907. Add(' ob:=tclassb.Create;');
  4908. Add(' if oo is tclassa then ;');
  4909. Add(' ob:=oo as tclassb;');
  4910. Add(' (oo as tclassb).procb;');
  4911. ConvertProgram;
  4912. CheckSource('TestClass_Inheritance',
  4913. LinesToStr([ // statements
  4914. 'rtl.createClass(this,"TObject",null,function(){',
  4915. ' this.$init = function () {',
  4916. ' };',
  4917. ' this.$final = function () {',
  4918. ' };',
  4919. ' this.Create = function () {',
  4920. ' };',
  4921. '});',
  4922. 'rtl.createClass(this,"TClassA",this.TObject,function(){',
  4923. '});',
  4924. 'rtl.createClass(this,"TClassB",this.TObject,function(){',
  4925. ' this.ProcB = function () {',
  4926. ' };',
  4927. '});',
  4928. 'this.oO = null;',
  4929. 'this.oA = null;',
  4930. 'this.oB = null;'
  4931. ]),
  4932. LinesToStr([ // this.$main
  4933. 'this.oO = this.TObject.$create("Create");',
  4934. 'this.oA = this.TClassA.$create("Create");',
  4935. 'this.oB = this.TClassB.$create("Create");',
  4936. 'if (this.TClassA.isPrototypeOf(this.oO));',
  4937. 'this.oB = rtl.as(this.oO, this.TClassB);',
  4938. 'rtl.as(this.oO, this.TClassB).ProcB();'
  4939. ]));
  4940. end;
  4941. procedure TTestModule.TestClass_AbstractMethod;
  4942. begin
  4943. StartProgram(false);
  4944. Add('type');
  4945. Add(' TObject = class');
  4946. Add(' public');
  4947. Add(' procedure DoIt; virtual; abstract;');
  4948. Add(' end;');
  4949. Add('begin');
  4950. ConvertProgram;
  4951. CheckSource('TestClass_AbstractMethod',
  4952. LinesToStr([ // statements
  4953. 'rtl.createClass(this,"TObject",null,function(){',
  4954. ' this.$init = function () {',
  4955. ' };',
  4956. ' this.$final = function () {',
  4957. ' };',
  4958. '});'
  4959. ]),
  4960. LinesToStr([ // this.$main
  4961. ''
  4962. ]));
  4963. end;
  4964. procedure TTestModule.TestClass_CallInherited_NoParams;
  4965. begin
  4966. StartProgram(false);
  4967. Add('type');
  4968. Add(' TObject = class');
  4969. Add(' procedure DoAbstract; virtual; abstract;');
  4970. Add(' procedure DoVirtual; virtual;');
  4971. Add(' procedure DoIt;');
  4972. Add(' end;');
  4973. Add(' TA = class');
  4974. Add(' procedure doabstract; override;');
  4975. Add(' procedure dovirtual; override;');
  4976. Add(' procedure DoSome;');
  4977. Add(' end;');
  4978. Add('procedure tobject.dovirtual;');
  4979. Add('begin');
  4980. Add(' inherited; // call non existing ancestor -> ignore silently');
  4981. Add('end;');
  4982. Add('procedure tobject.doit;');
  4983. Add('begin');
  4984. Add('end;');
  4985. Add('procedure ta.doabstract;');
  4986. Add('begin');
  4987. Add(' inherited dovirtual; // call TObject.DoVirtual');
  4988. Add('end;');
  4989. Add('procedure ta.dovirtual;');
  4990. Add('begin');
  4991. Add(' inherited; // call TObject.DoVirtual');
  4992. Add(' inherited dovirtual; // call TObject.DoVirtual');
  4993. Add(' inherited dovirtual(); // call TObject.DoVirtual');
  4994. Add(' doit;');
  4995. Add(' doit();');
  4996. Add('end;');
  4997. Add('procedure ta.dosome;');
  4998. Add('begin');
  4999. Add(' inherited; // call non existing ancestor method -> silently ignore');
  5000. Add('end;');
  5001. Add('begin');
  5002. ConvertProgram;
  5003. CheckSource('TestClass_CallInherited_NoParams',
  5004. LinesToStr([ // statements
  5005. 'rtl.createClass(this,"TObject",null,function(){',
  5006. ' this.$init = function () {',
  5007. ' };',
  5008. ' this.$final = function () {',
  5009. ' };',
  5010. ' this.DoVirtual = function () {',
  5011. ' };',
  5012. ' this.DoIt = function () {',
  5013. ' };',
  5014. '});',
  5015. 'rtl.createClass(this, "TA", this.TObject, function () {',
  5016. ' this.DoAbstract = function () {',
  5017. ' pas.program.TObject.DoVirtual.call(this);',
  5018. ' };',
  5019. ' this.DoVirtual = function () {',
  5020. ' pas.program.TObject.DoVirtual.apply(this, arguments);',
  5021. ' pas.program.TObject.DoVirtual.call(this);',
  5022. ' pas.program.TObject.DoVirtual.call(this);',
  5023. ' this.DoIt();',
  5024. ' this.DoIt();',
  5025. ' };',
  5026. ' this.DoSome = function () {',
  5027. ' };',
  5028. '});'
  5029. ]),
  5030. LinesToStr([ // this.$main
  5031. ''
  5032. ]));
  5033. end;
  5034. procedure TTestModule.TestClass_CallInherited_WithParams;
  5035. begin
  5036. StartProgram(false);
  5037. Add('type');
  5038. Add(' TObject = class');
  5039. Add(' procedure DoAbstract(pA: longint; pB: longint = 0); virtual; abstract;');
  5040. Add(' procedure DoVirtual(pA: longint; pB: longint = 0); virtual;');
  5041. Add(' procedure DoIt(pA: longint; pB: longint = 0);');
  5042. Add(' procedure DoIt2(pA: longint = 1; pB: longint = 2);');
  5043. Add(' end;');
  5044. Add(' TClassA = class');
  5045. Add(' procedure DoAbstract(pA: longint; pB: longint = 0); override;');
  5046. Add(' procedure DoVirtual(pA: longint; pB: longint = 0); override;');
  5047. Add(' end;');
  5048. Add('procedure tobject.dovirtual(pa: longint; pb: longint = 0);');
  5049. Add('begin');
  5050. Add('end;');
  5051. Add('procedure tobject.doit(pa: longint; pb: longint = 0);');
  5052. Add('begin');
  5053. Add('end;');
  5054. Add('procedure tobject.doit2(pa: longint; pb: longint = 0);');
  5055. Add('begin');
  5056. Add('end;');
  5057. Add('procedure tclassa.doabstract(pa: longint; pb: longint = 0);');
  5058. Add('begin');
  5059. Add(' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)');
  5060. Add(' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)');
  5061. Add('end;');
  5062. Add('procedure tclassa.dovirtual(pa: longint; pb: longint = 0);');
  5063. Add('begin');
  5064. Add(' inherited; // call TObject.DoVirtual(pA,pB)');
  5065. Add(' inherited dovirtual(pa,pb); // call TObject.DoVirtual(pA,pB)');
  5066. Add(' inherited dovirtual(pa); // call TObject.DoVirtual(pA,0)');
  5067. Add(' doit(pa,pb);');
  5068. Add(' doit(pa);');
  5069. Add(' doit2(pa);');
  5070. Add(' doit2;');
  5071. Add('end;');
  5072. Add('begin');
  5073. ConvertProgram;
  5074. CheckSource('TestClass_CallInherited_WithParams',
  5075. LinesToStr([ // statements
  5076. 'rtl.createClass(this,"TObject",null,function(){',
  5077. ' this.$init = function () {',
  5078. ' };',
  5079. ' this.$final = function () {',
  5080. ' };',
  5081. ' this.DoVirtual = function (pA,pB) {',
  5082. ' };',
  5083. ' this.DoIt = function (pA,pB) {',
  5084. ' };',
  5085. ' this.DoIt2 = function (pA,pB) {',
  5086. ' };',
  5087. '});',
  5088. 'rtl.createClass(this, "TClassA", this.TObject, function () {',
  5089. ' this.DoAbstract = function (pA,pB) {',
  5090. ' pas.program.TObject.DoVirtual.call(this,pA,pB);',
  5091. ' pas.program.TObject.DoVirtual.call(this,pA,0);',
  5092. ' };',
  5093. ' this.DoVirtual = function (pA,pB) {',
  5094. ' pas.program.TObject.DoVirtual.apply(this, arguments);',
  5095. ' pas.program.TObject.DoVirtual.call(this,pA,pB);',
  5096. ' pas.program.TObject.DoVirtual.call(this,pA,0);',
  5097. ' this.DoIt(pA,pB);',
  5098. ' this.DoIt(pA,0);',
  5099. ' this.DoIt2(pA,2);',
  5100. ' this.DoIt2(1,2);',
  5101. ' };',
  5102. '});'
  5103. ]),
  5104. LinesToStr([ // this.$main
  5105. ''
  5106. ]));
  5107. end;
  5108. procedure TTestModule.TestClasS_CallInheritedConstructor;
  5109. begin
  5110. StartProgram(false);
  5111. Add('type');
  5112. Add(' TObject = class');
  5113. Add(' constructor Create; virtual;');
  5114. Add(' constructor CreateWithB(b: boolean);');
  5115. Add(' end;');
  5116. Add(' TA = class');
  5117. Add(' constructor Create; override;');
  5118. Add(' constructor CreateWithC(c: char);');
  5119. Add(' procedure DoIt;');
  5120. Add(' class function DoSome: TObject;');
  5121. Add(' end;');
  5122. Add('constructor tobject.create;');
  5123. Add('begin');
  5124. Add(' inherited; // call non existing ancestor -> ignore silently');
  5125. Add('end;');
  5126. Add('constructor tobject.createwithb(b: boolean);');
  5127. Add('begin');
  5128. Add(' inherited; // call non existing ancestor -> ignore silently');
  5129. Add(' create; // normal call');
  5130. Add('end;');
  5131. Add('constructor ta.create;');
  5132. Add('begin');
  5133. Add(' inherited; // normal call TObject.Create');
  5134. Add(' inherited create; // normal call TObject.Create');
  5135. Add(' inherited createwithb(false); // normal call TObject.CreateWithB');
  5136. Add('end;');
  5137. Add('constructor ta.createwithc(c: char);');
  5138. Add('begin');
  5139. Add(' inherited create; // call TObject.Create');
  5140. Add(' inherited createwithb(true); // call TObject.CreateWithB');
  5141. Add(' doit;');
  5142. Add(' doit();');
  5143. Add(' dosome;');
  5144. Add('end;');
  5145. Add('procedure ta.doit;');
  5146. Add('begin');
  5147. Add(' create; // normal call');
  5148. Add(' createwithb(false); // normal call');
  5149. Add(' createwithc(''c''); // normal call');
  5150. Add('end;');
  5151. Add('class function ta.dosome: TObject;');
  5152. Add('begin');
  5153. Add(' Result:=create; // constructor');
  5154. Add(' Result:=createwithb(true); // constructor');
  5155. Add(' Result:=createwithc(''c''); // constructor');
  5156. Add('end;');
  5157. Add('begin');
  5158. ConvertProgram;
  5159. CheckSource('TestClass_CallInheritedConstructor',
  5160. LinesToStr([ // statements
  5161. 'rtl.createClass(this,"TObject",null,function(){',
  5162. ' this.$init = function () {',
  5163. ' };',
  5164. ' this.$final = function () {',
  5165. ' };',
  5166. ' this.Create = function () {',
  5167. ' };',
  5168. ' this.CreateWithB = function (b) {',
  5169. ' this.Create();',
  5170. ' };',
  5171. '});',
  5172. 'rtl.createClass(this, "TA", this.TObject, function () {',
  5173. ' this.Create = function () {',
  5174. ' pas.program.TObject.Create.apply(this, arguments);',
  5175. ' pas.program.TObject.Create.call(this);',
  5176. ' pas.program.TObject.CreateWithB.call(this, false);',
  5177. ' };',
  5178. ' this.CreateWithC = function (c) {',
  5179. ' pas.program.TObject.Create.call(this);',
  5180. ' pas.program.TObject.CreateWithB.call(this, true);',
  5181. ' this.DoIt();',
  5182. ' this.DoIt();',
  5183. ' this.$class.DoSome();',
  5184. ' };',
  5185. ' this.DoIt = function () {',
  5186. ' this.Create();',
  5187. ' this.CreateWithB(false);',
  5188. ' this.CreateWithC("c");',
  5189. ' };',
  5190. ' this.DoSome = function () {',
  5191. ' var Result = null;',
  5192. ' Result = this.$create("Create");',
  5193. ' Result = this.$create("CreateWithB", [true]);',
  5194. ' Result = this.$create("CreateWithC", ["c"]);',
  5195. ' return Result;',
  5196. ' };',
  5197. '});'
  5198. ]),
  5199. LinesToStr([ // this.$main
  5200. ''
  5201. ]));
  5202. end;
  5203. procedure TTestModule.TestClass_ClassVar;
  5204. begin
  5205. StartProgram(false);
  5206. Add('type');
  5207. Add(' TObject = class');
  5208. Add(' public');
  5209. Add(' class var vI: longint;');
  5210. Add(' class var Sub: TObject;');
  5211. Add(' constructor Create;');
  5212. Add(' class function GetIt(Par: longint): tobject;');
  5213. Add(' end;');
  5214. Add('constructor tobject.create;');
  5215. Add('begin');
  5216. Add(' vi:=vi+1;');
  5217. Add(' Self.vi:=Self.vi+1;');
  5218. Add('end;');
  5219. Add('class function tobject.getit(par: longint): tobject;');
  5220. Add('begin');
  5221. Add(' vi:=vi+par;');
  5222. Add(' Self.vi:=Self.vi+par;');
  5223. Add(' Result:=self.sub;');
  5224. Add('end;');
  5225. Add('var Obj: tobject;');
  5226. Add('begin');
  5227. Add(' obj:=tobject.create;');
  5228. Add(' tobject.vi:=3;');
  5229. Add(' if tobject.vi=4 then ;');
  5230. Add(' tobject.sub:=nil;');
  5231. Add(' obj.sub:=nil;');
  5232. Add(' obj.sub.sub:=nil;');
  5233. ConvertProgram;
  5234. CheckSource('TestClass_ClassVar',
  5235. LinesToStr([ // statements
  5236. 'rtl.createClass(this,"TObject",null,function(){',
  5237. ' this.vI = 0;',
  5238. ' this.Sub = null;',
  5239. ' this.$init = function () {',
  5240. ' };',
  5241. ' this.$final = function () {',
  5242. ' };',
  5243. ' this.Create = function(){',
  5244. ' this.$class.vI = this.vI+1;',
  5245. ' this.$class.vI = this.vI+1;',
  5246. ' };',
  5247. ' this.GetIt = function(Par){',
  5248. ' var Result = null;',
  5249. ' this.vI = this.vI + Par;',
  5250. ' this.vI = this.vI + Par;',
  5251. ' Result = this.Sub;',
  5252. ' return Result;',
  5253. ' };',
  5254. '});',
  5255. 'this.Obj = null;'
  5256. ]),
  5257. LinesToStr([ // this.$main
  5258. 'this.Obj = this.TObject.$create("Create");',
  5259. 'this.TObject.vI = 3;',
  5260. 'if (this.TObject.vI == 4);',
  5261. 'this.TObject.Sub=null;',
  5262. 'this.Obj.$class.Sub=null;',
  5263. 'this.Obj.Sub.$class.Sub=null;',
  5264. '']));
  5265. end;
  5266. procedure TTestModule.TestClass_CallClassMethod;
  5267. begin
  5268. StartProgram(false);
  5269. Add('type');
  5270. Add(' TObject = class');
  5271. Add(' public');
  5272. Add(' class var vI: longint;');
  5273. Add(' class var Sub: TObject;');
  5274. Add(' constructor Create;');
  5275. Add(' function GetMore(Par: longint): longint;');
  5276. Add(' class function GetIt(Par: longint): tobject;');
  5277. Add(' end;');
  5278. Add('constructor tobject.create;');
  5279. Add('begin');
  5280. Add(' sub:=getit(3);');
  5281. Add(' vi:=getmore(4);');
  5282. Add(' sub:=Self.getit(5);');
  5283. Add(' vi:=Self.getmore(6);');
  5284. Add('end;');
  5285. Add('function tobject.getmore(par: longint): longint;');
  5286. Add('begin');
  5287. Add(' sub:=getit(11);');
  5288. Add(' vi:=getmore(12);');
  5289. Add(' sub:=self.getit(13);');
  5290. Add(' vi:=self.getmore(14);');
  5291. Add('end;');
  5292. Add('class function tobject.getit(par: longint): tobject;');
  5293. Add('begin');
  5294. Add(' sub:=getit(21);');
  5295. Add(' vi:=sub.getmore(22);');
  5296. Add(' sub:=self.getit(23);');
  5297. Add(' vi:=self.sub.getmore(24);');
  5298. Add('end;');
  5299. Add('var Obj: tobject;');
  5300. Add('begin');
  5301. Add(' obj:=tobject.create;');
  5302. Add(' tobject.getit(5);');
  5303. Add(' obj.getit(6);');
  5304. Add(' obj.sub.getit(7);');
  5305. Add(' obj.sub.getit(8).SUB:=nil;');
  5306. Add(' obj.sub.getit(9).GETIT(10);');
  5307. Add(' obj.sub.getit(11).SuB.getit(12);');
  5308. ConvertProgram;
  5309. CheckSource('TestClass_CallClassMethod',
  5310. LinesToStr([ // statements
  5311. 'rtl.createClass(this,"TObject",null,function(){',
  5312. ' this.vI = 0;',
  5313. ' this.Sub = null;',
  5314. ' this.$init = function () {',
  5315. ' };',
  5316. ' this.$final = function () {',
  5317. ' };',
  5318. ' this.Create = function(){',
  5319. ' this.$class.Sub = this.$class.GetIt(3);',
  5320. ' this.$class.vI = this.GetMore(4);',
  5321. ' this.$class.Sub = this.$class.GetIt(5);',
  5322. ' this.$class.vI = this.GetMore(6);',
  5323. ' };',
  5324. ' this.GetMore = function(Par){',
  5325. ' var Result = 0;',
  5326. ' this.$class.Sub = this.$class.GetIt(11);',
  5327. ' this.$class.vI = this.GetMore(12);',
  5328. ' this.$class.Sub = this.$class.GetIt(13);',
  5329. ' this.$class.vI = this.GetMore(14);',
  5330. ' return Result;',
  5331. ' };',
  5332. ' this.GetIt = function(Par){',
  5333. ' var Result = null;',
  5334. ' this.Sub = this.GetIt(21);',
  5335. ' this.vI = this.Sub.GetMore(22);',
  5336. ' this.Sub = this.GetIt(23);',
  5337. ' this.vI = this.Sub.GetMore(24);',
  5338. ' return Result;',
  5339. ' };',
  5340. '});',
  5341. 'this.Obj = null;'
  5342. ]),
  5343. LinesToStr([ // this.$main
  5344. 'this.Obj = this.TObject.$create("Create");',
  5345. 'this.TObject.GetIt(5);',
  5346. 'this.Obj.$class.GetIt(6);',
  5347. 'this.Obj.Sub.$class.GetIt(7);',
  5348. 'this.Obj.Sub.$class.GetIt(8).$class.Sub=null;',
  5349. 'this.Obj.Sub.$class.GetIt(9).$class.GetIt(10);',
  5350. 'this.Obj.Sub.$class.GetIt(11).Sub.$class.GetIt(12);',
  5351. '']));
  5352. end;
  5353. procedure TTestModule.TestClass_Property;
  5354. begin
  5355. StartProgram(false);
  5356. Add('type');
  5357. Add(' TObject = class');
  5358. Add(' Fx: longint;');
  5359. Add(' Fy: longint;');
  5360. Add(' function GetInt: longint;');
  5361. Add(' procedure SetInt(Value: longint);');
  5362. Add(' procedure DoIt;');
  5363. Add(' property IntA: longint read Fx write Fy;');
  5364. Add(' property IntB: longint read GetInt write SetInt;');
  5365. Add(' end;');
  5366. Add('function tobject.getint: longint;');
  5367. Add('begin');
  5368. Add(' result:=fx;');
  5369. Add('end;');
  5370. Add('procedure tobject.setint(value: longint);');
  5371. Add('begin');
  5372. Add(' if value=fy then exit;');
  5373. Add(' fy:=value;');
  5374. Add('end;');
  5375. Add('procedure tobject.doit;');
  5376. Add('begin');
  5377. Add(' IntA:=IntA+1;');
  5378. Add(' Self.IntA:=Self.IntA+1;');
  5379. Add(' IntB:=IntB+1;');
  5380. Add(' Self.IntB:=Self.IntB+1;');
  5381. Add('end;');
  5382. Add('var Obj: tobject;');
  5383. Add('begin');
  5384. Add(' obj.inta:=obj.inta+1;');
  5385. Add(' if obj.intb=2 then;');
  5386. Add(' obj.intb:=obj.intb+2;');
  5387. Add(' obj.setint(obj.inta);');
  5388. ConvertProgram;
  5389. CheckSource('TestClass_Property',
  5390. LinesToStr([ // statements
  5391. 'rtl.createClass(this, "TObject", null, function () {',
  5392. ' this.$init = function () {',
  5393. ' this.Fx = 0;',
  5394. ' this.Fy = 0;',
  5395. ' };',
  5396. ' this.$final = function () {',
  5397. ' };',
  5398. ' this.GetInt = function () {',
  5399. ' var Result = 0;',
  5400. ' Result = this.Fx;',
  5401. ' return Result;',
  5402. ' };',
  5403. ' this.SetInt = function (Value) {',
  5404. ' if (Value == this.Fy) return;',
  5405. ' this.Fy = Value;',
  5406. ' };',
  5407. ' this.DoIt = function () {',
  5408. ' this.Fy = this.Fx + 1;',
  5409. ' this.Fy = this.Fx + 1;',
  5410. ' this.SetInt(this.GetInt() + 1);',
  5411. ' this.SetInt(this.GetInt() + 1);',
  5412. ' };',
  5413. '});',
  5414. 'this.Obj = null;'
  5415. ]),
  5416. LinesToStr([ // this.$main
  5417. 'this.Obj.Fy = this.Obj.Fx + 1;',
  5418. 'if (this.Obj.GetInt() == 2);',
  5419. 'this.Obj.SetInt(this.Obj.GetInt() + 2);',
  5420. 'this.Obj.SetInt(this.Obj.Fx);'
  5421. ]));
  5422. end;
  5423. procedure TTestModule.TestClass_Property_ClassMethod;
  5424. begin
  5425. StartProgram(false);
  5426. Add('type');
  5427. Add(' TObject = class');
  5428. Add(' class var Fx: longint;');
  5429. Add(' class var Fy: longint;');
  5430. Add(' class function GetInt: longint;');
  5431. Add(' class procedure SetInt(Value: longint);');
  5432. Add(' class procedure DoIt;');
  5433. Add(' class property IntA: longint read Fx write Fy;');
  5434. Add(' class property IntB: longint read GetInt write SetInt;');
  5435. Add(' end;');
  5436. Add('class function tobject.getint: longint;');
  5437. Add('begin');
  5438. Add(' result:=fx;');
  5439. Add('end;');
  5440. Add('class procedure tobject.setint(value: longint);');
  5441. Add('begin');
  5442. Add('end;');
  5443. Add('class procedure tobject.doit;');
  5444. Add('begin');
  5445. Add(' IntA:=IntA+1;');
  5446. Add(' Self.IntA:=Self.IntA+1;');
  5447. Add(' IntB:=IntB+1;');
  5448. Add(' Self.IntB:=Self.IntB+1;');
  5449. Add('end;');
  5450. Add('var Obj: tobject;');
  5451. Add('begin');
  5452. Add(' tobject.inta:=tobject.inta+1;');
  5453. Add(' if tobject.intb=2 then;');
  5454. Add(' tobject.intb:=tobject.intb+2;');
  5455. Add(' tobject.setint(tobject.inta);');
  5456. Add(' obj.inta:=obj.inta+1;');
  5457. Add(' if obj.intb=2 then;');
  5458. Add(' obj.intb:=obj.intb+2;');
  5459. Add(' obj.setint(obj.inta);');
  5460. ConvertProgram;
  5461. CheckSource('TestClass_Property_ClassMethod',
  5462. LinesToStr([ // statements
  5463. 'rtl.createClass(this, "TObject", null, function () {',
  5464. ' this.Fx = 0;',
  5465. ' this.Fy = 0;',
  5466. ' this.$init = function () {',
  5467. ' };',
  5468. ' this.$final = function () {',
  5469. ' };',
  5470. ' this.GetInt = function () {',
  5471. ' var Result = 0;',
  5472. ' Result = this.Fx;',
  5473. ' return Result;',
  5474. ' };',
  5475. ' this.SetInt = function (Value) {',
  5476. ' };',
  5477. ' this.DoIt = function () {',
  5478. ' this.Fy = this.Fx + 1;',
  5479. ' this.Fy = this.Fx + 1;',
  5480. ' this.SetInt(this.GetInt() + 1);',
  5481. ' this.SetInt(this.GetInt() + 1);',
  5482. ' };',
  5483. '});',
  5484. 'this.Obj = null;'
  5485. ]),
  5486. LinesToStr([ // this.$main
  5487. 'this.TObject.Fy = this.TObject.Fx + 1;',
  5488. 'if (this.TObject.GetInt() == 2);',
  5489. 'this.TObject.SetInt(this.TObject.GetInt() + 2);',
  5490. 'this.TObject.SetInt(this.TObject.Fx);',
  5491. 'this.Obj.$class.Fy = this.Obj.Fx + 1;',
  5492. 'if (this.Obj.$class.GetInt() == 2);',
  5493. 'this.Obj.$class.SetInt(this.Obj.$class.GetInt() + 2);',
  5494. 'this.Obj.$class.SetInt(this.Obj.Fx);'
  5495. ]));
  5496. end;
  5497. procedure TTestModule.TestClass_Property_Index;
  5498. begin
  5499. StartProgram(false);
  5500. Add('type');
  5501. Add(' TObject = class');
  5502. Add(' FItems: array of longint;');
  5503. Add(' function GetItems(Index: longint): longint;');
  5504. Add(' procedure SetItems(Index: longint; Value: longint);');
  5505. Add(' procedure DoIt;');
  5506. Add(' property Items[Index: longint]: longint read getitems write setitems;');
  5507. Add(' end;');
  5508. Add('function tobject.getitems(index: longint): longint;');
  5509. Add('begin');
  5510. Add(' Result:=fitems[index];');
  5511. Add('end;');
  5512. Add('procedure tobject.setitems(index: longint; value: longint);');
  5513. Add('begin');
  5514. Add(' fitems[index]:=value;');
  5515. Add('end;');
  5516. Add('procedure tobject.doit;');
  5517. Add('begin');
  5518. Add(' items[1]:=2;');
  5519. Add(' items[3]:=items[4];');
  5520. Add(' self.items[5]:=self.items[6];');
  5521. Add(' items[items[7]]:=items[items[8]];');
  5522. Add('end;');
  5523. Add('var Obj: tobject;');
  5524. Add('begin');
  5525. Add(' obj.Items[11]:=obj.Items[12];');
  5526. ConvertProgram;
  5527. CheckSource('TestClass_Property_Index',
  5528. LinesToStr([ // statements
  5529. 'rtl.createClass(this, "TObject", null, function () {',
  5530. ' this.$init = function () {',
  5531. ' this.FItems = [];',
  5532. ' };',
  5533. ' this.$final = function () {',
  5534. ' this.FItems = undefined;',
  5535. ' };',
  5536. ' this.GetItems = function (Index) {',
  5537. ' var Result = 0;',
  5538. ' Result = this.FItems[Index];',
  5539. ' return Result;',
  5540. ' };',
  5541. ' this.SetItems = function (Index, Value) {',
  5542. ' this.FItems[Index] = Value;',
  5543. ' };',
  5544. ' this.DoIt = function () {',
  5545. ' this.SetItems(1, 2);',
  5546. ' this.SetItems(3,this.GetItems(4));',
  5547. ' this.SetItems(5,this.GetItems(6));',
  5548. ' this.SetItems(this.GetItems(7), this.GetItems(this.GetItems(8)));',
  5549. ' };',
  5550. '});',
  5551. 'this.Obj = null;'
  5552. ]),
  5553. LinesToStr([ // this.$main
  5554. 'this.Obj.SetItems(11,this.Obj.GetItems(12));'
  5555. ]));
  5556. end;
  5557. procedure TTestModule.TestClass_PropertyOfTypeArray;
  5558. begin
  5559. StartProgram(false);
  5560. Add('type');
  5561. Add(' TArray = array of longint;');
  5562. Add(' TObject = class');
  5563. Add(' FItems: TArray;');
  5564. Add(' function GetItems: tarray;');
  5565. Add(' procedure SetItems(Value: tarray);');
  5566. Add(' property Items: tarray read getitems write setitems;');
  5567. Add(' end;');
  5568. Add('function tobject.getitems: tarray;');
  5569. Add('begin');
  5570. Add(' Result:=fitems;');
  5571. Add('end;');
  5572. Add('procedure tobject.setitems(value: tarray);');
  5573. Add('begin');
  5574. Add(' fitems:=value;');
  5575. Add(' fitems:=nil;');
  5576. Add(' Items:=nil;');
  5577. Add(' Items:=Items;');
  5578. Add(' Items[1]:=2;');
  5579. Add(' fitems[3]:=Items[4];');
  5580. Add(' Items[5]:=Items[6];');
  5581. Add(' Self.Items[7]:=8;');
  5582. Add(' Self.Items[9]:=Self.Items[10];');
  5583. Add(' Items[Items[11]]:=Items[Items[12]];');
  5584. Add('end;');
  5585. Add('var Obj: tobject;');
  5586. Add('begin');
  5587. Add(' obj.items:=nil;');
  5588. Add(' obj.items:=obj.items;');
  5589. Add(' obj.items[11]:=obj.items[12];');
  5590. ConvertProgram;
  5591. CheckSource('TestClass_PropertyOfTypeArray',
  5592. LinesToStr([ // statements
  5593. 'rtl.createClass(this, "TObject", null, function () {',
  5594. ' this.$init = function () {',
  5595. ' this.FItems = [];',
  5596. ' };',
  5597. ' this.$final = function () {',
  5598. ' this.FItems = undefined;',
  5599. ' };',
  5600. ' this.GetItems = function () {',
  5601. ' var Result = [];',
  5602. ' Result = this.FItems;',
  5603. ' return Result;',
  5604. ' };',
  5605. ' this.SetItems = function (Value) {',
  5606. ' this.FItems = Value;',
  5607. ' this.FItems = [];',
  5608. ' this.SetItems([]);',
  5609. ' this.SetItems(this.GetItems());',
  5610. ' this.GetItems()[1] = 2;',
  5611. ' this.FItems[3] = this.GetItems()[4];',
  5612. ' this.GetItems()[5] = this.GetItems()[6];',
  5613. ' this.GetItems()[7] = 8;',
  5614. ' this.GetItems()[9] = this.GetItems()[10];',
  5615. ' this.GetItems()[this.GetItems()[11]] = this.GetItems()[this.GetItems()[12]];',
  5616. ' };',
  5617. '});',
  5618. 'this.Obj = null;'
  5619. ]),
  5620. LinesToStr([ // this.$main
  5621. 'this.Obj.SetItems([]);',
  5622. 'this.Obj.SetItems(this.Obj.GetItems());',
  5623. 'this.Obj.GetItems()[11] = this.Obj.GetItems()[12];'
  5624. ]));
  5625. end;
  5626. procedure TTestModule.TestClass_PropertyDefault;
  5627. begin
  5628. StartProgram(false);
  5629. Add('type');
  5630. Add(' TArray = array of longint;');
  5631. Add(' TObject = class');
  5632. Add(' FItems: TArray;');
  5633. Add(' function GetItems(Index: longint): longint;');
  5634. Add(' procedure SetItems(Index, Value: longint);');
  5635. Add(' property Items[Index: longint]: longint read getitems write setitems; default;');
  5636. Add(' end;');
  5637. Add('function tobject.getitems(index: longint): longint;');
  5638. Add('begin');
  5639. Add('end;');
  5640. Add('procedure tobject.setitems(index, value: longint);');
  5641. Add('begin');
  5642. Add(' Self[1]:=2;');
  5643. Add(' Self[3]:=Self[index];');
  5644. Add(' Self[index]:=Self[Self[value]];');
  5645. Add(' Self[Self[4]]:=value;');
  5646. Add('end;');
  5647. Add('var Obj: tobject;');
  5648. Add('begin');
  5649. Add(' obj[11]:=12;');
  5650. Add(' obj[13]:=obj[14];');
  5651. Add(' obj[obj[15]]:=obj[obj[15]];');
  5652. ConvertProgram;
  5653. CheckSource('TestClass_PropertyDefault',
  5654. LinesToStr([ // statements
  5655. 'rtl.createClass(this, "TObject", null, function () {',
  5656. ' this.$init = function () {',
  5657. ' this.FItems = [];',
  5658. ' };',
  5659. ' this.$final = function () {',
  5660. ' this.FItems = undefined;',
  5661. ' };',
  5662. ' this.GetItems = function (Index) {',
  5663. ' var Result = 0;',
  5664. ' return Result;',
  5665. ' };',
  5666. ' this.SetItems = function (Index, Value) {',
  5667. ' this.SetItems(1, 2);',
  5668. ' this.SetItems(3, this.GetItems(Index));',
  5669. ' this.SetItems(Index, this.GetItems(this.GetItems(Value)));',
  5670. ' this.SetItems(this.GetItems(4), Value);',
  5671. ' };',
  5672. '});',
  5673. 'this.Obj = null;'
  5674. ]),
  5675. LinesToStr([ // this.$main
  5676. 'this.Obj.SetItems(11, 12);',
  5677. 'this.Obj.SetItems(13, this.Obj.GetItems(14));',
  5678. 'this.Obj.SetItems(this.Obj.GetItems(15), this.Obj.GetItems(this.Obj.GetItems(15)));'
  5679. ]));
  5680. end;
  5681. procedure TTestModule.TestClass_PropertyOverride;
  5682. begin
  5683. StartProgram(false);
  5684. Add('type');
  5685. Add(' integer = longint;');
  5686. Add(' TObject = class');
  5687. Add(' FItem: integer;');
  5688. Add(' function GetItem: integer; external name ''GetItem'';');
  5689. Add(' procedure SetItem(Value: integer); external name ''SetItem'';');
  5690. Add(' property Item: integer read getitem write setitem;');
  5691. Add(' end;');
  5692. Add(' TCar = class');
  5693. Add(' FBag: integer;');
  5694. Add(' function GetBag: integer; external name ''GetBag'';');
  5695. Add(' property Item read getbag;');
  5696. Add(' end;');
  5697. Add('var');
  5698. Add(' Obj: tobject;');
  5699. Add(' Car: tcar;');
  5700. Add('begin');
  5701. Add(' Obj.Item:=Obj.Item;');
  5702. Add(' Car.Item:=Car.Item;');
  5703. ConvertProgram;
  5704. CheckSource('TestClass_PropertyOverride',
  5705. LinesToStr([ // statements
  5706. 'rtl.createClass(this, "TObject", null, function () {',
  5707. ' this.$init = function () {',
  5708. ' this.FItem = 0;',
  5709. ' };',
  5710. ' this.$final = function () {',
  5711. ' };',
  5712. '});',
  5713. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  5714. ' this.$init = function () {',
  5715. ' pas.program.TObject.$init.call(this);',
  5716. ' this.FBag = 0;',
  5717. ' };',
  5718. '});',
  5719. 'this.Obj = null;',
  5720. 'this.Car = null;',
  5721. '']),
  5722. LinesToStr([ // this.$main
  5723. 'this.Obj.SetItem(this.Obj.GetItem());',
  5724. 'this.Car.SetItem(this.Car.GetBag());',
  5725. '']));
  5726. end;
  5727. procedure TTestModule.TestClass_Assigned;
  5728. begin
  5729. StartProgram(false);
  5730. Add('type');
  5731. Add(' TObject = class');
  5732. Add(' end;');
  5733. Add('var');
  5734. Add(' Obj: tobject;');
  5735. Add(' b: boolean;');
  5736. Add('begin');
  5737. Add(' if Assigned(obj) then ;');
  5738. Add(' b:=Assigned(obj) or false;');
  5739. ConvertProgram;
  5740. CheckSource('TestClass_Assigned',
  5741. LinesToStr([ // statements
  5742. 'rtl.createClass(this, "TObject", null, function () {',
  5743. ' this.$init = function () {',
  5744. ' };',
  5745. ' this.$final = function () {',
  5746. ' };',
  5747. '});',
  5748. 'this.Obj = null;',
  5749. 'this.b = false;'
  5750. ]),
  5751. LinesToStr([ // this.$main
  5752. 'if (this.Obj != null);',
  5753. 'this.b = (this.Obj != null) || false;'
  5754. ]));
  5755. end;
  5756. procedure TTestModule.TestClass_WithClassDoCreate;
  5757. begin
  5758. StartProgram(false);
  5759. Add('type');
  5760. Add(' TObject = class');
  5761. Add(' aBool: boolean;');
  5762. Add(' Arr: array of boolean;');
  5763. Add(' constructor Create;');
  5764. Add(' end;');
  5765. Add('constructor TObject.Create; begin end;');
  5766. Add('var');
  5767. Add(' Obj: tobject;');
  5768. Add(' b: boolean;');
  5769. Add('begin');
  5770. Add(' with tobject.create do begin');
  5771. Add(' b:=abool;');
  5772. Add(' abool:=b;');
  5773. Add(' b:=arr[1];');
  5774. Add(' arr[2]:=b;');
  5775. Add(' end;');
  5776. Add(' with tobject do');
  5777. Add(' obj:=create;');
  5778. Add(' with obj do begin');
  5779. Add(' create;');
  5780. Add(' b:=abool;');
  5781. Add(' abool:=b;');
  5782. Add(' b:=arr[3];');
  5783. Add(' arr[4]:=b;');
  5784. Add(' end;');
  5785. ConvertProgram;
  5786. CheckSource('TestClass_WithClassDoCreate',
  5787. LinesToStr([ // statements
  5788. 'rtl.createClass(this, "TObject", null, function () {',
  5789. ' this.$init = function () {',
  5790. ' this.aBool = false;',
  5791. ' this.Arr = [];',
  5792. ' };',
  5793. ' this.$final = function () {',
  5794. ' this.Arr = undefined;',
  5795. ' };',
  5796. ' this.Create = function () {',
  5797. ' };',
  5798. '});',
  5799. 'this.Obj = null;',
  5800. 'this.b = false;'
  5801. ]),
  5802. LinesToStr([ // this.$main
  5803. 'var $with1 = this.TObject.$create("Create");',
  5804. 'this.b = $with1.aBool;',
  5805. '$with1.aBool = this.b;',
  5806. 'this.b = $with1.Arr[1];',
  5807. '$with1.Arr[2] = this.b;',
  5808. 'var $with2 = this.TObject;',
  5809. 'this.Obj = $with2.$create("Create");',
  5810. 'var $with3 = this.Obj;',
  5811. '$with3.Create();',
  5812. 'this.b = $with3.aBool;',
  5813. '$with3.aBool = this.b;',
  5814. 'this.b = $with3.Arr[3];',
  5815. '$with3.Arr[4] = this.b;',
  5816. '']));
  5817. end;
  5818. procedure TTestModule.TestClass_WithClassInstDoProperty;
  5819. begin
  5820. StartProgram(false);
  5821. Add('type');
  5822. Add(' TObject = class');
  5823. Add(' FInt: longint;');
  5824. Add(' constructor Create;');
  5825. Add(' function GetSize: longint;');
  5826. Add(' procedure SetSize(Value: longint);');
  5827. Add(' property Int: longint read FInt write FInt;');
  5828. Add(' property Size: longint read GetSize write SetSize;');
  5829. Add(' end;');
  5830. Add('constructor TObject.Create; begin end;');
  5831. Add('function TObject.GetSize: longint; begin; end;');
  5832. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  5833. Add('var');
  5834. Add(' Obj: tobject;');
  5835. Add(' i: longint;');
  5836. Add('begin');
  5837. Add(' with TObject.Create do begin');
  5838. Add(' i:=int;');
  5839. Add(' int:=i;');
  5840. Add(' i:=size;');
  5841. Add(' size:=i;');
  5842. Add(' end;');
  5843. Add(' with obj do begin');
  5844. Add(' i:=int;');
  5845. Add(' int:=i;');
  5846. Add(' i:=size;');
  5847. Add(' size:=i;');
  5848. Add(' end;');
  5849. ConvertProgram;
  5850. CheckSource('TestClass_WithClassInstDoProperty',
  5851. LinesToStr([ // statements
  5852. 'rtl.createClass(this, "TObject", null, function () {',
  5853. ' this.$init = function () {',
  5854. ' this.FInt = 0;',
  5855. ' };',
  5856. ' this.$final = function () {',
  5857. ' };',
  5858. ' this.Create = function () {',
  5859. ' };',
  5860. ' this.GetSize = function () {',
  5861. ' var Result = 0;',
  5862. ' return Result;',
  5863. ' };',
  5864. ' this.SetSize = function (Value) {',
  5865. ' };',
  5866. '});',
  5867. 'this.Obj = null;',
  5868. 'this.i = 0;'
  5869. ]),
  5870. LinesToStr([ // this.$main
  5871. 'var $with1 = this.TObject.$create("Create");',
  5872. 'this.i = $with1.FInt;',
  5873. '$with1.FInt = this.i;',
  5874. 'this.i = $with1.GetSize();',
  5875. '$with1.SetSize(this.i);',
  5876. 'var $with2 = this.Obj;',
  5877. 'this.i = $with2.FInt;',
  5878. '$with2.FInt = this.i;',
  5879. 'this.i = $with2.GetSize();',
  5880. '$with2.SetSize(this.i);',
  5881. '']));
  5882. end;
  5883. procedure TTestModule.TestClass_WithClassInstDoPropertyWithParams;
  5884. begin
  5885. StartProgram(false);
  5886. Add('type');
  5887. Add(' TObject = class');
  5888. Add(' constructor Create;');
  5889. Add(' function GetItems(Index: longint): longint;');
  5890. Add(' procedure SetItems(Index, Value: longint);');
  5891. Add(' property Items[Index: longint]: longint read GetItems write SetItems;');
  5892. Add(' end;');
  5893. Add('constructor TObject.Create; begin end;');
  5894. Add('function tobject.getitems(index: longint): longint; begin; end;');
  5895. Add('procedure tobject.setitems(index, value: longint); begin; end;');
  5896. Add('var');
  5897. Add(' Obj: tobject;');
  5898. Add(' i: longint;');
  5899. Add('begin');
  5900. Add(' with TObject.Create do begin');
  5901. Add(' i:=Items[1];');
  5902. Add(' Items[2]:=i;');
  5903. Add(' end;');
  5904. Add(' with obj do begin');
  5905. Add(' i:=Items[3];');
  5906. Add(' Items[4]:=i;');
  5907. Add(' end;');
  5908. ConvertProgram;
  5909. CheckSource('TestClass_WithClassInstDoPropertyWithParams',
  5910. LinesToStr([ // statements
  5911. 'rtl.createClass(this, "TObject", null, function () {',
  5912. ' this.$init = function () {',
  5913. ' };',
  5914. ' this.$final = function () {',
  5915. ' };',
  5916. ' this.Create = function () {',
  5917. ' };',
  5918. ' this.GetItems = function (Index) {',
  5919. ' var Result = 0;',
  5920. ' return Result;',
  5921. ' };',
  5922. ' this.SetItems = function (Index, Value) {',
  5923. ' };',
  5924. '});',
  5925. 'this.Obj = null;',
  5926. 'this.i = 0;'
  5927. ]),
  5928. LinesToStr([ // this.$main
  5929. 'var $with1 = this.TObject.$create("Create");',
  5930. 'this.i = $with1.GetItems(1);',
  5931. '$with1.SetItems(2, this.i);',
  5932. 'var $with2 = this.Obj;',
  5933. 'this.i = $with2.GetItems(3);',
  5934. '$with2.SetItems(4, this.i);',
  5935. '']));
  5936. end;
  5937. procedure TTestModule.TestClass_WithClassInstDoFunc;
  5938. begin
  5939. StartProgram(false);
  5940. Add('type');
  5941. Add(' TObject = class');
  5942. Add(' constructor Create;');
  5943. Add(' function GetSize: longint;');
  5944. Add(' procedure SetSize(Value: longint);');
  5945. Add(' end;');
  5946. Add('constructor TObject.Create; begin end;');
  5947. Add('function TObject.GetSize: longint; begin; end;');
  5948. Add('procedure TObject.SetSize(Value: longint); begin; end;');
  5949. Add('var');
  5950. Add(' Obj: tobject;');
  5951. Add(' i: longint;');
  5952. Add('begin');
  5953. Add(' with TObject.Create do begin');
  5954. Add(' i:=GetSize;');
  5955. Add(' i:=GetSize();');
  5956. Add(' SetSize(i);');
  5957. Add(' end;');
  5958. Add(' with obj do begin');
  5959. Add(' i:=GetSize;');
  5960. Add(' i:=GetSize();');
  5961. Add(' SetSize(i);');
  5962. Add(' end;');
  5963. ConvertProgram;
  5964. CheckSource('TestClass_WithClassInstDoFunc',
  5965. LinesToStr([ // statements
  5966. 'rtl.createClass(this, "TObject", null, function () {',
  5967. ' this.$init = function () {',
  5968. ' };',
  5969. ' this.$final = function () {',
  5970. ' };',
  5971. ' this.Create = function () {',
  5972. ' };',
  5973. ' this.GetSize = function () {',
  5974. ' var Result = 0;',
  5975. ' return Result;',
  5976. ' };',
  5977. ' this.SetSize = function (Value) {',
  5978. ' };',
  5979. '});',
  5980. 'this.Obj = null;',
  5981. 'this.i = 0;'
  5982. ]),
  5983. LinesToStr([ // this.$main
  5984. 'var $with1 = this.TObject.$create("Create");',
  5985. 'this.i = $with1.GetSize();',
  5986. 'this.i = $with1.GetSize();',
  5987. '$with1.SetSize(this.i);',
  5988. 'var $with2 = this.Obj;',
  5989. 'this.i = $with2.GetSize();',
  5990. 'this.i = $with2.GetSize();',
  5991. '$with2.SetSize(this.i);',
  5992. '']));
  5993. end;
  5994. procedure TTestModule.TestClass_TypeCast;
  5995. begin
  5996. StartProgram(false);
  5997. Add('type');
  5998. Add(' TObject = class');
  5999. Add(' Next: TObject;');
  6000. Add(' constructor Create;');
  6001. Add(' end;');
  6002. Add(' TControl = class(TObject)');
  6003. Add(' Arr: array of TObject;');
  6004. Add(' function GetIt(vI: longint = 0): TObject;');
  6005. Add(' end;');
  6006. Add('constructor tobject.create; begin end;');
  6007. Add('function tcontrol.getit(vi: longint = 0): tobject; begin end;');
  6008. Add('var');
  6009. Add(' Obj: tobject;');
  6010. Add('begin');
  6011. Add(' obj:=tcontrol(obj).next;');
  6012. Add(' tcontrol(obj):=nil;');
  6013. Add(' obj:=tcontrol(obj);');
  6014. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit);');
  6015. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit());');
  6016. Add(' tcontrol(obj):=tcontrol(tcontrol(obj).getit(1));');
  6017. Add(' tcontrol(obj):=tcontrol(tcontrol(tcontrol(obj).getit).arr[2]);');
  6018. ConvertProgram;
  6019. CheckSource('TestClass_TypeCast',
  6020. LinesToStr([ // statements
  6021. 'rtl.createClass(this, "TObject", null, function () {',
  6022. ' this.$init = function () {',
  6023. ' this.Next = null;',
  6024. ' };',
  6025. ' this.$final = function () {',
  6026. ' this.Next = undefined;',
  6027. ' };',
  6028. ' this.Create = function () {',
  6029. ' };',
  6030. '});',
  6031. 'rtl.createClass(this, "TControl", this.TObject, function () {',
  6032. ' this.$init = function () {',
  6033. ' pas.program.TObject.$init.call(this);',
  6034. ' this.Arr = [];',
  6035. ' };',
  6036. ' this.$final = function () {',
  6037. ' this.Arr = undefined;',
  6038. ' pas.program.TObject.$final.call(this);',
  6039. ' };',
  6040. ' this.GetIt = function (vI) {',
  6041. ' var Result = null;',
  6042. ' return Result;',
  6043. ' };',
  6044. '});',
  6045. 'this.Obj = null;'
  6046. ]),
  6047. LinesToStr([ // this.$main
  6048. 'this.Obj = this.Obj.Next;',
  6049. 'this.Obj = null;',
  6050. 'this.Obj = this.Obj;',
  6051. 'this.Obj = this.Obj.GetIt(0);',
  6052. 'this.Obj = this.Obj.GetIt(0);',
  6053. 'this.Obj = this.Obj.GetIt(1);',
  6054. 'this.Obj = this.Obj.GetIt(0).Arr[2];',
  6055. '']));
  6056. end;
  6057. procedure TTestModule.TestClass_TypeCastUntypedParam;
  6058. begin
  6059. StartProgram(false);
  6060. Add('type');
  6061. Add(' TObject = class end;');
  6062. Add('procedure ProcA(var A);');
  6063. Add('begin');
  6064. Add(' TObject(A):=nil;');
  6065. Add(' TObject(A):=TObject(A);');
  6066. Add(' if TObject(A)=nil then ;');
  6067. Add(' if nil=TObject(A) then ;');
  6068. Add('end;');
  6069. Add('procedure ProcB(out A);');
  6070. Add('begin');
  6071. Add(' TObject(A):=nil;');
  6072. Add(' TObject(A):=TObject(A);');
  6073. Add(' if TObject(A)=nil then ;');
  6074. Add(' if nil=TObject(A) then ;');
  6075. Add('end;');
  6076. Add('procedure ProcC(const A);');
  6077. Add('begin');
  6078. Add(' if TObject(A)=nil then ;');
  6079. Add(' if nil=TObject(A) then ;');
  6080. Add('end;');
  6081. Add('var o: TObject;');
  6082. Add('begin');
  6083. Add(' ProcA(o);');
  6084. Add(' ProcB(o);');
  6085. Add(' ProcC(o);');
  6086. ConvertProgram;
  6087. CheckSource('TestClass_TypeCastUntypedParam',
  6088. LinesToStr([ // statements
  6089. 'rtl.createClass(this, "TObject", null, function () {',
  6090. ' this.$init = function () {',
  6091. ' };',
  6092. ' this.$final = function () {',
  6093. ' };',
  6094. '});',
  6095. 'this.ProcA = function (A) {',
  6096. ' A.set(null);',
  6097. ' A.set(A.get());',
  6098. ' if (A.get() == null);',
  6099. ' if (null == A.get());',
  6100. '};',
  6101. 'this.ProcB = function (A) {',
  6102. ' A.set(null);',
  6103. ' A.set(A.get());',
  6104. ' if (A.get() == null);',
  6105. ' if (null == A.get());',
  6106. '};',
  6107. 'this.ProcC = function (A) {',
  6108. ' if (A == null);',
  6109. ' if (null == A);',
  6110. '};',
  6111. 'this.o = null;',
  6112. '']),
  6113. LinesToStr([ // this.$main
  6114. 'this.ProcA({',
  6115. ' p: this,',
  6116. ' get: function () {',
  6117. ' return this.p.o;',
  6118. ' },',
  6119. ' set: function (v) {',
  6120. ' this.p.o = v;',
  6121. ' }',
  6122. '});',
  6123. 'this.ProcB({',
  6124. ' p: this,',
  6125. ' get: function () {',
  6126. ' return this.p.o;',
  6127. ' },',
  6128. ' set: function (v) {',
  6129. ' this.p.o = v;',
  6130. ' }',
  6131. '});',
  6132. 'this.ProcC(this.o);',
  6133. '']));
  6134. end;
  6135. procedure TTestModule.TestClass_Overloads;
  6136. begin
  6137. StartProgram(false);
  6138. Add('type');
  6139. Add(' TObject = class');
  6140. Add(' procedure DoIt;');
  6141. Add(' procedure DoIt(vI: longint);');
  6142. Add(' end;');
  6143. Add('procedure TObject.DoIt;');
  6144. Add('begin');
  6145. Add(' DoIt;');
  6146. Add(' DoIt(1);');
  6147. Add('end;');
  6148. Add('procedure TObject.DoIt(vI: longint); begin end;');
  6149. Add('begin');
  6150. ConvertProgram;
  6151. CheckSource('TestClass_Overloads',
  6152. LinesToStr([ // statements
  6153. 'rtl.createClass(this, "TObject", null, function () {',
  6154. ' this.$init = function () {',
  6155. ' };',
  6156. ' this.$final = function () {',
  6157. ' };',
  6158. ' this.DoIt = function () {',
  6159. ' this.DoIt();',
  6160. ' this.DoIt$1(1);',
  6161. ' };',
  6162. ' this.DoIt$1 = function (vI) {',
  6163. ' };',
  6164. '});',
  6165. '']),
  6166. LinesToStr([ // this.$main
  6167. '']));
  6168. end;
  6169. procedure TTestModule.TestClass_OverloadsAncestor;
  6170. begin
  6171. StartProgram(false);
  6172. Add('type');
  6173. Add(' TObject = class');
  6174. Add(' procedure DoIt(vA: longint);');
  6175. Add(' procedure DoIt(vA, vB: longint);');
  6176. Add(' end;');
  6177. Add(' TCar = class');
  6178. Add(' procedure DoIt(vA: longint);');
  6179. Add(' procedure DoIt(vA, vB: longint);');
  6180. Add(' end;');
  6181. Add('procedure tobject.doit(va: longint);');
  6182. Add('begin');
  6183. Add(' doit(1);');
  6184. Add(' doit(1,2);');
  6185. Add('end;');
  6186. Add('procedure tobject.doit(va, vb: longint); begin end;');
  6187. Add('procedure tcar.doit(va: longint);');
  6188. Add('begin');
  6189. Add(' doit(1);');
  6190. Add(' doit(1,2);');
  6191. Add(' inherited doit(1);');
  6192. Add(' inherited doit(1,2);');
  6193. Add('end;');
  6194. Add('procedure tcar.doit(va, vb: longint); begin end;');
  6195. Add('begin');
  6196. ConvertProgram;
  6197. CheckSource('TestClass_OverloadsAncestor',
  6198. LinesToStr([ // statements
  6199. 'rtl.createClass(this, "TObject", null, function () {',
  6200. ' this.$init = function () {',
  6201. ' };',
  6202. ' this.$final = function () {',
  6203. ' };',
  6204. ' this.DoIt = function (vA) {',
  6205. ' this.DoIt(1);',
  6206. ' this.DoIt$1(1,2);',
  6207. ' };',
  6208. ' this.DoIt$1 = function (vA, vB) {',
  6209. ' };',
  6210. '});',
  6211. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  6212. ' this.DoIt$2 = function (vA) {',
  6213. ' this.DoIt$2(1);',
  6214. ' this.DoIt$3(1, 2);',
  6215. ' pas.program.TObject.DoIt.call(this, 1);',
  6216. ' pas.program.TObject.DoIt$1.call(this, 1, 2);',
  6217. ' };',
  6218. ' this.DoIt$3 = function (vA, vB) {',
  6219. ' };',
  6220. '});',
  6221. '']),
  6222. LinesToStr([ // this.$main
  6223. '']));
  6224. end;
  6225. procedure TTestModule.TestClass_OverloadConstructor;
  6226. begin
  6227. StartProgram(false);
  6228. Add('type');
  6229. Add(' TObject = class');
  6230. Add(' constructor Create(vA: longint);');
  6231. Add(' constructor Create(vA, vB: longint);');
  6232. Add(' end;');
  6233. Add(' TCar = class');
  6234. Add(' constructor Create(vA: longint);');
  6235. Add(' constructor Create(vA, vB: longint);');
  6236. Add(' end;');
  6237. Add('constructor tobject.create(va: longint);');
  6238. Add('begin');
  6239. Add(' create(1);');
  6240. Add(' create(1,2);');
  6241. Add('end;');
  6242. Add('constructor tobject.create(va, vb: longint); begin end;');
  6243. Add('constructor tcar.create(va: longint);');
  6244. Add('begin');
  6245. Add(' create(1);');
  6246. Add(' create(1,2);');
  6247. Add(' inherited create(1);');
  6248. Add(' inherited create(1,2);');
  6249. Add('end;');
  6250. Add('constructor tcar.create(va, vb: longint); begin end;');
  6251. Add('begin');
  6252. Add(' tobject.create(1);');
  6253. Add(' tobject.create(1,2);');
  6254. Add(' tcar.create(1);');
  6255. Add(' tcar.create(1,2);');
  6256. ConvertProgram;
  6257. CheckSource('TestClass_OverloadConstructor',
  6258. LinesToStr([ // statements
  6259. 'rtl.createClass(this, "TObject", null, function () {',
  6260. ' this.$init = function () {',
  6261. ' };',
  6262. ' this.$final = function () {',
  6263. ' };',
  6264. ' this.Create = function (vA) {',
  6265. ' this.Create(1);',
  6266. ' this.Create$1(1,2);',
  6267. ' };',
  6268. ' this.Create$1 = function (vA, vB) {',
  6269. ' };',
  6270. '});',
  6271. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  6272. ' this.Create$2 = function (vA) {',
  6273. ' this.Create$2(1);',
  6274. ' this.Create$3(1, 2);',
  6275. ' pas.program.TObject.Create.call(this, 1);',
  6276. ' pas.program.TObject.Create$1.call(this, 1, 2);',
  6277. ' };',
  6278. ' this.Create$3 = function (vA, vB) {',
  6279. ' };',
  6280. '});',
  6281. '']),
  6282. LinesToStr([ // this.$main
  6283. 'this.TObject.$create("Create", [1]);',
  6284. 'this.TObject.$create("Create$1", [1, 2]);',
  6285. 'this.TCar.$create("Create$2", [1]);',
  6286. 'this.TCar.$create("Create$3", [1, 2]);',
  6287. '']));
  6288. end;
  6289. procedure TTestModule.TestClass_ReintroducedVar;
  6290. begin
  6291. StartProgram(false);
  6292. Add('type');
  6293. Add(' TObject = class');
  6294. Add(' strict private');
  6295. Add(' Some: longint;');
  6296. Add(' end;');
  6297. Add(' TMobile = class');
  6298. Add(' strict private');
  6299. Add(' Some: string;');
  6300. Add(' end;');
  6301. Add(' TCar = class(tmobile)');
  6302. Add(' procedure Some;');
  6303. Add(' procedure Some(vA: longint);');
  6304. Add(' end;');
  6305. Add('procedure tcar.some;');
  6306. Add('begin');
  6307. Add(' Some;');
  6308. Add(' Some(1);');
  6309. Add('end;');
  6310. Add('procedure tcar.some(va: longint); begin end;');
  6311. Add('begin');
  6312. ConvertProgram;
  6313. CheckSource('TestClass_ReintroducedVar',
  6314. LinesToStr([ // statements
  6315. 'rtl.createClass(this, "TObject", null, function () {',
  6316. ' this.$init = function () {',
  6317. ' this.Some = 0;',
  6318. ' };',
  6319. ' this.$final = function () {',
  6320. ' };',
  6321. '});',
  6322. 'rtl.createClass(this, "TMobile", this.TObject, function () {',
  6323. ' this.$init = function () {',
  6324. ' pas.program.TObject.$init.call(this);',
  6325. ' this.Some$1 = "";',
  6326. ' };',
  6327. '});',
  6328. 'rtl.createClass(this, "TCar", this.TMobile, function () {',
  6329. ' this.Some$2 = function () {',
  6330. ' this.Some$2();',
  6331. ' this.Some$3(1);',
  6332. ' };',
  6333. ' this.Some$3 = function (vA) {',
  6334. ' };',
  6335. '});',
  6336. '']),
  6337. LinesToStr([ // this.$main
  6338. '']));
  6339. end;
  6340. procedure TTestModule.TestClass_RaiseDescendant;
  6341. begin
  6342. StartProgram(false);
  6343. Add('type');
  6344. Add(' TObject = class');
  6345. Add(' constructor Create(Msg: string);');
  6346. Add(' end;');
  6347. Add(' Exception = class');
  6348. Add(' end;');
  6349. Add(' EConvertError = class(Exception)');
  6350. Add(' end;');
  6351. Add('constructor TObject.Create(Msg: string); begin end;');
  6352. Add('begin');
  6353. Add(' raise Exception.Create(''Bar1'');');
  6354. Add(' raise EConvertError.Create(''Bar2'');');
  6355. ConvertProgram;
  6356. CheckSource('TestClass_RaiseDescendant',
  6357. LinesToStr([ // statements
  6358. 'rtl.createClass(this, "TObject", null, function () {',
  6359. ' this.$init = function () {',
  6360. ' };',
  6361. ' this.$final = function () {',
  6362. ' };',
  6363. ' this.Create = function (Msg) {',
  6364. ' };',
  6365. '});',
  6366. 'rtl.createClass(this, "Exception", this.TObject, function () {',
  6367. '});',
  6368. 'rtl.createClass(this, "EConvertError", this.Exception, function () {',
  6369. '});',
  6370. '']),
  6371. LinesToStr([ // this.$main
  6372. 'throw this.Exception.$create("Create",["Bar1"]);',
  6373. 'throw this.EConvertError.$create("Create",["Bar2"]);',
  6374. '']));
  6375. end;
  6376. procedure TTestModule.TestClass_ExternalMethod;
  6377. begin
  6378. AddModuleWithIntfImplSrc('unit2.pas',
  6379. LinesToStr([
  6380. 'type',
  6381. ' TObject = class',
  6382. ' public',
  6383. ' procedure Intern; external name ''$DoIntern'';',
  6384. ' end;',
  6385. '']),
  6386. LinesToStr([
  6387. '']));
  6388. StartUnit(true);
  6389. Add('interface');
  6390. Add('uses unit2;');
  6391. Add('type');
  6392. Add(' TCar = class(TObject)');
  6393. Add(' public');
  6394. Add(' procedure Intern2; external name ''$DoIntern2'';');
  6395. Add(' procedure DoIt;');
  6396. Add(' end;');
  6397. Add('implementation');
  6398. Add('procedure tcar.doit;');
  6399. Add('begin');
  6400. Add(' Intern;');
  6401. Add(' Intern();');
  6402. Add(' Intern2;');
  6403. Add(' Intern2();');
  6404. Add('end;');
  6405. Add('var Obj: TCar;');
  6406. Add('begin');
  6407. Add(' obj.intern;');
  6408. Add(' obj.intern();');
  6409. Add(' obj.intern2;');
  6410. Add(' obj.intern2();');
  6411. Add(' obj.doit;');
  6412. Add(' obj.doit();');
  6413. Add(' with obj do begin');
  6414. Add(' Intern;');
  6415. Add(' Intern();');
  6416. Add(' Intern2;');
  6417. Add(' Intern2();');
  6418. Add(' end;');
  6419. ConvertUnit;
  6420. CheckSource('TestClass_ExternalMethod',
  6421. LinesToStr([
  6422. 'var $impl = {',
  6423. '};',
  6424. 'this.$impl = $impl;',
  6425. 'rtl.createClass(this, "TCar", pas.unit2.TObject, function () {',
  6426. ' this.DoIt = function () {',
  6427. ' this.$DoIntern();',
  6428. ' this.$DoIntern();',
  6429. ' this.$DoIntern2();',
  6430. ' this.$DoIntern2();',
  6431. ' };',
  6432. ' });',
  6433. '$impl.Obj = null;',
  6434. '']),
  6435. LinesToStr([
  6436. '$impl.Obj.$DoIntern();',
  6437. '$impl.Obj.$DoIntern();',
  6438. '$impl.Obj.$DoIntern2();',
  6439. '$impl.Obj.$DoIntern2();',
  6440. '$impl.Obj.DoIt();',
  6441. '$impl.Obj.DoIt();',
  6442. 'var $with1 = $impl.Obj;',
  6443. '$with1.$DoIntern();',
  6444. '$with1.$DoIntern();',
  6445. '$with1.$DoIntern2();',
  6446. '$with1.$DoIntern2();',
  6447. '']));
  6448. end;
  6449. procedure TTestModule.TestClass_ExternalVirtualNameMismatchFail;
  6450. begin
  6451. StartProgram(false);
  6452. Add('type');
  6453. Add(' TObject = class');
  6454. Add(' procedure DoIt; virtual; external name ''Foo'';');
  6455. Add(' end;');
  6456. Add('begin');
  6457. SetExpectedPasResolverError('Virtual method name must match external',
  6458. nVirtualMethodNameMustMatchExternal);
  6459. ConvertProgram;
  6460. end;
  6461. procedure TTestModule.TestClass_ExternalOverrideFail;
  6462. begin
  6463. StartProgram(false);
  6464. Add('type');
  6465. Add(' TObject = class');
  6466. Add(' procedure DoIt; virtual; external name ''DoIt'';');
  6467. Add(' end;');
  6468. Add(' TCar = class');
  6469. Add(' procedure DoIt; override; external name ''DoIt'';');
  6470. Add(' end;');
  6471. Add('begin');
  6472. SetExpectedPasResolverError('Invalid procedure modifiers override,external',
  6473. nInvalidProcModifiers);
  6474. ConvertProgram;
  6475. end;
  6476. procedure TTestModule.TestClass_ExternalVar;
  6477. begin
  6478. AddModuleWithIntfImplSrc('unit2.pas',
  6479. LinesToStr([
  6480. '{$modeswitch externalclass}',
  6481. 'type',
  6482. ' TObject = class',
  6483. ' public',
  6484. ' Intern: longint external name ''$Intern'';',
  6485. ' end;',
  6486. '']),
  6487. LinesToStr([
  6488. '']));
  6489. StartUnit(true);
  6490. Add('interface');
  6491. Add('uses unit2;');
  6492. Add('{$modeswitch externalclass}');
  6493. Add('type');
  6494. Add(' TCar = class(tobject)');
  6495. Add(' public');
  6496. Add(' Intern2: longint external name ''$Intern2'';');
  6497. Add(' procedure DoIt;');
  6498. Add(' end;');
  6499. Add('implementation');
  6500. Add('procedure tcar.doit;');
  6501. Add('begin');
  6502. Add(' Intern:=Intern+1;');
  6503. Add(' Intern2:=Intern2+2;');
  6504. Add('end;');
  6505. Add('var Obj: TCar;');
  6506. Add('begin');
  6507. Add(' obj.intern:=obj.intern+1;');
  6508. Add(' obj.intern2:=obj.intern2+2;');
  6509. Add(' with obj do begin');
  6510. Add(' intern:=intern+1;');
  6511. Add(' intern2:=intern2+2;');
  6512. Add(' end;');
  6513. ConvertUnit;
  6514. CheckSource('TestClass_ExternalVar',
  6515. LinesToStr([
  6516. 'var $impl = {',
  6517. '};',
  6518. 'this.$impl = $impl;',
  6519. 'rtl.createClass(this, "TCar", pas.unit2.TObject, function () {',
  6520. ' this.DoIt = function () {',
  6521. ' this.$Intern = this.$Intern + 1;',
  6522. ' this.$Intern2 = this.$Intern2 + 2;',
  6523. ' };',
  6524. ' });',
  6525. '$impl.Obj = null;',
  6526. '']),
  6527. LinesToStr([
  6528. '$impl.Obj.$Intern = $impl.Obj.$Intern + 1;',
  6529. '$impl.Obj.$Intern2 = $impl.Obj.$Intern2 + 2;',
  6530. 'var $with1 = $impl.Obj;',
  6531. '$with1.$Intern = $with1.$Intern + 1;',
  6532. '$with1.$Intern2 = $with1.$Intern2 + 2;',
  6533. '']));
  6534. end;
  6535. procedure TTestModule.TestClassOf_Create;
  6536. begin
  6537. StartProgram(false);
  6538. Add('type');
  6539. Add(' TObject = class');
  6540. Add(' constructor Create;');
  6541. Add(' end;');
  6542. Add(' TClass = class of TObject;');
  6543. Add('constructor tobject.create; begin end;');
  6544. Add('var');
  6545. Add(' Obj: tobject;');
  6546. Add(' C: tclass;');
  6547. Add('begin');
  6548. Add(' obj:=C.create;');
  6549. Add(' with c do obj:=create;');
  6550. ConvertProgram;
  6551. CheckSource('TestClassOf_Create',
  6552. LinesToStr([ // statements
  6553. 'rtl.createClass(this, "TObject", null, function () {',
  6554. ' this.$init = function () {',
  6555. ' };',
  6556. ' this.$final = function () {',
  6557. ' };',
  6558. ' this.Create = function () {',
  6559. ' };',
  6560. '});',
  6561. 'this.Obj = null;',
  6562. 'this.C = null;'
  6563. ]),
  6564. LinesToStr([ // this.$main
  6565. 'this.Obj = this.C.$create("Create");',
  6566. 'var $with1 = this.C;',
  6567. 'this.Obj = $with1.$create("Create");',
  6568. '']));
  6569. end;
  6570. procedure TTestModule.TestClassOf_Call;
  6571. begin
  6572. StartProgram(false);
  6573. Add('type');
  6574. Add(' TObject = class');
  6575. Add(' class procedure DoIt;');
  6576. Add(' end;');
  6577. Add(' TClass = class of TObject;');
  6578. Add('class procedure tobject.doit; begin end;');
  6579. Add('var');
  6580. Add(' C: tclass;');
  6581. Add('begin');
  6582. Add(' c.doit;');
  6583. Add(' with c do doit;');
  6584. ConvertProgram;
  6585. CheckSource('TestClassOf_Call',
  6586. LinesToStr([ // statements
  6587. 'rtl.createClass(this, "TObject", null, function () {',
  6588. ' this.$init = function () {',
  6589. ' };',
  6590. ' this.$final = function () {',
  6591. ' };',
  6592. ' this.DoIt = function () {',
  6593. ' };',
  6594. '});',
  6595. 'this.C = null;'
  6596. ]),
  6597. LinesToStr([ // this.$main
  6598. 'this.C.DoIt();',
  6599. 'var $with1 = this.C;',
  6600. '$with1.DoIt();',
  6601. '']));
  6602. end;
  6603. procedure TTestModule.TestClassOf_Assign;
  6604. begin
  6605. StartProgram(false);
  6606. Add('type');
  6607. Add(' TClass = class of TObject;');
  6608. Add(' TObject = class');
  6609. Add(' ClassType: TClass; ');
  6610. Add(' end;');
  6611. Add('var');
  6612. Add(' Obj: tobject;');
  6613. Add(' C: tclass;');
  6614. Add('begin');
  6615. Add(' c:=nil;');
  6616. Add(' c:=obj.classtype;');
  6617. ConvertProgram;
  6618. CheckSource('TestClassOf_Assign',
  6619. LinesToStr([ // statements
  6620. 'rtl.createClass(this, "TObject", null, function () {',
  6621. ' this.$init = function () {',
  6622. ' this.ClassType = null;',
  6623. ' };',
  6624. ' this.$final = function () {',
  6625. ' this.ClassType = undefined;',
  6626. ' };',
  6627. '});',
  6628. 'this.Obj = null;',
  6629. 'this.C = null;'
  6630. ]),
  6631. LinesToStr([ // this.$main
  6632. 'this.C = null;',
  6633. 'this.C = this.Obj.ClassType;',
  6634. '']));
  6635. end;
  6636. procedure TTestModule.TestClassOf_Is;
  6637. begin
  6638. StartProgram(false);
  6639. Add('type');
  6640. Add(' TClass = class of TObject;');
  6641. Add(' TObject = class');
  6642. Add(' end;');
  6643. Add(' TCar = class');
  6644. Add(' end;');
  6645. Add(' TCars = class of TCar;');
  6646. Add('var');
  6647. Add(' Obj: tobject;');
  6648. Add(' C: tclass;');
  6649. Add(' Cars: tcars;');
  6650. Add('begin');
  6651. Add(' if c is tcar then ;');
  6652. Add(' if c is tcars then ;');
  6653. ConvertProgram;
  6654. CheckSource('TestClassOf_Is',
  6655. LinesToStr([ // statements
  6656. 'rtl.createClass(this, "TObject", null, function () {',
  6657. ' this.$init = function () {',
  6658. ' };',
  6659. ' this.$final = function () {',
  6660. ' };',
  6661. '});',
  6662. 'rtl.createClass(this, "TCar", this.TObject, function () {',
  6663. '});',
  6664. 'this.Obj = null;',
  6665. 'this.C = null;',
  6666. 'this.Cars = null;'
  6667. ]),
  6668. LinesToStr([ // this.$main
  6669. 'if(rtl.is(this.C,this.TCar));',
  6670. 'if(rtl.is(this.C,this.TCar));',
  6671. '']));
  6672. end;
  6673. procedure TTestModule.TestClassOf_Compare;
  6674. begin
  6675. StartProgram(false);
  6676. Add('type');
  6677. Add(' TClass = class of TObject;');
  6678. Add(' TObject = class');
  6679. Add(' ClassType: TClass; ');
  6680. Add(' end;');
  6681. Add('var');
  6682. Add(' b: boolean;');
  6683. Add(' Obj: tobject;');
  6684. Add(' C: tclass;');
  6685. Add('begin');
  6686. Add(' b:=c=nil;');
  6687. Add(' b:=nil=c;');
  6688. Add(' b:=c=obj.classtype;');
  6689. Add(' b:=obj.classtype=c;');
  6690. Add(' b:=c=TObject;');
  6691. Add(' b:=TObject=c;');
  6692. Add(' b:=c<>nil;');
  6693. Add(' b:=nil<>c;');
  6694. Add(' b:=c<>obj.classtype;');
  6695. Add(' b:=obj.classtype<>c;');
  6696. Add(' b:=c<>TObject;');
  6697. Add(' b:=TObject<>c;');
  6698. ConvertProgram;
  6699. CheckSource('TestClassOf_Compare',
  6700. LinesToStr([ // statements
  6701. 'rtl.createClass(this, "TObject", null, function () {',
  6702. ' this.$init = function () {',
  6703. ' this.ClassType = null;',
  6704. ' };',
  6705. ' this.$final = function () {',
  6706. ' this.ClassType = undefined;',
  6707. ' };',
  6708. '});',
  6709. 'this.b = false;',
  6710. 'this.Obj = null;',
  6711. 'this.C = null;'
  6712. ]),
  6713. LinesToStr([ // this.$main
  6714. 'this.b = this.C == null;',
  6715. 'this.b = null == this.C;',
  6716. 'this.b = this.C == this.Obj.ClassType;',
  6717. 'this.b = this.Obj.ClassType == this.C;',
  6718. 'this.b = this.C == this.TObject;',
  6719. 'this.b = this.TObject == this.C;',
  6720. 'this.b = this.C != null;',
  6721. 'this.b = null != this.C;',
  6722. 'this.b = this.C != this.Obj.ClassType;',
  6723. 'this.b = this.Obj.ClassType != this.C;',
  6724. 'this.b = this.C != this.TObject;',
  6725. 'this.b = this.TObject != this.C;',
  6726. '']));
  6727. end;
  6728. procedure TTestModule.TestClassOf_ClassVar;
  6729. begin
  6730. StartProgram(false);
  6731. Add('type');
  6732. Add(' TObject = class');
  6733. Add(' class var id: longint;');
  6734. Add(' end;');
  6735. Add(' TClass = class of TObject;');
  6736. Add('var');
  6737. Add(' C: tclass;');
  6738. Add('begin');
  6739. Add(' C.id:=C.id;');
  6740. ConvertProgram;
  6741. CheckSource('TestClassOf_ClassVar',
  6742. LinesToStr([ // statements
  6743. 'rtl.createClass(this, "TObject", null, function () {',
  6744. ' this.id = 0;',
  6745. ' this.$init = function () {',
  6746. ' };',
  6747. ' this.$final = function () {',
  6748. ' };',
  6749. '});',
  6750. 'this.C = null;'
  6751. ]),
  6752. LinesToStr([ // this.$main
  6753. 'this.C.id = this.C.id;',
  6754. '']));
  6755. end;
  6756. procedure TTestModule.TestClassOf_ClassMethod;
  6757. begin
  6758. StartProgram(false);
  6759. Add('type');
  6760. Add(' TObject = class');
  6761. Add(' class function DoIt(i: longint = 0): longint;');
  6762. Add(' end;');
  6763. Add(' TClass = class of TObject;');
  6764. Add('class function tobject.doit(i: longint = 0): longint; begin end;');
  6765. Add('var');
  6766. Add(' i: longint;');
  6767. Add(' C: tclass;');
  6768. Add('begin');
  6769. Add(' C.DoIt;');
  6770. Add(' C.DoIt();');
  6771. Add(' i:=C.DoIt;');
  6772. Add(' i:=C.DoIt();');
  6773. ConvertProgram;
  6774. CheckSource('TestClassOf_ClassMethod',
  6775. LinesToStr([ // statements
  6776. 'rtl.createClass(this, "TObject", null, function () {',
  6777. ' this.$init = function () {',
  6778. ' };',
  6779. ' this.$final = function () {',
  6780. ' };',
  6781. ' this.DoIt = function (i) {',
  6782. ' var Result = 0;',
  6783. ' return Result;',
  6784. ' };',
  6785. '});',
  6786. 'this.i = 0;',
  6787. 'this.C = null;'
  6788. ]),
  6789. LinesToStr([ // this.$main
  6790. 'this.C.DoIt(0);',
  6791. 'this.C.DoIt(0);',
  6792. 'this.i = this.C.DoIt(0);',
  6793. 'this.i = this.C.DoIt(0);',
  6794. '']));
  6795. end;
  6796. procedure TTestModule.TestClassOf_ClassProperty;
  6797. begin
  6798. StartProgram(false);
  6799. Add('type');
  6800. Add(' TObject = class');
  6801. Add(' class var FA: longint;');
  6802. Add(' class function GetA: longint;');
  6803. Add(' class procedure SetA(Value: longint): longint;');
  6804. Add(' class property pA: longint read fa write fa;');
  6805. Add(' class property pB: longint read geta write seta;');
  6806. Add(' end;');
  6807. Add(' TObjectClass = class of tobject;');
  6808. Add('class function tobject.geta: longint; begin end;');
  6809. Add('class procedure tobject.seta(value: longint): longint; begin end;');
  6810. Add('var');
  6811. Add(' b: boolean;');
  6812. Add(' Obj: tobject;');
  6813. Add(' Cla: tobjectclass;');
  6814. Add('begin');
  6815. Add(' obj.pa:=obj.pa;');
  6816. Add(' obj.pb:=obj.pb;');
  6817. Add(' b:=obj.pa=4;');
  6818. Add(' b:=obj.pb=obj.pb;');
  6819. Add(' b:=5=obj.pa;');
  6820. Add(' cla.pa:=6;');
  6821. Add(' cla.pa:=cla.pa;');
  6822. Add(' cla.pb:=cla.pb;');
  6823. Add(' b:=cla.pa=7;');
  6824. Add(' b:=cla.pb=cla.pb;');
  6825. Add(' b:=8=cla.pa;');
  6826. Add(' tobject.pa:=9;');
  6827. Add(' tobject.pb:=tobject.pb;');
  6828. Add(' b:=tobject.pa=10;');
  6829. Add(' b:=11=tobject.pa;');
  6830. ConvertProgram;
  6831. CheckSource('TestClassOf_ClassProperty',
  6832. LinesToStr([ // statements
  6833. 'rtl.createClass(this, "TObject", null, function () {',
  6834. ' this.FA = 0;',
  6835. ' this.$init = function () {',
  6836. ' };',
  6837. ' this.$final = function () {',
  6838. ' };',
  6839. ' this.GetA = function () {',
  6840. ' var Result = 0;',
  6841. ' return Result;',
  6842. ' };',
  6843. ' this.SetA = function (Value) {',
  6844. ' };',
  6845. '});',
  6846. 'this.b = false;',
  6847. 'this.Obj = null;',
  6848. 'this.Cla = null;'
  6849. ]),
  6850. LinesToStr([ // this.$main
  6851. 'this.Obj.$class.FA = this.Obj.FA;',
  6852. 'this.Obj.$class.SetA(this.Obj.$class.GetA());',
  6853. 'this.b = this.Obj.FA == 4;',
  6854. 'this.b = this.Obj.$class.GetA() == this.Obj.$class.GetA();',
  6855. 'this.b = 5 == this.Obj.FA;',
  6856. 'this.Cla.FA = 6;',
  6857. 'this.Cla.FA = this.Cla.FA;',
  6858. 'this.Cla.SetA(this.Cla.GetA());',
  6859. 'this.b = this.Cla.FA == 7;',
  6860. 'this.b = this.Cla.GetA() == this.Cla.GetA();',
  6861. 'this.b = 8 == this.Cla.FA;',
  6862. 'this.TObject.FA = 9;',
  6863. 'this.TObject.SetA(this.TObject.GetA());',
  6864. 'this.b = this.TObject.FA == 10;',
  6865. 'this.b = 11 == this.TObject.FA;',
  6866. '']));
  6867. end;
  6868. procedure TTestModule.TestClassOf_ClassMethodSelf;
  6869. begin
  6870. StartProgram(false);
  6871. Add('type');
  6872. Add(' TObject = class');
  6873. Add(' class var GlobalId: longint;');
  6874. Add(' class procedure ProcA;');
  6875. Add(' end;');
  6876. Add('class procedure tobject.proca;');
  6877. Add('var b: boolean;');
  6878. Add('begin');
  6879. Add(' b:=self=nil;');
  6880. Add(' b:=self.globalid=3;');
  6881. Add(' b:=4=self.globalid;');
  6882. Add(' self.globalid:=5;');
  6883. Add(' self.proca;');
  6884. Add('end;');
  6885. Add('begin');
  6886. ConvertProgram;
  6887. CheckSource('TestClassOf_ClassMethodSelf',
  6888. LinesToStr([ // statements
  6889. 'rtl.createClass(this, "TObject", null, function () {',
  6890. ' this.GlobalId = 0;',
  6891. ' this.$init = function () {',
  6892. ' };',
  6893. ' this.$final = function () {',
  6894. ' };',
  6895. ' this.ProcA = function () {',
  6896. ' var b = false;',
  6897. ' b = this == null;',
  6898. ' b = this.GlobalId == 3;',
  6899. ' b = 4 == this.GlobalId;',
  6900. ' this.GlobalId = 5;',
  6901. ' this.ProcA();',
  6902. ' };',
  6903. '});'
  6904. ]),
  6905. LinesToStr([ // this.$main
  6906. '']));
  6907. end;
  6908. procedure TTestModule.TestClassOf_TypeCast;
  6909. begin
  6910. StartProgram(false);
  6911. Add('type');
  6912. Add(' TObject = class');
  6913. Add(' class procedure {#TObject_DoIt}DoIt;');
  6914. Add(' end;');
  6915. Add(' TClass = class of TObject;');
  6916. Add(' TMobile = class');
  6917. Add(' class procedure {#TMobile_DoIt}DoIt;');
  6918. Add(' end;');
  6919. Add(' TMobileClass = class of TMobile;');
  6920. Add(' TCar = class(TMobile)');
  6921. Add(' class procedure {#TCar_DoIt}DoIt;');
  6922. Add(' end;');
  6923. Add(' TCarClass = class of TCar;');
  6924. Add('class procedure TObject.DoIt;');
  6925. Add('begin');
  6926. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  6927. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  6928. Add('end;');
  6929. Add('class procedure TMobile.DoIt;');
  6930. Add('begin');
  6931. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  6932. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  6933. Add(' TCarClass(Self).{@TCar_DoIt}DoIt;');
  6934. Add('end;');
  6935. Add('class procedure TCar.DoIt; begin end;');
  6936. Add('var');
  6937. Add(' ObjC: TClass;');
  6938. Add(' MobileC: TMobileClass;');
  6939. Add(' CarC: TCarClass;');
  6940. Add('begin');
  6941. Add(' ObjC.{@TObject_DoIt}DoIt;');
  6942. Add(' MobileC.{@TMobile_DoIt}DoIt;');
  6943. Add(' CarC.{@TCar_DoIt}DoIt;');
  6944. Add(' TClass(ObjC).{@TObject_DoIt}DoIt;');
  6945. Add(' TMobileClass(ObjC).{@TMobile_DoIt}DoIt;');
  6946. Add(' TCarClass(ObjC).{@TCar_DoIt}DoIt;');
  6947. Add(' TClass(MobileC).{@TObject_DoIt}DoIt;');
  6948. Add(' TMobileClass(MobileC).{@TMobile_DoIt}DoIt;');
  6949. Add(' TCarClass(MobileC).{@TCar_DoIt}DoIt;');
  6950. Add(' TClass(CarC).{@TObject_DoIt}DoIt;');
  6951. Add(' TMobileClass(CarC).{@TMobile_DoIt}DoIt;');
  6952. Add(' TCarClass(CarC).{@TCar_DoIt}DoIt;');
  6953. ConvertProgram;
  6954. CheckSource('TestClassOf_TypeCast',
  6955. LinesToStr([ // statements
  6956. 'rtl.createClass(this, "TObject", null, function () {',
  6957. ' this.$init = function () {',
  6958. ' };',
  6959. ' this.$final = function () {',
  6960. ' };',
  6961. ' this.DoIt = function () {',
  6962. ' this.DoIt();',
  6963. ' this.DoIt$1();',
  6964. ' };',
  6965. '});',
  6966. 'rtl.createClass(this, "TMobile", this.TObject, function () {',
  6967. ' this.DoIt$1 = function () {',
  6968. ' this.DoIt();',
  6969. ' this.DoIt$1();',
  6970. ' this.DoIt$2();',
  6971. ' };',
  6972. '});',
  6973. 'rtl.createClass(this, "TCar", this.TMobile, function () {',
  6974. ' this.DoIt$2 = function () {',
  6975. ' };',
  6976. '});',
  6977. 'this.ObjC = null;',
  6978. 'this.MobileC = null;',
  6979. 'this.CarC = null;',
  6980. '']),
  6981. LinesToStr([ // this.$main
  6982. 'this.ObjC.DoIt();',
  6983. 'this.MobileC.DoIt$1();',
  6984. 'this.CarC.DoIt$2();',
  6985. 'this.ObjC.DoIt();',
  6986. 'this.ObjC.DoIt$1();',
  6987. 'this.ObjC.DoIt$2();',
  6988. 'this.MobileC.DoIt();',
  6989. 'this.MobileC.DoIt$1();',
  6990. 'this.MobileC.DoIt$2();',
  6991. 'this.CarC.DoIt();',
  6992. 'this.CarC.DoIt$1();',
  6993. 'this.CarC.DoIt$2();',
  6994. '']));
  6995. end;
  6996. procedure TTestModule.TestClassOf_ImplicitFunctionCall;
  6997. begin
  6998. StartProgram(false);
  6999. Add('type');
  7000. Add(' TObject = class');
  7001. Add(' function CurNow: longint; ');
  7002. Add(' class function Now: longint; ');
  7003. Add(' end;');
  7004. Add('function TObject.CurNow: longint; begin end;');
  7005. Add('class function TObject.Now: longint; begin end;');
  7006. Add('var');
  7007. Add(' Obj: tobject;');
  7008. Add(' vI: longint;');
  7009. Add('begin');
  7010. Add(' obj.curnow;');
  7011. Add(' vi:=obj.curnow;');
  7012. Add(' tobject.now;');
  7013. Add(' vi:=tobject.now;');
  7014. ConvertProgram;
  7015. CheckSource('TestClassOf_ImplicitFunctionCall',
  7016. LinesToStr([ // statements
  7017. 'rtl.createClass(this, "TObject", null, function () {',
  7018. ' this.$init = function () {',
  7019. ' };',
  7020. ' this.$final = function () {',
  7021. ' };',
  7022. ' this.CurNow = function () {',
  7023. ' var Result = 0;',
  7024. ' return Result;',
  7025. ' };',
  7026. ' this.Now = function () {',
  7027. ' var Result = 0;',
  7028. ' return Result;',
  7029. ' };',
  7030. '});',
  7031. 'this.Obj = null;',
  7032. 'this.vI = 0;',
  7033. '']),
  7034. LinesToStr([ // this.$main
  7035. 'this.Obj.CurNow();',
  7036. 'this.vI = this.Obj.CurNow();',
  7037. 'this.TObject.Now();',
  7038. 'this.vI = this.TObject.Now();',
  7039. '']));
  7040. end;
  7041. procedure TTestModule.TestExternalClass_Var;
  7042. begin
  7043. StartProgram(false);
  7044. Add('{$modeswitch externalclass}');
  7045. Add('type');
  7046. Add(' TExtA = class external name ''ExtObj''');
  7047. Add(' Id: longint external name ''$Id'';');
  7048. Add(' B: longint;');
  7049. Add(' end;');
  7050. Add('var Obj: TExtA;');
  7051. Add('begin');
  7052. Add(' obj.id:=obj.id+1;');
  7053. Add(' obj.B:=obj.B+1;');
  7054. ConvertProgram;
  7055. CheckSource('TestExternalClass_Var',
  7056. LinesToStr([ // statements
  7057. 'this.Obj = null;',
  7058. '']),
  7059. LinesToStr([ // this.$main
  7060. 'this.Obj.$Id = this.Obj.$Id + 1;',
  7061. 'this.Obj.B = this.Obj.B + 1;',
  7062. '']));
  7063. end;
  7064. procedure TTestModule.TestExternalClass_DuplicateVarFail;
  7065. begin
  7066. StartProgram(false);
  7067. Add('{$modeswitch externalclass}');
  7068. Add('type');
  7069. Add(' TExtA = class external name ''ExtA''');
  7070. Add(' Id: longint external name ''$Id'';');
  7071. Add(' end;');
  7072. Add(' TExtB = class external ''lib'' name ''ExtB''(TExtA)');
  7073. Add(' Id: longint;');
  7074. Add(' end;');
  7075. Add('begin');
  7076. SetExpectedPasResolverError('Duplicate identifier "Id" at test1.pp(6,6)',nDuplicateIdentifier);
  7077. ConvertProgram;
  7078. end;
  7079. procedure TTestModule.TestExternalClass_Method;
  7080. begin
  7081. StartProgram(false);
  7082. Add('{$modeswitch externalclass}');
  7083. Add('type');
  7084. Add(' TExtA = class external name ''ExtObj''');
  7085. Add(' procedure DoIt(Id: longint = 1); external name ''$Execute'';');
  7086. Add(' procedure DoSome(Id: longint = 1);');
  7087. Add(' end;');
  7088. Add('var Obj: texta;');
  7089. Add('begin');
  7090. Add(' obj.doit;');
  7091. Add(' obj.doit();');
  7092. Add(' obj.doit(2);');
  7093. Add(' with obj do begin');
  7094. Add(' doit;');
  7095. Add(' doit();');
  7096. Add(' doit(3);');
  7097. Add(' end;');
  7098. ConvertProgram;
  7099. CheckSource('TestExternalClass_Method',
  7100. LinesToStr([ // statements
  7101. 'this.Obj = null;',
  7102. '']),
  7103. LinesToStr([ // this.$main
  7104. 'this.Obj.$Execute(1);',
  7105. 'this.Obj.$Execute(1);',
  7106. 'this.Obj.$Execute(2);',
  7107. 'var $with1 = this.Obj;',
  7108. '$with1.$Execute(1);',
  7109. '$with1.$Execute(1);',
  7110. '$with1.$Execute(3);',
  7111. '']));
  7112. end;
  7113. procedure TTestModule.TestExternalClass_NonExternalOverride;
  7114. begin
  7115. StartProgram(false);
  7116. Add('{$modeswitch externalclass}');
  7117. Add('type');
  7118. Add(' TExtA = class external name ''ExtObjA''');
  7119. Add(' procedure ProcA; virtual;');
  7120. Add(' procedure ProcB; virtual;');
  7121. Add(' end;');
  7122. Add(' TExtB = class external name ''ExtObjB'' (TExtA)');
  7123. Add(' end;');
  7124. Add(' TExtC = class (TExtB)');
  7125. Add(' procedure ProcA; override;');
  7126. Add(' end;');
  7127. Add('procedure TExtC.ProcA;');
  7128. Add('begin');
  7129. Add(' ProcA;');
  7130. Add(' Self.ProcA;');
  7131. Add(' ProcB;');
  7132. Add(' Self.ProcB;');
  7133. Add('end;');
  7134. Add('var');
  7135. Add(' A: texta;');
  7136. Add(' B: textb;');
  7137. Add(' C: textc;');
  7138. Add('begin');
  7139. Add(' a.proca;');
  7140. Add(' b.proca;');
  7141. Add(' c.proca;');
  7142. ConvertProgram;
  7143. CheckSource('TestExternalClass_NonExternalOverride',
  7144. LinesToStr([ // statements
  7145. 'rtl.createClassExt(this, "TExtC", ExtObjB, "", function () {',
  7146. ' this.$init = function () {',
  7147. ' };',
  7148. ' this.$final = function () {',
  7149. ' };',
  7150. ' this.ProcA = function () {',
  7151. ' this.ProcA();',
  7152. ' this.ProcA();',
  7153. ' this.ProcB();',
  7154. ' this.ProcB();',
  7155. ' };',
  7156. '});',
  7157. 'this.A = null;',
  7158. 'this.B = null;',
  7159. 'this.C = null;',
  7160. '']),
  7161. LinesToStr([ // this.$main
  7162. 'this.A.ProcA();',
  7163. 'this.B.ProcA();',
  7164. 'this.C.ProcA();',
  7165. '']));
  7166. end;
  7167. procedure TTestModule.TestExternalClass_Property;
  7168. begin
  7169. StartProgram(false);
  7170. Add('{$modeswitch externalclass}');
  7171. Add('type');
  7172. Add(' TExtA = class external name ''ExtA''');
  7173. Add(' function getYear: longint;');
  7174. Add(' procedure setYear(Value: longint);');
  7175. Add(' property Year: longint read getyear write setyear;');
  7176. Add(' end;');
  7177. Add(' TExtB = class (TExtA)');
  7178. Add(' procedure OtherSetYear(Value: longint);');
  7179. Add(' property year write othersetyear;');
  7180. Add(' end;');
  7181. Add('procedure textb.othersetyear(value: longint);');
  7182. Add('begin');
  7183. Add(' setYear(Value+4);');
  7184. Add('end;');
  7185. Add('var');
  7186. Add(' A: texta;');
  7187. Add(' B: textb;');
  7188. Add('begin');
  7189. Add(' a.year:=a.year+1;');
  7190. Add(' b.year:=b.year+2;');
  7191. ConvertProgram;
  7192. CheckSource('TestExternalClass_NonExternalOverride',
  7193. LinesToStr([ // statements
  7194. 'rtl.createClassExt(this, "TExtB", ExtA, "", function () {',
  7195. ' this.$init = function () {',
  7196. ' };',
  7197. ' this.$final = function () {',
  7198. ' };',
  7199. ' this.OtherSetYear = function (Value) {',
  7200. ' this.setYear(Value+4);',
  7201. ' };',
  7202. '});',
  7203. 'this.A = null;',
  7204. 'this.B = null;',
  7205. '']),
  7206. LinesToStr([ // this.$main
  7207. 'this.A.setYear(this.A.getYear()+1);',
  7208. 'this.B.OtherSetYear(this.B.getYear()+2);',
  7209. '']));
  7210. end;
  7211. procedure TTestModule.TestExternalClass_ClassProperty;
  7212. begin
  7213. StartProgram(false);
  7214. Add('{$modeswitch externalclass}');
  7215. Add('type');
  7216. Add(' TExtA = class external name ''ExtA''');
  7217. Add(' class function getYear: longint;');
  7218. Add(' class procedure setYear(Value: longint);');
  7219. Add(' class property Year: longint read getyear write setyear;');
  7220. Add(' end;');
  7221. Add(' TExtB = class (TExtA)');
  7222. Add(' class function GetCentury: longint;');
  7223. Add(' class procedure SetCentury(Value: longint);');
  7224. Add(' class property Century: longint read getcentury write setcentury;');
  7225. Add(' end;');
  7226. Add('class function textb.getcentury: longint;');
  7227. Add('begin');
  7228. Add('end;');
  7229. Add('class procedure textb.setcentury(value: longint);');
  7230. Add('begin');
  7231. Add(' setyear(value+11);');
  7232. Add(' texta.year:=texta.year+12;');
  7233. Add(' year:=year+13;');
  7234. Add(' textb.century:=textb.century+14;');
  7235. Add(' century:=century+15;');
  7236. Add('end;');
  7237. Add('var');
  7238. Add(' A: texta;');
  7239. Add(' B: textb;');
  7240. Add('begin');
  7241. Add(' texta.year:=texta.year+1;');
  7242. Add(' textb.year:=textb.year+2;');
  7243. Add(' a.year:=a.year+3;');
  7244. Add(' b.year:=b.year+4;');
  7245. Add(' textb.century:=textb.century+5;');
  7246. Add(' b.century:=b.century+6;');
  7247. ConvertProgram;
  7248. CheckSource('TestExternalClass_ClassProperty',
  7249. LinesToStr([ // statements
  7250. 'rtl.createClassExt(this, "TExtB", ExtA, "", function () {',
  7251. ' this.$init = function () {',
  7252. ' };',
  7253. ' this.$final = function () {',
  7254. ' };',
  7255. ' this.GetCentury = function () {',
  7256. ' var Result = 0;',
  7257. ' return Result;',
  7258. ' };',
  7259. ' this.SetCentury = function (Value) {',
  7260. ' this.setYear(Value + 11);',
  7261. ' ExtA.setYear(ExtA.getYear() + 12);',
  7262. ' this.setYear(this.getYear() + 13);',
  7263. ' pas.program.TExtB.SetCentury(pas.program.TExtB.GetCentury() + 14);',
  7264. ' this.SetCentury(this.GetCentury() + 15);',
  7265. ' };',
  7266. '});',
  7267. 'this.A = null;',
  7268. 'this.B = null;',
  7269. '']),
  7270. LinesToStr([ // this.$main
  7271. 'ExtA.setYear(ExtA.getYear() + 1);',
  7272. 'this.TExtB.setYear(this.TExtB.getYear() + 2);',
  7273. 'this.A.setYear(this.A.getYear() + 3);',
  7274. 'this.B.setYear(this.B.getYear() + 4);',
  7275. 'this.TExtB.SetCentury(this.TExtB.GetCentury() + 5);',
  7276. 'this.B.$class.SetCentury(this.B.$class.GetCentury() + 6);',
  7277. '']));
  7278. end;
  7279. procedure TTestModule.TestExternalClass_ClassOf;
  7280. begin
  7281. StartProgram(false);
  7282. Add('{$modeswitch externalclass}');
  7283. Add('type');
  7284. Add(' TExtA = class external name ''ExtA''');
  7285. Add(' procedure ProcA; virtual;');
  7286. Add(' procedure ProcB; virtual;');
  7287. Add(' end;');
  7288. Add(' TExtAClass = class of TExtA;');
  7289. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  7290. Add(' end;');
  7291. Add(' TExtBClass = class of TExtB;');
  7292. Add(' TExtC = class (TExtB)');
  7293. Add(' procedure ProcA; override;');
  7294. Add(' end;');
  7295. Add(' TExtCClass = class of TExtC;');
  7296. Add('procedure TExtC.ProcA; begin end;');
  7297. Add('var');
  7298. Add(' A: texta; ClA: TExtAClass;');
  7299. Add(' B: textb; ClB: TExtBClass;');
  7300. Add(' C: textc; ClC: TExtCClass;');
  7301. Add('begin');
  7302. Add(' ClA:=texta;');
  7303. Add(' ClA:=textb;');
  7304. Add(' ClA:=textc;');
  7305. Add(' ClB:=textb;');
  7306. Add(' ClB:=textc;');
  7307. Add(' ClC:=textc;');
  7308. ConvertProgram;
  7309. CheckSource('TestExternalClass_ClassOf',
  7310. LinesToStr([ // statements
  7311. 'rtl.createClassExt(this, "TExtC", ExtB, "", function () {',
  7312. ' this.$init = function () {',
  7313. ' };',
  7314. ' this.$final = function () {',
  7315. ' };',
  7316. ' this.ProcA = function () {',
  7317. ' };',
  7318. '});',
  7319. 'this.A = null;',
  7320. 'this.ClA = null;',
  7321. 'this.B = null;',
  7322. 'this.ClB = null;',
  7323. 'this.C = null;',
  7324. 'this.ClC = null;',
  7325. '']),
  7326. LinesToStr([ // this.$main
  7327. 'this.ClA = ExtA;',
  7328. 'this.ClA = ExtB;',
  7329. 'this.ClA = this.TExtC;',
  7330. 'this.ClB = ExtB;',
  7331. 'this.ClB = this.TExtC;',
  7332. 'this.ClC = this.TExtC;',
  7333. '']));
  7334. end;
  7335. procedure TTestModule.TestExternalClass_ClassOtherUnit;
  7336. begin
  7337. AddModuleWithIntfImplSrc('unit2.pas',
  7338. LinesToStr([
  7339. '{$modeswitch externalclass}',
  7340. 'type',
  7341. ' TExtA = class external name ''ExtA''',
  7342. ' class var Id: longint;',
  7343. ' end;',
  7344. '']),
  7345. '');
  7346. StartUnit(true);
  7347. Add('interface');
  7348. Add('uses unit2;');
  7349. Add('implementation');
  7350. Add('begin');
  7351. Add(' unit2.texta.id:=unit2.texta.id+1;');
  7352. ConvertUnit;
  7353. CheckSource('TestExternalClass_ClassOtherUnit',
  7354. LinesToStr([
  7355. 'var $impl = {',
  7356. '};',
  7357. 'this.$impl = $impl;',
  7358. '']),
  7359. LinesToStr([
  7360. 'ExtA.Id = ExtA.Id + 1;',
  7361. '']));
  7362. end;
  7363. procedure TTestModule.TestExternalClass_Is;
  7364. begin
  7365. StartProgram(false);
  7366. Add('{$modeswitch externalclass}');
  7367. Add('type');
  7368. Add(' TExtA = class external name ''ExtA''');
  7369. Add(' end;');
  7370. Add(' TExtAClass = class of TExtA;');
  7371. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  7372. Add(' end;');
  7373. Add(' TExtBClass = class of TExtB;');
  7374. Add(' TExtC = class (TExtB)');
  7375. Add(' end;');
  7376. Add(' TExtCClass = class of TExtC;');
  7377. Add('var');
  7378. Add(' A: texta; ClA: TExtAClass;');
  7379. Add(' B: textb; ClB: TExtBClass;');
  7380. Add(' C: textc; ClC: TExtCClass;');
  7381. Add('begin');
  7382. Add(' if a is textb then ;');
  7383. Add(' if a is textc then ;');
  7384. Add(' if b is textc then ;');
  7385. Add(' if cla is textb then ;');
  7386. Add(' if cla is textc then ;');
  7387. Add(' if clb is textc then ;');
  7388. ConvertProgram;
  7389. CheckSource('TestExternalClass_Is',
  7390. LinesToStr([ // statements
  7391. 'rtl.createClassExt(this, "TExtC", ExtB, "", function () {',
  7392. ' this.$init = function () {',
  7393. ' };',
  7394. ' this.$final = function () {',
  7395. ' };',
  7396. '});',
  7397. 'this.A = null;',
  7398. 'this.ClA = null;',
  7399. 'this.B = null;',
  7400. 'this.ClB = null;',
  7401. 'this.C = null;',
  7402. 'this.ClC = null;',
  7403. '']),
  7404. LinesToStr([ // this.$main
  7405. 'if (rtl.isExt(this.A, ExtB)) ;',
  7406. 'if (this.TExtC.isPrototypeOf(this.A)) ;',
  7407. 'if (this.TExtC.isPrototypeOf(this.B)) ;',
  7408. 'if (rtl.isExt(this.ClA, ExtB)) ;',
  7409. 'if (rtl.is(this.ClA, this.TExtC)) ;',
  7410. 'if (rtl.is(this.ClB, this.TExtC)) ;',
  7411. '']));
  7412. end;
  7413. procedure TTestModule.TestExternalClass_As;
  7414. begin
  7415. StartProgram(false);
  7416. Add('{$modeswitch externalclass}');
  7417. Add('type');
  7418. Add(' TExtA = class external name ''ExtA''');
  7419. Add(' end;');
  7420. Add(' TExtB = class external name ''ExtB'' (TExtA)');
  7421. Add(' end;');
  7422. Add(' TExtC = class (TExtB)');
  7423. Add(' end;');
  7424. Add('var');
  7425. Add(' A: texta;');
  7426. Add(' B: textb;');
  7427. Add(' C: textc;');
  7428. Add('begin');
  7429. Add(' b:=a as textb;');
  7430. Add(' c:=a as textc;');
  7431. Add(' c:=b as textc;');
  7432. ConvertProgram;
  7433. CheckSource('TestExternalClass_Is',
  7434. LinesToStr([ // statements
  7435. 'rtl.createClassExt(this, "TExtC", ExtB, "", function () {',
  7436. ' this.$init = function () {',
  7437. ' };',
  7438. ' this.$final = function () {',
  7439. ' };',
  7440. '});',
  7441. 'this.A = null;',
  7442. 'this.B = null;',
  7443. 'this.C = null;',
  7444. '']),
  7445. LinesToStr([ // this.$main
  7446. 'this.B = rtl.asExt(this.A, ExtB);',
  7447. 'this.C = rtl.as(this.A, this.TExtC);',
  7448. 'this.C = rtl.as(this.B, this.TExtC);',
  7449. '']));
  7450. end;
  7451. procedure TTestModule.TestExternalClass_DestructorFail;
  7452. begin
  7453. StartProgram(false);
  7454. Add('{$modeswitch externalclass}');
  7455. Add('type');
  7456. Add(' TExtA = class external name ''ExtA''');
  7457. Add(' destructor Free;');
  7458. Add(' end;');
  7459. SetExpectedPasResolverError('Pascal element not supported: destructor',
  7460. nPasElementNotSupported);
  7461. ConvertProgram;
  7462. end;
  7463. procedure TTestModule.TestExternalClass_New;
  7464. begin
  7465. StartProgram(false);
  7466. Add('{$modeswitch externalclass}');
  7467. Add('type');
  7468. Add(' TExtA = class external name ''ExtA''');
  7469. Add(' constructor New;');
  7470. Add(' constructor New(i: longint; j: longint = 2);');
  7471. Add(' end;');
  7472. Add('var');
  7473. Add(' A: texta;');
  7474. Add('begin');
  7475. Add(' a:=texta.new;');
  7476. Add(' a:=texta.new();');
  7477. Add(' a:=texta.new(1);');
  7478. Add(' with texta do begin');
  7479. Add(' a:=new;');
  7480. Add(' a:=new();');
  7481. Add(' a:=new(2);');
  7482. Add(' end;');
  7483. Add(' a:=test1.texta.new;');
  7484. Add(' a:=test1.texta.new();');
  7485. Add(' a:=test1.texta.new(3);');
  7486. ConvertProgram;
  7487. CheckSource('TestExternalClass_ObjectCreate',
  7488. LinesToStr([ // statements
  7489. 'this.A = null;',
  7490. '']),
  7491. LinesToStr([ // this.$main
  7492. 'this.A = new ExtA();',
  7493. 'this.A = new ExtA();',
  7494. 'this.A = new ExtA(1,2);',
  7495. 'var $with1 = ExtA;',
  7496. 'this.A = new $with1();',
  7497. 'this.A = new $with1();',
  7498. 'this.A = new $with1(2,2);',
  7499. 'this.A = new ExtA();',
  7500. 'this.A = new ExtA();',
  7501. 'this.A = new ExtA(3,2);',
  7502. '']));
  7503. end;
  7504. procedure TTestModule.TestExternalClass_ClassOf_New;
  7505. begin
  7506. StartProgram(false);
  7507. Add('{$modeswitch externalclass}');
  7508. Add('type');
  7509. Add(' TExtAClass = class of TExtA;');
  7510. Add(' TExtA = class external name ''ExtA''');
  7511. Add(' constructor New;');
  7512. Add(' end;');
  7513. Add('var');
  7514. Add(' A: texta;');
  7515. Add(' C: textaclass;');
  7516. Add('begin');
  7517. Add(' a:=c.new;');
  7518. Add(' a:=c.new();');
  7519. Add(' with C do begin');
  7520. Add(' a:=new;');
  7521. Add(' a:=new();');
  7522. Add(' end;');
  7523. Add(' a:=test1.c.new;');
  7524. Add(' a:=test1.c.new();');
  7525. ConvertProgram;
  7526. CheckSource('TestExternalClass_ClassOf_New',
  7527. LinesToStr([ // statements
  7528. 'this.A = null;',
  7529. 'this.C = null;',
  7530. '']),
  7531. LinesToStr([ // this.$main
  7532. 'this.A = new this.C();',
  7533. 'this.A = new this.C();',
  7534. 'var $with1 = this.C;',
  7535. 'this.A = new $with1();',
  7536. 'this.A = new $with1();',
  7537. 'this.A = new this.C();',
  7538. 'this.A = new this.C();',
  7539. '']));
  7540. end;
  7541. procedure TTestModule.TestExternalClass_FuncClassOf_New;
  7542. begin
  7543. StartProgram(false);
  7544. Add('{$modeswitch externalclass}');
  7545. Add('type');
  7546. Add(' TExtAClass = class of TExtA;');
  7547. Add(' TExtA = class external name ''ExtA''');
  7548. Add(' constructor New;');
  7549. Add(' end;');
  7550. Add('function GetCreator: TExtAClass;');
  7551. Add('begin');
  7552. Add(' Result:=TExtA;');
  7553. Add('end;');
  7554. Add('var');
  7555. Add(' A: texta;');
  7556. Add('begin');
  7557. Add(' a:=getcreator.new;');
  7558. Add(' a:=getcreator().new;');
  7559. Add(' a:=getcreator().new();');
  7560. Add(' a:=getcreator.new();');
  7561. Add(' with getcreator do begin');
  7562. Add(' a:=new;');
  7563. Add(' a:=new();');
  7564. Add(' end;');
  7565. ConvertProgram;
  7566. CheckSource('TestExternalClass_FuncClassOf_New',
  7567. LinesToStr([ // statements
  7568. 'this.GetCreator = function () {',
  7569. ' var Result = null;',
  7570. ' Result = ExtA;',
  7571. ' return Result;',
  7572. '};',
  7573. 'this.A = null;',
  7574. '']),
  7575. LinesToStr([ // this.$main
  7576. 'this.A = new (this.GetCreator())();',
  7577. 'this.A = new (this.GetCreator())();',
  7578. 'this.A = new (this.GetCreator())();',
  7579. 'this.A = new (this.GetCreator())();',
  7580. 'var $with1 = this.GetCreator();',
  7581. 'this.A = new $with1();',
  7582. 'this.A = new $with1();',
  7583. '']));
  7584. end;
  7585. procedure TTestModule.TestExternalClass_LocalConstSameName;
  7586. begin
  7587. StartProgram(false);
  7588. Add('{$modeswitch externalclass}');
  7589. Add('type');
  7590. Add(' TExtA = class external name ''ExtA''');
  7591. Add(' constructor New;');
  7592. Add(' end;');
  7593. Add('function DoIt: longint;');
  7594. Add('const ExtA = 3;');
  7595. Add('begin');
  7596. Add(' Result:=ExtA;');
  7597. Add('end;');
  7598. Add('var');
  7599. Add(' A: texta;');
  7600. Add('begin');
  7601. Add(' a:=texta.new;');
  7602. ConvertProgram;
  7603. CheckSource('TestExternalClass_LocalConstSameName',
  7604. LinesToStr([ // statements
  7605. 'var ExtA$1 = 3;',
  7606. 'this.DoIt = function () {',
  7607. ' var Result = 0;',
  7608. ' Result = ExtA$1;',
  7609. ' return Result;',
  7610. '};',
  7611. 'this.A = null;',
  7612. '']),
  7613. LinesToStr([ // this.$main
  7614. 'this.A = new ExtA();',
  7615. '']));
  7616. end;
  7617. procedure TTestModule.TestExternalClass_ReintroduceOverload;
  7618. begin
  7619. StartProgram(false);
  7620. Add('{$modeswitch externalclass}');
  7621. Add('type');
  7622. Add(' TExtA = class external name ''ExtA''');
  7623. Add(' procedure DoIt;');
  7624. Add(' end;');
  7625. Add(' TMyA = class(TExtA)');
  7626. Add(' procedure DoIt;');
  7627. Add(' end;');
  7628. Add('procedure TMyA.DoIt; begin end;');
  7629. Add('begin');
  7630. ConvertProgram;
  7631. CheckSource('TestExternalClass_ReintroduceOverload',
  7632. LinesToStr([ // statements
  7633. 'rtl.createClassExt(this, "TMyA", ExtA, "", function () {',
  7634. ' this.$init = function () {',
  7635. ' };',
  7636. ' this.$final = function () {',
  7637. ' };',
  7638. ' this.DoIt$1 = function () {',
  7639. ' };',
  7640. '});',
  7641. '']),
  7642. LinesToStr([ // this.$main
  7643. '']));
  7644. end;
  7645. procedure TTestModule.TestExternalClass_Inherited;
  7646. begin
  7647. StartProgram(false);
  7648. Add('{$modeswitch externalclass}');
  7649. Add('type');
  7650. Add(' TExtA = class external name ''ExtA''');
  7651. Add(' procedure DoIt(i: longint = 1); virtual;');
  7652. Add(' procedure DoSome(j: longint = 2);');
  7653. Add(' end;');
  7654. Add(' TExtB = class external name ''ExtB''(TExtA)');
  7655. Add(' end;');
  7656. Add(' TMyC = class(TExtB)');
  7657. Add(' procedure DoIt(i: longint = 1); override;');
  7658. Add(' procedure DoSome(j: longint = 2); reintroduce;');
  7659. Add(' end;');
  7660. Add('procedure TMyC.DoIt(i: longint);');
  7661. Add('begin');
  7662. Add(' inherited;');
  7663. Add(' inherited DoIt;');
  7664. Add(' inherited DoIt();');
  7665. Add(' inherited DoIt(3);');
  7666. Add(' inherited DoSome;');
  7667. Add(' inherited DoSome();');
  7668. Add(' inherited DoSome(4);');
  7669. Add('end;');
  7670. Add('procedure TMyC.DoSome(j: longint);');
  7671. Add('begin');
  7672. Add(' inherited;');
  7673. Add('end;');
  7674. Add('begin');
  7675. ConvertProgram;
  7676. CheckSource('TestExternalClass_ReintroduceOverload',
  7677. LinesToStr([ // statements
  7678. 'rtl.createClassExt(this, "TMyC", ExtB, "", function () {',
  7679. ' this.$init = function () {',
  7680. ' };',
  7681. ' this.$final = function () {',
  7682. ' };',
  7683. ' this.DoIt = function (i) {',
  7684. ' ExtB.DoIt.apply(this, arguments);',
  7685. ' ExtB.DoIt.call(this, 1);',
  7686. ' ExtB.DoIt.call(this, 1);',
  7687. ' ExtB.DoIt.call(this, 3);',
  7688. ' ExtB.DoSome.call(this, 2);',
  7689. ' ExtB.DoSome.call(this, 2);',
  7690. ' ExtB.DoSome.call(this, 4);',
  7691. ' };',
  7692. ' this.DoSome$1 = function (j) {',
  7693. ' ExtB.DoSome.apply(this, arguments);',
  7694. ' };',
  7695. '});',
  7696. '']),
  7697. LinesToStr([ // this.$main
  7698. '']));
  7699. end;
  7700. procedure TTestModule.TestExternalClass_NewInstance;
  7701. begin
  7702. StartProgram(false);
  7703. Add('{$modeswitch externalclass}');
  7704. Add('type');
  7705. Add(' TExtA = class external name ''ExtA''');
  7706. Add(' end;');
  7707. Add(' TMyB = class(TExtA)');
  7708. Add(' protected');
  7709. Add(' class function NewInstance(fnname: string; const paramarray): TMyB; virtual;');
  7710. Add(' end;');
  7711. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  7712. Add('begin end;');
  7713. Add('begin');
  7714. ConvertProgram;
  7715. CheckSource('TestExternalClass_NewInstance',
  7716. LinesToStr([ // statements
  7717. 'rtl.createClassExt(this, "TMyB", ExtA, "NewInstance", function () {',
  7718. ' this.$init = function () {',
  7719. ' };',
  7720. ' this.$final = function () {',
  7721. ' };',
  7722. ' this.NewInstance = function (fnname, paramarray) {',
  7723. ' var Result = null;',
  7724. ' return Result;',
  7725. ' };',
  7726. '});',
  7727. '']),
  7728. LinesToStr([ // this.$main
  7729. '']));
  7730. end;
  7731. procedure TTestModule.TestExternalClass_NewInstance_NonVirtualFail;
  7732. begin
  7733. StartProgram(false);
  7734. Add('{$modeswitch externalclass}');
  7735. Add('type');
  7736. Add(' TExtA = class external name ''ExtA''');
  7737. Add(' end;');
  7738. Add(' TMyB = class(TExtA)');
  7739. Add(' protected');
  7740. Add(' class function NewInstance(fnname: string; const paramarray): TMyB;');
  7741. Add(' end;');
  7742. Add('class function TMyB.NewInstance(fnname: string; const paramarray): TMyB;');
  7743. Add('begin end;');
  7744. Add('begin');
  7745. SetExpectedPasResolverError(sNewInstanceFunctionMustBeVirtual,nNewInstanceFunctionMustBeVirtual);
  7746. ConvertProgram;
  7747. end;
  7748. procedure TTestModule.TestExternalClass_NewInstance_FirstParamNotString_Fail;
  7749. begin
  7750. StartProgram(false);
  7751. Add('{$modeswitch externalclass}');
  7752. Add('type');
  7753. Add(' TExtA = class external name ''ExtA''');
  7754. Add(' end;');
  7755. Add(' TMyB = class(TExtA)');
  7756. Add(' protected');
  7757. Add(' class function NewInstance(fnname: longint; const paramarray): TMyB; virtual;');
  7758. Add(' end;');
  7759. Add('class function TMyB.NewInstance(fnname: longint; const paramarray): TMyB;');
  7760. Add('begin end;');
  7761. Add('begin');
  7762. SetExpectedPasResolverError('Incompatible type arg no. 1: Got "Longint", expected "String"',
  7763. nIncompatibleTypeArgNo);
  7764. ConvertProgram;
  7765. end;
  7766. procedure TTestModule.TestExternalClass_NewInstance_SecondParamTyped_Fail;
  7767. begin
  7768. StartProgram(false);
  7769. Add('{$modeswitch externalclass}');
  7770. Add('type');
  7771. Add(' TExtA = class external name ''ExtA''');
  7772. Add(' end;');
  7773. Add(' TMyB = class(TExtA)');
  7774. Add(' protected');
  7775. Add(' class function NewInstance(fnname: string; const paramarray: string): TMyB; virtual;');
  7776. Add(' end;');
  7777. Add('class function TMyB.NewInstance(fnname: string; const paramarray: string): TMyB;');
  7778. Add('begin end;');
  7779. Add('begin');
  7780. SetExpectedPasResolverError('Incompatible type arg no. 2: Got "type", expected "untyped"',
  7781. nIncompatibleTypeArgNo);
  7782. ConvertProgram;
  7783. end;
  7784. procedure TTestModule.TestExternalClass_TypeCastToRootClass;
  7785. begin
  7786. StartProgram(false);
  7787. Add('{$modeswitch externalclass}');
  7788. Add('type');
  7789. Add(' TObject = class');
  7790. Add(' end;');
  7791. Add(' TChild = class');
  7792. Add(' end;');
  7793. Add(' TExtRootA = class external name ''ExtRootA''');
  7794. Add(' end;');
  7795. Add(' TExtChildA = class external name ''ExtChildA''(TExtRootA)');
  7796. Add(' end;');
  7797. Add(' TExtRootB = class external name ''ExtRootB''');
  7798. Add(' end;');
  7799. Add(' TExtChildB = class external name ''ExtChildB''(TExtRootB)');
  7800. Add(' end;');
  7801. Add('var');
  7802. Add(' Obj: TObject;');
  7803. Add(' Child: TChild;');
  7804. Add(' RootA: TExtRootA;');
  7805. Add(' ChildA: TExtChildA;');
  7806. Add(' RootB: TExtRootB;');
  7807. Add(' ChildB: TExtChildB;');
  7808. Add('begin');
  7809. Add(' obj:=tobject(roota);');
  7810. Add(' obj:=tobject(childa);');
  7811. Add(' child:=tchild(tobject(roota));');
  7812. Add(' roota:=textroota(obj);');
  7813. Add(' roota:=textroota(child);');
  7814. Add(' roota:=textroota(rootb);');
  7815. Add(' roota:=textroota(childb);');
  7816. Add(' childa:=textchilda(textroota(obj));');
  7817. ConvertProgram;
  7818. CheckSource('TestExternalClass_TypeCastToRootClass',
  7819. LinesToStr([ // statements
  7820. 'rtl.createClass(this, "TObject", null, function () {',
  7821. ' this.$init = function () {',
  7822. ' };',
  7823. ' this.$final = function () {',
  7824. ' };',
  7825. '});',
  7826. 'rtl.createClass(this, "TChild", this.TObject, function () {',
  7827. '});',
  7828. 'this.Obj = null;',
  7829. 'this.Child = null;',
  7830. 'this.RootA = null;',
  7831. 'this.ChildA = null;',
  7832. 'this.RootB = null;',
  7833. 'this.ChildB = null;',
  7834. '']),
  7835. LinesToStr([ // this.$main
  7836. 'this.Obj = this.RootA;',
  7837. 'this.Obj = this.ChildA;',
  7838. 'this.Child = this.RootA;',
  7839. 'this.RootA = this.Obj;',
  7840. 'this.RootA = this.Child;',
  7841. 'this.RootA = this.RootB;',
  7842. 'this.RootA = this.ChildB;',
  7843. 'this.ChildA = this.Obj;',
  7844. '']));
  7845. end;
  7846. procedure TTestModule.TestProcType;
  7847. begin
  7848. StartProgram(false);
  7849. Add('type');
  7850. Add(' TProcInt = procedure(vI: longint = 1);');
  7851. Add('procedure DoIt(vJ: longint);');
  7852. Add('begin end;');
  7853. Add('var');
  7854. Add(' b: boolean;');
  7855. Add(' vP, vQ: tprocint;');
  7856. Add('begin');
  7857. Add(' vp:=nil;');
  7858. Add(' vp:=vp;');
  7859. Add(' vp:=@doit;');
  7860. Add(' vp;');
  7861. Add(' vp();');
  7862. Add(' vp(2);');
  7863. Add(' b:=vp=nil;');
  7864. Add(' b:=nil=vp;');
  7865. Add(' b:=vp=vq;');
  7866. Add(' b:=vp=@doit;');
  7867. Add(' b:=@doit=vp;');
  7868. Add(' b:=vp<>nil;');
  7869. Add(' b:=nil<>vp;');
  7870. Add(' b:=vp<>vq;');
  7871. Add(' b:=vp<>@doit;');
  7872. Add(' b:=@doit<>vp;');
  7873. Add(' b:=Assigned(vp);');
  7874. ConvertProgram;
  7875. CheckSource('TestProcType',
  7876. LinesToStr([ // statements
  7877. 'this.DoIt = function(vJ) {',
  7878. '};',
  7879. 'this.b = false;',
  7880. 'this.vP = null;',
  7881. 'this.vQ = null;'
  7882. ]),
  7883. LinesToStr([ // this.$main
  7884. 'this.vP = null;',
  7885. 'this.vP = this.vP;',
  7886. 'this.vP = rtl.createCallback(this,"DoIt");',
  7887. 'this.vP(1);',
  7888. 'this.vP(1);',
  7889. 'this.vP(2);',
  7890. 'this.b = this.vP == null;',
  7891. 'this.b = null == this.vP;',
  7892. 'this.b = rtl.eqCallback(this.vP,this.vQ);',
  7893. 'this.b = rtl.eqCallback(this.vP, rtl.createCallback(this, "DoIt"));',
  7894. 'this.b = rtl.eqCallback(rtl.createCallback(this, "DoIt"), this.vP);',
  7895. 'this.b = this.vP != null;',
  7896. 'this.b = null != this.vP;',
  7897. 'this.b = !rtl.eqCallback(this.vP,this.vQ);',
  7898. 'this.b = !rtl.eqCallback(this.vP, rtl.createCallback(this, "DoIt"));',
  7899. 'this.b = !rtl.eqCallback(rtl.createCallback(this, "DoIt"), this.vP);',
  7900. 'this.b = this.vP != null;',
  7901. '']));
  7902. end;
  7903. procedure TTestModule.TestProcType_FunctionFPC;
  7904. begin
  7905. StartProgram(false);
  7906. Add('type');
  7907. Add(' TFuncInt = function(vA: longint = 1): longint;');
  7908. Add('function DoIt(vI: longint): longint;');
  7909. Add('begin end;');
  7910. Add('var');
  7911. Add(' b: boolean;');
  7912. Add(' vP, vQ: tfuncint;');
  7913. Add('begin');
  7914. Add(' vp:=nil;');
  7915. Add(' vp:=vp;');
  7916. Add(' vp:=@doit;'); // ok in fpc and delphi
  7917. //Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  7918. Add(' vp;'); // ok in fpc and delphi
  7919. Add(' vp();');
  7920. Add(' vp(2);');
  7921. Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  7922. Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  7923. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  7924. Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  7925. Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  7926. //Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  7927. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  7928. Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  7929. Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  7930. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  7931. Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  7932. Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  7933. //Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  7934. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  7935. Add(' b:=Assigned(vp);');
  7936. //Add(' doit(vp);'); // illegal in fpc, ok in delphi
  7937. Add(' doit(vp());'); // ok in fpc and delphi
  7938. Add(' doit(vp(2));'); // ok in fpc and delphi
  7939. ConvertProgram;
  7940. CheckSource('TestProcType_FunctionFPC',
  7941. LinesToStr([ // statements
  7942. 'this.DoIt = function(vI) {',
  7943. ' var Result = 0;',
  7944. ' return Result;',
  7945. '};',
  7946. 'this.b = false;',
  7947. 'this.vP = null;',
  7948. 'this.vQ = null;'
  7949. ]),
  7950. LinesToStr([ // this.$main
  7951. 'this.vP = null;',
  7952. 'this.vP = this.vP;',
  7953. 'this.vP = rtl.createCallback(this,"DoIt");',
  7954. 'this.vP(1);',
  7955. 'this.vP(1);',
  7956. 'this.vP(2);',
  7957. 'this.b = this.vP == null;',
  7958. 'this.b = null == this.vP;',
  7959. 'this.b = rtl.eqCallback(this.vP,this.vQ);',
  7960. 'this.b = rtl.eqCallback(this.vP, rtl.createCallback(this, "DoIt"));',
  7961. 'this.b = rtl.eqCallback(rtl.createCallback(this, "DoIt"), this.vP);',
  7962. 'this.b = 4 == this.vP(1);',
  7963. 'this.b = this.vP != null;',
  7964. 'this.b = null != this.vP;',
  7965. 'this.b = !rtl.eqCallback(this.vP,this.vQ);',
  7966. 'this.b = !rtl.eqCallback(this.vP, rtl.createCallback(this, "DoIt"));',
  7967. 'this.b = !rtl.eqCallback(rtl.createCallback(this, "DoIt"), this.vP);',
  7968. 'this.b = 6 != this.vP(1);',
  7969. 'this.b = this.vP != null;',
  7970. 'this.DoIt(this.vP(1));',
  7971. 'this.DoIt(this.vP(2));',
  7972. '']));
  7973. end;
  7974. procedure TTestModule.TestProcType_FunctionDelphi;
  7975. begin
  7976. StartProgram(false);
  7977. Add('{$mode Delphi}');
  7978. Add('type');
  7979. Add(' TFuncInt = function(vA: longint = 1): longint;');
  7980. Add('function DoIt(vI: longint): longint;');
  7981. Add('begin end;');
  7982. Add('var');
  7983. Add(' b: boolean;');
  7984. Add(' vP, vQ: tfuncint;');
  7985. Add('begin');
  7986. Add(' vp:=nil;');
  7987. Add(' vp:=vp;');
  7988. Add(' vp:=@doit;'); // ok in fpc and delphi
  7989. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  7990. Add(' vp;'); // ok in fpc and delphi
  7991. Add(' vp();');
  7992. Add(' vp(2);');
  7993. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  7994. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  7995. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  7996. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  7997. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  7998. Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  7999. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  8000. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  8001. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  8002. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  8003. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  8004. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  8005. Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  8006. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  8007. Add(' b:=Assigned(vp);');
  8008. Add(' doit(vp);'); // illegal in fpc, ok in delphi
  8009. Add(' doit(vp());'); // ok in fpc and delphi
  8010. Add(' doit(vp(2));'); // ok in fpc and delphi *)
  8011. ConvertProgram;
  8012. CheckSource('TestProcType_FunctionDelphi',
  8013. LinesToStr([ // statements
  8014. 'this.DoIt = function(vI) {',
  8015. ' var Result = 0;',
  8016. ' return Result;',
  8017. '};',
  8018. 'this.b = false;',
  8019. 'this.vP = null;',
  8020. 'this.vQ = null;'
  8021. ]),
  8022. LinesToStr([ // this.$main
  8023. 'this.vP = null;',
  8024. 'this.vP = this.vP;',
  8025. 'this.vP = rtl.createCallback(this,"DoIt");',
  8026. 'this.vP = rtl.createCallback(this,"DoIt");',
  8027. 'this.vP(1);',
  8028. 'this.vP(1);',
  8029. 'this.vP(2);',
  8030. 'this.b = this.vP(1) == this.vQ(1);',
  8031. 'this.b = this.vP(1) == 3;',
  8032. 'this.b = 4 == this.vP(1);',
  8033. 'this.b = this.vP(1) != this.vQ(1);',
  8034. 'this.b = this.vP(1) != 5;',
  8035. 'this.b = 6 != this.vP(1);',
  8036. 'this.b = this.vP != null;',
  8037. 'this.DoIt(this.vP(1));',
  8038. 'this.DoIt(this.vP(1));',
  8039. 'this.DoIt(this.vP(2));',
  8040. '']));
  8041. end;
  8042. procedure TTestModule.TestProcType_AsParam;
  8043. begin
  8044. StartProgram(false);
  8045. Add('type');
  8046. Add(' TFuncInt = function(vA: longint = 1): longint;');
  8047. Add('procedure DoIt(vG: tfuncint; const vH: tfuncint; var vI: tfuncint);');
  8048. Add('var vJ: tfuncint;');
  8049. Add('begin');
  8050. Add(' vg:=vg;');
  8051. Add(' vj:=vh;');
  8052. Add(' vi:=vi;');
  8053. Add(' doit(vg,vg,vg);');
  8054. Add(' doit(vh,vh,vj);');
  8055. Add(' doit(vi,vi,vi);');
  8056. Add(' doit(vj,vj,vj);');
  8057. Add('end;');
  8058. Add('var i: tfuncint;');
  8059. Add('begin');
  8060. Add(' doit(i,i,i);');
  8061. ConvertProgram;
  8062. CheckSource('TestProcType_AsParam',
  8063. LinesToStr([ // statements
  8064. 'this.DoIt = function (vG,vH,vI) {',
  8065. ' var vJ = null;',
  8066. ' vG = vG;',
  8067. ' vJ = vH;',
  8068. ' vI.set(vI.get());',
  8069. ' this.DoIt(vG, vG, {',
  8070. ' get: function () {',
  8071. ' return vG;',
  8072. ' },',
  8073. ' set: function (v) {',
  8074. ' vG = v;',
  8075. ' }',
  8076. ' });',
  8077. ' this.DoIt(vH, vH, {',
  8078. ' get: function () {',
  8079. ' return vJ;',
  8080. ' },',
  8081. ' set: function (v) {',
  8082. ' vJ = v;',
  8083. ' }',
  8084. ' });',
  8085. ' this.DoIt(vI.get(), vI.get(), vI);',
  8086. ' this.DoIt(vJ, vJ, {',
  8087. ' get: function () {',
  8088. ' return vJ;',
  8089. ' },',
  8090. ' set: function (v) {',
  8091. ' vJ = v;',
  8092. ' }',
  8093. ' });',
  8094. '};',
  8095. 'this.i = null;'
  8096. ]),
  8097. LinesToStr([
  8098. 'this.DoIt(this.i,this.i,{',
  8099. ' p: this,',
  8100. ' get: function () {',
  8101. ' return this.p.i;',
  8102. ' },',
  8103. ' set: function (v) {',
  8104. ' this.p.i = v;',
  8105. ' }',
  8106. '});'
  8107. ]));
  8108. end;
  8109. procedure TTestModule.TestProcType_MethodFPC;
  8110. begin
  8111. StartProgram(false);
  8112. Add('type');
  8113. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  8114. Add(' TObject = class');
  8115. Add(' function DoIt(vA: longint = 1): longint;');
  8116. Add(' end;');
  8117. Add('function TObject.DoIt(vA: longint = 1): longint;');
  8118. Add('begin');
  8119. Add('end;');
  8120. Add('var');
  8121. Add(' Obj: TObject;');
  8122. Add(' vP: tfuncint;');
  8123. Add(' b: boolean;');
  8124. Add('begin');
  8125. Add(' vp:[email protected];'); // ok in fpc and delphi
  8126. //Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  8127. Add(' vp;'); // ok in fpc and delphi
  8128. Add(' vp();');
  8129. Add(' vp(2);');
  8130. Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  8131. Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  8132. Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  8133. Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  8134. ConvertProgram;
  8135. CheckSource('TestProcType_MethodFPC',
  8136. LinesToStr([ // statements
  8137. 'rtl.createClass(this, "TObject", null, function () {',
  8138. ' this.$init = function () {',
  8139. ' };',
  8140. ' this.$final = function () {',
  8141. ' };',
  8142. ' this.DoIt = function (vA) {',
  8143. ' var Result = 0;',
  8144. ' return Result;',
  8145. ' };',
  8146. '});',
  8147. 'this.Obj = null;',
  8148. 'this.vP = null;',
  8149. 'this.b = false;'
  8150. ]),
  8151. LinesToStr([
  8152. 'this.vP = rtl.createCallback(this.Obj, "DoIt");',
  8153. 'this.vP(1);',
  8154. 'this.vP(1);',
  8155. 'this.vP(2);',
  8156. 'this.b = rtl.eqCallback(this.vP, rtl.createCallback(this.Obj, "DoIt"));',
  8157. 'this.b = rtl.eqCallback(rtl.createCallback(this.Obj, "DoIt"), this.vP);',
  8158. 'this.b = !rtl.eqCallback(this.vP, rtl.createCallback(this.Obj, "DoIt"));',
  8159. 'this.b = !rtl.eqCallback(rtl.createCallback(this.Obj, "DoIt"), this.vP);',
  8160. '']));
  8161. end;
  8162. procedure TTestModule.TestProcType_MethodDelphi;
  8163. begin
  8164. StartProgram(false);
  8165. Add('{$mode delphi}');
  8166. Add('type');
  8167. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  8168. Add(' TObject = class');
  8169. Add(' function DoIt(vA: longint = 1): longint;');
  8170. Add(' end;');
  8171. Add('function TObject.DoIt(vA: longint = 1): longint;');
  8172. Add('begin');
  8173. Add('end;');
  8174. Add('var');
  8175. Add(' Obj: TObject;');
  8176. Add(' vP: tfuncint;');
  8177. Add(' b: boolean;');
  8178. Add('begin');
  8179. Add(' vp:[email protected];'); // ok in fpc and delphi
  8180. Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  8181. Add(' vp;'); // ok in fpc and delphi
  8182. Add(' vp();');
  8183. Add(' vp(2);');
  8184. //Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  8185. //Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  8186. //Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  8187. //Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  8188. ConvertProgram;
  8189. CheckSource('TestProcType_MethodDelphi',
  8190. LinesToStr([ // statements
  8191. 'rtl.createClass(this, "TObject", null, function () {',
  8192. ' this.$init = function () {',
  8193. ' };',
  8194. ' this.$final = function () {',
  8195. ' };',
  8196. ' this.DoIt = function (vA) {',
  8197. ' var Result = 0;',
  8198. ' return Result;',
  8199. ' };',
  8200. '});',
  8201. 'this.Obj = null;',
  8202. 'this.vP = null;',
  8203. 'this.b = false;'
  8204. ]),
  8205. LinesToStr([
  8206. 'this.vP = rtl.createCallback(this.Obj, "DoIt");',
  8207. 'this.vP = rtl.createCallback(this.Obj, "DoIt");',
  8208. 'this.vP(1);',
  8209. 'this.vP(1);',
  8210. 'this.vP(2);',
  8211. '']));
  8212. end;
  8213. procedure TTestModule.TestProcType_PropertyFPC;
  8214. begin
  8215. StartProgram(false);
  8216. Add('type');
  8217. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  8218. Add(' TObject = class');
  8219. Add(' FOnFoo: TFuncInt;');
  8220. Add(' function DoIt(vA: longint = 1): longint;');
  8221. Add(' function GetFoo: TFuncInt;');
  8222. Add(' procedure SetFoo(const Value: TFuncInt);');
  8223. Add(' function GetEvents(Index: longint): TFuncInt;');
  8224. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  8225. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  8226. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  8227. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  8228. Add(' end;');
  8229. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  8230. Add('function tobject.getfoo: tfuncint; begin end;');
  8231. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  8232. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  8233. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  8234. Add('var');
  8235. Add(' Obj: TObject;');
  8236. Add(' vP: tfuncint;');
  8237. Add(' b: boolean;');
  8238. Add('begin');
  8239. Add(' obj.onfoo:=nil;');
  8240. Add(' obj.onbar:=nil;');
  8241. Add(' obj.events[1]:=nil;');
  8242. Add(' obj.onfoo:=obj.onfoo;');
  8243. Add(' obj.onbar:=obj.onbar;');
  8244. Add(' obj.events[2]:=obj.events[3];');
  8245. Add(' obj.onfoo:[email protected];');
  8246. Add(' obj.onbar:[email protected];');
  8247. Add(' obj.events[4]:[email protected];');
  8248. //Add(' obj.onfoo:=obj.doit;'); // delphi
  8249. //Add(' obj.onbar:=obj.doit;'); // delphi
  8250. //Add(' obj.events[4]:=obj.doit;'); // delphi
  8251. Add(' obj.onfoo;');
  8252. Add(' obj.onbar;');
  8253. //Add(' obj.events[5];'); ToDo in pasresolver
  8254. Add(' obj.onfoo();');
  8255. Add(' obj.onbar();');
  8256. Add(' obj.events[6]();');
  8257. Add(' b:=obj.onfoo=nil;');
  8258. Add(' b:=obj.onbar=nil;');
  8259. Add(' b:=obj.events[7]=nil;');
  8260. Add(' b:=obj.onfoo<>nil;');
  8261. Add(' b:=obj.onbar<>nil;');
  8262. Add(' b:=obj.events[8]<>nil;');
  8263. Add(' b:=obj.onfoo=vp;');
  8264. Add(' b:=obj.onbar=vp;');
  8265. Add(' b:=obj.events[9]=vp;');
  8266. Add(' b:=obj.onfoo=obj.onfoo;');
  8267. Add(' b:=obj.onbar=obj.onfoo;');
  8268. Add(' b:=obj.events[10]=obj.onfoo;');
  8269. Add(' b:=obj.onfoo<>obj.onfoo;');
  8270. Add(' b:=obj.onbar<>obj.onfoo;');
  8271. Add(' b:=obj.events[11]<>obj.onfoo;');
  8272. Add(' b:[email protected];');
  8273. Add(' b:[email protected];');
  8274. Add(' b:=obj.events[12][email protected];');
  8275. Add(' b:=obj.onfoo<>@obj.doit;');
  8276. Add(' b:=obj.onbar<>@obj.doit;');
  8277. Add(' b:=obj.events[12]<>@obj.doit;');
  8278. Add(' b:=Assigned(obj.onfoo);');
  8279. Add(' b:=Assigned(obj.onbar);');
  8280. Add(' b:=Assigned(obj.events[13]);');
  8281. ConvertProgram;
  8282. CheckSource('TestProcType_PropertyFPC',
  8283. LinesToStr([ // statements
  8284. 'rtl.createClass(this, "TObject", null, function () {',
  8285. ' this.$init = function () {',
  8286. ' this.FOnFoo = null;',
  8287. ' };',
  8288. ' this.$final = function () {',
  8289. ' this.FOnFoo = undefined;',
  8290. ' };',
  8291. ' this.DoIt = function (vA) {',
  8292. ' var Result = 0;',
  8293. ' return Result;',
  8294. ' };',
  8295. 'this.GetFoo = function () {',
  8296. ' var Result = null;',
  8297. ' return Result;',
  8298. '};',
  8299. 'this.SetFoo = function (Value) {',
  8300. '};',
  8301. 'this.GetEvents = function (Index) {',
  8302. ' var Result = null;',
  8303. ' return Result;',
  8304. '};',
  8305. 'this.SetEvents = function (Index, Value) {',
  8306. '};',
  8307. '});',
  8308. 'this.Obj = null;',
  8309. 'this.vP = null;',
  8310. 'this.b = false;'
  8311. ]),
  8312. LinesToStr([
  8313. 'this.Obj.FOnFoo = null;',
  8314. 'this.Obj.SetFoo(null);',
  8315. 'this.Obj.SetEvents(1, null);',
  8316. 'this.Obj.FOnFoo = this.Obj.FOnFoo;',
  8317. 'this.Obj.SetFoo(this.Obj.GetFoo());',
  8318. 'this.Obj.SetEvents(2, this.Obj.GetEvents(3));',
  8319. 'this.Obj.FOnFoo = rtl.createCallback(this.Obj, "DoIt");',
  8320. 'this.Obj.SetFoo(rtl.createCallback(this.Obj, "DoIt"));',
  8321. 'this.Obj.SetEvents(4, rtl.createCallback(this.Obj, "DoIt"));',
  8322. 'this.Obj.FOnFoo(1);',
  8323. 'this.Obj.GetFoo();',
  8324. 'this.Obj.FOnFoo(1);',
  8325. 'this.Obj.GetFoo()(1);',
  8326. 'this.Obj.GetEvents(6)(1);',
  8327. 'this.b = this.Obj.FOnFoo == null;',
  8328. 'this.b = this.Obj.GetFoo() == null;',
  8329. 'this.b = this.Obj.GetEvents(7) == null;',
  8330. 'this.b = this.Obj.FOnFoo != null;',
  8331. 'this.b = this.Obj.GetFoo() != null;',
  8332. 'this.b = this.Obj.GetEvents(8) != null;',
  8333. 'this.b = rtl.eqCallback(this.Obj.FOnFoo, this.vP);',
  8334. 'this.b = rtl.eqCallback(this.Obj.GetFoo(), this.vP);',
  8335. 'this.b = rtl.eqCallback(this.Obj.GetEvents(9), this.vP);',
  8336. 'this.b = rtl.eqCallback(this.Obj.FOnFoo, this.Obj.FOnFoo);',
  8337. 'this.b = rtl.eqCallback(this.Obj.GetFoo(), this.Obj.FOnFoo);',
  8338. 'this.b = rtl.eqCallback(this.Obj.GetEvents(10), this.Obj.FOnFoo);',
  8339. 'this.b = !rtl.eqCallback(this.Obj.FOnFoo, this.Obj.FOnFoo);',
  8340. 'this.b = !rtl.eqCallback(this.Obj.GetFoo(), this.Obj.FOnFoo);',
  8341. 'this.b = !rtl.eqCallback(this.Obj.GetEvents(11), this.Obj.FOnFoo);',
  8342. 'this.b = rtl.eqCallback(this.Obj.FOnFoo, rtl.createCallback(this.Obj, "DoIt"));',
  8343. 'this.b = rtl.eqCallback(this.Obj.GetFoo(), rtl.createCallback(this.Obj, "DoIt"));',
  8344. 'this.b = rtl.eqCallback(this.Obj.GetEvents(12), rtl.createCallback(this.Obj, "DoIt"));',
  8345. 'this.b = !rtl.eqCallback(this.Obj.FOnFoo, rtl.createCallback(this.Obj, "DoIt"));',
  8346. 'this.b = !rtl.eqCallback(this.Obj.GetFoo(), rtl.createCallback(this.Obj, "DoIt"));',
  8347. 'this.b = !rtl.eqCallback(this.Obj.GetEvents(12), rtl.createCallback(this.Obj, "DoIt"));',
  8348. 'this.b = this.Obj.FOnFoo != null;',
  8349. 'this.b = this.Obj.GetFoo() != null;',
  8350. 'this.b = this.Obj.GetEvents(13) != null;',
  8351. '']));
  8352. end;
  8353. procedure TTestModule.TestProcType_PropertyDelphi;
  8354. begin
  8355. StartProgram(false);
  8356. Add('{$mode delphi}');
  8357. Add('type');
  8358. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  8359. Add(' TObject = class');
  8360. Add(' FOnFoo: TFuncInt;');
  8361. Add(' function DoIt(vA: longint = 1): longint;');
  8362. Add(' function GetFoo: TFuncInt;');
  8363. Add(' procedure SetFoo(const Value: TFuncInt);');
  8364. Add(' function GetEvents(Index: longint): TFuncInt;');
  8365. Add(' procedure SetEvents(Index: longint; const Value: TFuncInt);');
  8366. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  8367. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  8368. Add(' property Events[Index: longint]: TFuncInt read GetEvents write SetEvents; default;');
  8369. Add(' end;');
  8370. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  8371. Add('function tobject.getfoo: tfuncint; begin end;');
  8372. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  8373. Add('function tobject.getevents(index: longint): tfuncint; begin end;');
  8374. Add('procedure tobject.setevents(index: longint; const value: tfuncint); begin end;');
  8375. Add('var');
  8376. Add(' Obj: TObject;');
  8377. Add(' vP: tfuncint;');
  8378. Add(' b: boolean;');
  8379. Add('begin');
  8380. Add(' obj.onfoo:=nil;');
  8381. Add(' obj.onbar:=nil;');
  8382. Add(' obj.events[1]:=nil;');
  8383. Add(' obj.onfoo:=obj.onfoo;');
  8384. Add(' obj.onbar:=obj.onbar;');
  8385. Add(' obj.events[2]:=obj.events[3];');
  8386. Add(' obj.onfoo:[email protected];');
  8387. Add(' obj.onbar:[email protected];');
  8388. Add(' obj.events[4]:[email protected];');
  8389. Add(' obj.onfoo:=obj.doit;'); // delphi
  8390. Add(' obj.onbar:=obj.doit;'); // delphi
  8391. Add(' obj.events[4]:=obj.doit;'); // delphi
  8392. Add(' obj.onfoo;');
  8393. Add(' obj.onbar;');
  8394. //Add(' obj.events[5];'); ToDo in pasresolver
  8395. Add(' obj.onfoo();');
  8396. Add(' obj.onbar();');
  8397. Add(' obj.events[6]();');
  8398. //Add(' b:=obj.onfoo=nil;'); // fpc
  8399. //Add(' b:=obj.onbar=nil;'); // fpc
  8400. //Add(' b:=obj.events[7]=nil;'); // fpc
  8401. //Add(' b:=obj.onfoo<>nil;'); // fpc
  8402. //Add(' b:=obj.onbar<>nil;'); // fpc
  8403. //Add(' b:=obj.events[8]<>nil;'); // fpc
  8404. Add(' b:=obj.onfoo=vp;');
  8405. Add(' b:=obj.onbar=vp;');
  8406. //Add(' b:=obj.events[9]=vp;'); ToDo in pasresolver
  8407. Add(' b:=obj.onfoo=obj.onfoo;');
  8408. Add(' b:=obj.onbar=obj.onfoo;');
  8409. //Add(' b:=obj.events[10]=obj.onfoo;'); // ToDo in pasresolver
  8410. Add(' b:=obj.onfoo<>obj.onfoo;');
  8411. Add(' b:=obj.onbar<>obj.onfoo;');
  8412. //Add(' b:=obj.events[11]<>obj.onfoo;'); // ToDo in pasresolver
  8413. //Add(' b:[email protected];'); // fpc
  8414. //Add(' b:[email protected];'); // fpc
  8415. //Add(' b:=obj.events[12][email protected];'); // fpc
  8416. //Add(' b:=obj.onfoo<>@obj.doit;'); // fpc
  8417. //Add(' b:=obj.onbar<>@obj.doit;'); // fpc
  8418. //Add(' b:=obj.events[12]<>@obj.doit;'); // fpc
  8419. Add(' b:=Assigned(obj.onfoo);');
  8420. Add(' b:=Assigned(obj.onbar);');
  8421. Add(' b:=Assigned(obj.events[13]);');
  8422. ConvertProgram;
  8423. CheckSource('TestProcType_PropertyDelphi',
  8424. LinesToStr([ // statements
  8425. 'rtl.createClass(this, "TObject", null, function () {',
  8426. ' this.$init = function () {',
  8427. ' this.FOnFoo = null;',
  8428. ' };',
  8429. ' this.$final = function () {',
  8430. ' this.FOnFoo = undefined;',
  8431. ' };',
  8432. ' this.DoIt = function (vA) {',
  8433. ' var Result = 0;',
  8434. ' return Result;',
  8435. ' };',
  8436. 'this.GetFoo = function () {',
  8437. ' var Result = null;',
  8438. ' return Result;',
  8439. '};',
  8440. 'this.SetFoo = function (Value) {',
  8441. '};',
  8442. 'this.GetEvents = function (Index) {',
  8443. ' var Result = null;',
  8444. ' return Result;',
  8445. '};',
  8446. 'this.SetEvents = function (Index, Value) {',
  8447. '};',
  8448. '});',
  8449. 'this.Obj = null;',
  8450. 'this.vP = null;',
  8451. 'this.b = false;'
  8452. ]),
  8453. LinesToStr([
  8454. 'this.Obj.FOnFoo = null;',
  8455. 'this.Obj.SetFoo(null);',
  8456. 'this.Obj.SetEvents(1, null);',
  8457. 'this.Obj.FOnFoo = this.Obj.FOnFoo;',
  8458. 'this.Obj.SetFoo(this.Obj.GetFoo());',
  8459. 'this.Obj.SetEvents(2, this.Obj.GetEvents(3));',
  8460. 'this.Obj.FOnFoo = rtl.createCallback(this.Obj, "DoIt");',
  8461. 'this.Obj.SetFoo(rtl.createCallback(this.Obj, "DoIt"));',
  8462. 'this.Obj.SetEvents(4, rtl.createCallback(this.Obj, "DoIt"));',
  8463. 'this.Obj.FOnFoo = rtl.createCallback(this.Obj, "DoIt");',
  8464. 'this.Obj.SetFoo(rtl.createCallback(this.Obj, "DoIt"));',
  8465. 'this.Obj.SetEvents(4, rtl.createCallback(this.Obj, "DoIt"));',
  8466. 'this.Obj.FOnFoo(1);',
  8467. 'this.Obj.GetFoo();',
  8468. 'this.Obj.FOnFoo(1);',
  8469. 'this.Obj.GetFoo()(1);',
  8470. 'this.Obj.GetEvents(6)(1);',
  8471. 'this.b = this.Obj.FOnFoo(1) == this.vP(1);',
  8472. 'this.b = this.Obj.GetFoo() == this.vP(1);',
  8473. 'this.b = this.Obj.FOnFoo(1) == this.Obj.FOnFoo(1);',
  8474. 'this.b = this.Obj.GetFoo() == this.Obj.FOnFoo(1);',
  8475. 'this.b = this.Obj.FOnFoo(1) != this.Obj.FOnFoo(1);',
  8476. 'this.b = this.Obj.GetFoo() != this.Obj.FOnFoo(1);',
  8477. 'this.b = this.Obj.FOnFoo != null;',
  8478. 'this.b = this.Obj.GetFoo() != null;',
  8479. 'this.b = this.Obj.GetEvents(13) != null;',
  8480. '']));
  8481. end;
  8482. procedure TTestModule.TestProcType_WithClassInstDoPropertyFPC;
  8483. begin
  8484. StartProgram(false);
  8485. Add('type');
  8486. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  8487. Add(' TObject = class');
  8488. Add(' FOnFoo: TFuncInt;');
  8489. Add(' function DoIt(vA: longint = 1): longint;');
  8490. Add(' function GetFoo: TFuncInt;');
  8491. Add(' procedure SetFoo(const Value: TFuncInt);');
  8492. Add(' property OnFoo: TFuncInt read FOnFoo write FOnFoo;');
  8493. Add(' property OnBar: TFuncInt read GetFoo write SetFoo;');
  8494. Add(' end;');
  8495. Add('function tobject.doit(va: longint = 1): longint; begin end;');
  8496. Add('function tobject.getfoo: tfuncint; begin end;');
  8497. Add('procedure tobject.setfoo(const value: tfuncint); begin end;');
  8498. Add('var');
  8499. Add(' Obj: TObject;');
  8500. Add(' vP: tfuncint;');
  8501. Add(' b: boolean;');
  8502. Add('begin');
  8503. Add('with obj do begin');
  8504. Add(' fonfoo:=nil;');
  8505. Add(' onfoo:=nil;');
  8506. Add(' onbar:=nil;');
  8507. Add(' fonfoo:=fonfoo;');
  8508. Add(' onfoo:=onfoo;');
  8509. Add(' onbar:=onbar;');
  8510. Add(' fonfoo:=@doit;');
  8511. Add(' onfoo:=@doit;');
  8512. Add(' onbar:=@doit;');
  8513. //Add(' fonfoo:=doit;'); // delphi
  8514. //Add(' onfoo:=doit;'); // delphi
  8515. //Add(' onbar:=doit;'); // delphi
  8516. Add(' fonfoo;');
  8517. Add(' onfoo;');
  8518. Add(' onbar;');
  8519. Add(' fonfoo();');
  8520. Add(' onfoo();');
  8521. Add(' onbar();');
  8522. Add(' b:=fonfoo=nil;');
  8523. Add(' b:=onfoo=nil;');
  8524. Add(' b:=onbar=nil;');
  8525. Add(' b:=fonfoo<>nil;');
  8526. Add(' b:=onfoo<>nil;');
  8527. Add(' b:=onbar<>nil;');
  8528. Add(' b:=fonfoo=vp;');
  8529. Add(' b:=onfoo=vp;');
  8530. Add(' b:=onbar=vp;');
  8531. Add(' b:=fonfoo=fonfoo;');
  8532. Add(' b:=onfoo=onfoo;');
  8533. Add(' b:=onbar=onfoo;');
  8534. Add(' b:=fonfoo<>fonfoo;');
  8535. Add(' b:=onfoo<>onfoo;');
  8536. Add(' b:=onbar<>onfoo;');
  8537. Add(' b:=fonfoo=@doit;');
  8538. Add(' b:=onfoo=@doit;');
  8539. Add(' b:=onbar=@doit;');
  8540. Add(' b:=fonfoo<>@doit;');
  8541. Add(' b:=onfoo<>@doit;');
  8542. Add(' b:=onbar<>@doit;');
  8543. Add(' b:=Assigned(fonfoo);');
  8544. Add(' b:=Assigned(onfoo);');
  8545. Add(' b:=Assigned(onbar);');
  8546. Add('end;');
  8547. ConvertProgram;
  8548. CheckSource('TestProcType_WithClassInstDoPropertyFPC',
  8549. LinesToStr([ // statements
  8550. 'rtl.createClass(this, "TObject", null, function () {',
  8551. ' this.$init = function () {',
  8552. ' this.FOnFoo = null;',
  8553. ' };',
  8554. ' this.$final = function () {',
  8555. ' this.FOnFoo = undefined;',
  8556. ' };',
  8557. ' this.DoIt = function (vA) {',
  8558. ' var Result = 0;',
  8559. ' return Result;',
  8560. ' };',
  8561. ' this.GetFoo = function () {',
  8562. ' var Result = null;',
  8563. ' return Result;',
  8564. ' };',
  8565. ' this.SetFoo = function (Value) {',
  8566. ' };',
  8567. '});',
  8568. 'this.Obj = null;',
  8569. 'this.vP = null;',
  8570. 'this.b = false;'
  8571. ]),
  8572. LinesToStr([
  8573. 'var $with1 = this.Obj;',
  8574. '$with1.FOnFoo = null;',
  8575. '$with1.FOnFoo = null;',
  8576. '$with1.SetFoo(null);',
  8577. '$with1.FOnFoo = $with1.FOnFoo;',
  8578. '$with1.FOnFoo = $with1.FOnFoo;',
  8579. '$with1.SetFoo($with1.GetFoo());',
  8580. '$with1.FOnFoo = rtl.createCallback($with1, "DoIt");',
  8581. '$with1.FOnFoo = rtl.createCallback($with1, "DoIt");',
  8582. '$with1.SetFoo(rtl.createCallback($with1, "DoIt"));',
  8583. '$with1.FOnFoo(1);',
  8584. '$with1.FOnFoo(1);',
  8585. '$with1.GetFoo();',
  8586. '$with1.FOnFoo(1);',
  8587. '$with1.FOnFoo(1);',
  8588. '$with1.GetFoo()(1);',
  8589. 'this.b = $with1.FOnFoo == null;',
  8590. 'this.b = $with1.FOnFoo == null;',
  8591. 'this.b = $with1.GetFoo() == null;',
  8592. 'this.b = $with1.FOnFoo != null;',
  8593. 'this.b = $with1.FOnFoo != null;',
  8594. 'this.b = $with1.GetFoo() != null;',
  8595. 'this.b = rtl.eqCallback($with1.FOnFoo, this.vP);',
  8596. 'this.b = rtl.eqCallback($with1.FOnFoo, this.vP);',
  8597. 'this.b = rtl.eqCallback($with1.GetFoo(), this.vP);',
  8598. 'this.b = rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  8599. 'this.b = rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  8600. 'this.b = rtl.eqCallback($with1.GetFoo(), $with1.FOnFoo);',
  8601. 'this.b = !rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  8602. 'this.b = !rtl.eqCallback($with1.FOnFoo, $with1.FOnFoo);',
  8603. 'this.b = !rtl.eqCallback($with1.GetFoo(), $with1.FOnFoo);',
  8604. 'this.b = rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  8605. 'this.b = rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  8606. 'this.b = rtl.eqCallback($with1.GetFoo(), rtl.createCallback($with1, "DoIt"));',
  8607. 'this.b = !rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  8608. 'this.b = !rtl.eqCallback($with1.FOnFoo, rtl.createCallback($with1, "DoIt"));',
  8609. 'this.b = !rtl.eqCallback($with1.GetFoo(), rtl.createCallback($with1, "DoIt"));',
  8610. 'this.b = $with1.FOnFoo != null;',
  8611. 'this.b = $with1.FOnFoo != null;',
  8612. 'this.b = $with1.GetFoo() != null;',
  8613. '']));
  8614. end;
  8615. procedure TTestModule.TestJSValue_AssignToJSValue;
  8616. begin
  8617. StartProgram(false);
  8618. Add('var');
  8619. Add(' v: jsvalue;');
  8620. Add(' i: longint;');
  8621. Add(' s: string;');
  8622. Add(' b: boolean;');
  8623. Add(' d: double;');
  8624. Add('begin');
  8625. Add(' v:=v;');
  8626. Add(' v:=1;');
  8627. Add(' v:=i;');
  8628. Add(' v:='''';');
  8629. Add(' v:=''c'';');
  8630. Add(' v:=''foo'';');
  8631. Add(' v:=s;');
  8632. Add(' v:=false;');
  8633. Add(' v:=true;');
  8634. Add(' v:=b;');
  8635. Add(' v:=0.1;');
  8636. Add(' v:=d;');
  8637. Add(' v:=nil;');
  8638. ConvertProgram;
  8639. CheckSource('TestJSValue_AssignToJSValue',
  8640. LinesToStr([ // statements
  8641. 'this.v = undefined;',
  8642. 'this.i = 0;',
  8643. 'this.s = "";',
  8644. 'this.b = false;',
  8645. 'this.d = 0.0;',
  8646. '']),
  8647. LinesToStr([ // this.$main
  8648. 'this.v = this.v;',
  8649. 'this.v = 1;',
  8650. 'this.v = this.i;',
  8651. 'this.v = "";',
  8652. 'this.v = "c";',
  8653. 'this.v = "foo";',
  8654. 'this.v = this.s;',
  8655. 'this.v = false;',
  8656. 'this.v = true;',
  8657. 'this.v = this.b;',
  8658. 'this.v = 0.1;',
  8659. 'this.v = this.d;',
  8660. 'this.v = null;',
  8661. '']));
  8662. end;
  8663. procedure TTestModule.TestJSValue_TypeCastToBaseType;
  8664. begin
  8665. StartProgram(false);
  8666. Add('type');
  8667. Add(' integer = longint;');
  8668. Add(' TYesNo = boolean;');
  8669. Add(' TFloat = double;');
  8670. Add(' TCaption = string;');
  8671. Add(' TChar = char;');
  8672. Add('var');
  8673. Add(' v: jsvalue;');
  8674. Add(' i: integer;');
  8675. Add(' s: TCaption;');
  8676. Add(' b: TYesNo;');
  8677. Add(' d: TFloat;');
  8678. Add(' c: char;');
  8679. Add('begin');
  8680. Add(' i:=longint(v);');
  8681. Add(' i:=integer(v);');
  8682. Add(' s:=string(v);');
  8683. Add(' s:=TCaption(v);');
  8684. Add(' b:=boolean(v);');
  8685. Add(' b:=TYesNo(v);');
  8686. Add(' d:=double(v);');
  8687. Add(' d:=TFloat(v);');
  8688. Add(' c:=char(v);');
  8689. Add(' c:=TChar(v);');
  8690. ConvertProgram;
  8691. CheckSource('TestJSValue_TypeCastToBaseType',
  8692. LinesToStr([ // statements
  8693. 'this.v = undefined;',
  8694. 'this.i = 0;',
  8695. 'this.s = "";',
  8696. 'this.b = false;',
  8697. 'this.d = 0.0;',
  8698. 'this.c = "";',
  8699. '']),
  8700. LinesToStr([ // this.$main
  8701. 'this.i = Math.floor(this.v);',
  8702. 'this.i = Math.floor(this.v);',
  8703. 'this.s = "" + this.v;',
  8704. 'this.s = "" + this.v;',
  8705. 'this.b = !(this.v == false);',
  8706. 'this.b = !(this.v == false);',
  8707. 'this.d = rtl.getNumber(this.v);',
  8708. 'this.d = rtl.getNumber(this.v);',
  8709. 'this.c = rtl.getChar(this.v);',
  8710. 'this.c = rtl.getChar(this.v);',
  8711. '']));
  8712. end;
  8713. procedure TTestModule.TestJSValue_Enum;
  8714. begin
  8715. StartProgram(false);
  8716. Add('type');
  8717. Add(' TColor = (red, blue);');
  8718. Add(' TRedBlue = TColor;');
  8719. Add('var');
  8720. Add(' v: jsvalue;');
  8721. Add(' e: TColor;');
  8722. Add('begin');
  8723. Add(' v:=e;');
  8724. Add(' v:=TColor(e);');
  8725. Add(' v:=TRedBlue(e);');
  8726. Add(' e:=TColor(v);');
  8727. Add(' e:=TRedBlue(v);');
  8728. ConvertProgram;
  8729. CheckSource('TestJSValue_Enum',
  8730. LinesToStr([ // statements
  8731. 'this.TColor = {',
  8732. ' "0": "red",',
  8733. ' red: 0,',
  8734. ' "1": "blue",',
  8735. ' blue: 1',
  8736. '};',
  8737. 'this.v = undefined;',
  8738. 'this.e = 0;',
  8739. '']),
  8740. LinesToStr([ // this.$main
  8741. 'this.v = this.e;',
  8742. 'this.v = this.e;',
  8743. 'this.v = this.e;',
  8744. 'this.e = this.v;',
  8745. 'this.e = this.v;',
  8746. '']));
  8747. end;
  8748. procedure TTestModule.TestJSValue_ClassInstance;
  8749. begin
  8750. StartProgram(false);
  8751. Add('type');
  8752. Add(' TObject = class');
  8753. Add(' end;');
  8754. Add(' TBirdObject = TObject;');
  8755. Add('var');
  8756. Add(' v: jsvalue;');
  8757. Add(' o: TObject;');
  8758. Add('begin');
  8759. Add(' v:=o;');
  8760. Add(' v:=TObject(o);');
  8761. Add(' v:=TBirdObject(o);');
  8762. Add(' o:=TObject(v);');
  8763. Add(' o:=TBirdObject(v);');
  8764. ConvertProgram;
  8765. CheckSource('TestJSValue_ClassInstance',
  8766. LinesToStr([ // statements
  8767. 'rtl.createClass(this, "TObject", null, function () {',
  8768. ' this.$init = function () {',
  8769. ' };',
  8770. ' this.$final = function () {',
  8771. ' };',
  8772. '});',
  8773. 'this.v = undefined;',
  8774. 'this.o = null;',
  8775. '']),
  8776. LinesToStr([ // this.$main
  8777. 'this.v = this.o;',
  8778. 'this.v = this.o;',
  8779. 'this.v = this.o;',
  8780. 'this.o = rtl.getObject(this.v);',
  8781. 'this.o = rtl.getObject(this.v);',
  8782. '']));
  8783. end;
  8784. procedure TTestModule.TestJSValue_ClassOf;
  8785. begin
  8786. StartProgram(false);
  8787. Add('type');
  8788. Add(' TClass = class of TObject;');
  8789. Add(' TObject = class');
  8790. Add(' end;');
  8791. Add(' TBirds = class of TBird;');
  8792. Add(' TBird = class(TObject) end;');
  8793. Add('var');
  8794. Add(' v: jsvalue;');
  8795. Add(' c: TClass;');
  8796. Add('begin');
  8797. Add(' v:=c;');
  8798. Add(' v:=TClass(c);');
  8799. Add(' v:=TBirds(c);');
  8800. Add(' c:=TClass(v);');
  8801. Add(' c:=TBirds(v);');
  8802. ConvertProgram;
  8803. CheckSource('TestJSValue_ClassOf',
  8804. LinesToStr([ // statements
  8805. 'rtl.createClass(this, "TObject", null, function () {',
  8806. ' this.$init = function () {',
  8807. ' };',
  8808. ' this.$final = function () {',
  8809. ' };',
  8810. '});',
  8811. 'rtl.createClass(this, "TBird", this.TObject, function () {',
  8812. '});',
  8813. 'this.v = undefined;',
  8814. 'this.c = null;',
  8815. '']),
  8816. LinesToStr([ // this.$main
  8817. 'this.v = this.c;',
  8818. 'this.v = this.c;',
  8819. 'this.v = this.c;',
  8820. 'this.c = rtl.getObject(this.v);',
  8821. 'this.c = rtl.getObject(this.v);',
  8822. '']));
  8823. end;
  8824. procedure TTestModule.TestJSValue_ArrayOfJSValue;
  8825. begin
  8826. StartProgram(false);
  8827. Add('type');
  8828. Add(' integer = longint;');
  8829. Add(' TArray = array of JSValue;');
  8830. Add(' TArrgh = tarray;');
  8831. Add('var');
  8832. Add(' v: jsvalue;');
  8833. Add(' TheArray: TArray;');
  8834. Add(' Arr: TArrgh;');
  8835. Add(' i: integer;');
  8836. Add('begin');
  8837. Add(' Arr:=TheArray;');
  8838. Add(' TheArray:=Arr;');
  8839. Add(' SetLength(Arr,2);');
  8840. Add(' SetLength(TheArray,3);');
  8841. Add(' Arr[4]:=v;');
  8842. Add(' Arr[5]:=i;');
  8843. Add(' Arr[6]:=nil;');
  8844. Add(' Arr[7]:=TheArray[8];');
  8845. ConvertProgram;
  8846. CheckSource('TestJSValue_ArrayOfJSValue',
  8847. LinesToStr([ // statements
  8848. 'this.v = undefined;',
  8849. 'this.TheArray = [];',
  8850. 'this.Arr = [];',
  8851. 'this.i = 0;',
  8852. '']),
  8853. LinesToStr([ // this.$main
  8854. 'this.Arr = this.TheArray;',
  8855. 'this.TheArray = this.Arr;',
  8856. 'this.Arr.length = 2;',
  8857. 'this.TheArray.length = 3;',
  8858. 'this.Arr[4] = this.v;',
  8859. 'this.Arr[5] = this.i;',
  8860. 'this.Arr[6] = null;',
  8861. 'this.Arr[7] = this.TheArray[8];',
  8862. '']));
  8863. end;
  8864. procedure TTestModule.TestJSValue_Params;
  8865. begin
  8866. StartProgram(false);
  8867. Add('type');
  8868. Add(' integer = longint;');
  8869. Add(' TYesNo = boolean;');
  8870. Add(' TFloat = double;');
  8871. Add(' TCaption = string;');
  8872. Add(' TChar = char;');
  8873. Add('function DoIt(a: jsvalue; const b: jsvalue; var c: jsvalue; out d: jsvalue): jsvalue;');
  8874. Add('var');
  8875. Add(' l: jsvalue;');
  8876. Add('begin');
  8877. Add(' a:=a;');
  8878. Add(' l:=b;');
  8879. Add(' c:=c;');
  8880. Add(' d:=d;');
  8881. Add(' Result:=l;');
  8882. Add('end;');
  8883. Add('function DoSome(a: jsvalue; const b: jsvalue): jsvalue; begin end;');
  8884. Add('var');
  8885. Add(' v: jsvalue;');
  8886. Add(' i: integer;');
  8887. Add(' b: TYesNo;');
  8888. Add(' d: TFloat;');
  8889. Add(' s: TCaption;');
  8890. Add(' c: TChar;');
  8891. Add('begin');
  8892. Add(' v:=doit(v,v,v,v);');
  8893. Add(' i:=integer(dosome(i,i));');
  8894. Add(' b:=TYesNo(dosome(b,b));');
  8895. Add(' d:=TFloat(dosome(d,d));');
  8896. Add(' s:=TCaption(dosome(s,s));');
  8897. Add(' c:=TChar(dosome(c,c));');
  8898. ConvertProgram;
  8899. CheckSource('TestJSValue_Params',
  8900. LinesToStr([ // statements
  8901. 'this.DoIt = function (a, b, c, d) {',
  8902. ' var Result = undefined;',
  8903. ' var l = undefined;',
  8904. ' a = a;',
  8905. ' l = b;',
  8906. ' c.set(c.get());',
  8907. ' d.set(d.get());',
  8908. ' Result = l;',
  8909. ' return Result;',
  8910. '};',
  8911. 'this.DoSome = function (a, b) {',
  8912. ' var Result = undefined;',
  8913. ' return Result;',
  8914. '};',
  8915. 'this.v = undefined;',
  8916. 'this.i = 0;',
  8917. 'this.b = false;',
  8918. 'this.d = 0.0;',
  8919. 'this.s = "";',
  8920. 'this.c = "";',
  8921. '']),
  8922. LinesToStr([ // this.$main
  8923. 'this.v = this.DoIt(this.v, this.v, {',
  8924. ' p: this,',
  8925. ' get: function () {',
  8926. ' return this.p.v;',
  8927. ' },',
  8928. ' set: function (v) {',
  8929. ' this.p.v = v;',
  8930. ' }',
  8931. '}, {',
  8932. ' p: this,',
  8933. ' get: function () {',
  8934. ' return this.p.v;',
  8935. ' },',
  8936. ' set: function (v) {',
  8937. ' this.p.v = v;',
  8938. ' }',
  8939. '});',
  8940. 'this.i = Math.floor(this.DoSome(this.i, this.i));',
  8941. 'this.b = !(this.DoSome(this.b, this.b) == false);',
  8942. 'this.d = rtl.getNumber(this.DoSome(this.d, this.d));',
  8943. 'this.s = "" + this.DoSome(this.s, this.s);',
  8944. 'this.c = rtl.getChar(this.DoSome(this.c, this.c));',
  8945. '']));
  8946. end;
  8947. procedure TTestModule.TestJSValue_UntypedParam;
  8948. begin
  8949. StartProgram(false);
  8950. Add('function DoIt(const a; var b; out c): jsvalue;');
  8951. Add('begin');
  8952. Add(' Result:=a;');
  8953. Add(' Result:=b;');
  8954. Add(' Result:=c;');
  8955. Add(' b:=Result;');
  8956. Add(' c:=Result;');
  8957. Add('end;');
  8958. Add('var i: longint;');
  8959. Add('begin');
  8960. Add(' doit(i,i,i);');
  8961. ConvertProgram;
  8962. CheckSource('TestJSValue_UntypedParam',
  8963. LinesToStr([ // statements
  8964. 'this.DoIt = function (a, b, c) {',
  8965. ' var Result = undefined;',
  8966. ' Result = a;',
  8967. ' Result = b.get();',
  8968. ' Result = c.get();',
  8969. ' b.set(Result);',
  8970. ' c.set(Result);',
  8971. ' return Result;',
  8972. '};',
  8973. 'this.i = 0;',
  8974. '']),
  8975. LinesToStr([ // this.$main
  8976. 'this.DoIt(this.i, {',
  8977. ' p: this,',
  8978. ' get: function () {',
  8979. ' return this.p.i;',
  8980. ' },',
  8981. ' set: function (v) {',
  8982. ' this.p.i = v;',
  8983. ' }',
  8984. '}, {',
  8985. ' p: this,',
  8986. ' get: function () {',
  8987. ' return this.p.i;',
  8988. ' },',
  8989. ' set: function (v) {',
  8990. ' this.p.i = v;',
  8991. ' }',
  8992. '});',
  8993. '']));
  8994. end;
  8995. procedure TTestModule.TestJSValue_FuncType;
  8996. begin
  8997. StartProgram(false);
  8998. Add('type');
  8999. Add(' integer = longint;');
  9000. Add(' TJSValueArray = array of JSValue;');
  9001. Add(' TListSortCompare = function(Item1, Item2: JSValue): Integer;');
  9002. Add('procedure Sort(P: JSValue; aList: TJSValueArray; const Compare: TListSortCompare);');
  9003. Add('begin');
  9004. Add(' while Compare(P,aList[0])>0 do ;');
  9005. Add('end;');
  9006. Add('var');
  9007. Add(' Compare: TListSortCompare;');
  9008. Add(' V: JSValue;');
  9009. Add(' i: integer;');
  9010. Add('begin');
  9011. Add(' if Compare(V,V)>0 then ;');
  9012. Add(' if Compare(i,i)>1 then ;');
  9013. Add(' if Compare(nil,false)>2 then ;');
  9014. Add(' if Compare(1,true)>3 then ;');
  9015. ConvertProgram;
  9016. CheckSource('TestJSValue_UntypedParam',
  9017. LinesToStr([ // statements
  9018. 'this.Sort = function (P, aList, Compare) {',
  9019. ' while (Compare(P, aList[0]) > 0) {',
  9020. ' };',
  9021. '};',
  9022. 'this.Compare = null;',
  9023. 'this.V = undefined;',
  9024. 'this.i = 0;',
  9025. '']),
  9026. LinesToStr([ // this.$main
  9027. 'if (this.Compare(this.V, this.V) > 0) ;',
  9028. 'if (this.Compare(this.i, this.i) > 1) ;',
  9029. 'if (this.Compare(null, false) > 2) ;',
  9030. 'if (this.Compare(1, true) > 3) ;',
  9031. '']));
  9032. end;
  9033. Initialization
  9034. RegisterTests([TTestModule]);
  9035. end.