tcresolver.pas 517 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640
  1. {
  2. Examples:
  3. ./testpassrc --suite=TTestResolver.TestEmpty
  4. }
  5. (*
  6. CheckReferenceDirectives:
  7. {#a} label "a", labels all elements at the following token
  8. {@a} reference "a", search at next token for an element e with
  9. TResolvedReference(e.CustomData).Declaration points to an element
  10. labeled "a".
  11. {=a} is "a", search at next token for a TPasAliasType t with t.DestType
  12. points to an element labeled "a"
  13. *)
  14. unit TCResolver;
  15. {$mode objfpc}
  16. {$H+}
  17. {$codepage Utf8}
  18. {$DEFINE NOCONSOLE}
  19. interface
  20. uses
  21. Classes, SysUtils, contnrs, strutils, fpcunit, testregistry,
  22. PasTree, PScanner, PParser, PasResolver, PasResolveEval,
  23. tcbaseparser;
  24. type
  25. TSrcMarkerKind = (
  26. mkLabel,
  27. mkResolverReference,
  28. mkDirectReference
  29. );
  30. PSrcMarker = ^TSrcMarker;
  31. TSrcMarker = record
  32. Kind: TSrcMarkerKind;
  33. Filename: string;
  34. Row: cardinal;
  35. StartCol, EndCol: integer; // token start, end column
  36. Identifier: string;
  37. Param: string;
  38. Next: PSrcMarker;
  39. end;
  40. const
  41. SrcMarker: array[TSrcMarkerKind] of AnsiChar = (
  42. '#', // mkLabel
  43. '@', // mkResolverReference
  44. '=' // mkDirectReference
  45. );
  46. type
  47. TOnFindUnit = function(Sender: TPasResolver;
  48. const aUnitName, InFilename: String;
  49. NameExpr, InFileExpr: TPasExpr): TPasModule of object;
  50. TOnContinueParsing = procedure(Sender: TPasResolver) of object;
  51. { TTestEnginePasResolver }
  52. TTestEnginePasResolver = class(TPasResolver)
  53. private
  54. FFilename: string;
  55. FModule: TPasModule;
  56. FOnFindUnit: TOnFindUnit;
  57. FParser: TPasParser;
  58. FStreamResolver: TStreamResolver;
  59. FScanner: TPascalScanner;
  60. FSource: string;
  61. procedure SetModule(AValue: TPasModule);
  62. public
  63. constructor Create;
  64. destructor Destroy; override;
  65. function CreateElement(AClass: TPTreeElement; const AName: String;
  66. AParent: TPasElement; AVisibility: TPasMemberVisibility;
  67. const ASrcPos: TPasSourcePos; TypeParams: TFPList = nil): TPasElement;
  68. overload; override;
  69. function FindUnit(const AName, InFilename: String; NameExpr,
  70. InFileExpr: TPasExpr): TPasModule; override;
  71. procedure UsedInterfacesFinished(Section: TPasSection); override;
  72. property OnFindUnit: TOnFindUnit read FOnFindUnit write FOnFindUnit;
  73. property Filename: string read FFilename write FFilename;
  74. property StreamResolver: TStreamResolver read FStreamResolver write FStreamResolver;
  75. property Scanner: TPascalScanner read FScanner write FScanner;
  76. property Parser: TPasParser read FParser write FParser;
  77. property Source: string read FSource write FSource;
  78. property Module: TPasModule read FModule write SetModule;
  79. end;
  80. { TTestResolverMessage }
  81. TTestResolverMessage = class
  82. public
  83. Id: int64;
  84. MsgType: TMessageType;
  85. MsgNumber: integer;
  86. Msg: string;
  87. SourcePos: TPasSourcePos;
  88. end;
  89. TTestResolverReferenceData = record
  90. Filename: string;
  91. Row: integer;
  92. StartCol: integer;
  93. EndCol: integer;
  94. Found: TFPList; // list of TPasElement at this token
  95. end;
  96. PTestResolverReferenceData = ^TTestResolverReferenceData;
  97. TSystemUnitPart = (
  98. supTObject,
  99. supTVarRec,
  100. supTTypeKind
  101. );
  102. TSystemUnitParts = set of TSystemUnitPart;
  103. { TCustomTestResolver }
  104. TCustomTestResolver = Class(TTestParser)
  105. Private
  106. FHub: TPasResolverHub;
  107. FFirstStatement: TPasImplBlock;
  108. FResolvers: TObjectList;// list of TTestEnginePasResolver
  109. FResolverEngine: TTestEnginePasResolver;
  110. FResolverMsgs: TObjectList; // list of TTestResolverMessage
  111. FResolverGoodMsgs: TFPList; // list of TTestResolverMessage marked as expected
  112. function GetModuleCount: integer;
  113. function GetModules(Index: integer): TTestEnginePasResolver;
  114. function GetMsgCount: integer;
  115. function GetMsgs(Index: integer): TTestResolverMessage;
  116. procedure OnPasResolverContinueParsing(Sender: TPasResolver);
  117. function OnPasResolverFindUnit(SrcResolver: TPasResolver;
  118. const aUnitName, InFilename: String; NameExpr, InFileExpr: TPasExpr): TPasModule;
  119. procedure OnFindReference(El: TPasElement; FindData: pointer);
  120. procedure OnCheckElementParent(El: TPasElement; arg: pointer);
  121. procedure FreeSrcMarkers;
  122. procedure OnPasResolverLog(Sender: TObject; const Msg: String);
  123. procedure OnScannerDirective(Sender: TObject; Directive, Param: TPasScannerString;
  124. var Handled: boolean);
  125. procedure OnScannerLog(Sender: TObject; const Msg: String);
  126. Protected
  127. FirstSrcMarker, LastSrcMarker: PSrcMarker;
  128. Procedure SetUp; override;
  129. Procedure TearDown; override;
  130. procedure CreateEngine(var TheEngine: TPasTreeContainer); override;
  131. procedure ParseModule; override;
  132. procedure ParseMain(ExpectedModuleClass: TPasModuleClass); virtual;
  133. procedure ParseProgram; virtual;
  134. procedure ParseLibrary; virtual;
  135. procedure ParseUnit; virtual;
  136. procedure CheckReferenceDirectives; virtual;
  137. procedure CheckResolverHint(MsgType: TMessageType; MsgNumber: integer;
  138. Msg: string; Marker: PSrcMarker = nil); virtual;
  139. procedure CheckResolverUnexpectedHints(WithSourcePos: boolean = false); virtual;
  140. procedure CheckResolverException(Msg: string; MsgNumber: integer);
  141. procedure CheckParserException(Msg: string; MsgNumber: integer);
  142. procedure CheckAccessMarkers; virtual;
  143. procedure CheckParamsExpr_pkSet_Markers; virtual;
  144. procedure CheckAttributeMarkers; virtual;
  145. procedure CheckRTTIVisibility(aMarker: PSrcMarker; El: TPasMembersType; Explicit: boolean;
  146. const ExpectedFields, ExpectedMethods, ExpectedProperties: TPasMembersType.TRTTIVisibilitySections); virtual;
  147. procedure CheckRTTIVisibilityMarkers; virtual;
  148. procedure GetSrc(Index: integer; out SrcLines: TStringList; out aFilename: string);
  149. function FindElementsAt(aFilename: string; aLine, aStartCol, aEndCol: integer): TFPList;// list of TPasElement
  150. function FindElementsAt(aMarker: PSrcMarker; ErrorOnNoElements: boolean = true): TFPList;// list of TPasElement
  151. function FindSrcLabel(const Identifier: string): PSrcMarker;
  152. function FindElementsAtSrcLabel(const Identifier: string; ErrorOnNoElements: boolean = true): TFPList;// list of TPasElement
  153. procedure WriteSources(const aFilename: string; aRow, aCol: integer);
  154. procedure RaiseErrorAtSrc(Msg: string; const aFilename: string; aRow, aCol: integer);
  155. procedure RaiseErrorAtSrcMarker(Msg: string; aMarker: PSrcMarker);
  156. procedure HandleError(CurEngine: TTestEnginePasResolver; E: Exception);
  157. Public
  158. constructor Create; override;
  159. destructor Destroy; override;
  160. function FindModuleWithFilename(aFilename: string): TTestEnginePasResolver;
  161. function AddModule(aFilename: string): TTestEnginePasResolver;
  162. function AddModuleWithSrc(aFilename, Src: string): TTestEnginePasResolver;
  163. function AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  164. ImplementationSrc: string): TTestEnginePasResolver;
  165. procedure AddSystemUnit(Parts: TSystemUnitParts = []);
  166. procedure StartProgram(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []);
  167. procedure StartLibrary(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []);
  168. procedure StartUnit(NeedSystemUnit: boolean; SystemUnitParts: TSystemUnitParts = []);
  169. property Modules[Index: integer]: TTestEnginePasResolver read GetModules;
  170. property ModuleCount: integer read GetModuleCount;
  171. property Hub: TPasResolverHub read FHub;
  172. property ResolverEngine: TTestEnginePasResolver read FResolverEngine;
  173. property MsgCount: integer read GetMsgCount;
  174. property Msgs[Index: integer]: TTestResolverMessage read GetMsgs;
  175. end;
  176. { TTestResolver }
  177. TTestResolver = Class(TCustomTestResolver)
  178. Published
  179. Procedure TestEmpty;
  180. // alias
  181. Procedure TestAliasType;
  182. Procedure TestAlias2Type;
  183. Procedure TestAliasTypeRefs;
  184. Procedure TestAliasOfVarFail;
  185. Procedure TestAliasType_UnitPrefix;
  186. Procedure TestAliasType_UnitPrefix_CycleFail;
  187. Procedure TestAliasTypeNotFoundPosition;
  188. Procedure TestTypeAliasType;
  189. // vars, const
  190. Procedure TestVarLongint;
  191. Procedure TestVarInteger;
  192. Procedure TestConstInteger;
  193. Procedure TestConstInteger2;
  194. Procedure TestDuplicateVar;
  195. Procedure TestVarInitConst;
  196. Procedure TestVarOfVarFail;
  197. Procedure TestConstOfVarFail;
  198. Procedure TestConstSelfFail;
  199. Procedure TestTypedConstWrongExprFail;
  200. Procedure TestVarWrongExprFail;
  201. Procedure TestArgWrongExprFail;
  202. Procedure TestTypedConstInConstExprFail;
  203. Procedure TestVarExternal;
  204. Procedure TestVarNoSemicolonBeginFail;
  205. Procedure TestConstIntOperators;
  206. Procedure TestConstBitwiseOps;
  207. Procedure TestConstExternal;
  208. Procedure TestIntegerTypeCast;
  209. Procedure TestConstFloatOperators;
  210. Procedure TestFloatTypeCast;
  211. Procedure TestCurrency;
  212. Procedure TestWritableConst;
  213. Procedure TestWritableConst_AssignFail;
  214. Procedure TestWritableConst_PassVarFail;
  215. // boolean
  216. Procedure TestBoolTypeCast;
  217. Procedure TestConstBoolOperators;
  218. Procedure TestBoolSet_Const;
  219. Procedure TestBool_ForIn;
  220. Procedure TestBool_Assert;
  221. Procedure TestBool_AssertSysutils;
  222. // integer range
  223. Procedure TestIntegerRange;
  224. Procedure TestIntegerRangeHighLowerLowFail;
  225. Procedure TestIntegerRangeLowHigh;
  226. Procedure TestAssignIntRangeWarning;
  227. Procedure TestByteRangeWarning;
  228. Procedure TestByteRangeWarningOff;
  229. Procedure TestCustomIntRangeWarning;
  230. Procedure TestIntSet_Const;
  231. Procedure TestIntSet_ConstDuplicateElement;
  232. Procedure TestInt_ForIn;
  233. // strings
  234. Procedure TestChar_BuiltInProcs;
  235. Procedure TestString_BuiltInProcs;
  236. Procedure TestString_Element;
  237. Procedure TestStringElement_MissingArgFail;
  238. Procedure TestStringElement_IndexNonIntFail;
  239. Procedure TestStringElement_AsVarArgFail;
  240. Procedure TestString_DoubleQuotesFail;
  241. Procedure TestString_ShortstringType;
  242. Procedure TestConstStringOperators;
  243. Procedure TestConstUnicodeStringOperators;
  244. Procedure TestCharSet_Const;
  245. Procedure TestCharSet_Custom;
  246. Procedure TestCharAssignStringFail;
  247. Procedure TestChar_ForIn;
  248. // enums and sets
  249. Procedure TestEnums;
  250. Procedure TestEnumRangeFail;
  251. Procedure TestEnumDotValueFail;
  252. Procedure TestSets;
  253. Procedure TestSetOperators;
  254. Procedure TestEnumParams;
  255. Procedure TestSetParams;
  256. Procedure TestSetFunctions;
  257. Procedure TestEnumHighLow;
  258. Procedure TestEnumOrd;
  259. Procedure TestEnumPredSucc;
  260. Procedure TestEnum_EqualNilFail;
  261. Procedure TestEnum_CastIntegerToEnum;
  262. Procedure TestEnum_Str;
  263. Procedure TestConstEnumOperators;
  264. Procedure TestEnumSetConstRange;
  265. Procedure TestEnumSet_AnonymousEnumtype;
  266. Procedure TestEnumSet_AnonymousEnumtypeName;
  267. Procedure TestEnumSet_Const;
  268. Procedure TestSet_IntRange_Const;
  269. Procedure TestSet_Byte_Const;
  270. Procedure TestEnumRange;
  271. Procedure TestEnum_ForIn;
  272. Procedure TestEnum_ForInRangeFail;
  273. Procedure TestEnum_ScopedEnums;
  274. Procedure TestEnum_ScopedEnumsFail;
  275. // operators
  276. Procedure TestPrgAssignment;
  277. Procedure TestPrgProcVar;
  278. Procedure TestUnitProcVar;
  279. Procedure TestAssignIntegers;
  280. Procedure TestAssignString;
  281. Procedure TestAssignIntToStringFail;
  282. Procedure TestAssignStringToIntFail;
  283. Procedure TestIntegerOperators;
  284. Procedure TestIntegerBoolFail;
  285. Procedure TestBooleanOperators;
  286. Procedure TestStringOperators;
  287. Procedure TestWideCharOperators_DelphiUnicode;
  288. Procedure TestFloatOperators;
  289. Procedure TestCAssignments;
  290. Procedure TestTypeCastBaseTypes;
  291. Procedure TestTypeCastAliasBaseTypes;
  292. Procedure TestTypeCastStrToIntFail;
  293. Procedure TestTypeCastStrToCharFail;
  294. Procedure TestTypeCastIntToStrFail;
  295. Procedure TestTypeCastDoubleToStrFail;
  296. Procedure TestTypeCastDoubleToIntFail;
  297. Procedure TestTypeCastDoubleToBoolFail;
  298. Procedure TestTypeCastBooleanToDoubleFail;
  299. Procedure TestAssign_Access;
  300. Procedure TestAssignedIntFail;
  301. // misc built-in functions
  302. Procedure TestHighLow;
  303. Procedure TestStr_BaseTypes;
  304. Procedure TestStr_StringFail;
  305. Procedure TestStr_CharFail;
  306. Procedure TestIncDec;
  307. Procedure TestIncStringFail;
  308. Procedure TestTypeInfo;
  309. Procedure TestTypeInfo_FailRTTIDisabled;
  310. Procedure TestGetTypeKind;
  311. // statements
  312. Procedure TestForLoop;
  313. Procedure TestForLoop_NestedSameVarFail;
  314. Procedure TestForLoop_AssignVarFail;
  315. Procedure TestForLoop_PassVarFail;
  316. Procedure TestForLoop_FieldFail;
  317. Procedure TestStatements;
  318. Procedure TestCaseOfInt;
  319. Procedure TestCaseOfIntExtConst;
  320. Procedure TestCaseIntDuplicateFail;
  321. Procedure TestCaseOfStringDuplicateFail;
  322. Procedure TestCaseOfStringRangeDuplicateFail;
  323. Procedure TestCaseOfBaseType;
  324. Procedure TestCaseOfExprNonOrdFail;
  325. Procedure TestCaseOfIncompatibleValueFail;
  326. Procedure TestTryStatement;
  327. Procedure TestTryExceptOnNonTypeFail;
  328. Procedure TestTryExceptOnNonClassFail;
  329. Procedure TestTryStatementMissingOnFail;
  330. Procedure TestRaiseNonVarFail;
  331. Procedure TestRaiseNonClassFail;
  332. Procedure TestRaiseDescendant;
  333. Procedure TestStatementsRefs;
  334. Procedure TestRepeatUntilNonBoolFail;
  335. Procedure TestWhileDoNonBoolFail;
  336. Procedure TestIfThen;
  337. Procedure TestIfThenNonBoolFail;
  338. Procedure TestIfAssignMissingSemicolonFail;
  339. Procedure TestForLoopVarNonVarFail;
  340. Procedure TestForLoopStartIncompFail;
  341. Procedure TestForLoopEndIncompFail;
  342. Procedure TestSimpleStatement_VarFail;
  343. Procedure TestLabelStatementFail;
  344. Procedure TestLabelStatementDelphiFail;
  345. // units
  346. Procedure TestUnitForwardOverloads;
  347. Procedure TestUnitIntfInitialization;
  348. Procedure TestUnitUseSystem;
  349. Procedure TestUnitUseIntf;
  350. Procedure TestUnitUseImplFail;
  351. Procedure TestUnit_DuplicateUsesFail;
  352. Procedure TestUnit_DuplicateUsesIntfImplFail;
  353. Procedure TestUnit_NestedFail;
  354. Procedure TestUnitUseDotted;
  355. Procedure TestUnit_ProgramDefaultNamespace;
  356. Procedure TestUnit_DottedIdentifier;
  357. Procedure TestUnit_DottedPrg;
  358. Procedure TestUnit_DottedUnit;
  359. Procedure TestUnit_DottedExpr;
  360. Procedure TestUnit_DottedSystem;
  361. Procedure TestUnit_DuplicateDottedUsesFail;
  362. Procedure TestUnit_DuplicateUsesDiffName;
  363. Procedure TestUnit_Unit1DotUnit2Fail;
  364. Procedure TestUnit_InFilename;
  365. Procedure TestUnit_InFilenameAliasDelphiFail;
  366. Procedure TestUnit_InFilenameInUnitDelphiFail;
  367. Procedure TestUnit_MissingUnitErrorPos;
  368. Procedure TestUnit_UnitNotFoundErrorPos;
  369. Procedure TestUnit_AccessIndirectUsedUnitFail;
  370. Procedure TestUnit_Intf1Impl2Intf1;
  371. Procedure TestUnit_Intf1Impl2Intf1_Duplicate;
  372. // procs
  373. Procedure TestProcParam;
  374. Procedure TestProcParamAccess;
  375. Procedure TestProcParamConstRef;
  376. Procedure TestFunctionResult;
  377. Procedure TestProcedureResultFail;
  378. Procedure TestProc_ArgVarPrecisionLossFail;
  379. Procedure TestProc_ArgVarTypeAliasObjFPC;
  380. Procedure TestProc_ArgVarTypeAliasDelphi;
  381. Procedure TestProc_ArgVarTypeAliasDelphiMismatchFail;
  382. Procedure TestProc_ArgAnonymouseRangeTypeFail;
  383. Procedure TestProc_ArgAnonymouseEnumTypeFail;
  384. Procedure TestProc_ArgAnonymouseSetTypeFail;
  385. Procedure TestProc_ArgAnonymousePointerTypeFail;
  386. Procedure TestProc_ArgMissingSemicolonFail;
  387. Procedure TestProcOverload;
  388. Procedure TestProcOverloadImplDuplicateFail;
  389. Procedure TestProcOverloadImplDuplicate2Fail;
  390. Procedure TestProcOverloadOtherUnit;
  391. Procedure TestProcOverloadWithBaseTypes;
  392. Procedure TestProcOverloadWithBaseTypes2;
  393. Procedure TestProcOverloadWithDefaultArgs;
  394. Procedure TestProcOverloadNearestHigherPrecision;
  395. Procedure TestProcOverloadForLoopIntDouble;
  396. Procedure TestProcOverloadStringArgCount;
  397. Procedure TestProcCallLowPrecision;
  398. Procedure TestProcOverloadUntyped;
  399. Procedure TestProcOverloadMultiLowPrecisionFail;
  400. Procedure TestProcOverload_TypeAlias;
  401. Procedure TestProcOverload_TypeAliasLiteralFail;
  402. Procedure TestProcOverloadWithClassTypes;
  403. Procedure TestProcOverloadWithInhClassTypes;
  404. Procedure TestProcOverloadWithInhAliasClassTypes;
  405. Procedure TestProcOverloadWithInterfaces;
  406. Procedure TestProcOverloadBaseTypeOtherUnit;
  407. Procedure TestProcOverloadBaseProcNoHint;
  408. Procedure TestProcOverload_UnitOrderFail;
  409. Procedure TestProcOverload_UnitSameSignature;
  410. Procedure TestProcOverloadDelphiMissingNextOverload;
  411. Procedure TestProcOverloadDelphiMissingPrevOverload;
  412. Procedure TestProcOverloadDelphiUnit;
  413. Procedure TestProcOverloadDelphiUnitNoOverloadFail;
  414. Procedure TestProcOverloadObjFPCUnitWithoutOverloadMod;
  415. Procedure TestProcOverloadDelphiWithObjFPC;
  416. Procedure TestProcOverloadDelphiOverride;
  417. Procedure TestProcOverloadDelphiOverrideOne;
  418. Procedure TestProcDuplicate;
  419. Procedure TestNestedProc;
  420. Procedure TestNestedProc_ResultString;
  421. Procedure TestFuncAssignFail;
  422. Procedure TestForwardProc;
  423. Procedure TestForwardProcUnresolved;
  424. Procedure TestNestedForwardProc;
  425. Procedure TestNestedForwardProcUnresolved;
  426. Procedure TestForwardProcFuncMismatch;
  427. Procedure TestForwardFuncResultMismatch;
  428. Procedure TestForwardProcAssemblerMismatch;
  429. Procedure TestUnitIntfProc;
  430. Procedure TestUnitIntfProcUnresolved;
  431. Procedure TestUnitIntfMismatchArgName;
  432. Procedure TestProcOverloadIsNotFunc;
  433. Procedure TestProcCallMissingParams;
  434. Procedure TestProcArgDefaultValue;
  435. Procedure TestProcArgDefaultValueTypeMismatch;
  436. Procedure TestProcPassConstToVar;
  437. Procedure TestBuiltInProcCallMissingParams;
  438. Procedure TestAssignFunctionResult;
  439. Procedure TestAssignProcResultFail;
  440. Procedure TestFunctionResultInCondition;
  441. Procedure TestExit;
  442. Procedure TestBreak;
  443. Procedure TestContinue;
  444. Procedure TestProcedureExternal;
  445. Procedure TestProc_UntypedParam_Forward;
  446. Procedure TestProc_Varargs;
  447. Procedure TestProc_VarargsOfT;
  448. Procedure TestProc_VarargsOfTMismatch;
  449. Procedure TestProc_ParameterExprAccess;
  450. Procedure TestProc_FunctionResult_DeclProc;
  451. Procedure TestProc_TypeCastFunctionResult;
  452. Procedure TestProc_ImplicitCalls;
  453. Procedure TestProc_Absolute;
  454. Procedure TestProc_LocalInit;
  455. Procedure TestProc_ExtNamePropertyFail;
  456. // anonymous procs
  457. Procedure TestAnonymousProc_Assign;
  458. Procedure TestAnonymousProc_AssignSemicolonFail;
  459. Procedure TestAnonymousProc_Assign_ReferenceToMissingFail;
  460. Procedure TestAnonymousProc_Assign_WrongParamListFail;
  461. Procedure TestAnonymousProc_Arg;
  462. Procedure TestAnonymousProc_ArgSemicolonFail;
  463. Procedure TestAnonymousProc_EqualFail;
  464. Procedure TestAnonymousProc_ConstFail;
  465. Procedure TestAnonymousProc_Assembler;
  466. Procedure TestAnonymousProc_NameFail;
  467. Procedure TestAnonymousProc_StatementFail;
  468. Procedure TestAnonymousProc_Typecast_ObjFPC;
  469. Procedure TestAnonymousProc_Typecast_Delphi;
  470. Procedure TestAnonymousProc_TypecastToResultFail;
  471. Procedure TestAnonymousProc_WithDo;
  472. Procedure TestAnonymousProc_ExceptOn;
  473. Procedure TestAnonymousProc_Nested;
  474. Procedure TestAnonymousProc_ForLoop;
  475. // record
  476. Procedure TestRecord;
  477. Procedure TestRecordVariant;
  478. Procedure TestRecordVariantNested;
  479. Procedure TestRecord_WriteConstParamFail;
  480. Procedure TestRecord_WriteConstParam_WithDoFail;
  481. Procedure TestRecord_WriteNestedConstParamFail;
  482. Procedure TestRecord_WriteNestedConstParamWithDoFail;
  483. Procedure TestRecord_TypeCast;
  484. Procedure TestRecord_NewDispose;
  485. Procedure TestRecord_Const;
  486. Procedure TestRecord_Const_DuplicateFail;
  487. Procedure TestRecord_Const_ExprMismatchFail;
  488. Procedure TestRecord_Const_MissingHint;
  489. Procedure TestRecord_Const_UntypedFail;
  490. Procedure TestRecord_Const_NestedRecord;
  491. Procedure TestRecord_Const_Variant;
  492. Procedure TestRecord_Default;
  493. Procedure TestRecord_VarExternal;
  494. Procedure TestRecord_VarSelfFail;
  495. // advanced record
  496. Procedure TestAdvRecord;
  497. Procedure TestAdvRecord_Private;
  498. Procedure TestAdvRecord_StrictPrivate;
  499. Procedure TestAdvRecord_StrictPrivateFail;
  500. Procedure TestAdvRecord_MethodImplMissingFail;
  501. Procedure TestAdvRecord_VarConst;
  502. Procedure TestAdvRecord_RecVal_ConstFail;
  503. Procedure TestAdvRecord_RecVal_ClassVarFail;
  504. Procedure TestAdvRecord_LocalForwardType;
  505. Procedure TestAdvRecord_Constructor_NewInstance;
  506. Procedure TestAdvRecord_ConstructorNoParamsFail;
  507. Procedure TestAdvRecord_ClassConstructor;
  508. Procedure TestAdvRecord_ClassConstructorParamsFail;
  509. Procedure TestAdvRecord_ClassConstructor_CallFail;
  510. Procedure TestAdvRecord_ClassConstructorDuplicateFail;
  511. Procedure TestAdvRecord_NestedRecordType;
  512. Procedure TestAdvRecord_NestedArgConstFail;
  513. Procedure TestAdvRecord_Property;
  514. Procedure TestAdvRecord_ClassProperty;
  515. Procedure TestAdvRecord_PropertyDefault;
  516. Procedure TestAdvRecord_RecordAsFuncResult;
  517. Procedure TestAdvRecord_InheritedFail;
  518. Procedure TestAdvRecord_ForInEnumerator;
  519. Procedure TestAdvRecord_InFunctionFail;
  520. Procedure TestAdvRecord_SubClass;
  521. // anonymous record
  522. Procedure TestRecordAnonym_ResultTypeFail;
  523. Procedure TestRecordAnonym_ArgumentFail;
  524. Procedure TestRecordAnonym_Advanced_ConstFail;
  525. Procedure TestRecordAnonym_Advanced_MethodFail;
  526. Procedure TestRecordAnonym_Advanced_TypeFail;
  527. Procedure TestRecordAnonym_Advanced_PropertyFail;
  528. Procedure TestRecordAnonym_Var;
  529. Procedure TestRecordAnonym_Nested;
  530. Procedure TestRecordAnonym_Advanced_Visibility;
  531. // class
  532. Procedure TestClass;
  533. Procedure TestClassDefaultInheritance;
  534. Procedure TestClassTripleInheritance;
  535. Procedure TestClassInheritanceCycleFail;
  536. Procedure TestClassDefaultVisibility;
  537. Procedure TestClassForward;
  538. Procedure TestClassForwardAsAncestorFail;
  539. Procedure TestClassForwardNotResolved;
  540. Procedure TestClassForwardDuplicateFail;
  541. Procedure TestClassForwardDelphiFail;
  542. Procedure TestClassForwardObjFPCProgram;
  543. Procedure TestClassForwardObjFPCUnit;
  544. Procedure TestClassForwardNestedTypeFail;
  545. Procedure TestClass_Method;
  546. Procedure TestClass_ConstructorMissingDotFail;
  547. Procedure TestClass_MethodImplDuplicateFail;
  548. Procedure TestClass_MethodWithoutClassFail;
  549. Procedure TestClass_MethodInOtherUnitFail;
  550. Procedure TestClass_MethodWithParams;
  551. Procedure TestClass_MethodUnresolvedPrg;
  552. Procedure TestClass_MethodUnresolvedUnit;
  553. Procedure TestClass_MethodAbstract;
  554. Procedure TestClass_MethodAbstractWithoutVirtualFail;
  555. Procedure TestClass_MethodAbstractHasBodyFail;
  556. Procedure TestClass_MethodUnresolvedWithAncestor;
  557. Procedure TestClass_ProcFuncMismatch;
  558. Procedure TestClass_MethodOverload;
  559. Procedure TestClass_MethodInvalidOverload;
  560. Procedure TestClass_MethodOverride;
  561. Procedure TestClass_MethodOverride2;
  562. Procedure TestClass_MethodOverrideAndOverload;
  563. Procedure TestClass_MethodOverrideTwiceAndOverload;
  564. Procedure TestClass_MethodOverrideFixCase;
  565. Procedure TestClass_MethodOverrideSameResultType;
  566. Procedure TestClass_MethodOverrideDiffResultTypeFail;
  567. Procedure TestClass_MethodOverrideDiffVarName;
  568. Procedure TestClass_MethodOverloadMissingInDelphi;
  569. Procedure TestClass_MethodOverloadAncestor;
  570. Procedure TestClass_MethodOverloadUnit;
  571. Procedure TestClass_HintMethodHidesNonVirtualMethod;
  572. Procedure TestClass_HintMethodHidesNonVirtualMethodWithoutBody_NoHint;
  573. Procedure TestClass_NoHintMethodHidesPrivateMethod;
  574. Procedure TestClass_MethodReintroduce;
  575. Procedure TestClass_MethodOverloadArrayOfTClass;
  576. Procedure TestClass_ConstructorHidesAncestorWarning;
  577. Procedure TestClass_ConstructorOverride;
  578. Procedure TestClass_ConstructorAccessHiddenAncestorFail;
  579. Procedure TestClass_ConstructorNoteAbstractMethods;
  580. Procedure TestClass_ConstructorNoNoteAbstractMethods;
  581. Procedure TestClass_MethodScope;
  582. Procedure TestClass_IdentifierSelf;
  583. Procedure TestClassCallInherited;
  584. Procedure TestClassCallInheritedNoParamsAbstractFail;
  585. Procedure TestClassCallInheritedWithParamsAbstractFail;
  586. Procedure TestClassCallInheritedConstructor;
  587. Procedure TestClassCallInheritedNested;
  588. Procedure TestClassCallInheritedAs;
  589. Procedure TestClassAssignNil;
  590. Procedure TestClassAssign;
  591. Procedure TestClassNilAsParam;
  592. Procedure TestClass_Operators_Is_As;
  593. Procedure TestClass_OperatorIsOnNonTypeFail;
  594. Procedure TestClass_OperatorAsOnNonDescendantFail;
  595. Procedure TestClass_OperatorAsOnNonTypeFail;
  596. Procedure TestClassAsFuncResult;
  597. Procedure TestClassTypeCast;
  598. Procedure TestClassTypeCastUnrelatedWarn;
  599. Procedure TestClass_TypeCastSelf;
  600. Procedure TestClass_TypeCaseMultipleParamsFail;
  601. Procedure TestClass_TypeCastAssign;
  602. Procedure TestClass_AccessMemberViaClassFail;
  603. Procedure TestClass_FuncReturningObjectMember;
  604. Procedure TestClass_StaticWithoutClassFail;
  605. Procedure TestClass_SelfInStaticFail;
  606. Procedure TestClass_SelfDotInStaticFail;
  607. Procedure TestClass_ProcStaticMismatchFail;
  608. Procedure TestClass_PrivateProtectedInSameUnit;
  609. Procedure TestClass_PrivateInMainBeginFail;
  610. Procedure TestClass_PrivateInDescendantFail;
  611. Procedure TestClass_ProtectedInDescendant;
  612. Procedure TestClass_StrictPrivateInMainBeginFail;
  613. Procedure TestClass_StrictProtectedInMainBeginFail;
  614. Procedure TestClass_Constructor_NewInstance;
  615. Procedure TestClass_Destructor_FreeInstance;
  616. Procedure TestClass_ConDestructor_CallInherited;
  617. Procedure TestClass_Constructor_Inherited;
  618. Procedure TestClass_SubObject;
  619. Procedure TestClass_WithDoClassInstance;
  620. Procedure TestClass_ProcedureExternal;
  621. Procedure TestClass_ReintroducePublicVarObjFPCFail;
  622. Procedure TestClass_ReintroducePublicVarDelphi;
  623. Procedure TestClass_ReintroducePrivateVar;
  624. Procedure TestClass_ReintroduceProc;
  625. Procedure TestClass_UntypedParam_TypeCast;
  626. Procedure TestClass_Sealed;
  627. Procedure TestClass_SealedDescendFail;
  628. Procedure TestClass_Abstract;
  629. Procedure TestClass_AbstractCreateFail;
  630. Procedure TestClass_VarExternal;
  631. Procedure TestClass_WarnOverrideLowerVisibility;
  632. Procedure TestClass_Const;
  633. Procedure TestClass_ClassMissingVarFail;
  634. Procedure TestClass_ClassConstFail;
  635. Procedure TestClass_Enumerator;
  636. Procedure TestClass_EnumeratorFunc;
  637. Procedure TestClass_ForInPropertyStaticArray;
  638. Procedure TestClass_TypeAlias;
  639. Procedure TestClass_Message;
  640. Procedure TestClass_Message_MissingParamFail;
  641. Procedure TestClass_ExtRTTI_Explicit;
  642. // published
  643. Procedure TestClass_PublishedClassVarFail;
  644. Procedure TestClass_PublishedClassPropertyFail;
  645. Procedure TestClass_PublishedClassFunctionFail;
  646. Procedure TestClass_PublishedOverloadFail;
  647. // nested class
  648. Procedure TestNestedClass;
  649. Procedure TestNestedClass_Forward;
  650. procedure TestNestedClass_StrictPrivateFail;
  651. procedure TestNestedClass_AccessStrictPrivate;
  652. procedure TestNestedClass_AccessParent;
  653. procedure TestNestedClass_BodyAccessParentVarFail;
  654. procedure TestNestedClass_PropertyAccessParentVarFail;
  655. // external class
  656. Procedure TestExternalClass;
  657. Procedure TestExternalClass_Descendant;
  658. Procedure TestExternalClass_HintMethodHidesNonVirtualMethodExact;
  659. // class of
  660. Procedure TestClassOf;
  661. Procedure TestClassOfAlias;
  662. Procedure TestClassOfNonClassFail;
  663. Procedure TestClassOfAssignClassOfFail;
  664. Procedure TestClassOfIsOperatorFail;
  665. Procedure TestClassOfAsOperatorFail;
  666. Procedure TestClassOfIsOperator;
  667. Procedure TestClass_ClassVar;
  668. Procedure TestClassOfDotClassVar;
  669. Procedure TestClassOfDotVarFail;
  670. Procedure TestClassOfDotClassProc;
  671. Procedure TestClassOfDotProcFail;
  672. Procedure TestClassOfDotClassProperty;
  673. Procedure TestClassOfDotPropertyFail;
  674. Procedure TestClass_ClassProcSelf;
  675. Procedure TestClass_ClassProcSelfTypeCastFail;
  676. Procedure TestClass_ClassMembers;
  677. Procedure TestClassOf_AsFail;
  678. Procedure TestClassOf_MemberAsFail;
  679. Procedure TestClassOf_IsFail;
  680. Procedure TestClass_TypeCast;
  681. Procedure TestClassOf_AlwaysForward;
  682. Procedure TestClassOf_ClassOfBeforeClass_FuncResult;
  683. Procedure TestClassOf_Const;
  684. Procedure TestClassOf_Const2;
  685. // property
  686. Procedure TestProperty1;
  687. Procedure TestPropertyAccessorNotInFront;
  688. Procedure TestPropertyReadAndWriteMissingFail;
  689. Procedure TestPropertyReadAccessorVarWrongType;
  690. Procedure TestPropertyReadAccessorProcNotFunc;
  691. Procedure TestPropertyReadAccessorFuncWrongResult;
  692. Procedure TestPropertyReadAccessorFuncWrongArgCount;
  693. Procedure TestPropertyReadAccessorFunc;
  694. Procedure TestPropertyReadAccessorStrictPrivate;
  695. Procedure TestPropertyReadAccessorNonClassFail;
  696. Procedure TestPropertyWriteAccessorVarWrongType;
  697. Procedure TestPropertyWriteAccessorFuncNotProc;
  698. Procedure TestPropertyWriteAccessorProcWrongArgCount;
  699. Procedure TestPropertyWriteAccessorProcWrongArg;
  700. Procedure TestPropertyWriteAccessorProcWrongArgType;
  701. Procedure TestPropertyWriteAccessorProc;
  702. Procedure TestPropertyTypeless;
  703. Procedure TestPropertyTypelessNoAncestorFail;
  704. Procedure TestPropertyStoredAccessor;
  705. Procedure TestPropertyStoredAccessorVarWrongType;
  706. Procedure TestPropertyStoredAccessorProcNotFunc;
  707. Procedure TestPropertyStoredAccessorFuncWrongResult;
  708. Procedure TestPropertyStoredAccessorFuncWrongArgCount;
  709. Procedure TestPropertyIndexSpec;
  710. Procedure TestPropertyIndexSpec_ReadAccessorWrongArgCount;
  711. Procedure TestPropertyIndexSpec_ReadAccessorWrongIndexArgType;
  712. Procedure TestPropertyDefaultValue;
  713. Procedure TestPropertyAssign;
  714. Procedure TestPropertyAssignReadOnlyFail;
  715. Procedure TestProperty_PassAsParam;
  716. Procedure TestPropertyReadNonReadableFail;
  717. Procedure TestPropertyArgs1;
  718. Procedure TestPropertyArgs2;
  719. Procedure TestPropertyArgsWithDefaultsFail;
  720. Procedure TestPropertyArgs_StringConstDefault;
  721. Procedure TestPropertyInherited;
  722. Procedure TestClassProperty;
  723. Procedure TestClassPropertyNonStaticFail;
  724. Procedure TestClassPropertyNonStaticAllow;
  725. Procedure TestArrayProperty;
  726. Procedure TestArrayProperty_PassImplicitCallClassFunc;
  727. Procedure TestProperty_WrongTypeAsIndexFail;
  728. Procedure TestProperty_Option_ClassPropertyNonStatic;
  729. Procedure TestDefaultProperty;
  730. Procedure TestDefaultPropertyIncVisibility;
  731. Procedure TestProperty_MissingDefault;
  732. Procedure TestProperty_DefaultDotFail;
  733. // class interfaces
  734. Procedure TestClassInterface;
  735. Procedure TestClassInterfaceForward;
  736. Procedure TestClassInterfaceVarFail;
  737. Procedure TestClassInterfaceConstFail;
  738. Procedure TestClassInterfaceClassMethodFail;
  739. Procedure TestClassInterfaceNestedTypeFail;
  740. Procedure TestClassInterfacePropertyStoredFail;
  741. Procedure TestClassInterface_ConstructorFail;
  742. Procedure TestClassInterface_DelphiClassAncestorIntfFail;
  743. Procedure TestClassInterface_ObjFPCClassAncestorIntf;
  744. Procedure TestClassInterface_MethodVirtualFail;
  745. Procedure TestClassInterface_Overloads;
  746. Procedure TestClassInterface_OverloadHint;
  747. Procedure TestClassInterface_OverloadNoHint;
  748. Procedure TestClassInterface_IntfListClassFail;
  749. Procedure TestClassInterface_IntfListDuplicateFail;
  750. Procedure TestClassInterface_MissingMethodFail;
  751. Procedure TestClassInterface_MissingAncestorMethodFail;
  752. Procedure TestClassInterface_DefaultProperty;
  753. Procedure TestClassInterface_MethodResolution;
  754. Procedure TestClassInterface_MethodResolutionDuplicateFail;
  755. Procedure TestClassInterface_DelegationIntf;
  756. Procedure TestClassInterface_Delegation_DuplPropFail;
  757. Procedure TestClassInterface_Delegation_MethodResFail;
  758. Procedure TestClassInterface_DelegationClass;
  759. Procedure TestClassInterface_DelegationFQN;
  760. Procedure TestClassInterface_Assign;
  761. Procedure TestClassInterface_AssignObjVarIntfVarFail;
  762. Procedure TestClassInterface_AssignDescendentFail;
  763. Procedure TestClassInterface_Args;
  764. Procedure TestClassInterface_Enumerator;
  765. Procedure TestClassInterface_PassTypecastClassToIntfAsVarParamFail;
  766. Procedure TestClassInterface_PassTypecastIntfToClassAsVarParamFail;
  767. Procedure TestClassInterface_GUID;
  768. // with-do
  769. Procedure TestWithDo1;
  770. Procedure TestWithDo2;
  771. Procedure TestWithDoFuncResult;
  772. Procedure TestWithDoConstructor;
  773. // arrays
  774. Procedure TestDynArrayOfLongint;
  775. Procedure TestDynArrayOfSelfFail;
  776. Procedure TestStaticArray;
  777. Procedure TestStaticArrayOfChar;
  778. Procedure TestStaticArrayOfCharDelphi;
  779. Procedure TestStaticArrayOfRangeElCheckFail;
  780. Procedure TestArrayOfChar_String;
  781. Procedure TestArrayOfArray;
  782. Procedure TestArrayOfArray_NameAnonymous;
  783. Procedure TestFunctionReturningArray;
  784. Procedure TestArray_LowHigh;
  785. Procedure TestArray_LowVarFail;
  786. Procedure TestArray_AssignDiffElTypeFail;
  787. Procedure TestArray_AssignSameSignatureDelphiFail;
  788. Procedure TestArray_Assigned;
  789. Procedure TestPropertyOfTypeArray;
  790. Procedure TestArrayElementFromFuncResult_AsParams;
  791. Procedure TestArrayEnumTypeRange;
  792. Procedure TestArrayEnumTypeConstNotEnoughValuesFail1;
  793. Procedure TestArrayEnumTypeConstNotEnoughValuesFail2;
  794. Procedure TestArrayEnumTypeConstWrongTypeFail;
  795. Procedure TestArrayEnumTypeConstNonConstFail;
  796. Procedure TestArrayEnumTypeSetLengthFail;
  797. Procedure TestArrayEnumCustomRange;
  798. Procedure TestArray_DynArrayConstObjFPC;
  799. Procedure TestArray_DynArrayConstDelphi;
  800. Procedure TestArray_DynArrAssignStaticDelphiFail;
  801. Procedure TestArray_Static_Const;
  802. Procedure TestArray_Record_Const;
  803. Procedure TestArray_MultiDim_Const;
  804. Procedure TestArray_AssignNilToStaticArrayFail1;
  805. Procedure TestArray_SetLengthProperty;
  806. Procedure TestStaticArray_SetlengthFail;
  807. Procedure TestArray_PassArrayElementToVarParam;
  808. Procedure TestArray_OpenArrayOfString;
  809. Procedure TestArray_OpenArrayOfString_IntFail;
  810. Procedure TestArray_OpenArrayOverride;
  811. Procedure TestArray_OpenArrayAsDynArraySetLengthFail;
  812. Procedure TestArray_OpenArrayAsDynArray;
  813. Procedure TestArray_OpenArrayDelphi;
  814. Procedure TestArray_OpenArrayChar;
  815. Procedure TestArray_DynArrayChar;
  816. Procedure TestArray_CopyConcat;
  817. Procedure TestStaticArray_CopyConcat;// ToDo
  818. Procedure TestRecordArray_CopyConcat;
  819. Procedure TestArray_CopyMismatchFail;
  820. Procedure TestArray_InsertDeleteAccess;
  821. Procedure TestArray_InsertArray;
  822. Procedure TestStaticArray_InsertFail;
  823. Procedure TestStaticArray_DeleteFail;
  824. Procedure TestArray_InsertItemMismatchFail;
  825. Procedure TestArray_TypeCast;
  826. Procedure TestArray_TypeCastWrongElTypeFail;
  827. Procedure TestArray_ConstDynArrayWrite;
  828. Procedure TestArray_ConstOpenArrayWriteFail;
  829. Procedure TestArray_ForIn;
  830. Procedure TestArray_Arg_AnonymousStaticFail;
  831. Procedure TestArray_Arg_AnonymousMultiDimFail;
  832. // array of const
  833. Procedure TestArrayOfConst;
  834. Procedure TestArrayOfConst_PassDynArrayOfIntFail;
  835. Procedure TestArrayOfConst_AssignNilFail;
  836. Procedure TestArrayOfConst_SetLengthFail;
  837. // static arrays
  838. Procedure TestArrayIntRange_OutOfRange;
  839. Procedure TestArrayIntRange_OutOfRangeError;
  840. Procedure TestArrayCharRange_OutOfRange;
  841. // procedure types
  842. Procedure TestProcTypesAssignObjFPC;
  843. Procedure TestMethodTypesAssignObjFPC;
  844. Procedure TestProcTypeCall;
  845. Procedure TestProcType_FunctionFPC;
  846. Procedure TestProcType_FunctionDelphi;
  847. Procedure TestProcType_ProcedureDelphi;
  848. Procedure TestProcType_MethodFPC;
  849. Procedure TestProcType_MethodDelphi;
  850. Procedure TestAssignProcToMethodFail;
  851. Procedure TestAssignMethodToProcFail;
  852. Procedure TestAssignProcToFunctionFail;
  853. Procedure TestAssignProcWrongArgsFail;
  854. Procedure TestAssignProcWrongArgAccessFail;
  855. Procedure TestProcType_SameSignatureObjFPC;
  856. Procedure TestProcType_AssignNestedProcFail;
  857. Procedure TestArrayOfProc;
  858. Procedure TestProcType_Assigned;
  859. Procedure TestProcType_TNotifyEvent;
  860. Procedure TestProcType_TNotifyEvent_NoAtFPC_Fail1;
  861. Procedure TestProcType_TNotifyEvent_NoAtFPC_Fail2;
  862. Procedure TestProcType_TNotifyEvent_NoAtFPC_Fail3;
  863. Procedure TestProcType_PassAsArg_NoAtFPC_Fail;
  864. Procedure TestProcType_PassAsArg_NoAtDelphi;
  865. Procedure TestProcType_WhileListCompare;
  866. Procedure TestProcType_IsNested;
  867. Procedure TestProcType_IsNested_AssignProcFail;
  868. Procedure TestProcType_ReferenceTo;
  869. Procedure TestProcType_AllowNested;
  870. Procedure TestProcType_AllowNestedOfObject;
  871. Procedure TestProcType_AsArgOtherUnit;
  872. Procedure TestProcType_Property;
  873. Procedure TestProcType_PropertyCallWrongArgFail;
  874. Procedure TestProcType_Typecast;
  875. Procedure TestProcType_InsideFunction;
  876. Procedure TestProcType_PassProcToUntyped;
  877. // anonymous procedure type
  878. Procedure TestProcTypeAnonymous_Var;
  879. Procedure TestProcTypeAnonymous_FunctionFunctionFail;
  880. Procedure TestProcTypeAnonymous_ResultTypeFail;
  881. Procedure TestProcTypeAnonymous_ArgumentFail;
  882. Procedure TestProcTypeAnonymous_PropertyFail;
  883. // pointer
  884. Procedure TestPointer;
  885. Procedure TestPointer_AnonymousSetFail;
  886. Procedure TestPointer_AssignPointerToClassFail;
  887. Procedure TestPointer_TypecastToMethodTypeFail;
  888. Procedure TestPointer_TypecastFromMethodTypeFail;
  889. Procedure TestPointer_TypecastMethod_proMethodAddrAsPointer;
  890. Procedure TestPointer_OverloadSignature;
  891. Procedure TestPointer_Assign;
  892. Procedure TestPointerTyped;
  893. Procedure TestPointerTypedForwardMissingFail;
  894. Procedure TestPointerTyped_CycleFail;
  895. Procedure TestPointerTyped_AssignMismatchFail;
  896. Procedure TestPointerTyped_AddrAddrFail;
  897. Procedure TestPointerTyped_RecordObjFPC;
  898. Procedure TestPointerTyped_RecordDelphi;
  899. Procedure TestPointerTyped_Arithmetic;
  900. // resourcestrings
  901. Procedure TestResourcestring;
  902. Procedure TestResourcestringAssignFail;
  903. Procedure TestResourcestringLocalFail;
  904. Procedure TestResourcestringInConstFail;
  905. Procedure TestResourcestringPassVarArgFail;
  906. // hints
  907. Procedure TestHint_ElementHintModifiers;
  908. Procedure TestHint_ElementHintsMsg;
  909. Procedure TestHint_ElementHintsAlias;
  910. Procedure TestHint_ElementHints_WarnOff_SymbolDeprecated;
  911. Procedure TestHint_ClassElementHints;
  912. Procedure TestHint_UsesHints;
  913. Procedure TestHint_Garbage;
  914. // helpers
  915. Procedure TestClassHelper;
  916. Procedure TestClassHelper_AncestorIsNotHelperForDescendantFail;
  917. Procedure TestClassHelper_HelperForParentFail;
  918. Procedure TestClassHelper_ForInterfaceFail;
  919. Procedure TestClassHelper_FieldFail;
  920. Procedure TestClassHelper_AbstractFail;
  921. Procedure TestClassHelper_VirtualObjFPCFail;
  922. Procedure TestClassHelper_VirtualDelphiFail;
  923. Procedure TestClassHelper_DestructorFail;
  924. Procedure TestClassHelper_ClassRefersToTypeHelperOfAncestor;
  925. Procedure TestClassHelper_InheritedObjFPC;
  926. Procedure TestClassHelper_InheritedObjFPC2;
  927. Procedure TestClassHelper_InheritedObjFPCStrictPrivateFail;
  928. Procedure TestClassHelper_InheritedClassObjFPC;
  929. Procedure TestClassHelper_InheritedDelphi;
  930. Procedure TestClassHelper_NestedInheritedParentFail;
  931. Procedure TestClassHelper_AccessFields;
  932. Procedure TestClassHelper_HelperDotClassMethodFail;
  933. Procedure TestClassHelper_WithDoHelperFail;
  934. Procedure TestClassHelper_AsTypeFail;
  935. Procedure TestClassHelper_WithDo;
  936. Procedure TestClassHelper_ClassMethod;
  937. Procedure TestClassHelper_Enumerator;
  938. Procedure TestClassHelper_FromUnitInterface;
  939. Procedure TestClassHelper_Constructor_NewInstance;
  940. Procedure TestClassHelper_ReintroduceHides_CallFail;
  941. Procedure TestClassHelper_DefaultProperty;
  942. Procedure TestClassHelper_DefaultClassProperty;
  943. Procedure TestClassHelper_MultiHelpers;
  944. Procedure TestRecordHelper;
  945. Procedure TestRecordHelper_ForByteFail;
  946. Procedure TestRecordHelper_ClassNonStaticFail;
  947. Procedure TestRecordHelper_InheritedObjFPC;
  948. Procedure TestRecordHelper_Constructor_NewInstance;
  949. Procedure TestTypeHelper;
  950. Procedure TestTypeHelper_HelperForProcTypeFail;
  951. Procedure TestTypeHelper_DefaultPropertyFail;
  952. Procedure TestTypeHelper_Enum;
  953. Procedure TestTypeHelper_EnumDotValueFail;
  954. Procedure TestTypeHelper_EnumHelperDotProcFail;
  955. Procedure TestTypeHelper_Set;
  956. Procedure TestTypeHelper_Enumerator;
  957. Procedure TestTypeHelper_String;
  958. Procedure TestTypeHelper_StringOtherUnit;
  959. Procedure TestTypeHelper_Boolean;
  960. Procedure TestTypeHelper_Double;
  961. Procedure TestTypeHelper_DoubleAlias;
  962. Procedure TestTypeHelper_Constructor_NewInstance;
  963. Procedure TestTypeHelper_Interface;
  964. Procedure TestTypeHelper_Interface_ConstructorFail;
  965. Procedure TestTypeHelper_TypeAliasType;
  966. // attributes
  967. Procedure TestAttributes_Globals;
  968. Procedure TestAttributes_NonConstParam_Fail;
  969. Procedure TestAttributes_UnknownAttrWarning;
  970. Procedure TestAttributes_Members;
  971. Procedure TestAttributes_MethodParams;
  972. Procedure TestAttributes_MethodParamsGroup;
  973. // library
  974. Procedure TestLibrary_Empty;
  975. Procedure TestLibrary_ExportFunc;
  976. Procedure TestLibrary_ExportFunc_NameIntFail;
  977. Procedure TestLibrary_ExportFunc_IndexStringFail;
  978. Procedure TestLibrary_ExportVar;
  979. Procedure TestLibrary_ExportLocalFuncFail;
  980. Procedure TestLibrary_Initialization_Finalization;
  981. Procedure TestLibrary_ExportFuncOverloadFail;
  982. Procedure TestLibrary_UnitExports;
  983. end;
  984. function LinesToStr(Args: array of const): string;
  985. implementation
  986. function LinesToStr(Args: array of const): string;
  987. var
  988. s: String;
  989. i: Integer;
  990. begin
  991. s:='';
  992. for i:=Low(Args) to High(Args) do
  993. case Args[i].VType of
  994. vtChar: s += Args[i].VChar+LineEnding;
  995. vtString: s += Args[i].VString^+LineEnding;
  996. vtPChar: s += Args[i].VPChar+LineEnding;
  997. vtWideChar: s += AnsiString(Args[i].VWideChar)+LineEnding;
  998. vtPWideChar: s += AnsiString(Args[i].VPWideChar)+LineEnding;
  999. vtAnsiString: s += AnsiString(Args[i].VAnsiString)+LineEnding;
  1000. vtWidestring: s += AnsiString(WideString(Args[i].VWideString))+LineEnding;
  1001. vtUnicodeString:s += AnsiString(UnicodeString(Args[i].VUnicodeString))+LineEnding;
  1002. end;
  1003. Result:=s;
  1004. end;
  1005. { TTestEnginePasResolver }
  1006. procedure TTestEnginePasResolver.SetModule(AValue: TPasModule);
  1007. begin
  1008. if FModule=AValue then Exit;
  1009. FModule:=AValue;
  1010. {$IFDEF CheckPasTreeRefCount}
  1011. if Module<>nil then
  1012. Module.ChangeRefId('CreateElement','TTestEnginePasResolver.Module');
  1013. {$ENDIF}
  1014. end;
  1015. constructor TTestEnginePasResolver.Create;
  1016. begin
  1017. inherited Create;
  1018. StoreSrcColumns:=true;
  1019. end;
  1020. destructor TTestEnginePasResolver.Destroy;
  1021. begin
  1022. FStreamResolver:=nil;
  1023. FreeAndNil(FParser);
  1024. FreeAndNil(FScanner);
  1025. inherited Destroy;
  1026. Module:=nil;
  1027. end;
  1028. function TTestEnginePasResolver.CreateElement(AClass: TPTreeElement;
  1029. const AName: String; AParent: TPasElement; AVisibility: TPasMemberVisibility;
  1030. const ASrcPos: TPasSourcePos; TypeParams: TFPList): TPasElement;
  1031. begin
  1032. Result:=inherited CreateElement(AClass, AName, AParent, AVisibility, ASrcPos, TypeParams);
  1033. if (FModule=nil) and AClass.InheritsFrom(TPasModule) then
  1034. Module:=TPasModule(Result);
  1035. end;
  1036. function TTestEnginePasResolver.FindUnit(const AName, InFilename: String;
  1037. NameExpr, InFileExpr: TPasExpr): TPasModule;
  1038. begin
  1039. Result:=OnFindUnit(Self,AName,InFilename,NameExpr,InFileExpr);
  1040. end;
  1041. procedure TTestEnginePasResolver.UsedInterfacesFinished(Section: TPasSection);
  1042. begin
  1043. if Section=nil then ;
  1044. // do not parse recursively
  1045. // using a queue
  1046. end;
  1047. { TCustomTestResolver }
  1048. procedure TCustomTestResolver.SetUp;
  1049. begin
  1050. FResolvers:=TObjectList.Create(true);
  1051. FHub:=TPasResolverHub.Create(Self);
  1052. inherited SetUp;
  1053. Parser.Options:=Parser.Options+[po_ResolveStandardTypes];
  1054. Parser.CurrentModeswitches:=[msObjfpc];
  1055. Scanner.OnDirective:=@OnScannerDirective;
  1056. Scanner.OnLog:=@OnScannerLog;
  1057. end;
  1058. procedure TCustomTestResolver.TearDown;
  1059. begin
  1060. FResolverMsgs.Clear;
  1061. FResolverGoodMsgs.Clear;
  1062. {$IFDEF VerbosePasResolverMem}
  1063. writeln('TTestResolver.TearDown START FreeSrcMarkers');
  1064. {$ENDIF}
  1065. FreeSrcMarkers;
  1066. {$IFDEF VerbosePasResolverMem}
  1067. writeln('TTestResolver.TearDown ResolverEngine.Clear');
  1068. {$ENDIF}
  1069. if ResolverEngine.Parser=Parser then
  1070. ResolverEngine.Parser:=nil;
  1071. ResolverEngine.Clear;
  1072. if FResolvers<>nil then
  1073. begin
  1074. {$IFDEF VerbosePasResolverMem}
  1075. writeln('TTestResolver.TearDown FResolvers');
  1076. {$ENDIF}
  1077. FResolvers.OwnsObjects:=false;
  1078. FResolvers.Remove(ResolverEngine); // remove reference
  1079. FResolvers.OwnsObjects:=true;
  1080. FreeAndNil(FResolvers);// free all other resolvers (the TPasElements are owned by the resolvers)
  1081. end;
  1082. FreeAndNil(FHub);
  1083. {$IFDEF VerbosePasResolverMem}
  1084. writeln('TTestResolver.TearDown inherited');
  1085. {$ENDIF}
  1086. inherited TearDown;
  1087. FResolverEngine:=nil;
  1088. {$IFDEF VerbosePasResolverMem}
  1089. writeln('TTestResolver.TearDown END');
  1090. {$ENDIF}
  1091. end;
  1092. procedure TCustomTestResolver.CreateEngine(var TheEngine: TPasTreeContainer);
  1093. begin
  1094. FResolverEngine:=AddModule(MainFilename);
  1095. TheEngine:=ResolverEngine;
  1096. end;
  1097. procedure TCustomTestResolver.ParseModule;
  1098. var
  1099. Section: TPasSection;
  1100. i: Integer;
  1101. CurResolver: TTestEnginePasResolver;
  1102. Found: Boolean;
  1103. begin
  1104. if ResolverEngine.Parser=nil then
  1105. ResolverEngine.Parser:=Parser;
  1106. inherited ParseModule;
  1107. repeat
  1108. Found:=false;
  1109. for i:=0 to ModuleCount-1 do
  1110. begin
  1111. CurResolver:=Modules[i];
  1112. if CurResolver.Parser=nil then continue;
  1113. if not CurResolver.Parser.CanParseContinue(Section) then
  1114. continue;
  1115. {$IFDEF VerbosePasResolver}
  1116. writeln('TCustomTestResolver.ParseModule continue parsing section=',GetObjName(Section),' of ',CurResolver.Filename);
  1117. {$ENDIF}
  1118. Found:=true;
  1119. CurResolver.Parser.ParseContinue;
  1120. break;
  1121. end;
  1122. until not Found;
  1123. for i:=0 to ModuleCount-1 do
  1124. begin
  1125. CurResolver:=Modules[i];
  1126. if CurResolver.Parser=nil then
  1127. begin
  1128. if CurResolver.CurrentParser<>nil then
  1129. Fail(CurResolver.Filename+' Parser<>CurrentParser Parser="'+GetObjName(CurResolver.Parser)+'" CurrentParser='+GetObjName(CurResolver.CurrentParser));
  1130. continue;
  1131. end;
  1132. if CurResolver.Parser.CurModule<>nil then
  1133. begin
  1134. Section:=CurResolver.Parser.GetLastSection;
  1135. {$IFDEF VerbosePasResolver}
  1136. writeln('TCustomTestResolver.ParseModule module not finished "',GetObjName(CurResolver.RootElement),'" LastSection=',GetObjName(Section)+' PendingUsedIntf='+GetObjName(Section.PendingUsedIntf));
  1137. if (Section<>nil) and (Section.PendingUsedIntf<>nil) then
  1138. writeln('TCustomTestResolver.ParseModule PendingUsedIntf=',GetObjName(Section.PendingUsedIntf.Module));
  1139. {$ENDIF}
  1140. Fail('module not finished "'+GetObjName(CurResolver.RootElement)+'"');
  1141. end;
  1142. end;
  1143. end;
  1144. procedure TCustomTestResolver.ParseMain(ExpectedModuleClass: TPasModuleClass);
  1145. var
  1146. {$IFNDEF NOCONSOLE}
  1147. aFilename: String;
  1148. {$ENDIF}
  1149. aRow, aCol: Integer;
  1150. begin
  1151. FFirstStatement:=nil;
  1152. if ExpectedModuleClass=nil then ;
  1153. try
  1154. ParseModule;
  1155. except
  1156. on E: EParserError do
  1157. begin
  1158. {$IFNDEF NOCONSOLE}
  1159. aFilename:=E.Filename;
  1160. {$ENDIF}
  1161. aRow:=E.Row;
  1162. aCol:=E.Column;
  1163. {$IFNDEF NOCONSOLE}
  1164. WriteSources(aFilename,aRow,aCol);
  1165. writeln('ERROR: TTestResolver.ParseMain ',ExpectedModuleClass.ClassName,' Parser: '+E.ClassName+':'+E.Message,
  1166. ' Scanner at'
  1167. +' '+aFilename+'('+IntToStr(aRow)+','+IntToStr(aCol)+')'
  1168. +' Line="'+Scanner.CurLine+'"');
  1169. {$ENDIF}
  1170. Fail(E.Message);
  1171. end;
  1172. on E: EPasResolve do
  1173. begin
  1174. {$IFNDEF NOCONSOLE}
  1175. aFilename:=Scanner.CurFilename;
  1176. {$ENDIF}
  1177. aRow:=Scanner.CurRow;
  1178. aCol:=Scanner.CurColumn;
  1179. if E.PasElement<>nil then
  1180. begin
  1181. {$IFNDEF NOCONSOLE}
  1182. aFilename:=E.PasElement.SourceFilename;
  1183. {$ENDIF}
  1184. ResolverEngine.UnmangleSourceLineNumber(E.PasElement.SourceLinenumber,aRow,aCol);
  1185. end;
  1186. {$IFNDEF NOCONSOLE}
  1187. WriteSources(aFilename,aRow,aCol);
  1188. writeln('ERROR: TTestResolver.ParseMain ',ExpectedModuleClass.ClassName,' PasResolver: '+E.ClassName+':'+E.Message
  1189. +' at '+aFilename+'('+IntToStr(aRow)+','+IntToStr(aCol)+')');
  1190. {$ENDIF}
  1191. Fail(E.Message);
  1192. end;
  1193. on E: Exception do
  1194. begin
  1195. {$IFNDEF NOCONSOLE}
  1196. writeln('ERROR: TTestResolver.ParseMain ',ExpectedModuleClass.ClassName,' Exception: '+E.ClassName+':'+E.Message);
  1197. {$ENDIF}
  1198. Fail(E.Message);
  1199. end;
  1200. end;
  1201. TAssert.AssertSame('Has resolver',ResolverEngine,Parser.Engine);
  1202. end;
  1203. procedure TCustomTestResolver.ParseProgram;
  1204. begin
  1205. ParseMain(TPasProgram);
  1206. AssertEquals('Has program',TPasProgram,Module.ClassType);
  1207. AssertNotNull('Has program section',PasProgram.ProgramSection);
  1208. AssertNotNull('Has initialization section',PasProgram.InitializationSection);
  1209. if (PasProgram.InitializationSection.Elements.Count>0) then
  1210. if TObject(PasProgram.InitializationSection.Elements[0]) is TPasImplBlock then
  1211. FFirstStatement:=TPasImplBlock(PasProgram.InitializationSection.Elements[0]);
  1212. CheckReferenceDirectives;
  1213. end;
  1214. procedure TCustomTestResolver.ParseLibrary;
  1215. begin
  1216. ParseMain(TPasLibrary);
  1217. AssertEquals('Has library',TPasLibrary,Module.ClassType);
  1218. AssertNotNull('Has library section',PasLibrary.LibrarySection);
  1219. AssertNotNull('Has initialization section',PasLibrary.InitializationSection);
  1220. CheckReferenceDirectives;
  1221. end;
  1222. procedure TCustomTestResolver.ParseUnit;
  1223. begin
  1224. ParseMain(TPasModule);
  1225. AssertEquals('Has unit',TPasModule,Module.ClassType);
  1226. AssertNotNull('Has interface section',Module.InterfaceSection);
  1227. AssertNotNull('Has implementation section',Module.ImplementationSection);
  1228. if (Module.InitializationSection<>nil)
  1229. and (Module.InitializationSection.Elements.Count>0) then
  1230. if TObject(Module.InitializationSection.Elements[0]) is TPasImplBlock then
  1231. FFirstStatement:=TPasImplBlock(Module.InitializationSection.Elements[0]);
  1232. CheckReferenceDirectives;
  1233. end;
  1234. procedure TCustomTestResolver.CheckReferenceDirectives;
  1235. var
  1236. Filename: string;
  1237. LineNumber: Integer;
  1238. SrcLine: String;
  1239. CommentStartP, CommentEndP: PChar;
  1240. procedure RaiseError(Msg: string; p: PChar);
  1241. begin
  1242. RaiseErrorAtSrc(Msg,Filename,LineNumber,p-PChar(SrcLine)+1);
  1243. end;
  1244. procedure AddMarker(Marker: PSrcMarker);
  1245. begin
  1246. if LastSrcMarker<>nil then
  1247. LastSrcMarker^.Next:=Marker
  1248. else
  1249. FirstSrcMarker:=Marker;
  1250. LastSrcMarker:=Marker;
  1251. end;
  1252. function AddMarker(Kind: TSrcMarkerKind; const aFilename: string;
  1253. aLine, aStartCol, aEndCol: integer; const Identifier, Param: string): PSrcMarker;
  1254. begin
  1255. New(Result);
  1256. Result^.Kind:=Kind;
  1257. Result^.Filename:=aFilename;
  1258. Result^.Row:=aLine;
  1259. Result^.StartCol:=aStartCol;
  1260. Result^.EndCol:=aEndCol;
  1261. Result^.Identifier:=Identifier;
  1262. Result^.Param:=Param;
  1263. Result^.Next:=nil;
  1264. //writeln('AddMarker Line="',SrcLine,'" Identifier=',Identifier,' Col=',aStartCol,'-',aEndCol,' "',copy(SrcLine,aStartCol,aEndCol-aStartCol),'"');
  1265. AddMarker(Result);
  1266. end;
  1267. function AddMarkerForTokenBehindComment(Kind: TSrcMarkerKind;
  1268. const Identifier, Param: string): PSrcMarker;
  1269. var
  1270. TokenStart, p: PChar;
  1271. begin
  1272. p:=CommentEndP;
  1273. ReadNextPascalToken(p,TokenStart,false,false);
  1274. Result:=AddMarker(Kind,Filename,LineNumber,
  1275. CommentEndP-PChar(SrcLine)+1,p-PChar(SrcLine)+1,Identifier,Param);
  1276. end;
  1277. function ReadIdentifier(var p: PChar): string;
  1278. var
  1279. StartP: PChar;
  1280. begin
  1281. if not (p^ in ['a'..'z','A'..'Z','_']) then
  1282. RaiseError('identifier expected',p);
  1283. StartP:=p;
  1284. inc(p);
  1285. while p^ in ['a'..'z','A'..'Z','_','0'..'9'] do inc(p);
  1286. Result:='';
  1287. SetLength(Result,p-StartP);
  1288. Move(StartP^,Result[1],length(Result)*SizeOf(Char));
  1289. end;
  1290. function ReadParam(p: PChar): string;
  1291. begin
  1292. while p^ in [' ',#9,#10,#13] do inc(p);
  1293. SetLength(Result{%H-},CommentEndP-p-1);
  1294. if Result>'' then
  1295. Move(p^,Result[1],length(Result)*SizeOf(Char));
  1296. end;
  1297. procedure AddLabel;
  1298. var
  1299. Identifier: String;
  1300. p: PChar;
  1301. begin
  1302. p:=CommentStartP+2;
  1303. Identifier:=ReadIdentifier(p);
  1304. //writeln('TTestResolver.CheckReferenceDirectives.AddLabel ',Identifier);
  1305. if FindSrcLabel(Identifier)<>nil then
  1306. RaiseError('duplicate label "'+Identifier+'"',p);
  1307. AddMarkerForTokenBehindComment(mkLabel,Identifier,ReadParam(p));
  1308. end;
  1309. procedure AddResolverReference;
  1310. var
  1311. Identifier: String;
  1312. p: PChar;
  1313. begin
  1314. p:=CommentStartP+2;
  1315. Identifier:=ReadIdentifier(p);
  1316. //writeln('TTestResolver.CheckReferenceDirectives.AddReference ',Identifier);
  1317. AddMarkerForTokenBehindComment(mkResolverReference,Identifier,ReadParam(p));
  1318. end;
  1319. procedure AddDirectReference;
  1320. var
  1321. Identifier: String;
  1322. p: PChar;
  1323. begin
  1324. p:=CommentStartP+2;
  1325. Identifier:=ReadIdentifier(p);
  1326. //writeln('TTestResolver.CheckReferenceDirectives.AddDirectReference ',Identifier);
  1327. AddMarkerForTokenBehindComment(mkDirectReference,Identifier,ReadParam(p));
  1328. end;
  1329. procedure ParseCode(SrcLines: TStringList; aFilename: string);
  1330. var
  1331. p,StartP,EndP: PChar;
  1332. IsDirective: Boolean;
  1333. begin
  1334. //writeln('TTestResolver.CheckReferenceDirectives.ParseCode File=',aFilename);
  1335. Filename:=aFilename;
  1336. // parse code, find all labels
  1337. LineNumber:=0;
  1338. while LineNumber<SrcLines.Count do
  1339. begin
  1340. inc(LineNumber);
  1341. SrcLine:=SrcLines[LineNumber-1];
  1342. if SrcLine='' then continue;
  1343. //writeln('TTestResolver.CheckReferenceDirectives Line=',SrcLine);
  1344. StartP:=PChar(SrcLine);
  1345. EndP:=StartP;
  1346. inc(EndP,length(SrcLine));
  1347. p:=StartP;
  1348. repeat
  1349. case p^ of
  1350. #0: if (p>=EndP) then break;
  1351. '{':
  1352. begin
  1353. CommentStartP:=p;
  1354. inc(p);
  1355. IsDirective:=p^ in ['#','@','='];
  1356. // skip to end of comment
  1357. repeat
  1358. case p^ of
  1359. #0:
  1360. if (p>=EndP) then
  1361. begin
  1362. // multi line comment
  1363. if IsDirective then
  1364. RaiseError('directive missing closing bracket',CommentStartP);
  1365. repeat
  1366. inc(LineNumber);
  1367. if LineNumber>SrcLines.Count then exit;
  1368. SrcLine:=SrcLines[LineNumber-1];
  1369. //writeln('TTestResolver.CheckReferenceDirectives Comment Line=',SrcLine);
  1370. until SrcLine<>'';
  1371. StartP:=PChar(SrcLine);
  1372. EndP:=StartP;
  1373. inc(EndP,length(SrcLine));
  1374. p:=StartP;
  1375. continue;
  1376. end;
  1377. '}':
  1378. begin
  1379. inc(p);
  1380. break;
  1381. end;
  1382. end;
  1383. inc(p);
  1384. until false;
  1385. CommentEndP:=p;
  1386. case CommentStartP[1] of
  1387. '#': AddLabel;
  1388. '@': AddResolverReference;
  1389. '=': AddDirectReference;
  1390. end;
  1391. p:=CommentEndP;
  1392. continue;
  1393. end;
  1394. '/':
  1395. if p[1]='/' then
  1396. break; // rest of line is comment -> skip
  1397. end;
  1398. inc(p);
  1399. until false;
  1400. end;
  1401. end;
  1402. procedure CheckResolverReference(aMarker: PSrcMarker);
  1403. // check if one element at {@a} has a TResolvedReference to an element labeled {#a}
  1404. var
  1405. aLabel: PSrcMarker;
  1406. ReferenceElements, LabelElements: TFPList;
  1407. i, j: Integer;
  1408. {$IFNDEF NOCONSOLE}
  1409. aLine, aCol: Integer;
  1410. {$ENDIF}
  1411. El, Ref, LabelEl: TPasElement;
  1412. begin
  1413. //writeln('CheckResolverReference searching reference: ',aMarker^.Filename,' Line=',aMarker^.Row,' Col=',aMarker^.StartCol,'-',aMarker^.EndCol,' Label="',aMarker^.Identifier,'"');
  1414. aLabel:=FindSrcLabel(aMarker^.Identifier);
  1415. if aLabel=nil then
  1416. RaiseErrorAtSrc('label "'+aMarker^.Identifier+'" not found',aMarker^.Filename,aMarker^.Row,aMarker^.StartCol);
  1417. LabelElements:=nil;
  1418. ReferenceElements:=nil;
  1419. try
  1420. LabelElements:=FindElementsAt(aLabel);
  1421. ReferenceElements:=FindElementsAt(aMarker);
  1422. for i:=0 to ReferenceElements.Count-1 do
  1423. begin
  1424. El:=TPasElement(ReferenceElements[i]);
  1425. Ref:=nil;
  1426. if El.CustomData is TResolvedReference then
  1427. Ref:=TResolvedReference(El.CustomData).Declaration
  1428. else if El.CustomData is TPasPropertyScope then
  1429. Ref:=TPasPropertyScope(El.CustomData).AncestorProp
  1430. else if El.CustomData is TPasSpecializeTypeData then
  1431. Ref:=TPasSpecializeTypeData(El.CustomData).SpecializedType;
  1432. if Ref<>nil then
  1433. for j:=0 to LabelElements.Count-1 do
  1434. begin
  1435. LabelEl:=TPasElement(LabelElements[j]);
  1436. if Ref=LabelEl then
  1437. exit; // success
  1438. end;
  1439. end;
  1440. // failure write candidates
  1441. for i:=0 to ReferenceElements.Count-1 do
  1442. begin
  1443. El:=TPasElement(ReferenceElements[i]);
  1444. {$IFNDEF NOCONSOLE}
  1445. write('Reference candidate for "',aMarker^.Identifier,'" at reference ',aMarker^.Filename,'(',aMarker^.Row,',',aMarker^.StartCol,'-',aMarker^.EndCol,')');
  1446. write(' El=',GetObjName(El));
  1447. if EL is TPrimitiveExpr then
  1448. begin
  1449. writeln('CheckResolverReference ',TPrimitiveExpr(El).Value);
  1450. end;
  1451. {$ENDIF}
  1452. Ref:=nil;
  1453. if El.CustomData is TResolvedReference then
  1454. Ref:=TResolvedReference(El.CustomData).Declaration
  1455. else if El.CustomData is TPasPropertyScope then
  1456. Ref:=TPasPropertyScope(El.CustomData).AncestorProp
  1457. else if El.CustomData is TPasSpecializeTypeData then
  1458. Ref:=TPasSpecializeTypeData(El.CustomData).SpecializedType;
  1459. {$IFNDEF NOCONSOLE}
  1460. if Ref<>nil then
  1461. begin
  1462. write(' Decl=',GetObjName(Ref));
  1463. ResolverEngine.UnmangleSourceLineNumber(Ref.SourceLinenumber,aLine,aCol);
  1464. write(',',Ref.SourceFilename,'(',aLine,',',aCol,')');
  1465. end
  1466. else
  1467. write(' has no TResolvedReference. El.CustomData=',GetObjName(El.CustomData));
  1468. writeln;
  1469. {$ENDIF}
  1470. end;
  1471. {$IFNDEF NOCONSOLE}
  1472. for i:=0 to LabelElements.Count-1 do
  1473. begin
  1474. El:=TPasElement(LabelElements[i]);
  1475. write('Label candidate for "',aLabel^.Identifier,'" at reference ',aLabel^.Filename,'(',aLabel^.Row,',',aLabel^.StartCol,'-',aLabel^.EndCol,')');
  1476. write(' El=',GetObjName(El));
  1477. writeln;
  1478. end;
  1479. {$ENDIF}
  1480. RaiseErrorAtSrcMarker('wrong resolved reference "'+aMarker^.Identifier+'"',aMarker);
  1481. finally
  1482. LabelElements.Free;
  1483. ReferenceElements.Free;
  1484. end;
  1485. end;
  1486. procedure CheckDirectReference(aMarker: PSrcMarker);
  1487. // check if one element at {=a} is a TPasAliasType pointing to an element labeled {#a}
  1488. var
  1489. aLabel: PSrcMarker;
  1490. ReferenceElements, LabelElements: TFPList;
  1491. i, LabelLine, LabelCol, j: Integer;
  1492. El, LabelEl: TPasElement;
  1493. DeclEl, TypeEl: TPasType;
  1494. begin
  1495. //writeln('CheckDirectReference searching pointer: ',aMarker^.Filename,' Line=',aMarker^.Row,' Col=',aMarker^.StartCol,'-',aMarker^.EndCol,' Label="',aMarker^.Identifier,'"');
  1496. aLabel:=FindSrcLabel(aMarker^.Identifier);
  1497. if aLabel=nil then
  1498. RaiseErrorAtSrcMarker('label "'+aMarker^.Identifier+'" not found',aMarker);
  1499. LabelElements:=nil;
  1500. ReferenceElements:=nil;
  1501. try
  1502. //writeln('CheckDirectReference finding elements at label ...');
  1503. LabelElements:=FindElementsAt(aLabel);
  1504. //writeln('CheckDirectReference finding elements at reference ...');
  1505. ReferenceElements:=FindElementsAt(aMarker);
  1506. for i:=0 to ReferenceElements.Count-1 do
  1507. begin
  1508. El:=TPasElement(ReferenceElements[i]);
  1509. //writeln('CheckDirectReference ',i,'/',ReferenceElements.Count,' ',GetTreeDbg(El,2));
  1510. if El.ClassType=TPasVariable then
  1511. begin
  1512. if TPasVariable(El).VarType=nil then
  1513. begin
  1514. //writeln('CheckDirectReference Var without Type: ',GetObjName(El),' El.Parent=',GetObjName(El.Parent));
  1515. AssertNotNull('TPasVariable(El='+El.Name+').VarType',TPasVariable(El).VarType);
  1516. end;
  1517. TypeEl:=TPasVariable(El).VarType;
  1518. for j:=0 to LabelElements.Count-1 do
  1519. begin
  1520. LabelEl:=TPasElement(LabelElements[j]);
  1521. if TypeEl=LabelEl then
  1522. exit; // success
  1523. end;
  1524. end
  1525. else if El is TPasAliasType then
  1526. begin
  1527. DeclEl:=TPasAliasType(El).DestType;
  1528. ResolverEngine.UnmangleSourceLineNumber(DeclEl.SourceLinenumber,LabelLine,LabelCol);
  1529. if (aLabel^.Filename=DeclEl.SourceFilename)
  1530. and (integer(aLabel^.Row)=LabelLine)
  1531. and (aLabel^.StartCol<=LabelCol)
  1532. and (aLabel^.EndCol>=LabelCol) then
  1533. exit; // success
  1534. end
  1535. else if El.ClassType=TPasArgument then
  1536. begin
  1537. TypeEl:=TPasArgument(El).ArgType;
  1538. for j:=0 to LabelElements.Count-1 do
  1539. begin
  1540. LabelEl:=TPasElement(LabelElements[j]);
  1541. if TypeEl=LabelEl then
  1542. exit; // success
  1543. end;
  1544. end;
  1545. end;
  1546. // failed -> show candidates
  1547. {$IFNDEF NOCONSOLE}
  1548. writeln('CheckDirectReference failed: Labels:');
  1549. for j:=0 to LabelElements.Count-1 do
  1550. begin
  1551. LabelEl:=TPasElement(LabelElements[j]);
  1552. writeln(' Label ',GetObjName(LabelEl),' at ',ResolverEngine.GetElementSourcePosStr(LabelEl));
  1553. end;
  1554. writeln('CheckDirectReference failed: References:');
  1555. for i:=0 to ReferenceElements.Count-1 do
  1556. begin
  1557. El:=TPasElement(ReferenceElements[i]);
  1558. writeln(' Reference ',GetObjName(El),' at ',ResolverEngine.GetElementSourcePosStr(El));
  1559. //if EL is TPasVariable then
  1560. // writeln('CheckDirectReference ',GetObjPath(TPasVariable(El).VarType),' ',ResolverEngine.GetElementSourcePosStr(TPasVariable(EL).VarType));
  1561. end;
  1562. {$ENDIF}
  1563. RaiseErrorAtSrcMarker('wrong direct reference "'+aMarker^.Identifier+'"',aMarker);
  1564. finally
  1565. LabelElements.Free;
  1566. ReferenceElements.Free;
  1567. end;
  1568. end;
  1569. var
  1570. aMarker: PSrcMarker;
  1571. i: Integer;
  1572. SrcLines: TStringList;
  1573. begin
  1574. Module.ForEachCall(@OnCheckElementParent,nil);
  1575. //writeln('TTestResolver.CheckReferenceDirectives find all markers');
  1576. // find all markers
  1577. for i:=0 to Resolver.Streams.Count-1 do
  1578. begin
  1579. GetSrc(i,SrcLines,Filename);
  1580. ParseCode(SrcLines,Filename);
  1581. SrcLines.Free;
  1582. end;
  1583. //writeln('TTestResolver.CheckReferenceDirectives check references');
  1584. // check references
  1585. aMarker:=FirstSrcMarker;
  1586. while aMarker<>nil do
  1587. begin
  1588. case aMarker^.Kind of
  1589. mkResolverReference: CheckResolverReference(aMarker);
  1590. mkDirectReference: CheckDirectReference(aMarker);
  1591. end;
  1592. aMarker:=aMarker^.Next;
  1593. end;
  1594. //writeln('TTestResolver.CheckReferenceDirectives COMPLETE');
  1595. end;
  1596. procedure TCustomTestResolver.CheckResolverHint(MsgType: TMessageType;
  1597. MsgNumber: integer; Msg: string; Marker: PSrcMarker);
  1598. var
  1599. i: Integer;
  1600. Item: TTestResolverMessage;
  1601. Expected,Actual: string;
  1602. begin
  1603. //writeln('TCustomTestResolver.CheckResolverHint MsgCount=',MsgCount);
  1604. for i:=0 to MsgCount-1 do
  1605. begin
  1606. Item:=Msgs[i];
  1607. if (Item.MsgNumber<>MsgNumber) or (Item.Msg<>Msg) then continue;
  1608. if (Marker<>nil) then
  1609. begin
  1610. if Item.SourcePos.Row<>Marker^.Row then continue;
  1611. if (integer(Item.SourcePos.Column)<Marker^.StartCol)
  1612. or (integer(Item.SourcePos.Column)>Marker^.EndCol) then continue;
  1613. end;
  1614. // found
  1615. FResolverGoodMsgs.Add(Item);
  1616. str(Item.MsgType,Actual);
  1617. str(MsgType,Expected);
  1618. AssertEquals('MsgType',Expected,Actual);
  1619. exit;
  1620. end;
  1621. // needed message missing -> show emitted messages
  1622. {$IFNDEF NOCONSOLE}
  1623. WriteSources('',0,0);
  1624. for i:=0 to MsgCount-1 do
  1625. begin
  1626. Item:=Msgs[i];
  1627. write('TCustomTestResolver.CheckResolverHint ',i,'/',MsgCount,' ',Item.MsgType,
  1628. ' ('+IntToStr(Item.MsgNumber),')');
  1629. if Marker<>nil then
  1630. write(' '+ExtractFileName(Item.SourcePos.FileName),'(',Item.SourcePos.Row,',',Item.SourcePos.Column,')');
  1631. writeln(' {',Item.Msg,'}');
  1632. end;
  1633. {$ENDIF}
  1634. str(MsgType,Expected);
  1635. Actual:='Missing '+Expected+' ('+IntToStr(MsgNumber)+')';
  1636. if Marker<>nil then
  1637. Actual:=Actual+' '+ExtractFileName(Marker^.Filename)+'('+IntToStr(Marker^.Row)+','+IntToStr(Marker^.StartCol)+'..'+IntToStr(Marker^.EndCol)+')';
  1638. Actual:=Actual+' '+Msg;
  1639. Fail(Actual);
  1640. end;
  1641. procedure TCustomTestResolver.CheckResolverUnexpectedHints(
  1642. WithSourcePos: boolean);
  1643. var
  1644. i: Integer;
  1645. s, Txt: String;
  1646. Msg: TTestResolverMessage;
  1647. begin
  1648. for i:=0 to MsgCount-1 do
  1649. begin
  1650. Msg:=Msgs[i];
  1651. if FResolverGoodMsgs.IndexOf(Msg)>=0 then continue;
  1652. s:='';
  1653. str(Msg.MsgType,s);
  1654. Txt:='Unexpected resolver message found ['+IntToStr(Msg.Id)+'] '
  1655. +s+': ('+IntToStr(Msg.MsgNumber)+')';
  1656. if WithSourcePos then
  1657. Txt:=Txt+' '+ExtractFileName(Msg.SourcePos.FileName)+'('+IntToStr(Msg.SourcePos.Row)+','+IntToStr(Msg.SourcePos.Column)+')';
  1658. Txt:=Txt+' {'+Msg.Msg+'}';
  1659. Fail(Txt);
  1660. end;
  1661. end;
  1662. procedure TCustomTestResolver.CheckResolverException(Msg: string; MsgNumber: integer);
  1663. var
  1664. ok: Boolean;
  1665. Full: String;
  1666. begin
  1667. ok:=false;
  1668. try
  1669. ParseModule;
  1670. except
  1671. on E: EPasResolve do
  1672. begin
  1673. AssertEquals('Expected {'+Msg+'}, but got msg {'+E.Message+'} number',
  1674. MsgNumber,E.MsgNumber);
  1675. Full:=E.Message+' at '+E.SourcePos.FileName+' ('+IntToStr(E.SourcePos.Row)+','+IntToStr(E.SourcePos.Column)+')';
  1676. if (Msg<>E.Message) and (Msg<>E.MsgPattern) and (Msg<>Full) then
  1677. begin
  1678. {$IFDEF VerbosePasResolver}
  1679. writeln('TCustomTestResolver.CheckResolverException E.MsgPattern={',E.MsgPattern,'} E.Message={',E.Message,'} Full={',Full,'}');
  1680. {$ENDIF}
  1681. AssertEquals('Expected message ('+IntToStr(MsgNumber)+')',
  1682. '{'+Msg+'}','{'+E.Message+'} OR {'+E.MsgPattern+'} OR {'+Full+'}');
  1683. end;
  1684. ok:=true;
  1685. end;
  1686. on E: Exception do
  1687. Fail('Expected EPasResolve but got '+E.ClassName);
  1688. end;
  1689. AssertEquals('Missing resolver error {'+Msg+'} ('+IntToStr(MsgNumber)+')',true,ok);
  1690. end;
  1691. procedure TCustomTestResolver.CheckParserException(Msg: string; MsgNumber: integer);
  1692. var
  1693. ok: Boolean;
  1694. begin
  1695. ok:=false;
  1696. try
  1697. ParseModule;
  1698. except
  1699. on E: EParserError do
  1700. begin
  1701. if (Parser.LastMsg<>Msg) and (Parser.LastMsgPattern<>Msg) and (E.Message<>Msg) then
  1702. Fail('Expected msg {'+Msg+'}, but got {'+Parser.LastMsg+'} OR pattern {'+Parser.LastMsgPattern+'} OR E.Message {'+E.Message+'}');
  1703. AssertEquals('Expected {'+Msg+'}, but got msg {'+E.Message+'} number',
  1704. MsgNumber,Parser.LastMsgNumber);
  1705. ok:=true;
  1706. end;
  1707. on E: Exception do
  1708. Fail('Expected EParserError but got '+E.ClassName);
  1709. end;
  1710. AssertEquals('Missing parser error '+Msg+' ('+IntToStr(MsgNumber)+')',true,ok);
  1711. end;
  1712. procedure TCustomTestResolver.CheckAccessMarkers;
  1713. const
  1714. AccessNames: array[TResolvedRefAccess] of string = (
  1715. 'none',
  1716. 'read',
  1717. 'assign',
  1718. 'readandassign',
  1719. 'var',
  1720. 'out',
  1721. 'paramtest'
  1722. );
  1723. var
  1724. aMarker: PSrcMarker;
  1725. Elements: TFPList;
  1726. ActualAccess, ExpectedAccess: TResolvedRefAccess;
  1727. i, j: Integer;
  1728. El, El2: TPasElement;
  1729. Ref: TResolvedReference;
  1730. p: SizeInt;
  1731. AccessPostfix: String;
  1732. begin
  1733. aMarker:=FirstSrcMarker;
  1734. while aMarker<>nil do
  1735. begin
  1736. //writeln('TTestResolver.CheckAccessMarkers ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  1737. p:=RPos('_',aMarker^.Identifier);
  1738. if p>1 then
  1739. begin
  1740. AccessPostfix:=copy(aMarker^.Identifier,p+1);
  1741. ExpectedAccess:=High(TResolvedRefAccess);
  1742. repeat
  1743. if CompareText(AccessPostfix,AccessNames[ExpectedAccess])=0 then break;
  1744. if ExpectedAccess=Low(TResolvedRefAccess) then
  1745. RaiseErrorAtSrcMarker('unknown access postfix of reference at "#'+aMarker^.Identifier+'"',aMarker);
  1746. ExpectedAccess:=Pred(ExpectedAccess);
  1747. until false;
  1748. Elements:=FindElementsAt(aMarker);
  1749. try
  1750. ActualAccess:=rraNone;
  1751. for i:=0 to Elements.Count-1 do
  1752. begin
  1753. El:=TPasElement(Elements[i]);
  1754. //writeln('TTestResolver.CheckAccessMarkers ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  1755. if not (El.CustomData is TResolvedReference) then continue;
  1756. Ref:=TResolvedReference(El.CustomData);
  1757. if ActualAccess<>rraNone then
  1758. begin
  1759. //writeln('TTestResolver.CheckAccessMarkers multiple references at "#'+aMarker^.Identifier+'":');
  1760. for j:=0 to Elements.Count-1 do
  1761. begin
  1762. El2:=TPasElement(Elements[i]);
  1763. if not (El2.CustomData is TResolvedReference) then continue;
  1764. //writeln('TTestResolver.CheckAccessMarkers ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  1765. Ref:=TResolvedReference(El.CustomData);
  1766. //writeln(' ',j,'/',Elements.Count,' Element=',GetObjName(El2),' ',AccessNames[Ref.Access],' Declaration="',El2.GetDeclaration(true),'"');
  1767. end;
  1768. RaiseErrorAtSrcMarker('multiple references at "#'+aMarker^.Identifier+'"',aMarker);
  1769. end;
  1770. ActualAccess:=Ref.Access;
  1771. if ActualAccess=rraNone then
  1772. RaiseErrorAtSrcMarker('missing Access in reference at "#'+aMarker^.Identifier+'"',aMarker);
  1773. end;
  1774. if ActualAccess<>ExpectedAccess then
  1775. RaiseErrorAtSrcMarker('expected "'+AccessNames[ExpectedAccess]+'" at "#'+aMarker^.Identifier+'", but got "'+AccessNames[ActualAccess]+'"',aMarker);
  1776. finally
  1777. Elements.Free;
  1778. end;
  1779. end;
  1780. aMarker:=aMarker^.Next;
  1781. end;
  1782. end;
  1783. procedure TCustomTestResolver.CheckParamsExpr_pkSet_Markers;
  1784. // e.g. {#a_set} {#b_array}
  1785. var
  1786. aMarker: PSrcMarker;
  1787. p: SizeInt;
  1788. AccessPostfix: String;
  1789. Elements: TFPList;
  1790. i: Integer;
  1791. El: TPasElement;
  1792. Ref: TResolvedReference;
  1793. ParamsExpr: TParamsExpr;
  1794. NeedArray: Boolean;
  1795. begin
  1796. aMarker:=FirstSrcMarker;
  1797. while aMarker<>nil do
  1798. begin
  1799. //writeln('TTestResolver.CheckParamsExpr_pkSet_Markers ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  1800. p:=RPos('_',aMarker^.Identifier);
  1801. if p>1 then
  1802. begin
  1803. AccessPostfix:=copy(aMarker^.Identifier,p+1);
  1804. if SameText(AccessPostfix,'set') then
  1805. NeedArray:=false
  1806. else if SameText(AccessPostfix,'array') then
  1807. NeedArray:=true
  1808. else
  1809. RaiseErrorAtSrcMarker('unknown set/array postfix of [] expression at "#'+aMarker^.Identifier+'"',aMarker);
  1810. Elements:=FindElementsAt(aMarker);
  1811. try
  1812. ParamsExpr:=nil;
  1813. for i:=0 to Elements.Count-1 do
  1814. begin
  1815. El:=TPasElement(Elements[i]);
  1816. //writeln('TTestResolver.CheckParamsExpr_pkSet_Markers ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  1817. if El.ClassType<>TParamsExpr then continue;
  1818. if ParamsExpr<>nil then
  1819. RaiseErrorAtSrcMarker('multiple paramsexpr found at "#'+aMarker^.Identifier+'"',aMarker);
  1820. ParamsExpr:=TParamsExpr(El);
  1821. if NeedArray then
  1822. begin
  1823. if not (El.CustomData is TResolvedReference) then
  1824. RaiseErrorAtSrcMarker('array expr has no TResolvedReference at "#'+aMarker^.Identifier+'"',aMarker);
  1825. Ref:=TResolvedReference(El.CustomData);
  1826. if not (Ref.Declaration is TPasArrayType) then
  1827. RaiseErrorAtSrcMarker('array expr Ref.Decl is not TPasArrayType (is '+GetObjName(Ref.Declaration)+') at "#'+aMarker^.Identifier+'"',aMarker);
  1828. end
  1829. else
  1830. begin
  1831. if not (El.CustomData is TResolvedReference) then
  1832. continue; // good
  1833. Ref:=TResolvedReference(El.CustomData);
  1834. if Ref.Declaration is TPasArrayType then
  1835. RaiseErrorAtSrcMarker('set expr Ref.Decl is '+GetObjName(Ref.Declaration)+' at "#'+aMarker^.Identifier+'"',aMarker);
  1836. end;
  1837. end;
  1838. if TParamsExpr=nil then
  1839. RaiseErrorAtSrcMarker('missing paramsexpr at "#'+aMarker^.Identifier+'"',aMarker);
  1840. finally
  1841. Elements.Free;
  1842. end;
  1843. end;
  1844. aMarker:=aMarker^.Next;
  1845. end;
  1846. end;
  1847. procedure TCustomTestResolver.CheckAttributeMarkers;
  1848. // check markers of the form {#Attr__ClassMarker__ConstructorMarker[__OptionalName]}
  1849. var
  1850. aMarker, ClassMarker, ConstructorMarker: PSrcMarker;
  1851. Elements: TFPList;
  1852. i: Integer;
  1853. El: TPasElement;
  1854. Ref: TResolvedReference;
  1855. s, ClassMarkerName, ConstructorMarkerName: String;
  1856. p: SizeInt;
  1857. ExpectedClass: TPasClassType;
  1858. ExpectedConstrucor, ActualConstructor: TPasConstructor;
  1859. begin
  1860. aMarker:=FirstSrcMarker;
  1861. while aMarker<>nil do
  1862. begin
  1863. s:=aMarker^.Identifier;
  1864. if SameText(LeftStr(s,6),'Attr__') then
  1865. begin
  1866. //writeln('TCustomTestResolver.CheckAttributeMarkers ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  1867. Delete(s,1,6);
  1868. p:=Pos('__',s);
  1869. if p<1 then
  1870. RaiseErrorAtSrcMarker('missing second __ at "#'+aMarker^.Identifier+'"',aMarker);
  1871. ClassMarkerName:=LeftStr(s,p-1);
  1872. Delete(s,1,p+1);
  1873. p:=Pos('__',s);
  1874. if p<1 then
  1875. ConstructorMarkerName:=s
  1876. else
  1877. ConstructorMarkerName:=copy(s,1,p-1);
  1878. // find attribute class at ClassMarkerName
  1879. ClassMarker:=FindSrcLabel(ClassMarkerName);
  1880. if ClassMarker=nil then
  1881. RaiseErrorAtSrcMarker('ClassMarker "'+ClassMarkerName+'" not found at "#'+aMarker^.Identifier+'"',aMarker);
  1882. ExpectedClass:=nil;
  1883. Elements:=FindElementsAt(ClassMarker);
  1884. try
  1885. for i:=0 to Elements.Count-1 do
  1886. begin
  1887. El:=TPasElement(Elements[i]);
  1888. if El is TPasClassType then
  1889. begin
  1890. ExpectedClass:=TPasClassType(El);
  1891. break;
  1892. end;
  1893. end;
  1894. if ExpectedClass=nil then
  1895. RaiseErrorAtSrcMarker('ClassMarker "'+ClassMarkerName+'" at "#'+aMarker^.Identifier+'" has no TPasClassType',aMarker);
  1896. finally
  1897. Elements.Free;
  1898. end;
  1899. // find constructor at ConstructorMarkerName
  1900. ConstructorMarker:=FindSrcLabel(ConstructorMarkerName);
  1901. if ConstructorMarker=nil then
  1902. RaiseErrorAtSrcMarker('ConstructorMarker "'+ConstructorMarkerName+'" not found at "#'+aMarker^.Identifier+'"',aMarker);
  1903. ExpectedConstrucor:=nil;
  1904. Elements:=FindElementsAt(ConstructorMarker);
  1905. try
  1906. for i:=0 to Elements.Count-1 do
  1907. begin
  1908. El:=TPasElement(Elements[i]);
  1909. if El is TPasConstructor then
  1910. begin
  1911. ExpectedConstrucor:=TPasConstructor(El);
  1912. break;
  1913. end;
  1914. end;
  1915. if ExpectedConstrucor=nil then
  1916. RaiseErrorAtSrcMarker('ConstructorMarker "'+ConstructorMarkerName+'" at "#'+aMarker^.Identifier+'" has no TPasConstructor',aMarker);
  1917. finally
  1918. Elements.Free;
  1919. end;
  1920. Elements:=FindElementsAt(aMarker);
  1921. try
  1922. for i:=0 to Elements.Count-1 do
  1923. begin
  1924. El:=TPasElement(Elements[i]);
  1925. //writeln('TCustomTestResolver.CheckAttributeMarkers ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  1926. if not (El.CustomData is TResolvedReference) then continue;
  1927. Ref:=TResolvedReference(El.CustomData);
  1928. if Ref.Declaration<>ExpectedClass then
  1929. RaiseErrorAtSrcMarker('Ref.Declaration at "#'+aMarker^.Identifier+'", expected "'+ExpectedClass.FullName+'" but found "'+Ref.Declaration.FullName+'", El='+GetObjName(El),aMarker);
  1930. if not (Ref.Context is TResolvedRefCtxAttrProc) then
  1931. RaiseErrorAtSrcMarker('Ref.Context at "#'+aMarker^.Identifier+'", expected "TResolvedRefCtxAttrConstructor" but found "'+GetObjName(Ref.Context)+'", El='+GetObjName(El),aMarker);
  1932. ActualConstructor:=TResolvedRefCtxAttrProc(Ref.Context).Proc;
  1933. if ActualConstructor<>ExpectedConstrucor then
  1934. RaiseErrorAtSrcMarker('Ref.Context.Proc at "#'+aMarker^.Identifier+'", expected "'+ExpectedConstrucor.FullName+'" but found "'+ActualConstructor.FullName+'", El='+GetObjName(El),aMarker);
  1935. break;
  1936. end;
  1937. finally
  1938. Elements.Free;
  1939. end;
  1940. end;
  1941. aMarker:=aMarker^.Next;
  1942. end;
  1943. end;
  1944. procedure TCustomTestResolver.CheckRTTIVisibility(aMarker: PSrcMarker; El: TPasMembersType;
  1945. Explicit: boolean; const ExpectedFields, ExpectedMethods, ExpectedProperties: TPasMembersType.
  1946. TRTTIVisibilitySections);
  1947. procedure Check(const Types: string; const Expected, Actual: TPasMembersType.TRTTIVisibilitySections);
  1948. begin
  1949. if Expected=Actual then exit;
  1950. RaiseErrorAtSrcMarker(Types+' visibility expected '+dbgs(Expected)+', but found '+dbgs(Actual),aMarker);
  1951. end;
  1952. begin
  1953. if Explicit<>El.RTTIVisibility.Explicit then
  1954. if Explicit then
  1955. RaiseErrorAtSrcMarker('rtti visibility explicit expected',aMarker)
  1956. else
  1957. RaiseErrorAtSrcMarker('rtti visibility inherit expected',aMarker);
  1958. Check('Fields',El.RTTIVisibility.Fields,ExpectedFields);
  1959. Check('Methods',El.RTTIVisibility.Methods,ExpectedMethods);
  1960. Check('Properties',El.RTTIVisibility.Properties,ExpectedProperties);
  1961. end;
  1962. procedure TCustomTestResolver.CheckRTTIVisibilityMarkers;
  1963. var
  1964. aMarker: PSrcMarker;
  1965. Elements: TFPList;
  1966. i: Integer;
  1967. Visibility: TPasMembersType.TRTTIVisibility;
  1968. MemberEl: TPasMembersType;
  1969. begin
  1970. aMarker:=FirstSrcMarker;
  1971. while aMarker<>nil do
  1972. begin
  1973. if lowercase(LeftStr(aMarker^.Identifier,5))='rtti_' then
  1974. begin
  1975. //writeln('TTestResolver.CheckRTTIVisibilityMarkers ',aMarker^.Identifier,' "',aMarker^.Param,'" ',aMarker^.StartCol,' ',aMarker^.EndCol);
  1976. if not Parser.ParseRTTIDirective(aMarker^.Param,Visibility) then
  1977. RaiseErrorAtSrcMarker('invalid rtti marker',aMarker);
  1978. Elements:=FindElementsAt(aMarker);
  1979. try
  1980. i:=Elements.Count-1;
  1981. while (i>=0) and not (TPasElement(Elements[i]) is TPasMembersType) do dec(i);
  1982. if i<0 then
  1983. RaiseErrorAtSrcMarker('rtti marker not at membertype',aMarker);
  1984. MemberEl:=TPasMembersType(Elements[i]);
  1985. CheckRTTIVisibility(aMarker,MemberEl,Visibility.Explicit,
  1986. Visibility.Fields,Visibility.Methods,Visibility.Properties);
  1987. finally
  1988. Elements.Free;
  1989. end;
  1990. end;
  1991. aMarker:=aMarker^.Next;
  1992. end;
  1993. end;
  1994. procedure TCustomTestResolver.GetSrc(Index: integer; out SrcLines: TStringList; out
  1995. aFilename: string);
  1996. var
  1997. aStream: TStream;
  1998. begin
  1999. SrcLines:=TStringList.Create;
  2000. aStream:=Resolver.Streams.Objects[Index] as TStream;
  2001. aStream.Position:=0;
  2002. SrcLines.LoadFromStream(aStream);
  2003. aFilename:=Resolver.Streams[Index];
  2004. end;
  2005. function TCustomTestResolver.FindElementsAt(aFilename: string; aLine, aStartCol,
  2006. aEndCol: integer): TFPList;
  2007. var
  2008. ok: Boolean;
  2009. FoundRefs: TTestResolverReferenceData;
  2010. i: Integer;
  2011. CurResolver: TTestEnginePasResolver;
  2012. begin
  2013. //writeln('TCustomTestResolver.FindElementsAt START "',aFilename,'" Line=',aLine,' Col=',aStartCol,'-',aEndCol);
  2014. FoundRefs:=Default(TTestResolverReferenceData);
  2015. FoundRefs.Filename:=aFilename;
  2016. FoundRefs.Row:=aLine;
  2017. FoundRefs.StartCol:=aStartCol;
  2018. FoundRefs.EndCol:=aEndCol;
  2019. FoundRefs.Found:=TFPList.Create;
  2020. ok:=false;
  2021. try
  2022. // find all markers
  2023. Module.ForEachCall(@OnFindReference,@FoundRefs);
  2024. for i:=0 to ModuleCount-1 do
  2025. begin
  2026. CurResolver:=Modules[i];
  2027. if CurResolver.Module=Module then continue;
  2028. //writeln('TCustomTestResolver.FindElementsAt ',CurResolver.Filename);
  2029. CurResolver.Module.ForEachCall(@OnFindReference,@FoundRefs);
  2030. end;
  2031. ok:=true;
  2032. finally
  2033. if not ok then
  2034. FreeAndNil(FoundRefs.Found);
  2035. end;
  2036. Result:=FoundRefs.Found;
  2037. FoundRefs.Found:=nil;
  2038. end;
  2039. function TCustomTestResolver.FindElementsAt(aMarker: PSrcMarker;
  2040. ErrorOnNoElements: boolean): TFPList;
  2041. begin
  2042. Result:=FindElementsAt(aMarker^.Filename,aMarker^.Row,aMarker^.StartCol,aMarker^.EndCol);
  2043. if ErrorOnNoElements and ((Result=nil) or (Result.Count=0)) then
  2044. RaiseErrorAtSrcMarker('marker '+SrcMarker[aMarker^.Kind]+aMarker^.Identifier+' has no elements',aMarker);
  2045. end;
  2046. function TCustomTestResolver.FindSrcLabel(const Identifier: string): PSrcMarker;
  2047. begin
  2048. Result:=FirstSrcMarker;
  2049. while Result<>nil do
  2050. begin
  2051. if (Result^.Kind=mkLabel)
  2052. and (CompareText(Result^.Identifier,Identifier)=0) then
  2053. exit;
  2054. Result:=Result^.Next;
  2055. end;
  2056. end;
  2057. function TCustomTestResolver.FindElementsAtSrcLabel(const Identifier: string;
  2058. ErrorOnNoElements: boolean): TFPList;
  2059. var
  2060. SrcLabel: PSrcMarker;
  2061. begin
  2062. SrcLabel:=FindSrcLabel(Identifier);
  2063. if SrcLabel=nil then
  2064. Fail('missing label "'+Identifier+'"');
  2065. Result:=FindElementsAt(SrcLabel,ErrorOnNoElements);
  2066. end;
  2067. procedure TCustomTestResolver.WriteSources(const aFilename: string; aRow,
  2068. aCol: integer);
  2069. var
  2070. IsSrc: Boolean;
  2071. i, j: Integer;
  2072. SrcLines: TStringList;
  2073. SrcFilename, Line: string;
  2074. begin
  2075. for i:=0 to Resolver.Streams.Count-1 do
  2076. begin
  2077. GetSrc(i,SrcLines,SrcFilename);
  2078. IsSrc:=ExtractFilename(SrcFilename)=ExtractFileName(aFilename);
  2079. writeln('Testcode:-File="',SrcFilename,'"----------------------------------:');
  2080. for j:=1 to SrcLines.Count do
  2081. begin
  2082. Line:=SrcLines[j-1];
  2083. if IsSrc and (j=aRow) then
  2084. begin
  2085. write('*');
  2086. Line:=LeftStr(Line,aCol-1)+'|'+copy(Line,aCol,length(Line));
  2087. end;
  2088. writeln(Format('%:4d: ',[j]),Line);
  2089. end;
  2090. SrcLines.Free;
  2091. end;
  2092. end;
  2093. procedure TCustomTestResolver.RaiseErrorAtSrc(Msg: string; const aFilename: string;
  2094. aRow, aCol: integer);
  2095. var
  2096. s: String;
  2097. begin
  2098. s:='[TTestResolver.RaiseErrorAtSrc] '+aFilename+'('+IntToStr(aRow)+','+IntToStr(aCol)+') Error: '+Msg;
  2099. {$IFNDEF NOCONSOLE}
  2100. WriteSources(aFilename,aRow,aCol);
  2101. writeln('ERROR: ',s);
  2102. {$ENDIF}
  2103. Fail(s);
  2104. end;
  2105. procedure TCustomTestResolver.RaiseErrorAtSrcMarker(Msg: string; aMarker: PSrcMarker);
  2106. begin
  2107. RaiseErrorAtSrc(Msg,aMarker^.Filename,aMarker^.Row,aMarker^.StartCol);
  2108. end;
  2109. procedure TCustomTestResolver.HandleError(CurEngine: TTestEnginePasResolver;
  2110. E: Exception);
  2111. {$IFNDEF NOCONSOLE}
  2112. var
  2113. ErrFilename: String;
  2114. ErrRow, ErrCol: Integer;
  2115. {$ENDIF}
  2116. begin
  2117. if CurEngine=nil then ;
  2118. {$IFNDEF NOCONSOLE}
  2119. ErrFilename:=CurEngine.Scanner.CurFilename;
  2120. ErrRow:=CurEngine.Scanner.CurRow;
  2121. ErrCol:=CurEngine.Scanner.CurColumn;
  2122. writeln('ERROR: TCustomTestResolver.HandleError during parsing: '+E.ClassName+':'+E.Message
  2123. +' File='+ErrFilename
  2124. +' LineNo='+IntToStr(ErrRow)
  2125. +' Col='+IntToStr(ErrCol)
  2126. +' Line="'+CurEngine.Scanner.CurLine+'"'
  2127. );
  2128. WriteSources(ErrFilename,ErrRow,ErrCol);
  2129. {$ENDIF}
  2130. Fail(E.Message);
  2131. end;
  2132. constructor TCustomTestResolver.Create;
  2133. begin
  2134. inherited Create;
  2135. FResolverMsgs:=TObjectList.Create(true);
  2136. FResolverGoodMsgs:=TFPList.Create;
  2137. end;
  2138. destructor TCustomTestResolver.Destroy;
  2139. begin
  2140. FreeAndNil(FResolverMsgs);
  2141. FreeAndNil(FResolverGoodMsgs);
  2142. inherited Destroy;
  2143. end;
  2144. function TCustomTestResolver.FindModuleWithFilename(aFilename: string
  2145. ): TTestEnginePasResolver;
  2146. var
  2147. i: Integer;
  2148. begin
  2149. for i:=0 to ModuleCount-1 do
  2150. if CompareText(Modules[i].Filename,aFilename)=0 then
  2151. exit(Modules[i]);
  2152. Result:=nil;
  2153. end;
  2154. function TCustomTestResolver.AddModule(aFilename: string): TTestEnginePasResolver;
  2155. begin
  2156. //writeln('TTestResolver.AddModule ',aFilename);
  2157. if FindModuleWithFilename(aFilename)<>nil then
  2158. Fail('TTestResolver.AddModule: file "'+aFilename+'" already exists');
  2159. Result:=TTestEnginePasResolver.Create;
  2160. Result.Filename:=aFilename;
  2161. Result.AddObjFPCBuiltInIdentifiers;
  2162. Result.OnFindUnit:=@OnPasResolverFindUnit;
  2163. Result.OnLog:=@OnPasResolverLog;
  2164. Result.Hub:=Hub;
  2165. Result.ExprEvaluator.DefaultStringCodePage:=CP_UTF8;
  2166. Result.ExprEvaluator.DefaultSourceCodePage:=CP_UTF8;
  2167. FResolvers.Add(Result);
  2168. end;
  2169. function TCustomTestResolver.AddModuleWithSrc(aFilename, Src: string
  2170. ): TTestEnginePasResolver;
  2171. begin
  2172. Result:=AddModule(aFilename);
  2173. Result.Source:=Src;
  2174. end;
  2175. function TCustomTestResolver.AddModuleWithIntfImplSrc(aFilename, InterfaceSrc,
  2176. ImplementationSrc: string): TTestEnginePasResolver;
  2177. var
  2178. Src: String;
  2179. begin
  2180. Src:='{$mode objfpc}';
  2181. Src+='unit '+ExtractFileUnitName(aFilename)+';'+LineEnding;
  2182. Src+=LineEnding;
  2183. Src+='interface'+LineEnding;
  2184. Src+=LineEnding;
  2185. Src+=InterfaceSrc;
  2186. Src+='implementation'+LineEnding;
  2187. Src+=LineEnding;
  2188. Src+=ImplementationSrc;
  2189. Src+='end.'+LineEnding;
  2190. Result:=AddModuleWithSrc(aFilename,Src);
  2191. end;
  2192. procedure TCustomTestResolver.AddSystemUnit(Parts: TSystemUnitParts);
  2193. var
  2194. Intf, Impl: TStringList;
  2195. begin
  2196. Intf:=TStringList.Create;
  2197. // interface
  2198. Intf.Add('type');
  2199. if supTTypeKind in Parts then
  2200. begin
  2201. Intf.Add(' TTypeKind=(tkUnknown,tkInteger,tkChar,tkEnumeration,tkFloat,');
  2202. Intf.Add(' tkSet,tkMethod,tkSString,tkLString,tkAString,');
  2203. Intf.Add(' tkWString,tkVariant,tkArray,tkRecord,tkInterface,');
  2204. Intf.Add(' tkClass,tkObject,tkWChar,tkBool,tkInt64,tkQWord,');
  2205. Intf.Add(' tkDynArray,tkInterfaceRaw,tkProcVar,tkUString,tkUChar,');
  2206. Intf.Add(' tkHelper,tkFile,tkClassRef,tkPointer);');
  2207. end;
  2208. Intf.Add(' integer=longint;');
  2209. Intf.Add(' sizeint=int64;');
  2210. //'const',
  2211. //' LineEnding = #10;',
  2212. //' DirectorySeparator = ''/'';',
  2213. //' DriveSeparator = '''';',
  2214. //' AllowDirectorySeparators : set of AnsiChar = [''\'',''/''];',
  2215. //' AllowDriveSeparators : set of AnsiChar = [];',
  2216. if supTObject in Parts then
  2217. begin
  2218. Intf.AddStrings([
  2219. 'type',
  2220. ' TClass = class of TObject;',
  2221. ' TObject = class',
  2222. ' constructor Create;',
  2223. ' destructor Destroy; virtual;',
  2224. ' class function ClassType: TClass; assembler;',
  2225. ' class function ClassName: String; assembler;',
  2226. ' class function ClassNameIs(const Name: string): boolean;',
  2227. ' class function ClassParent: TClass; assembler;',
  2228. ' class function InheritsFrom(aClass: TClass): boolean; assembler;',
  2229. ' class function UnitName: String; assembler;',
  2230. ' procedure AfterConstruction; virtual;',
  2231. ' procedure BeforeDestruction;virtual;',
  2232. ' function Equals(Obj: TObject): boolean; virtual;',
  2233. ' function ToString: String; virtual;',
  2234. ' end;']);
  2235. end;
  2236. if supTVarRec in Parts then
  2237. begin
  2238. Intf.AddStrings([
  2239. 'const',
  2240. ' vtInteger = 0;',
  2241. ' vtBoolean = 1;',
  2242. 'type',
  2243. ' PVarRec = ^TVarRec;',
  2244. ' TVarRec = record',
  2245. ' case VType : sizeint of',
  2246. ' vtInteger : (VInteger: Longint);',
  2247. ' vtBoolean : (VBoolean: Boolean);',
  2248. ' end;']);
  2249. end;
  2250. Intf.Add('var');
  2251. Intf.Add(' ExitCode: Longint = 0;');
  2252. // implementation
  2253. Impl:=TStringList.Create;
  2254. if supTObject in Parts then
  2255. begin
  2256. Impl.AddStrings([
  2257. '// needed by ClassNameIs, the real SameText is in SysUtils',
  2258. 'function SameText(const s1, s2: String): Boolean; assembler;',
  2259. 'asm',
  2260. 'end;',
  2261. 'constructor TObject.Create; begin end;',
  2262. 'destructor TObject.Destroy; begin end;',
  2263. 'class function TObject.ClassType: TClass; assembler;',
  2264. 'asm',
  2265. 'end;',
  2266. 'class function TObject.ClassName: String; assembler;',
  2267. 'asm',
  2268. 'end;',
  2269. 'class function TObject.ClassNameIs(const Name: string): boolean;',
  2270. 'begin',
  2271. ' Result:=SameText(Name,ClassName);',
  2272. 'end;',
  2273. 'class function TObject.ClassParent: TClass; assembler;',
  2274. 'asm',
  2275. 'end;',
  2276. 'class function TObject.InheritsFrom(aClass: TClass): boolean; assembler;',
  2277. 'asm',
  2278. 'end;',
  2279. 'class function TObject.UnitName: String; assembler;',
  2280. 'asm',
  2281. 'end;',
  2282. 'procedure TObject.AfterConstruction; begin end;',
  2283. 'procedure TObject.BeforeDestruction; begin end;',
  2284. 'function TObject.Equals(Obj: TObject): boolean;',
  2285. 'begin',
  2286. ' Result:=Obj=Self;',
  2287. 'end;',
  2288. 'function TObject.ToString: String;',
  2289. 'begin',
  2290. ' Result:=ClassName;',
  2291. 'end;'
  2292. ]);
  2293. end;
  2294. try
  2295. AddModuleWithIntfImplSrc('system.pp',Intf.Text,Impl.Text);
  2296. finally
  2297. Intf.Free;
  2298. Impl.Free;
  2299. end;
  2300. end;
  2301. procedure TCustomTestResolver.StartProgram(NeedSystemUnit: boolean;
  2302. SystemUnitParts: TSystemUnitParts);
  2303. begin
  2304. if NeedSystemUnit then
  2305. AddSystemUnit(SystemUnitParts)
  2306. else
  2307. Parser.ImplicitUses.Clear;
  2308. Add('program '+ExtractFileUnitName(MainFilename)+';');
  2309. end;
  2310. procedure TCustomTestResolver.StartLibrary(NeedSystemUnit: boolean;
  2311. SystemUnitParts: TSystemUnitParts);
  2312. begin
  2313. if NeedSystemUnit then
  2314. AddSystemUnit(SystemUnitParts)
  2315. else
  2316. Parser.ImplicitUses.Clear;
  2317. Add('library '+ExtractFileUnitName(MainFilename)+';');
  2318. end;
  2319. procedure TCustomTestResolver.StartUnit(NeedSystemUnit: boolean;
  2320. SystemUnitParts: TSystemUnitParts);
  2321. begin
  2322. if NeedSystemUnit then
  2323. AddSystemUnit(SystemUnitParts)
  2324. else
  2325. Parser.ImplicitUses.Clear;
  2326. Add('unit '+ExtractFileUnitName(MainFilename)+';');
  2327. end;
  2328. function TCustomTestResolver.OnPasResolverFindUnit(SrcResolver: TPasResolver;
  2329. const aUnitName, InFilename: String; NameExpr, InFileExpr: TPasExpr
  2330. ): TPasModule;
  2331. function InitUnit(CurEngine: TTestEnginePasResolver): TPasModule;
  2332. begin
  2333. if CurEngine.Module<>nil then
  2334. Fail('InitUnit '+GetObjName(CurEngine.Module));
  2335. CurEngine.StreamResolver:=Resolver;
  2336. //writeln('TTestResolver.OnPasResolverFindUnit SOURCE=',CurEngine.Source);
  2337. CurEngine.StreamResolver.AddStream(CurEngine.FileName,
  2338. TStringStream.Create(CurEngine.Source));
  2339. CurEngine.Scanner:=TPascalScanner.Create(CurEngine.StreamResolver);
  2340. CurEngine.Scanner.CurrentBoolSwitches:=[bsHints,bsNotes,bsWarnings];
  2341. CurEngine.Parser:=TPasParser.Create(CurEngine.Scanner,
  2342. CurEngine.StreamResolver,CurEngine);
  2343. CurEngine.Parser.Options:=CurEngine.Parser.Options+[po_StopOnUnitInterface];
  2344. if CompareText(ExtractFileUnitName(CurEngine.Filename),'System')=0 then
  2345. CurEngine.Parser.ImplicitUses.Clear;
  2346. CurEngine.Scanner.OpenFile(CurEngine.Filename);
  2347. try
  2348. CurEngine.Parser.NextToken;
  2349. CurEngine.Parser.ParseUnit(CurEngine.FModule);
  2350. except
  2351. on E: Exception do
  2352. HandleError(CurEngine,E);
  2353. end;
  2354. //writeln('TTestResolver.OnPasResolverFindUnit END ',CurUnitName);
  2355. Result:=CurEngine.Module;
  2356. end;
  2357. function FindUnit(const aUnitName: String): TPasModule;
  2358. var
  2359. i: Integer;
  2360. CurEngine: TTestEnginePasResolver;
  2361. CurUnitName: String;
  2362. begin
  2363. {$IFDEF VerboseUnitSearch}
  2364. writeln('TTestResolver.OnPasResolverFindUnit START Unit="',aUnitName,'"');
  2365. {$ENDIF}
  2366. Result:=nil;
  2367. for i:=0 to ModuleCount-1 do
  2368. begin
  2369. CurEngine:=Modules[i];
  2370. CurUnitName:=ExtractFileUnitName(CurEngine.Filename);
  2371. {$IFDEF VerboseUnitSearch}
  2372. writeln('TTestResolver.OnPasResolverFindUnit Checking ',i,'/',ModuleCount,' ',CurEngine.Filename,' ',CurUnitName);
  2373. {$ENDIF}
  2374. if CompareText(aUnitName,CurUnitName)=0 then
  2375. begin
  2376. Result:=CurEngine.Module;
  2377. {$IFDEF VerboseUnitSearch}
  2378. writeln('TTestResolver.OnPasResolverFindUnit Found unit "',CurEngine.Filename,'" Module=',GetObjName(Result));
  2379. {$ENDIF}
  2380. if Result<>nil then exit;
  2381. {$IFDEF VerboseUnitSearch}
  2382. writeln('TTestResolver.OnPasResolverFindUnit PARSING unit "',CurEngine.Filename,'"');
  2383. {$ENDIF}
  2384. Result:=InitUnit(CurEngine);
  2385. exit;
  2386. end;
  2387. end;
  2388. end;
  2389. function GetResolver(aFilename: string): boolean;
  2390. var
  2391. CurEngine: TTestEnginePasResolver;
  2392. aModule: TPasModule;
  2393. begin
  2394. {$IFDEF VerbosePasResolver}
  2395. writeln('TCustomTestResolver.OnPasResolverFindUnit searching file "',aFilename,'"');
  2396. {$ENDIF}
  2397. CurEngine:=FindModuleWithFilename(aFilename);
  2398. if CurEngine=nil then exit(false);
  2399. if CurEngine.Module=nil then
  2400. begin
  2401. aModule:=InitUnit(CurEngine);
  2402. if aModule=nil then exit(false);
  2403. end
  2404. else
  2405. aModule:=CurEngine.Module;
  2406. OnPasResolverFindUnit:=aModule;
  2407. Result:=true;
  2408. end;
  2409. var
  2410. aFilename: String;
  2411. begin
  2412. if SrcResolver=nil then ;
  2413. if NameExpr=nil then ;
  2414. if InFilename<>'' then
  2415. begin
  2416. // uses IN parameter
  2417. {$IFDEF VerbosePasResolver}
  2418. writeln('TCustomTestResolver.OnPasResolverFindUnit searching IN-file "',InFilename,'"');
  2419. {$ENDIF}
  2420. if SrcResolver<>ResolverEngine then
  2421. SrcResolver.RaiseMsg(20180222004753,100000,'in-file only allowed in program',
  2422. [],InFileExpr);
  2423. aFilename:=InFilename;
  2424. DoDirSeparators(aFilename);
  2425. if FilenameIsAbsolute(aFilename) then
  2426. if GetResolver(aFilename) then exit;
  2427. aFilename:=ExtractFilePath(ResolverEngine.Filename)+aFilename;
  2428. if GetResolver(aFilename) then exit;
  2429. SrcResolver.RaiseMsg(20180222004311,100001,'in-file ''%s'' not found',
  2430. [InFilename],InFileExpr);
  2431. end;
  2432. if (Pos('.',aUnitName)<1) and (ResolverEngine.DefaultNameSpace<>'') then
  2433. begin
  2434. // first search in default program namespace
  2435. {$IFDEF VerbosePasResolver}
  2436. writeln('TCustomTestResolver.OnPasResolverFindUnit searching "',aUnitName,'" in default program/library namespace "',ResolverEngine.DefaultNameSpace,'"');
  2437. {$ENDIF}
  2438. Result:=FindUnit(ResolverEngine.DefaultNameSpace+'.'+aUnitName);
  2439. if Result<>nil then exit;
  2440. end;
  2441. Result:=FindUnit(aUnitName);
  2442. if Result<>nil then exit;
  2443. {$IFDEF VerbosePasResolver}
  2444. writeln('TTestResolver.OnPasResolverFindUnit missing unit "',aUnitName,'"');
  2445. {$ENDIF}
  2446. end;
  2447. procedure TCustomTestResolver.OnFindReference(El: TPasElement; FindData: pointer);
  2448. var
  2449. Data: PTestResolverReferenceData absolute FindData;
  2450. Line, Col: integer;
  2451. begin
  2452. ResolverEngine.UnmangleSourceLineNumber(El.SourceLinenumber,Line,Col);
  2453. //writeln('TTestResolver.OnFindReference ',El.SourceFilename,' Line=',Line,',Col=',Col,' ',GetObjName(El),' SearchFile=',Data^.Filename,',Line=',Data^.Row,',Col=',Data^.StartCol,'-',Data^.EndCol);
  2454. if (Data^.Filename=El.SourceFilename)
  2455. and (Data^.Row=Line)
  2456. and (Data^.StartCol<=Col)
  2457. and (Data^.EndCol>=Col)
  2458. then
  2459. Data^.Found.Add(El);
  2460. end;
  2461. procedure TCustomTestResolver.OnCheckElementParent(El: TPasElement; arg: pointer);
  2462. var
  2463. SubEl: TPasElement;
  2464. i: Integer;
  2465. procedure E(Msg: string);
  2466. var
  2467. s: String;
  2468. begin
  2469. s:='TTestResolver.OnCheckElementParent El='+GetTreeDbg(El)+' '+
  2470. ResolverEngine.GetElementSourcePosStr(El)+' '+Msg;
  2471. {$IFNDEF NOCONSOLE}
  2472. writeln('ERROR: ',s);
  2473. {$ENDIF}
  2474. Fail(s);
  2475. end;
  2476. begin
  2477. if arg=nil then ;
  2478. //writeln('TTestResolver.OnCheckElementParent ',GetObjName(El));
  2479. if El=nil then exit;
  2480. if El.Parent=El then
  2481. E('El.Parent=El='+GetObjName(El));
  2482. if El is TBinaryExpr then
  2483. begin
  2484. if (TBinaryExpr(El).Left<>nil) and (TBinaryExpr(El).Left.Parent<>El) then
  2485. E('TBinaryExpr(El).left.Parent='+GetObjName(TBinaryExpr(El).Left.Parent)+'<>El');
  2486. if (TBinaryExpr(El).Right<>nil) and (TBinaryExpr(El).Right.Parent<>El) then
  2487. E('TBinaryExpr(El).right.Parent='+GetObjName(TBinaryExpr(El).Right.Parent)+'<>El');
  2488. end
  2489. else if El is TParamsExpr then
  2490. begin
  2491. if (TParamsExpr(El).Value<>nil) and (TParamsExpr(El).Value.Parent<>El) then
  2492. E('TParamsExpr(El).Value.Parent='+GetObjName(TParamsExpr(El).Value.Parent)+'<>El');
  2493. for i:=0 to length(TParamsExpr(El).Params)-1 do
  2494. if TParamsExpr(El).Params[i].Parent<>El then
  2495. E('TParamsExpr(El).Params[i].Parent='+GetObjName(TParamsExpr(El).Params[i].Parent)+'<>El');
  2496. end
  2497. else if El is TProcedureExpr then
  2498. begin
  2499. if (TProcedureExpr(El).Proc<>nil) and (TProcedureExpr(El).Proc.Parent<>El) then
  2500. E('TProcedureExpr(El).Proc.Parent='+GetObjName(TProcedureExpr(El).Proc.Parent)+'<>El');
  2501. end
  2502. else if El is TPasDeclarations then
  2503. begin
  2504. for i:=0 to TPasDeclarations(El).Declarations.Count-1 do
  2505. begin
  2506. SubEl:=TPasElement(TPasDeclarations(El).Declarations[i]);
  2507. if SubEl.Parent<>El then
  2508. E('SubEl=TPasElement(TPasDeclarations(El).Declarations[i])='+GetObjName(SubEl)+' SubEl.Parent='+GetObjName(SubEl.Parent)+'<>El');
  2509. end;
  2510. end
  2511. else if El is TPasImplBlock then
  2512. begin
  2513. for i:=0 to TPasImplBlock(El).Elements.Count-1 do
  2514. begin
  2515. SubEl:=TPasElement(TPasImplBlock(El).Elements[i]);
  2516. if SubEl.Parent<>El then
  2517. E('TPasElement(TPasImplBlock(El).Elements[i]).Parent='+GetObjName(SubEl.Parent)+'<>El');
  2518. end;
  2519. end
  2520. else if El is TPasImplWithDo then
  2521. begin
  2522. for i:=0 to TPasImplWithDo(El).Expressions.Count-1 do
  2523. begin
  2524. SubEl:=TPasExpr(TPasImplWithDo(El).Expressions[i]);
  2525. if SubEl.Parent<>El then
  2526. E('TPasExpr(TPasImplWithDo(El).Expressions[i]).Parent='+GetObjName(SubEl.Parent)+'<>El');
  2527. end;
  2528. end
  2529. else if El is TPasProcedure then
  2530. begin
  2531. if TPasProcedure(El).ProcType.Parent<>El then
  2532. E('TPasProcedure(El).ProcType.Parent='+GetObjName(TPasProcedure(El).ProcType.Parent)+'<>El');
  2533. end
  2534. else if El is TPasProcedureType then
  2535. begin
  2536. for i:=0 to TPasProcedureType(El).Args.Count-1 do
  2537. if TPasArgument(TPasProcedureType(El).Args[i]).Parent<>El then
  2538. E('TPasArgument(TPasProcedureType(El).Args[i]).Parent='+GetObjName(TPasArgument(TPasProcedureType(El).Args[i]).Parent)+'<>El');
  2539. end;
  2540. end;
  2541. procedure TCustomTestResolver.FreeSrcMarkers;
  2542. var
  2543. aMarker, Last: PSrcMarker;
  2544. begin
  2545. aMarker:=FirstSrcMarker;
  2546. while aMarker<>nil do
  2547. begin
  2548. Last:=aMarker;
  2549. aMarker:=aMarker^.Next;
  2550. Dispose(Last);
  2551. end;
  2552. FirstSrcMarker:=nil;
  2553. LastSrcMarker:=nil;
  2554. end;
  2555. procedure TCustomTestResolver.OnPasResolverLog(Sender: TObject;
  2556. const Msg: String);
  2557. var
  2558. aResolver: TTestEnginePasResolver;
  2559. Item: TTestResolverMessage;
  2560. begin
  2561. aResolver:=Sender as TTestEnginePasResolver;
  2562. Item:=TTestResolverMessage.Create;
  2563. Item.Id:=aResolver.LastMsgId;
  2564. Item.MsgType:=aResolver.LastMsgType;
  2565. Item.MsgNumber:=aResolver.LastMsgNumber;
  2566. Item.Msg:=Msg;
  2567. Item.SourcePos:=aResolver.LastSourcePos;
  2568. {$IFDEF VerbosePasResolver}
  2569. writeln('TCustomTestResolver.OnPasResolverLog ',GetObjName(Sender),' ',Item.MsgType,' (',Item.MsgNumber,') {',Msg,'}');
  2570. {$ENDIF}
  2571. FResolverMsgs.Add(Item);
  2572. end;
  2573. procedure TCustomTestResolver.OnScannerDirective(Sender: TObject; Directive,
  2574. Param: TPasScannerString; var Handled: boolean);
  2575. var
  2576. aScanner: TPascalScanner;
  2577. begin
  2578. if Handled then exit;
  2579. aScanner:=Sender as TPascalScanner;
  2580. aScanner.LastMsgType:=mtError;
  2581. aScanner.LastMsg:='unknown directive "'+Directive+'"';
  2582. aScanner.LastMsgPattern:=aScanner.LastMsg;
  2583. aScanner.LastMsgArgs:=nil;
  2584. raise EScannerError.Create(aScanner.LastMsg);
  2585. if Param='' then ;
  2586. end;
  2587. procedure TCustomTestResolver.OnScannerLog(Sender: TObject; const Msg: String);
  2588. var
  2589. aScanner: TPascalScanner;
  2590. begin
  2591. aScanner:=TPascalScanner(Sender);
  2592. if aScanner=nil then exit;
  2593. {$IFDEF VerbosePasResolver}
  2594. writeln('TCustomTestResolver.OnScannerLog ',GetObjName(Sender),' ',aScanner.LastMsgType,' ',aScanner.LastMsgNumber,' Msg="', Msg,'"');
  2595. {$ENDIF}
  2596. end;
  2597. function TCustomTestResolver.GetModules(Index: integer): TTestEnginePasResolver;
  2598. begin
  2599. Result:=TTestEnginePasResolver(FResolvers[Index]);
  2600. end;
  2601. function TCustomTestResolver.GetMsgCount: integer;
  2602. begin
  2603. Result:=FResolverMsgs.Count;
  2604. end;
  2605. function TCustomTestResolver.GetMsgs(Index: integer): TTestResolverMessage;
  2606. begin
  2607. Result:=TTestResolverMessage(FResolverMsgs[Index]);
  2608. end;
  2609. procedure TCustomTestResolver.OnPasResolverContinueParsing(Sender: TPasResolver
  2610. );
  2611. var
  2612. CurEngine: TTestEnginePasResolver;
  2613. begin
  2614. CurEngine:=Sender as TTestEnginePasResolver;
  2615. {$IFDEF VerbosePasResolver}
  2616. writeln('TCustomTestResolver.OnPasResolverContinueParsing "',CurEngine.Module.Name,'"...');
  2617. {$ENDIF}
  2618. try
  2619. CurEngine.Parser.ParseContinue;
  2620. except
  2621. on E: Exception do
  2622. HandleError(CurEngine,E);
  2623. end;
  2624. end;
  2625. function TCustomTestResolver.GetModuleCount: integer;
  2626. begin
  2627. Result:=FResolvers.Count;
  2628. end;
  2629. { TTestResolver }
  2630. procedure TTestResolver.TestEmpty;
  2631. begin
  2632. StartProgram(false);
  2633. Add('begin');
  2634. ParseProgram;
  2635. AssertEquals('No statements',0,PasProgram.InitializationSection.Elements.Count);
  2636. end;
  2637. procedure TTestResolver.TestAliasType;
  2638. var
  2639. El: TPasElement;
  2640. T: TPasAliasType;
  2641. begin
  2642. StartProgram(false);
  2643. Add('type');
  2644. Add(' tint=longint;');
  2645. Add('begin');
  2646. ParseProgram;
  2647. AssertEquals('1 declaration',1,PasProgram.ProgramSection.Declarations.Count);
  2648. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  2649. AssertEquals('Type',TPasAliasType,El.ClassType);
  2650. T:=TPasAliasType(El);
  2651. AssertEquals('Type tint','tint',T.Name);
  2652. AssertEquals('Type built-in',TPasUnresolvedSymbolRef,T.DestType.ClassType);
  2653. AssertEquals('longint type','longint',lowercase(T.DestType.Name));
  2654. end;
  2655. procedure TTestResolver.TestAlias2Type;
  2656. var
  2657. El: TPasElement;
  2658. T1, T2: TPasAliasType;
  2659. DestT1, DestT2: TPasType;
  2660. begin
  2661. StartProgram(false);
  2662. Add('type');
  2663. Add(' tint1=longint;');
  2664. Add(' tint2=tint1;');
  2665. Add('begin');
  2666. ParseProgram;
  2667. AssertEquals('2 declaration',2,PasProgram.ProgramSection.Declarations.Count);
  2668. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  2669. AssertEquals('Type',TPasAliasType,El.ClassType);
  2670. T1:=TPasAliasType(El);
  2671. AssertEquals('Type tint1','tint1',T1.Name);
  2672. DestT1:=T1.DestType;
  2673. AssertEquals('built-in',TPasUnresolvedSymbolRef,DestT1.ClassType);
  2674. AssertEquals('built-in longint','longint',lowercase(DestT1.Name));
  2675. El:=TPasElement(PasProgram.ProgramSection.Declarations[1]);
  2676. AssertEquals('Type',TPasAliasType,El.ClassType);
  2677. T2:=TPasAliasType(El);
  2678. AssertEquals('Type tint2','tint2',T2.Name);
  2679. DestT2:=T2.DestType;
  2680. AssertEquals('points to alias type',TPasAliasType,DestT2.ClassType);
  2681. AssertEquals('points to tint1','tint1',DestT2.Name);
  2682. end;
  2683. procedure TTestResolver.TestAliasTypeRefs;
  2684. begin
  2685. StartProgram(false);
  2686. Add('type');
  2687. Add(' {#a}a=longint;');
  2688. Add(' {#b}{=a}b=a;');
  2689. Add('var');
  2690. Add(' {=a}c: a;');
  2691. Add(' {=b}d: b;');
  2692. Add('begin');
  2693. ParseProgram;
  2694. end;
  2695. procedure TTestResolver.TestAliasOfVarFail;
  2696. begin
  2697. StartProgram(false);
  2698. Add('var');
  2699. Add(' a: AnsiChar;');
  2700. Add('type');
  2701. Add(' t=a;');
  2702. Add('begin');
  2703. CheckParserException('Expected type, but got variable',PParser.nParserExpectedTypeButGot);
  2704. end;
  2705. procedure TTestResolver.TestAliasType_UnitPrefix;
  2706. begin
  2707. StartUnit(false);
  2708. Add('interface');
  2709. Add('type');
  2710. Add(' {#a}a=longint;');
  2711. Add(' {#b}{=a}b=afile.a;');
  2712. Add('var');
  2713. Add(' {=a}c: a;');
  2714. Add(' {=b}d: b;');
  2715. Add('implementation');
  2716. ParseUnit;
  2717. end;
  2718. procedure TTestResolver.TestAliasType_UnitPrefix_CycleFail;
  2719. begin
  2720. StartUnit(false);
  2721. Add('interface');
  2722. Add('type');
  2723. Add(' {#a}a=afile.a;');
  2724. Add('implementation');
  2725. CheckResolverException('identifier not found "a"',nIdentifierNotFound);
  2726. end;
  2727. procedure TTestResolver.TestAliasTypeNotFoundPosition;
  2728. begin
  2729. StartProgram(false);
  2730. Add('type');
  2731. Add(' integer = longint;');
  2732. Add(' TColor = NotThere;');
  2733. CheckResolverException('identifier not found "NotThere"',nIdentifierNotFound);
  2734. // TColor element was not created yet, so LastElement must be nil
  2735. AssertNull('ResolverEngine.LastElement',ResolverEngine.LastElement);
  2736. with ResolverEngine.LastSourcePos do
  2737. begin
  2738. //writeln('TTestResolver.TestAliasTypeNotFoundPosition ',FileName,' ',Row,' ',Col);
  2739. //WriteSources(FileName,Row,Column);
  2740. AssertEquals('ResolverEngine.LastSourcePos.Filename','afile.pp',FileName);
  2741. AssertEquals('ResolverEngine.LastSourcePos.Row',4,Row);
  2742. AssertEquals('ResolverEngine.LastSourcePos.Column',20,Column);
  2743. end;
  2744. end;
  2745. procedure TTestResolver.TestTypeAliasType;
  2746. begin
  2747. StartProgram(false);
  2748. Add([
  2749. 'type',
  2750. ' {#integer}integer = longint;',
  2751. ' {#tcolor}TColor = type integer;',
  2752. 'var',
  2753. ' {=integer}i: integer;',
  2754. ' {=tcolor}c: TColor;',
  2755. 'begin',
  2756. ' c:=i;',
  2757. ' i:=c;',
  2758. ' i:=integer(c);',
  2759. ' c:=TColor(i);',
  2760. '']);
  2761. ParseProgram;
  2762. end;
  2763. procedure TTestResolver.TestVarLongint;
  2764. var
  2765. El: TPasElement;
  2766. V1: TPasVariable;
  2767. DestT1: TPasType;
  2768. begin
  2769. StartProgram(false);
  2770. Add('var');
  2771. Add(' v1:longint;');
  2772. Add('begin');
  2773. ParseProgram;
  2774. AssertEquals('1 declaration',1,PasProgram.ProgramSection.Declarations.Count);
  2775. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  2776. AssertEquals('var',TPasVariable,El.ClassType);
  2777. V1:=TPasVariable(El);
  2778. AssertEquals('var v1','v1',V1.Name);
  2779. DestT1:=V1.VarType;
  2780. AssertEquals('built-in',TPasUnresolvedSymbolRef,DestT1.ClassType);
  2781. AssertEquals('built-in longint','longint',lowercase(DestT1.Name));
  2782. end;
  2783. procedure TTestResolver.TestVarInteger;
  2784. var
  2785. El: TPasElement;
  2786. V1: TPasVariable;
  2787. DestT1: TPasType;
  2788. begin
  2789. StartProgram(true);
  2790. Add('var');
  2791. Add(' v1:integer;'); // defined in system.pp
  2792. Add('begin');
  2793. ParseProgram;
  2794. AssertEquals('1 declaration',1,PasProgram.ProgramSection.Declarations.Count);
  2795. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  2796. AssertEquals('var',TPasVariable,El.ClassType);
  2797. V1:=TPasVariable(El);
  2798. AssertEquals('var v1','v1',V1.Name);
  2799. DestT1:=V1.VarType;
  2800. AssertNotNull('v1 type',DestT1);
  2801. AssertEquals('built-in',TPasAliasType,DestT1.ClassType);
  2802. AssertEquals('built-in integer','integer',DestT1.Name);
  2803. AssertNull('v1 no expr',V1.Expr);
  2804. end;
  2805. procedure TTestResolver.TestConstInteger;
  2806. var
  2807. El: TPasElement;
  2808. C1: TPasConst;
  2809. DestT1: TPasType;
  2810. ExprC1: TPrimitiveExpr;
  2811. begin
  2812. StartProgram(true);
  2813. Add('const');
  2814. Add(' c1: integer=3;'); // defined in system.pp
  2815. Add('begin');
  2816. ParseProgram;
  2817. AssertEquals('1 declaration',1,PasProgram.ProgramSection.Declarations.Count);
  2818. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  2819. AssertEquals('const',TPasConst,El.ClassType);
  2820. C1:=TPasConst(El);
  2821. AssertEquals('const c1','c1',C1.Name);
  2822. DestT1:=C1.VarType;
  2823. AssertNotNull('c1 type',DestT1);
  2824. AssertEquals('built-in',TPasAliasType,DestT1.ClassType);
  2825. AssertEquals('built-in integer','integer',DestT1.Name);
  2826. ExprC1:=TPrimitiveExpr(C1.Expr);
  2827. AssertNotNull('c1 expr',ExprC1);
  2828. AssertEquals('c1 expr primitive',TPrimitiveExpr,ExprC1.ClassType);
  2829. AssertEquals('c1 expr value','3',ExprC1.Value);
  2830. end;
  2831. procedure TTestResolver.TestConstInteger2;
  2832. begin
  2833. StartProgram(false);
  2834. Add('const');
  2835. Add(' c1 = 3');
  2836. Add(' c2: longint=c1;');
  2837. Add('begin');
  2838. CheckResolverUnexpectedHints;
  2839. end;
  2840. procedure TTestResolver.TestDuplicateVar;
  2841. begin
  2842. StartProgram(false);
  2843. Add('var a: longint;');
  2844. Add('var a: string;');
  2845. Add('begin');
  2846. CheckResolverException(sDuplicateIdentifier,nDuplicateIdentifier);
  2847. end;
  2848. procedure TTestResolver.TestVarInitConst;
  2849. begin
  2850. StartProgram(false);
  2851. Add('const {#c}c=1;');
  2852. Add('var a: longint = {@c}c;');
  2853. Add('begin');
  2854. ParseProgram;
  2855. CheckResolverUnexpectedHints;
  2856. end;
  2857. procedure TTestResolver.TestVarOfVarFail;
  2858. begin
  2859. StartProgram(false);
  2860. Add('var');
  2861. Add(' a: AnsiChar;');
  2862. Add(' b: a;');
  2863. Add('begin');
  2864. CheckParserException('Expected type, but got variable',PParser.nParserExpectedTypeButGot);
  2865. end;
  2866. procedure TTestResolver.TestConstOfVarFail;
  2867. begin
  2868. StartProgram(false);
  2869. Add('var');
  2870. Add(' a: longint;');
  2871. Add('const');
  2872. Add(' b: a = 1;');
  2873. Add('begin');
  2874. CheckParserException('Expected type, but got variable',PParser.nParserExpectedTypeButGot);
  2875. end;
  2876. procedure TTestResolver.TestConstSelfFail;
  2877. begin
  2878. StartProgram(false);
  2879. Add('const');
  2880. Add(' a = a;');
  2881. Add('begin');
  2882. CheckResolverException('identifier not found "a"',nIdentifierNotFound);
  2883. end;
  2884. procedure TTestResolver.TestTypedConstWrongExprFail;
  2885. begin
  2886. StartProgram(false);
  2887. Add('const');
  2888. Add(' a: string = 1;');
  2889. Add('begin');
  2890. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  2891. nIncompatibleTypesGotExpected);
  2892. end;
  2893. procedure TTestResolver.TestVarWrongExprFail;
  2894. begin
  2895. StartProgram(false);
  2896. Add('var');
  2897. Add(' a: string = 1;');
  2898. Add('begin');
  2899. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  2900. nIncompatibleTypesGotExpected);
  2901. end;
  2902. procedure TTestResolver.TestArgWrongExprFail;
  2903. begin
  2904. StartProgram(false);
  2905. Add('procedure ProcA(a: string = 1);');
  2906. Add('begin');
  2907. Add('end;');
  2908. Add('begin');
  2909. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  2910. nIncompatibleTypesGotExpected);
  2911. end;
  2912. procedure TTestResolver.TestTypedConstInConstExprFail;
  2913. begin
  2914. StartProgram(false);
  2915. Add('const');
  2916. Add(' a: longint = 3;');
  2917. Add(' b: longint = a;');
  2918. Add('begin');
  2919. CheckResolverException('Constant expression expected',nConstantExpressionExpected);
  2920. end;
  2921. procedure TTestResolver.TestVarExternal;
  2922. begin
  2923. StartProgram(false);
  2924. Add('var');
  2925. Add(' NaN: double; external name ''Global.Nan'';');
  2926. Add('begin');
  2927. ParseProgram;
  2928. end;
  2929. procedure TTestResolver.TestVarNoSemicolonBeginFail;
  2930. begin
  2931. StartProgram(false);
  2932. Add('procedure DoIt; begin end;');
  2933. Add('var');
  2934. Add(' i: longint');
  2935. Add('begin');
  2936. Add(' doit;');
  2937. CheckParserException('Expected ";"',
  2938. nParserExpectTokenError);
  2939. end;
  2940. procedure TTestResolver.TestConstIntOperators;
  2941. begin
  2942. StartProgram(false);
  2943. Add([
  2944. 'type',
  2945. ' integer = longint;',
  2946. 'const',
  2947. ' a:byte=1+2;',
  2948. ' b:shortint=1-2;',
  2949. ' c:word=2*3;',
  2950. ' d:smallint=5 div 2;',
  2951. ' e:longword=5 mod 2;',
  2952. ' f:longint=5 shl 2;',
  2953. ' g:qword=5 shr 2;',
  2954. ' h:boolean=5=2;',
  2955. ' i:boolean=5<>2;',
  2956. ' j:boolean=5<2;',
  2957. ' k:boolean=5>2;',
  2958. ' l:boolean=5<=2;',
  2959. ' m:boolean=5>=2;',
  2960. ' n:longword=5 and 2;',
  2961. ' o:longword=5 or 2;',
  2962. ' p:longword=5 xor 2;',
  2963. ' q:longword=not (5 or not 2);',
  2964. ' r=low(word)+high(int64);',
  2965. ' s=low(longint)+high(integer);',
  2966. ' t=succ(2)+pred(2);',
  2967. ' lo1:byte=lo(word($1234));',
  2968. ' hi1:byte=hi(word($1234));',
  2969. ' lo2:word=lo(longword($1234CDEF));',
  2970. ' hi2:word=hi(longword($1234CDEF));',
  2971. ' lo3:word=lo(LongInt(-$1234CDEF));',
  2972. ' hi3:word=hi(LongInt(-$1234CDEF));',
  2973. ' lo4:byte=lo(byte($34));',
  2974. ' hi4:byte=hi(byte($34));',
  2975. ' lo5:byte=lo(shortint(-$34));',
  2976. ' hi5:byte=hi(shortint(-$34));',
  2977. ' lo6:longword=lo($123456789ABCDEF0);',
  2978. ' hi6:longword=hi($123456789ABCDEF0);',
  2979. ' lo7:longword=lo(-$123456789ABCDEF0);',
  2980. ' hi7:longword=hi(-$123456789ABCDEF0);',
  2981. 'begin']);
  2982. ParseProgram;
  2983. CheckResolverUnexpectedHints;
  2984. end;
  2985. procedure TTestResolver.TestConstBitwiseOps;
  2986. begin
  2987. StartProgram(false);
  2988. Add([
  2989. 'const',
  2990. ' a=3;',
  2991. ' b=not a;',
  2992. ' c=not word(a);',
  2993. ' d=1 shl 2;',
  2994. ' e=13 shr 1;',
  2995. ' f=13 and 5;',
  2996. ' g=10 or 5;',
  2997. ' h=5 xor 7;',
  2998. 'begin']);
  2999. ParseProgram;
  3000. CheckResolverUnexpectedHints;
  3001. end;
  3002. procedure TTestResolver.TestConstExternal;
  3003. begin
  3004. Parser.Options:=Parser.Options+[po_ExtConstWithoutExpr];
  3005. StartProgram(false);
  3006. Add([
  3007. 'const',
  3008. ' PI: double; external name ''Global.PI'';',
  3009. ' Tau = 2*PI;',
  3010. ' TauD: double = 2*PI;',
  3011. 'var',
  3012. ' d: double = PI;',
  3013. ' e: double = PI+Tau;',
  3014. 'begin',
  3015. ' d:=pi+tau;']);
  3016. ParseProgram;
  3017. // ToDo: fail on const Tau = 2*Var
  3018. end;
  3019. procedure TTestResolver.TestIntegerTypeCast;
  3020. begin
  3021. StartProgram(false);
  3022. Add([
  3023. 'const',
  3024. ' a=longint(-11);',
  3025. ' b=not shortint(-12);',
  3026. ' c=word(-2);',
  3027. ' d=word(longword(-3));',
  3028. 'begin']);
  3029. ParseProgram;
  3030. CheckResolverUnexpectedHints;
  3031. end;
  3032. procedure TTestResolver.TestConstFloatOperators;
  3033. begin
  3034. StartProgram(false);
  3035. Add([
  3036. 'const',
  3037. ' a=4/2 + 6.1/3 + 8.1/4.1 + 10/5.1;',
  3038. ' b=(1.1+1) + (2.1+3.1) + (4+5.1);',
  3039. ' c=(1.1-1) + (2.1-3.1) + (4-5.1);',
  3040. ' d=4*2 + 6.1*3 + 8.1*4.1 + 10*5.1;',
  3041. ' e=a=b;',
  3042. ' f=a<>b;',
  3043. ' g=a>b;',
  3044. ' h=a>=b;',
  3045. ' i=a<b;',
  3046. ' j=a<=b;',
  3047. ' k=(1.1<1) or (2.1<3.1) or (4<5.1);',
  3048. ' l=(1.1=1) or (2.1=3.1) or (4=5.1);',
  3049. 'begin']);
  3050. ParseProgram;
  3051. CheckResolverUnexpectedHints;
  3052. end;
  3053. procedure TTestResolver.TestFloatTypeCast;
  3054. begin
  3055. StartProgram(false);
  3056. Add([
  3057. 'const',
  3058. ' a=-123456890123456789012345;',
  3059. ' b: double=-123456890123456789012345;',
  3060. ' c=single(double(-123456890123456789012345));',
  3061. ' d=single(-1);',
  3062. ' e=single(word(-1));',
  3063. 'begin']);
  3064. ParseProgram;
  3065. CheckResolverUnexpectedHints;
  3066. end;
  3067. procedure TTestResolver.TestCurrency;
  3068. begin
  3069. StartProgram(false);
  3070. Add([
  3071. 'const',
  3072. ' a: currency = -922337203685477.5808;',
  3073. ' b: currency = 922337203685477.5807;',
  3074. ' c=double(currency(-123456890123456));',
  3075. ' d=currency(-1);',
  3076. ' e=currency(word(-1));',
  3077. 'var',
  3078. ' i: longint = 1;',
  3079. ' i64: int64;',
  3080. ' f: double;',
  3081. 'begin',
  3082. ' a:=i;',
  3083. ' a:=i+a;',
  3084. ' a:=a+i;',
  3085. ' a:=-a+b;',
  3086. ' a:=a*b;',
  3087. ' a:=a/b;',
  3088. ' a:=a/1.23;',
  3089. ' a:=1.2345;',
  3090. ' a:=a-i;',
  3091. ' a:=i-a;',
  3092. ' a:=a*i;',
  3093. ' a:=i*a;',
  3094. ' a:=a/i;',
  3095. ' a:=i/a;',
  3096. ' a:=i64;',
  3097. ' a:=currency(i64);',
  3098. //' i64:=a;', not allowed
  3099. ' i64:=int64(a);', // truncates a
  3100. ' a:=f;',
  3101. ' a:=currency(f);',
  3102. ' f:=a;',
  3103. ' f:=double(a);',
  3104. '']);
  3105. ParseProgram;
  3106. CheckResolverUnexpectedHints;
  3107. end;
  3108. procedure TTestResolver.TestWritableConst;
  3109. begin
  3110. StartProgram(false);
  3111. Add([
  3112. '{$writeableconst off}',
  3113. 'const i: longint = 3;',
  3114. 'begin',
  3115. '']);
  3116. ParseProgram;
  3117. end;
  3118. procedure TTestResolver.TestWritableConst_AssignFail;
  3119. begin
  3120. StartProgram(false);
  3121. Add([
  3122. '{$writeableconst off}',
  3123. 'const i: longint = 3;',
  3124. 'begin',
  3125. ' i:=4;',
  3126. '']);
  3127. CheckResolverException(sCantAssignValuesToConstVariable,nCantAssignValuesToConstVariable);
  3128. end;
  3129. procedure TTestResolver.TestWritableConst_PassVarFail;
  3130. begin
  3131. StartProgram(false);
  3132. Add([
  3133. '{$writeableconst off}',
  3134. 'const i: longint = 3;',
  3135. 'procedure DoIt(var j: longint); external;',
  3136. 'begin',
  3137. ' DoIt(i);',
  3138. '']);
  3139. CheckResolverException(sCantAssignValuesToConstVariable,nCantAssignValuesToConstVariable);
  3140. end;
  3141. procedure TTestResolver.TestBoolTypeCast;
  3142. begin
  3143. StartProgram(false);
  3144. Add('var');
  3145. Add(' a: boolean = boolean(0);');
  3146. Add(' b: boolean = boolean(1);');
  3147. Add('begin');
  3148. ParseProgram;
  3149. CheckResolverUnexpectedHints;
  3150. end;
  3151. procedure TTestResolver.TestConstBoolOperators;
  3152. begin
  3153. StartProgram(false);
  3154. Add([
  3155. 'const',
  3156. ' a=true and false;',
  3157. ' b=true or false;',
  3158. ' c=true xor false;',
  3159. ' d=not b;',
  3160. ' e=a=b;',
  3161. ' f=a<>b;',
  3162. ' g=low(boolean) or high(boolean);',
  3163. ' h=succ(false) or pred(true);',
  3164. ' i=ord(false)+ord(true);',
  3165. 'begin']);
  3166. ParseProgram;
  3167. CheckResolverUnexpectedHints;
  3168. end;
  3169. procedure TTestResolver.TestBoolSet_Const;
  3170. begin
  3171. StartProgram(false);
  3172. Add([
  3173. 'const',
  3174. ' s1 = [true];',
  3175. ' s2 = [false,true];',
  3176. ' s3 = [false..true];',
  3177. ' s7 = [true]*s2;',
  3178. ' s8 = s2-s1;',
  3179. ' s9 = s1+s2;',
  3180. ' s10 = s1><s2;',
  3181. ' s11 = s2=s3;',
  3182. ' s12 = s2<>s3;',
  3183. ' s13 = s2<=s3;',
  3184. ' s14 = s2>=s3;',
  3185. ' s15 = true in s2;',
  3186. 'begin']);
  3187. ParseProgram;
  3188. CheckResolverUnexpectedHints;
  3189. end;
  3190. procedure TTestResolver.TestBool_ForIn;
  3191. begin
  3192. StartProgram(false);
  3193. Add([
  3194. 'type',
  3195. //' TBoolRg = false..true;',
  3196. ' TSetOfBool = set of boolean;',
  3197. //' TSetOfBoolRg = set of TBoolRg;',
  3198. 'var',
  3199. ' b: boolean;',
  3200. //' br: TBoolRg;',
  3201. 'begin',
  3202. ' for b in boolean do;',
  3203. //' for b in TBoolRg do;',
  3204. ' for b in TSetOfBool do;',
  3205. //' for b in TSetOfBoolRg do;',
  3206. //' for br in TBoolRg do;',
  3207. //' for br in TSetOfBoolRg do;',
  3208. '']);
  3209. ParseProgram;
  3210. end;
  3211. procedure TTestResolver.TestBool_Assert;
  3212. begin
  3213. StartProgram(false);
  3214. Add([
  3215. 'var',
  3216. ' b : boolean;',
  3217. ' s: string;',
  3218. 'begin',
  3219. ' Assert(true);',
  3220. ' Assert(b);',
  3221. ' Assert(b,''error'');',
  3222. ' Assert(false,''error''+s);',
  3223. ' Assert(not b);',
  3224. '']);
  3225. ParseProgram;
  3226. end;
  3227. procedure TTestResolver.TestBool_AssertSysutils;
  3228. begin
  3229. AddModuleWithIntfImplSrc('SysUtils.pas',
  3230. LinesToStr([
  3231. 'type',
  3232. ' TObject = class',
  3233. ' constructor Create;',
  3234. ' end;',
  3235. ' EAssertionFailed = class',
  3236. ' constructor Create(s: string);',
  3237. ' end;',
  3238. '']),
  3239. LinesToStr([
  3240. 'constructor TObject.Create;',
  3241. 'begin end;',
  3242. 'constructor EAssertionFailed.Create(s: string);',
  3243. 'begin end;',
  3244. '']) );
  3245. StartProgram(true);
  3246. Add([
  3247. 'uses sysutils;',
  3248. 'procedure DoIt;',
  3249. 'var',
  3250. ' b: boolean;',
  3251. ' s: string;',
  3252. 'begin',
  3253. ' {$Assertions on}',
  3254. ' Assert(b);',
  3255. ' Assert(b,s);',
  3256. 'end;',
  3257. 'begin',
  3258. ' DoIt;',
  3259. '']);
  3260. ParseProgram;
  3261. end;
  3262. procedure TTestResolver.TestIntegerRange;
  3263. begin
  3264. StartProgram(false);
  3265. Add([
  3266. 'const',
  3267. ' MinInt = -1;',
  3268. ' MaxInt = +1;',
  3269. 'type',
  3270. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  3271. ' TInt2 = 1..3;',
  3272. 'var',
  3273. ' i: TMyInt;',
  3274. ' i2: TInt2;',
  3275. 'begin',
  3276. ' i:=i2;',
  3277. ' if i=i2 then ;',
  3278. ' i:=ord(i);',
  3279. '']);
  3280. ParseProgram;
  3281. CheckResolverUnexpectedHints;
  3282. end;
  3283. procedure TTestResolver.TestIntegerRangeHighLowerLowFail;
  3284. begin
  3285. StartProgram(false);
  3286. Add('const');
  3287. Add(' MinInt = -1;');
  3288. Add(' MaxInt = +1;');
  3289. Add('type');
  3290. Add(' {#TMyInt}TMyInt = MaxInt..MinInt;');
  3291. Add('begin');
  3292. CheckResolverException(sHighRangeLimitLTLowRangeLimit,
  3293. nHighRangeLimitLTLowRangeLimit);
  3294. end;
  3295. procedure TTestResolver.TestIntegerRangeLowHigh;
  3296. begin
  3297. StartProgram(false);
  3298. Add([
  3299. 'const',
  3300. ' MinInt = -1;',
  3301. ' MaxInt = +10;',
  3302. 'type',
  3303. ' {#TMyInt}TMyInt = MinInt..MaxInt;',
  3304. 'const',
  3305. ' a = low(TMyInt)+High(TMyInt);',
  3306. 'var',
  3307. ' i: TMyInt;',
  3308. 'begin',
  3309. ' i:=low(i)+high(i);']);
  3310. ParseProgram;
  3311. CheckResolverUnexpectedHints;
  3312. end;
  3313. procedure TTestResolver.TestAssignIntRangeWarning;
  3314. begin
  3315. StartProgram(false);
  3316. Add([
  3317. 'type TMyInt = 1..2;',
  3318. 'var i: TMyInt;',
  3319. 'begin',
  3320. ' i:=3;']);
  3321. ParseProgram;
  3322. CheckResolverHint(mtWarning,nRangeCheckEvaluatingConstantsVMinMax,
  3323. 'range check error while evaluating constants (3 is not between 1 and 2)');
  3324. CheckResolverUnexpectedHints;
  3325. end;
  3326. procedure TTestResolver.TestByteRangeWarning;
  3327. begin
  3328. StartProgram(false);
  3329. Add([
  3330. 'var b:byte=300;',
  3331. 'begin']);
  3332. ParseProgram;
  3333. CheckResolverHint(mtWarning,nRangeCheckEvaluatingConstantsVMinMax,
  3334. 'range check error while evaluating constants (300 is not between 0 and 255)');
  3335. CheckResolverUnexpectedHints;
  3336. end;
  3337. procedure TTestResolver.TestByteRangeWarningOff;
  3338. begin
  3339. StartProgram(false);
  3340. Add([
  3341. '{$warnings off}',
  3342. 'var b:byte=300;',
  3343. 'begin']);
  3344. ParseProgram;
  3345. CheckResolverUnexpectedHints;
  3346. end;
  3347. procedure TTestResolver.TestCustomIntRangeWarning;
  3348. begin
  3349. StartProgram(false);
  3350. Add([
  3351. 'const i:1..2 = 3;',
  3352. 'begin']);
  3353. ParseProgram;
  3354. CheckResolverHint(mtWarning,nRangeCheckEvaluatingConstantsVMinMax,
  3355. 'range check error while evaluating constants (3 is not between 1 and 2)');
  3356. CheckResolverUnexpectedHints;
  3357. end;
  3358. procedure TTestResolver.TestIntSet_Const;
  3359. begin
  3360. StartProgram(false);
  3361. Add([
  3362. 'const',
  3363. ' s1 = [1];',
  3364. ' s2 = [1,2];',
  3365. ' s3 = [1..3];',
  3366. ' s4 = [1..2,4..5,6];',
  3367. ' s5 = [low(shortint)..high(shortint)];',
  3368. ' s6 = [succ(low(shortint))..pred(high(shortint))];',
  3369. ' s7 = [1..3]*[2..4];',
  3370. ' s8 = [1..5]-[2,5];',
  3371. ' s9 = [1,3..4]+[2,5];',
  3372. ' s10 = [1..3]><[2..5];',
  3373. ' s11 = s2=s3;',
  3374. ' s12 = s2<>s3;',
  3375. ' s13 = s2<=s3;',
  3376. ' s14 = s2>=s3;',
  3377. ' s15 = 1 in s2;',
  3378. 'var',
  3379. ' w: word;',
  3380. 'begin',
  3381. ' if w in [1..12] then ;',
  3382. '']);
  3383. ParseProgram;
  3384. CheckResolverUnexpectedHints;
  3385. end;
  3386. procedure TTestResolver.TestIntSet_ConstDuplicateElement;
  3387. begin
  3388. StartProgram(false);
  3389. Add([
  3390. 'const',
  3391. ' s1 = [1,1..2];',
  3392. 'begin']);
  3393. CheckResolverException(sRangeCheckInSetConstructor,nRangeCheckInSetConstructor);
  3394. end;
  3395. procedure TTestResolver.TestInt_ForIn;
  3396. begin
  3397. StartProgram(false);
  3398. Add([
  3399. 'type',
  3400. ' TIntRg = 2..4;',
  3401. ' TSetOfInt = set of byte;',
  3402. ' TSetOfIntRg = set of TIntRg;',
  3403. 'var',
  3404. ' i: longint;',
  3405. ' ir: TIntRg;',
  3406. 'begin',
  3407. ' for i in longint do;',
  3408. ' for i in TIntRg do;',
  3409. ' for i in TSetOfInt do;',
  3410. ' for i in TSetOfIntRg do;',
  3411. ' for ir in TIntRg do;',
  3412. ' for ir in TSetOfIntRg do;',
  3413. '']);
  3414. ParseProgram;
  3415. end;
  3416. procedure TTestResolver.TestChar_BuiltInProcs;
  3417. begin
  3418. StartProgram(false);
  3419. Add([
  3420. 'var',
  3421. ' c: AnsiChar;',
  3422. ' i: longint;',
  3423. 'begin',
  3424. ' i:=ord(c);',
  3425. ' c:=chr(i);',
  3426. ' c:=pred(c);',
  3427. ' c:=succ(c);',
  3428. ' c:=low(c);',
  3429. ' c:=high(c);',
  3430. '']);
  3431. ParseProgram;
  3432. end;
  3433. procedure TTestResolver.TestString_BuiltInProcs;
  3434. begin
  3435. StartProgram(false);
  3436. Add([
  3437. 'var',
  3438. ' s: string;',
  3439. 'begin',
  3440. ' SetLength({#a_var}s,3);',
  3441. ' SetLength({#b_var}s,length({#c_read}s));',
  3442. ' s:=concat(''a'',s);',
  3443. '']);
  3444. ParseProgram;
  3445. CheckAccessMarkers;
  3446. end;
  3447. procedure TTestResolver.TestString_Element;
  3448. begin
  3449. StartProgram(false);
  3450. Add([
  3451. 'var',
  3452. ' s: string;',
  3453. ' c: AnsiChar;',
  3454. 'begin',
  3455. ' if s[1]=s then ;',
  3456. ' if s=s[2] then ;',
  3457. ' if s[3+4]=c then ;',
  3458. ' if c=s[5] then ;',
  3459. ' c:=s[6];',
  3460. ' s[7]:=c;',
  3461. ' s[8]:=''a'';',
  3462. ' s[9+1]:=''b'';',
  3463. ' s[10]:='''''''';',
  3464. ' s[11]:=^g;',
  3465. ' s[12]:=^H;',
  3466. '']);
  3467. ParseProgram;
  3468. end;
  3469. procedure TTestResolver.TestStringElement_MissingArgFail;
  3470. begin
  3471. StartProgram(false);
  3472. Add('var s: string;');
  3473. Add('begin');
  3474. Add(' if s[]=s then ;');
  3475. CheckResolverException('Missing parameter character index',nMissingParameterX);
  3476. end;
  3477. procedure TTestResolver.TestStringElement_IndexNonIntFail;
  3478. begin
  3479. StartProgram(false);
  3480. Add('var s: string;');
  3481. Add('begin');
  3482. Add(' if s[true]=s then ;');
  3483. CheckResolverException('Incompatible types: got "Boolean" expected "integer"',
  3484. nIncompatibleTypesGotExpected);
  3485. end;
  3486. procedure TTestResolver.TestStringElement_AsVarArgFail;
  3487. begin
  3488. StartProgram(false);
  3489. Add('procedure DoIt(var c: AnsiChar);');
  3490. Add('begin');
  3491. Add('end;');
  3492. Add('var s: string;');
  3493. Add('begin');
  3494. Add(' DoIt(s[1]);');
  3495. CheckResolverException('Variable identifier expected',
  3496. nVariableIdentifierExpected);
  3497. end;
  3498. procedure TTestResolver.TestString_DoubleQuotesFail;
  3499. begin
  3500. StartProgram(false);
  3501. Add('var s: string;');
  3502. Add('begin');
  3503. Add(' s:="abc" + "def";');
  3504. CheckParserException('Invalid character ''"''',PScanner.nErrInvalidCharacter);
  3505. end;
  3506. procedure TTestResolver.TestString_ShortstringType;
  3507. begin
  3508. StartProgram(false);
  3509. Add([
  3510. 'type t = string[12];',
  3511. 'var',
  3512. ' s: t;',
  3513. 'begin',
  3514. ' s:=''abc'';',
  3515. '']);
  3516. ParseProgram;
  3517. end;
  3518. procedure TTestResolver.TestConstStringOperators;
  3519. begin
  3520. StartProgram(false);
  3521. Add([
  3522. 'const',
  3523. ' a=''o''+''x''+''''+''ab'';',
  3524. //' b=#65#66;',
  3525. //' c=a=b;',
  3526. //' d=a<>b;',
  3527. //' e=a<b;',
  3528. //' f=a<=b;',
  3529. //' g=a>b;',
  3530. //' h=a>=b;',
  3531. //' i=a[1];',
  3532. //' j=length(a);',
  3533. //' k=chr(97);',
  3534. //' l=ord(a[1]);',
  3535. //' m=low(AnsiChar)+high(AnsiChar);',
  3536. //' n = string(''A'');',
  3537. //' o = UnicodeString(''A'');',
  3538. //' p = ^C''bird'';',
  3539. 'begin']);
  3540. ParseProgram;
  3541. CheckResolverUnexpectedHints;
  3542. end;
  3543. procedure TTestResolver.TestConstUnicodeStringOperators;
  3544. begin
  3545. ResolverEngine.ExprEvaluator.DefaultStringCodePage:=CP_UTF8;
  3546. StartProgram(false);
  3547. Add([
  3548. 'const',
  3549. ' a=''大''+''学'';',
  3550. ' b=#22823+#23398;',
  3551. ' c=a=b;',
  3552. ' d=a<>b;',
  3553. ' e=a<b;',
  3554. ' f=a<=b;',
  3555. ' g=a>b;',
  3556. ' h=a>=b;',
  3557. ' i=b[1];',
  3558. ' j=length(b);',
  3559. ' k=chr(22823);',
  3560. ' l=ord(b[1]);',
  3561. ' m=low(widechar)+high(widechar);',
  3562. ' n=#65#22823;',
  3563. ' ascii=#65;',
  3564. ' o=ascii+b;',
  3565. 'begin']);
  3566. ParseProgram;
  3567. CheckResolverUnexpectedHints;
  3568. end;
  3569. procedure TTestResolver.TestCharSet_Const;
  3570. begin
  3571. StartProgram(false);
  3572. Add([
  3573. 'const',
  3574. ' s1 = [''a''];',
  3575. ' s2 = [''a'',''b''];',
  3576. ' s3 = [''a''..''c''];',
  3577. ' s4 = [''a''..''b'',''d''..''e'',''f''];',
  3578. ' s5 = [low(AnsiChar)..high(AnsiChar)];',
  3579. ' s6 = [succ(low(AnsiChar))..pred(high(AnsiChar))];',
  3580. ' s7 = [''a''..''c'']*[''b''..''d''];',
  3581. ' s8 = [''a''..''e'']-[''b'',''e''];',
  3582. ' s9 = [''a'',''c''..''d'']+[''b'',''e''];',
  3583. ' s10 = [''a''..''c'']><[''b''..''e''];',
  3584. ' s11 = [''a'',''b'']=[''a''..''b''];',
  3585. ' s12 = [''a'',''b'']<>[''a''..''b''];',
  3586. ' s13 = [''a'',''b'']<=[''a''..''b''];',
  3587. ' s14 = [''a'',''b'']>=[''a''..''b''];',
  3588. ' s15 = ''a'' in [''a'',''b''];',
  3589. ' s16 = [#0..#127,#22823..#23398];',
  3590. ' s17 = #22823 in s16;',
  3591. 'var c: AnsiChar;',
  3592. 'begin',
  3593. ' if c in s3 then ;']);
  3594. ParseProgram;
  3595. CheckResolverUnexpectedHints;
  3596. end;
  3597. procedure TTestResolver.TestCharSet_Custom;
  3598. begin
  3599. StartProgram(false);
  3600. Add([
  3601. 'type',
  3602. ' TCharRg = ''a''..''z'';',
  3603. ' TSetOfCharRg = set of TCharRg;',
  3604. ' TCharRg2 = ''m''..''p'';',
  3605. 'const',
  3606. ' crg: TCharRg = ''b'';',
  3607. 'var',
  3608. ' c: AnsiChar;',
  3609. ' crg2: TCharRg2;',
  3610. ' s: TSetOfCharRg;',
  3611. 'begin',
  3612. ' c:=crg;',
  3613. ' crg:=c;',
  3614. ' crg2:=crg;',
  3615. ' if c=crg then ;',
  3616. ' if crg=c then ;',
  3617. ' if crg=crg2 then ;',
  3618. ' if c in s then ;',
  3619. ' if crg2 in s then ;',
  3620. '']);
  3621. ParseProgram;
  3622. CheckResolverUnexpectedHints;
  3623. end;
  3624. procedure TTestResolver.TestCharAssignStringFail;
  3625. begin
  3626. StartProgram(false);
  3627. Add([
  3628. 'var',
  3629. ' c: AnsiChar;',
  3630. ' s: string;',
  3631. 'begin',
  3632. ' c:=s;']);
  3633. CheckResolverException('Incompatible types: got "String" expected "AnsiChar"',
  3634. nIncompatibleTypesGotExpected);
  3635. end;
  3636. procedure TTestResolver.TestChar_ForIn;
  3637. begin
  3638. StartProgram(false);
  3639. Add([
  3640. 'type',
  3641. ' TCharRg = ''a''..''z'';',
  3642. ' TSetOfChar = set of AnsiChar;',
  3643. ' TSetOfCharRg = set of TCharRg;',
  3644. 'const Foo = ''foo'';',
  3645. 'var',
  3646. ' c: AnsiChar;',
  3647. ' cr: TCharRg;',
  3648. ' s: string;',
  3649. ' a: array of AnsiChar;',
  3650. ' b: array[1..3] of AnsiChar;',
  3651. ' soc: TSetOfChar;',
  3652. ' socr: TSetOfCharRg;',
  3653. 'begin',
  3654. ' for c in foo do;',
  3655. ' for c in s do;',
  3656. ' for c in a do;',
  3657. ' for c in b do;',
  3658. ' for c in AnsiChar do;',
  3659. ' for c in TCharRg do;',
  3660. ' for c in TSetOfChar do;',
  3661. ' for c in TSetOfCharRg do;',
  3662. ' for c in soc do;',
  3663. ' for c in socr do;',
  3664. ' for c in [''A''..''C''] do ;',
  3665. ' for cr in TCharRg do;',
  3666. ' for cr in TSetOfCharRg do;',
  3667. ' for cr in socr do;',
  3668. //' for cr in [''b''..''d''] do ;',
  3669. '']);
  3670. ParseProgram;
  3671. end;
  3672. procedure TTestResolver.TestEnums;
  3673. begin
  3674. StartProgram(false);
  3675. Add([
  3676. 'type',
  3677. ' {#TFlag}TFlag = ({#Red}Red, {#Green}Green, {#Blue}Blue);',
  3678. ' {#TAlias}TAlias = TFlag;',
  3679. 'var',
  3680. ' {#f}{=TFlag}f: TFlag;',
  3681. ' {#v}{=TFlag}v: TFlag = Green;',
  3682. ' {#i}i: longint;',
  3683. 'begin',
  3684. ' {@f}f:={@Red}Red;',
  3685. ' {@f}f:={@v}v;',
  3686. ' if {@f}f={@Red}Red then ;',
  3687. ' if {@f}f={@v}v then ;',
  3688. ' if {@f}f>{@v}v then ;',
  3689. ' if {@f}f<{@v}v then ;',
  3690. ' if {@f}f>={@v}v then ;',
  3691. ' if {@f}f<={@v}v then ;',
  3692. ' if {@f}f<>{@v}v then ;',
  3693. ' if ord({@f}f)<>ord({@Red}Red) then ;',
  3694. ' {@f}f:={@TFlag}TFlag.{@Red}Red;',
  3695. ' {@f}f:={@TFlag}TFlag({@i}i);',
  3696. ' {@i}i:=longint({@f}f);',
  3697. ' {@f}f:={@TAlias}TAlias.{@Green}Green;',
  3698. '']);
  3699. ParseProgram;
  3700. end;
  3701. procedure TTestResolver.TestEnumRangeFail;
  3702. begin
  3703. StartProgram(false);
  3704. Add([
  3705. 'type TFlag = (a,b,c);',
  3706. 'const all = a..c;',
  3707. 'begin']);
  3708. CheckParserException('Const ranges are not allowed',nParserNoConstRangeAllowed);
  3709. end;
  3710. procedure TTestResolver.TestEnumDotValueFail;
  3711. begin
  3712. StartProgram(false);
  3713. Add([
  3714. 'type TFlag = (a,b,c);',
  3715. 'var f: TFlag;',
  3716. 'begin',
  3717. ' f:=f.a;']);
  3718. CheckResolverException('illegal qualifier "." after "f:TFlag"',nIllegalQualifierAfter);
  3719. end;
  3720. procedure TTestResolver.TestSets;
  3721. begin
  3722. StartProgram(false);
  3723. Add('type');
  3724. Add(' {#TFlag}TFlag = ({#Red}Red, {#Green}Green, {#Blue}Blue, {#Gray}Gray, {#Black}Black, {#White}White);');
  3725. Add(' {#TFlags}TFlags = set of TFlag;');
  3726. Add(' {#TChars}TChars = set of AnsiChar;');
  3727. Add(' {#TMyInt}TMyInt = 0..17;');
  3728. Add(' {#TMyInts}TMyInts = set of TMyInt;');
  3729. Add(' {#TMyBools}TMyBools = set of boolean;');
  3730. Add('const');
  3731. Add(' {#Colors}Colors = [{@Red}Red..{@Blue}Blue];');
  3732. Add(' {#ExtColors}ExtColors = {@Colors}Colors+[{@White}White,{@Black}Black];');
  3733. Add('var');
  3734. Add(' {#f}{=TFlag}f: TFlag;');
  3735. Add(' {#s}{=TFlags}s: TFlags;');
  3736. Add(' {#t}{=TFlags}t: TFlags = [Green,Gray];');
  3737. Add(' {#Chars}{=TChars}Chars: TChars;');
  3738. Add(' {#MyInts}{=TMyInts}MyInts: TMyInts;');
  3739. Add(' {#MyBools}{=TMyBools}MyBools: TMyBools;');
  3740. Add('begin');
  3741. Add(' {@s}s:=[];');
  3742. Add(' {@s}s:={@t}t;');
  3743. Add(' {@s}s:=[{@Red}Red];');
  3744. Add(' {@s}s:=[{@Red}Red,{@Blue}Blue];');
  3745. Add(' {@s}s:=[{@Gray}Gray..{@White}White];');
  3746. Add(' {@MyInts}MyInts:=[1];');
  3747. Add(' {@MyInts}MyInts:=[1,2];');
  3748. Add(' {@MyInts}MyInts:=[1..2];');
  3749. Add(' {@MyInts}MyInts:=[1..2,3];');
  3750. Add(' {@MyInts}MyInts:=[1..2,3..4];');
  3751. Add(' {@MyInts}MyInts:=[1,2..3];');
  3752. Add(' {@MyBools}MyBools:=[false];');
  3753. Add(' {@MyBools}MyBools:=[false,true];');
  3754. Add(' {@MyBools}MyBools:=[false..true];');
  3755. ParseProgram;
  3756. end;
  3757. procedure TTestResolver.TestSetOperators;
  3758. begin
  3759. StartProgram(false);
  3760. Add('type');
  3761. Add(' {#TFlag}TFlag = ({#Red}Red, {#Green}Green, {#Blue}Blue, {#Gray}Gray, {#Black}Black, {#White}White);');
  3762. Add(' {#TFlags}TFlags = set of TFlag;');
  3763. Add(' {#TChars}TChars = set of AnsiChar;');
  3764. Add(' {#TMyInt}TMyInt = 0..17;');
  3765. Add(' {#TMyInts}TMyInts = set of TMyInt;');
  3766. Add(' {#TMyBools}TMyBools = set of boolean;');
  3767. Add('const');
  3768. Add(' {#Colors}Colors = [{@Red}Red..{@Blue}Blue];');
  3769. Add(' {#ExtColors}ExtColors = {@Colors}Colors+[{@White}White,{@Black}Black];');
  3770. Add('var');
  3771. Add(' {#f}{=TFlag}f: TFlag;');
  3772. Add(' {#s}{=TFlags}s: TFlags;');
  3773. Add(' {#t}{=TFlags}t: TFlags = [Green,Gray];');
  3774. Add(' {#Chars}{=TChars}Chars: TChars;');
  3775. Add(' {#MyInts}{=TMyInts}MyInts: TMyInts;');
  3776. Add(' {#MyBools}{=TMyBools}MyBools: TMyBools;');
  3777. Add('begin');
  3778. Add(' {@s}s:=[];');
  3779. Add(' {@s}s:=[{@Red}Red]+[{@Blue}Blue,{@Gray}Gray];');
  3780. Add(' {@s}s:=[{@Blue}Blue,{@Gray}Gray]-[{@Blue}Blue];');
  3781. Add(' {@s}s:={@t}t+[];');
  3782. Add(' {@s}s:=[{@Red}Red]+{@s}s;');
  3783. Add(' {@s}s:={@s}s+[{@Red}Red];');
  3784. Add(' {@s}s:=[{@Red}Red]-{@s}s;');
  3785. Add(' {@s}s:={@s}s-[{@Red}Red];');
  3786. Add(' Include({@s}s,{@Blue}Blue);');
  3787. Add(' Include({@s}s,{@f}f);');
  3788. Add(' Exclude({@s}s,{@Blue}Blue);');
  3789. Add(' Exclude({@s}s,{@f}f);');
  3790. Add(' {@s}s:={@s}s+[{@f}f];');
  3791. Add(' if {@Green}Green in {@s}s then ;');
  3792. Add(' if {@Blue}Blue in {@Colors}Colors then ;');
  3793. Add(' if {@f}f in {@ExtColors}ExtColors then ;');
  3794. Add(' {@s}s:={@s}s * {@Colors}Colors;');
  3795. Add(' {@s}s:={@Colors}Colors * {@s}s;');
  3796. Add(' {@s}s:={@ExtColors}ExtColors * {@Colors}Colors;');
  3797. Add(' {@s}s:=Colors >< {@ExtColors}ExtColors;');
  3798. Add(' {@s}s:={@s}s >< {@ExtColors}ExtColors;');
  3799. Add(' {@s}s:={@ExtColors}ExtColors >< s;');
  3800. Add(' {@s}s:={@s}s >< {@s}s;');
  3801. Add(' if ''p'' in [''a''..''z''] then ; ');
  3802. Add(' if ''p'' in [''a''..''z'',''A''..''Z'',''0''..''9'',''_''] then ; ');
  3803. Add(' if ''p'' in {@Chars}Chars then ; ');
  3804. Add(' if 7 in {@MyInts}MyInts then ; ');
  3805. Add(' if 7 in [1+2,(3*4)+5,(-2+6)..(8-3)] then ; ');
  3806. Add(' if [red,blue]*s=[red,blue] then ;');
  3807. Add(' if {@s}s = t then;');
  3808. Add(' if {@s}s = {@Colors}Colors then;');
  3809. Add(' if {@Colors}Colors = s then;');
  3810. Add(' if {@s}s <> t then;');
  3811. Add(' if {@s}s <> {@Colors}Colors then;');
  3812. Add(' if {@Colors}Colors <> s then;');
  3813. Add(' if {@s}s <= t then;');
  3814. Add(' if {@s}s <= {@Colors}Colors then;');
  3815. Add(' if {@Colors}Colors <= s then;');
  3816. Add(' if {@s}s >= t then;');
  3817. Add(' if {@s}s >= {@Colors}Colors then;');
  3818. Add(' if {@Colors}Colors >= {@s}s then;');
  3819. ParseProgram;
  3820. end;
  3821. procedure TTestResolver.TestEnumParams;
  3822. begin
  3823. StartProgram(false);
  3824. Add('type');
  3825. Add(' TFlag = (red, green, blue);');
  3826. Add('function {#A1}FuncA: TFlag;');
  3827. Add('begin');
  3828. Add(' Result:=red;');
  3829. Add('end;');
  3830. Add('function {#A2}FuncA(f: TFlag): TFlag;');
  3831. Add('begin');
  3832. Add(' Result:=f;');
  3833. Add('end;');
  3834. Add('var');
  3835. Add(' f: TFlag;');
  3836. Add('begin');
  3837. Add(' f:={@A1}FuncA;');
  3838. Add(' f:={@A1}FuncA();');
  3839. Add(' f:={@A2}FuncA(f);');
  3840. ParseProgram;
  3841. end;
  3842. procedure TTestResolver.TestSetParams;
  3843. begin
  3844. StartProgram(false);
  3845. Add('type');
  3846. Add(' TFlag = (red, green, blue);');
  3847. Add(' TFlags = set of TFlag;');
  3848. Add('function {#A1}FuncA: TFlags;');
  3849. Add('begin');
  3850. Add(' Result:=[red];');
  3851. Add(' Include(Result,green);');
  3852. Add(' Exclude(Result,blue);');
  3853. Add('end;');
  3854. Add('function {#A2}FuncA(f: TFlags): TFlags;');
  3855. Add('begin');
  3856. Add(' Include(f,green);');
  3857. Add(' Result:=f;');
  3858. Add('end;');
  3859. Add('var');
  3860. Add(' f: TFlags;');
  3861. Add('begin');
  3862. Add(' f:={@A1}FuncA;');
  3863. Add(' f:={@A1}FuncA();');
  3864. Add(' f:={@A2}FuncA(f);');
  3865. Add(' f:={@A2}FuncA([green]);');
  3866. ParseProgram;
  3867. end;
  3868. procedure TTestResolver.TestSetFunctions;
  3869. begin
  3870. StartProgram(false);
  3871. Add('type');
  3872. Add(' TFlag = (red, green, blue);');
  3873. Add(' TFlags = set of TFlag;');
  3874. Add('var');
  3875. Add(' e: TFlag;');
  3876. Add(' s: TFlags;');
  3877. Add('begin');
  3878. Add(' e:=Low(TFlags);');
  3879. Add(' e:=Low(s);');
  3880. Add(' e:=High(TFlags);');
  3881. Add(' e:=High(s);');
  3882. ParseProgram;
  3883. end;
  3884. procedure TTestResolver.TestEnumHighLow;
  3885. begin
  3886. StartProgram(false);
  3887. Add('type');
  3888. Add(' TFlag = (red, green, blue);');
  3889. Add('var f: TFlag;');
  3890. Add('begin');
  3891. Add(' for f:=low(TFlag) to high(TFlag) do ;');
  3892. ParseProgram;
  3893. end;
  3894. procedure TTestResolver.TestEnumOrd;
  3895. begin
  3896. StartProgram(false);
  3897. Add('type');
  3898. Add(' TFlag = (red, green, blue);');
  3899. Add('var');
  3900. Add(' f: TFlag;');
  3901. Add(' i: longint;');
  3902. Add('begin');
  3903. Add(' i:=ord(f);');
  3904. Add(' i:=ord(green);');
  3905. Add(' if i=ord(f) then ;');
  3906. Add(' if ord(f)=i then ;');
  3907. ParseProgram;
  3908. end;
  3909. procedure TTestResolver.TestEnumPredSucc;
  3910. begin
  3911. StartProgram(false);
  3912. Add('type');
  3913. Add(' TFlag = (red, green, blue);');
  3914. Add('var');
  3915. Add(' f: TFlag;');
  3916. Add('begin');
  3917. Add(' f:=Pred(f);');
  3918. Add(' if Pred(green)=Pred(TFlag.Blue) then;');
  3919. Add(' f:=Succ(f);');
  3920. Add(' if Succ(green)=Succ(TFlag.Blue) then;');
  3921. ParseProgram;
  3922. end;
  3923. procedure TTestResolver.TestEnum_EqualNilFail;
  3924. begin
  3925. StartProgram(false);
  3926. Add('type');
  3927. Add(' TFlag = (red, green);');
  3928. Add('var');
  3929. Add(' f: TFlag;');
  3930. Add('begin');
  3931. Add(' if f=nil then ;');
  3932. CheckResolverException('Incompatible types: got "nil" expected "TFlag"',
  3933. nIncompatibleTypesGotExpected);
  3934. end;
  3935. procedure TTestResolver.TestEnum_CastIntegerToEnum;
  3936. begin
  3937. StartProgram(false);
  3938. Add('type');
  3939. Add(' TFlag = (red, green, blue);');
  3940. Add('var');
  3941. Add(' f: TFlag;');
  3942. Add(' i: longint;');
  3943. Add('begin');
  3944. Add(' f:=TFlag(1);');
  3945. Add(' f:=TFlag({#a_read}i);');
  3946. Add(' if TFlag({#b_read}i)=TFlag(1) then;');
  3947. ParseProgram;
  3948. CheckAccessMarkers;
  3949. end;
  3950. procedure TTestResolver.TestEnum_Str;
  3951. begin
  3952. StartProgram(false);
  3953. Add([
  3954. 'type',
  3955. ' TFlag = (red, green, blue);',
  3956. 'var',
  3957. ' f: TFlag;',
  3958. ' i: longint;',
  3959. ' aString: string;',
  3960. 'begin',
  3961. ' aString:=str(f);',
  3962. ' aString:=str(f:3);',
  3963. ' str(f,aString);',
  3964. ' writestr(astring,f,i);',
  3965. ' val(aString,f,i);']);
  3966. ParseProgram;
  3967. end;
  3968. procedure TTestResolver.TestConstEnumOperators;
  3969. begin
  3970. StartProgram(false);
  3971. Add([
  3972. 'type',
  3973. ' TEnum = (red,blue,green);',
  3974. 'const',
  3975. ' a=ord(red);',
  3976. ' b=succ(low(TEnum));',
  3977. ' c=pred(high(TEnum));',
  3978. ' d=TEnum(0);',
  3979. ' e=TEnum(2);',
  3980. 'begin']);
  3981. ParseProgram;
  3982. CheckResolverUnexpectedHints;
  3983. end;
  3984. procedure TTestResolver.TestEnumSetConstRange;
  3985. begin
  3986. StartProgram(false);
  3987. Add([
  3988. 'type',
  3989. ' TEnum = (red,blue,green);',
  3990. ' TEnums = set of TEnum;',
  3991. 'const',
  3992. ' teAny = [low(TEnum)..high(TEnum)];',
  3993. ' teRedBlue = [low(TEnum)..pred(high(TEnum))];',
  3994. 'var',
  3995. ' e: TEnum;',
  3996. ' s: TEnums;',
  3997. 'begin',
  3998. ' if blue in teAny then;',
  3999. ' if blue in teAny+[e] then;',
  4000. ' if blue in teAny+teRedBlue then;',
  4001. ' s:=teAny;',
  4002. ' s:=teAny+[e];',
  4003. ' s:=[e]+teAny;',
  4004. ' s:=teAny+teRedBlue;',
  4005. ' s:=teAny+teRedBlue+[e];',
  4006. '']);
  4007. ParseProgram;
  4008. CheckResolverUnexpectedHints;
  4009. end;
  4010. procedure TTestResolver.TestEnumSet_AnonymousEnumtype;
  4011. begin
  4012. StartProgram(false);
  4013. Add('type');
  4014. Add(' TFlags = set of (red, green);');
  4015. Add('const');
  4016. Add(' favorite = red;');
  4017. Add('var');
  4018. Add(' f: TFlags;');
  4019. Add(' i: longint;');
  4020. Add('begin');
  4021. Add(' Include(f,red);');
  4022. Add(' Include(f,favorite);');
  4023. Add(' i:=ord(red);');
  4024. Add(' i:=ord(favorite);');
  4025. Add(' i:=ord(low(TFlags));');
  4026. Add(' i:=ord(low(f));');
  4027. Add(' i:=ord(low(favorite));');
  4028. Add(' i:=ord(high(TFlags));');
  4029. Add(' i:=ord(high(f));');
  4030. Add(' i:=ord(high(favorite));');
  4031. Add(' f:=[green,favorite];');
  4032. ParseProgram;
  4033. end;
  4034. procedure TTestResolver.TestEnumSet_AnonymousEnumtypeName;
  4035. begin
  4036. ResolverEngine.AnonymousElTypePostfix:='$enum';
  4037. StartProgram(false);
  4038. Add('type');
  4039. Add(' TFlags = set of (red, green);');
  4040. Add('const');
  4041. Add(' favorite = red;');
  4042. Add('var');
  4043. Add(' f: TFlags;');
  4044. Add(' i: longint;');
  4045. Add('begin');
  4046. Add(' Include(f,red);');
  4047. Add(' Include(f,favorite);');
  4048. Add(' i:=ord(red);');
  4049. Add(' i:=ord(favorite);');
  4050. Add(' i:=ord(low(TFlags));');
  4051. Add(' i:=ord(low(f));');
  4052. Add(' i:=ord(low(favorite));');
  4053. Add(' i:=ord(high(TFlags));');
  4054. Add(' i:=ord(high(f));');
  4055. Add(' i:=ord(high(favorite));');
  4056. Add(' f:=[green,favorite];');
  4057. ParseProgram;
  4058. end;
  4059. procedure TTestResolver.TestEnumSet_Const;
  4060. begin
  4061. StartProgram(false);
  4062. Add([
  4063. 'type',
  4064. ' TFlag = (a,b,c,d,e,f);',
  4065. 'const',
  4066. ' s1 = [a];',
  4067. ' s2 = [a,b];',
  4068. ' s3 = [a..c];',
  4069. ' s4 = [a..b,d..e,f];',
  4070. ' s5 = [low(TFlag)..high(TFlag)];',
  4071. ' s6 = [succ(low(TFlag))..pred(high(TFlag))];',
  4072. ' s7 = [a..c]*[b..d];',
  4073. ' s8 = [a..e]-[b,e];',
  4074. ' s9 = [a,c..d]+[b,e];',
  4075. ' s10 = [a..c]><[b..e];',
  4076. ' s11 = [a,b]=[a..b];',
  4077. ' s12 = [a,b]<>[a..b];',
  4078. ' s13 = [a,b]<=[a..b];',
  4079. ' s14 = [a,b]>=[a..b];',
  4080. ' s15 = a in [a,b];',
  4081. 'var',
  4082. ' Flag: TFlag;',
  4083. 'begin',
  4084. ' if Flag in [b,c] then ;']);
  4085. ParseProgram;
  4086. CheckResolverUnexpectedHints;
  4087. end;
  4088. procedure TTestResolver.TestSet_IntRange_Const;
  4089. begin
  4090. StartProgram(false);
  4091. Add([
  4092. 'type',
  4093. ' TIntRg = 2..6;',
  4094. ' TFiveSet = set of TIntRg;',
  4095. 'const',
  4096. ' Three = 3;',
  4097. ' a: TFiveSet = [2..Three,5]+[4];',
  4098. ' b = low(TIntRg)+high(TIntRg);',
  4099. ' c = [low(TIntRg)..high(TIntRg)];',
  4100. 'var',
  4101. ' s: TFiveSet;',
  4102. 'begin',
  4103. ' s:= {#s1_set}[];',
  4104. ' s:= {#s2_set}[3];',
  4105. ' s:= {#s3_set}[3..4];',
  4106. ' s:= {#s4_set}[Three];',
  4107. ' if 3 in a then ;',
  4108. ' s:=c;',
  4109. ' Include(s,3);',
  4110. '']);
  4111. ParseProgram;
  4112. CheckParamsExpr_pkSet_Markers;
  4113. CheckResolverUnexpectedHints;
  4114. end;
  4115. procedure TTestResolver.TestSet_Byte_Const;
  4116. begin
  4117. StartProgram(false);
  4118. Add([
  4119. 'type',
  4120. ' TIntRg = byte;',
  4121. ' TFiveSet = set of TIntRg;',
  4122. 'const',
  4123. ' Three = 3;',
  4124. ' a: TFiveSet = [2..Three,5]+[4];',
  4125. ' b = low(TIntRg)+high(TIntRg);',
  4126. ' c = [low(TIntRg)..high(TIntRg)];',
  4127. 'var',
  4128. ' s: TFiveSet;',
  4129. 'begin',
  4130. ' s:= {#s1_set}[];',
  4131. ' s:= {#s2_set}[3];',
  4132. ' s:= {#s3_set}[3..4];',
  4133. ' s:= {#s4_set}[Three];',
  4134. ' if 3 in a then ;',
  4135. ' s:=c;',
  4136. //' Include(s,Three);', // ToDo
  4137. '']);
  4138. ParseProgram;
  4139. CheckParamsExpr_pkSet_Markers;
  4140. CheckResolverUnexpectedHints;
  4141. end;
  4142. procedure TTestResolver.TestEnumRange;
  4143. begin
  4144. StartProgram(false);
  4145. Add([
  4146. 'type',
  4147. ' TEnum = (a,b,c,d,e);',
  4148. ' TEnumRg = b..d;',
  4149. ' TEnumRg2 = c..e;',
  4150. ' TSetOfEnumRg = set of TEnumRg;',
  4151. 'const',
  4152. ' c1: TEnumRg = c;',
  4153. ' c2: TEnumRg = succ(low(TEnumRg));',
  4154. ' c3: TEnumRg = pred(high(TEnumRg));',
  4155. ' c4: TEnumRg = TEnumRg(2);',
  4156. ' c5: TEnumRg2 = e;',
  4157. 'var',
  4158. ' er: TEnumRg;',
  4159. ' er2: TEnumRg2;',
  4160. ' Enum: TEnum;',
  4161. ' i: longint;',
  4162. ' sr: TSetOfEnumRg;',
  4163. 'begin',
  4164. ' er:=d;',
  4165. ' Enum:=er;',
  4166. ' if Enum=er then ;',
  4167. ' if er=Enum then ;',
  4168. ' if er=c then ;',
  4169. ' if c=er then ;',
  4170. ' if er=er2 then ;',
  4171. ' er:=er2;',
  4172. ' i:=ord(er);',
  4173. ' er:=TEnumRg(i);',
  4174. ' i:=longint(er);',
  4175. ' if b in sr then ;',
  4176. ' if er in sr then ;',
  4177. ' er:=low(TEnumRg);',
  4178. ' er:=high(TEnumRg);',
  4179. ' er:=succ(er);',
  4180. ' er:=pred(er);',
  4181. ' inc(er);',
  4182. ' dec(er);',
  4183. ' case er of',
  4184. ' c: ;',
  4185. ' end;',
  4186. '']);
  4187. ParseProgram;
  4188. CheckResolverUnexpectedHints;
  4189. end;
  4190. procedure TTestResolver.TestEnum_ForIn;
  4191. begin
  4192. StartProgram(false);
  4193. Add([
  4194. 'type',
  4195. ' TEnum = (red,green,blue);',
  4196. ' TEnumRg = green..blue;',
  4197. ' TSetOfEnum = set of TEnum;',
  4198. ' TSetOfEnumRg = set of TEnumRg;',
  4199. ' TArrOfEnum = array[TEnum] of byte;',
  4200. ' TArrOfEnumRg = array[TEnumRg] of byte;',
  4201. 'var',
  4202. ' e: TEnum;',
  4203. ' er: TEnumRg;',
  4204. 'begin',
  4205. ' for e in TEnum do;',
  4206. ' for e in TEnumRg do;',
  4207. ' for e in TSetOfEnum do;',
  4208. ' for e in TSetOfEnumRg do;',
  4209. ' for e in [] do;',
  4210. ' for e in [red..green] do;',
  4211. ' for e in [green,blue] do;',
  4212. ' for e in TArrOfEnum do;',
  4213. ' for e in TArrOfEnumRg do;',
  4214. ' for er in TEnumRg do;',
  4215. ' for er in TSetOfEnumRg do;',
  4216. ' for er in [green..blue] do;',
  4217. ' for er in TArrOfEnumRg do;',
  4218. '']);
  4219. ParseProgram;
  4220. end;
  4221. procedure TTestResolver.TestEnum_ForInRangeFail;
  4222. begin
  4223. StartProgram(false);
  4224. Add([
  4225. 'type',
  4226. ' TEnum = (red,green,blue);',
  4227. 'var',
  4228. ' e: TEnum;',
  4229. 'begin',
  4230. ' for e in red..green do;',
  4231. '']);
  4232. CheckResolverException('Cannot find an enumerator for the type "range.."',nCannotFindEnumeratorForType);
  4233. end;
  4234. procedure TTestResolver.TestEnum_ScopedEnums;
  4235. begin
  4236. StartProgram(false);
  4237. Add([
  4238. 'type',
  4239. ' {$scopedenums on}',
  4240. ' TEnum = (red, green);',
  4241. ' TFlags = set of (red,blue);',
  4242. ' ',
  4243. 'var e: TEnum;',
  4244. ' f: TFlags;',
  4245. 'begin',
  4246. ' e:=TEnum.red;',
  4247. ' if red in f then ;',
  4248. '']);
  4249. ParseProgram;
  4250. end;
  4251. procedure TTestResolver.TestEnum_ScopedEnumsFail;
  4252. begin
  4253. StartProgram(false);
  4254. Add([
  4255. 'type',
  4256. ' {$ScopedEnums on}',
  4257. ' TEnum = (red, green);',
  4258. 'var e: TEnum;',
  4259. 'begin',
  4260. ' e:=red;'
  4261. ]);
  4262. CheckResolverException(sIdentifierNotFound,nIdentifierNotFound);
  4263. end;
  4264. procedure TTestResolver.TestPrgAssignment;
  4265. var
  4266. El: TPasElement;
  4267. V1: TPasVariable;
  4268. ImplAssign: TPasImplAssign;
  4269. Ref1: TPrimitiveExpr;
  4270. Resolver1: TResolvedReference;
  4271. begin
  4272. StartProgram(false);
  4273. Add('var');
  4274. Add(' v1:longint;');
  4275. Add('begin');
  4276. Add(' v1:=3;');
  4277. ParseProgram;
  4278. AssertEquals('1 declaration',1,PasProgram.ProgramSection.Declarations.Count);
  4279. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  4280. AssertEquals('var',TPasVariable,El.ClassType);
  4281. V1:=TPasVariable(El);
  4282. AssertEquals('var v1','v1',V1.Name);
  4283. AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
  4284. AssertEquals('Assignment statement',TPasImplAssign,FFirstStatement.ClassType);
  4285. ImplAssign:=FFirstStatement as TPasImplAssign;
  4286. AssertEquals('Normal assignment',akDefault,ImplAssign.Kind);
  4287. AssertExpression('Right side is constant',ImplAssign.Right,pekNumber,'3');
  4288. AssertExpression('Left side is variable',ImplAssign.Left,pekIdent,'v1');
  4289. AssertEquals('Left side is variable, primitive',TPrimitiveExpr,ImplAssign.Left.ClassType);
  4290. Ref1:=TPrimitiveExpr(ImplAssign.Left);
  4291. AssertNotNull('variable has customdata',Ref1.CustomData);
  4292. AssertEquals('variable has resolver',TResolvedReference,Ref1.CustomData.ClassType);
  4293. Resolver1:=TResolvedReference(Ref1.CustomData);
  4294. AssertSame('variable resolver element',Resolver1.Element,Ref1);
  4295. AssertSame('variable resolver declaration v1',Resolver1.Declaration,V1);
  4296. end;
  4297. procedure TTestResolver.TestPrgProcVar;
  4298. begin
  4299. StartProgram(false);
  4300. Add('procedure Proc1;');
  4301. Add('type');
  4302. Add(' t1=longint;');
  4303. Add('var');
  4304. Add(' v1:t1;');
  4305. Add('begin');
  4306. Add('end;');
  4307. Add('begin');
  4308. ParseProgram;
  4309. AssertEquals('1 declaration',1,PasProgram.ProgramSection.Declarations.Count);
  4310. end;
  4311. procedure TTestResolver.TestUnitProcVar;
  4312. var
  4313. El: TPasElement;
  4314. IntfProc1, ImplProc1: TPasProcedure;
  4315. IntfType1, ProcSubType1: TPasAliasType;
  4316. ImplVar1, ProcSubVar1: TPasVariable;
  4317. ImplVar1Type, ProcSubVar1Type: TPasType;
  4318. begin
  4319. StartUnit(false);
  4320. Add('interface');
  4321. Add('');
  4322. Add('type t1=string; // unit scope');
  4323. Add('procedure Proc1;');
  4324. Add('');
  4325. Add('implementation');
  4326. Add('');
  4327. Add('procedure Proc1;');
  4328. Add('type t1=longint; // local proc scope');
  4329. Add('var v1:t1; // using local t1');
  4330. Add('begin');
  4331. Add('end;');
  4332. Add('var v2:t1; // using interface t1');
  4333. ParseUnit;
  4334. // interface
  4335. AssertEquals('2 intf declarations',2,Module.InterfaceSection.Declarations.Count);
  4336. El:=TPasElement(Module.InterfaceSection.Declarations[0]);
  4337. AssertEquals('intf type',TPasAliasType,El.ClassType);
  4338. IntfType1:=TPasAliasType(El);
  4339. AssertEquals('intf type t1','t1',IntfType1.Name);
  4340. El:=TPasElement(Module.InterfaceSection.Declarations[1]);
  4341. AssertEquals('intf proc',TPasProcedure,El.ClassType);
  4342. IntfProc1:=TPasProcedure(El);
  4343. AssertEquals('intf proc Proc1','Proc1',IntfProc1.Name);
  4344. // implementation
  4345. AssertEquals('2 impl declarations',2,Module.ImplementationSection.Declarations.Count);
  4346. El:=TPasElement(Module.ImplementationSection.Declarations[0]);
  4347. AssertEquals('impl proc',TPasProcedure,El.ClassType);
  4348. ImplProc1:=TPasProcedure(El);
  4349. AssertEquals('impl proc Proc1','Proc1',ImplProc1.Name);
  4350. El:=TPasElement(Module.ImplementationSection.Declarations[1]);
  4351. AssertEquals('impl var',TPasVariable,El.ClassType);
  4352. ImplVar1:=TPasVariable(El);
  4353. AssertEquals('impl var v2','v2',ImplVar1.Name);
  4354. ImplVar1Type:=TPasType(ImplVar1.VarType);
  4355. AssertSame('impl var type is intf t1',IntfType1,ImplVar1Type);
  4356. // proc
  4357. AssertEquals('2 proc sub declarations',2,ImplProc1.Body.Declarations.Count);
  4358. // proc sub type t1
  4359. El:=TPasElement(ImplProc1.Body.Declarations[0]);
  4360. AssertEquals('proc sub type',TPasAliasType,El.ClassType);
  4361. ProcSubType1:=TPasAliasType(El);
  4362. AssertEquals('proc sub type t1','t1',ProcSubType1.Name);
  4363. // proc sub var v1
  4364. El:=TPasElement(ImplProc1.Body.Declarations[1]);
  4365. AssertEquals('proc sub var',TPasVariable,El.ClassType);
  4366. ProcSubVar1:=TPasVariable(El);
  4367. AssertEquals('proc sub var v1','v1',ProcSubVar1.Name);
  4368. ProcSubVar1Type:=TPasType(ProcSubVar1.VarType);
  4369. AssertSame('proc sub var type is proc sub t1',ProcSubType1,ProcSubVar1Type);
  4370. end;
  4371. procedure TTestResolver.TestAssignIntegers;
  4372. begin
  4373. StartProgram(false);
  4374. Add('var');
  4375. Add(' {#vbyte}vbyte:byte;');
  4376. Add(' {#vshortint}vshortint:shortint;');
  4377. Add(' {#vword}vword:word;');
  4378. Add(' {#vsmallint}vsmallint:smallint;');
  4379. Add(' {#vlongword}vlongword:longword;');
  4380. Add(' {#vlongint}vlongint:longint;');
  4381. Add(' {#vqword}vqword:qword;');
  4382. Add(' {#vint64}vint64:int64;');
  4383. Add(' {#vcomp}vcomp:comp;');
  4384. Add('begin');
  4385. Add(' {@vbyte}vbyte:=0;');
  4386. Add(' {@vbyte}vbyte:=255;');
  4387. Add(' {@vshortint}vshortint:=0;');
  4388. Add(' {@vshortint}vshortint:=-128;');
  4389. Add(' {@vshortint}vshortint:= 127;');
  4390. Add(' {@vword}vword:=0;');
  4391. Add(' {@vword}vword:=+$ffff;');
  4392. Add(' {@vsmallint}vsmallint:=0;');
  4393. Add(' {@vsmallint}vsmallint:=-$8000;');
  4394. Add(' {@vsmallint}vsmallint:= $7fff;');
  4395. Add(' {@vlongword}vlongword:=0;');
  4396. Add(' {@vlongword}vlongword:=$ffffffff;');
  4397. Add(' {@vlongint}vlongint:=0;');
  4398. Add(' {@vlongint}vlongint:=-$80000000;');
  4399. Add(' {@vlongint}vlongint:= $7fffffff;');
  4400. Add(' {@vlongint}vlongint:={@vbyte}vbyte;');
  4401. Add(' {@vlongint}vlongint:={@vshortint}vshortint;');
  4402. Add(' {@vlongint}vlongint:={@vword}vword;');
  4403. Add(' {@vlongint}vlongint:={@vsmallint}vsmallint;');
  4404. Add(' {@vlongint}vlongint:={@vlongint}vlongint;');
  4405. Add(' {@vint64}vint64:=0;');
  4406. Add(' {@vint64}vint64:=-$8000000000000000;');
  4407. Add(' {@vint64}vint64:= $7fffffffffffffff;');
  4408. Add(' {@vqword}vqword:=0;');
  4409. Add(' {@vqword}vqword:=$ffffffffffffffff;');
  4410. Add(' {@vcomp}vcomp:=0;');
  4411. Add(' {@vcomp}vcomp:=-$8000000000000000;');
  4412. Add(' {@vcomp}vcomp:= $7fffffffffffffff;');
  4413. ParseProgram;
  4414. end;
  4415. procedure TTestResolver.TestAssignString;
  4416. begin
  4417. StartProgram(false);
  4418. Add('var');
  4419. Add(' vstring:string;');
  4420. Add(' vchar:AnsiChar;');
  4421. Add('begin');
  4422. Add(' vstring:='''';');
  4423. Add(' vstring:=''abc'';');
  4424. Add(' vstring:=''a'';');
  4425. Add(' vchar:=''c'';');
  4426. Add(' vchar:=vstring[1];');
  4427. ParseProgram;
  4428. end;
  4429. procedure TTestResolver.TestAssignIntToStringFail;
  4430. begin
  4431. StartProgram(false);
  4432. Add('var');
  4433. Add(' vstring:string;');
  4434. Add('begin');
  4435. Add(' vstring:=2;');
  4436. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  4437. nIncompatibleTypesGotExpected);
  4438. end;
  4439. procedure TTestResolver.TestAssignStringToIntFail;
  4440. begin
  4441. StartProgram(false);
  4442. Add('var');
  4443. Add(' v:longint;');
  4444. Add('begin');
  4445. Add(' v:=''A'';');
  4446. CheckResolverException('Incompatible types: got "Char" expected "Longint"',
  4447. nIncompatibleTypesGotExpected);
  4448. end;
  4449. procedure TTestResolver.TestIntegerOperators;
  4450. begin
  4451. StartProgram(false);
  4452. Add('var');
  4453. Add(' i,j,k:longint;');
  4454. Add('begin');
  4455. Add(' i:=1;');
  4456. Add(' i:=1+2;');
  4457. Add(' i:=1+2+3;');
  4458. Add(' i:=1-2;');
  4459. Add(' i:=j;');
  4460. Add(' i:=j+1;');
  4461. Add(' i:=-j+1;');
  4462. Add(' i:=j+k;');
  4463. Add(' i:=-j+k;');
  4464. Add(' i:=j*k;');
  4465. Add(' i:=j**k;');
  4466. Add(' i:=10**3;');
  4467. Add(' i:=j div k;');
  4468. Add(' i:=10 div 3;');
  4469. Add(' i:=j mod k;');
  4470. Add(' i:=10 mod 3;');
  4471. Add(' i:=j shl k;');
  4472. Add(' i:=j shr k;');
  4473. Add(' i:=j and k;');
  4474. Add(' i:=j or k;');
  4475. Add(' i:=j and not k;');
  4476. Add(' i:=(j+k) div 3;');
  4477. Add(' if i=j then;');
  4478. Add(' if i<>j then;');
  4479. Add(' if i>j then;');
  4480. Add(' if i>=j then;');
  4481. Add(' if i<j then;');
  4482. Add(' if i<=j then;');
  4483. Add(' i:=lo($1234);');
  4484. Add(' i:=lo($1234CDEF);');
  4485. Add(' i:=hi($1234);');
  4486. Add(' i:=hi($1234CDEF);');
  4487. ParseProgram;
  4488. end;
  4489. procedure TTestResolver.TestIntegerBoolFail;
  4490. begin
  4491. StartProgram(false);
  4492. Add([
  4493. 'var i: longint;',
  4494. 'begin',
  4495. ' i:=3 * false;']);
  4496. CheckResolverException('Operator is not overloaded: "Longint" * "Boolean"',
  4497. nOperatorIsNotOverloadedAOpB);
  4498. end;
  4499. procedure TTestResolver.TestBooleanOperators;
  4500. begin
  4501. StartProgram(false);
  4502. Add('var');
  4503. Add(' i,j,k:boolean;');
  4504. Add('begin');
  4505. Add(' i:=false;');
  4506. Add(' i:=true;');
  4507. Add(' i:=j and k;');
  4508. Add(' i:=j or k;');
  4509. Add(' i:=j or not k;');
  4510. Add(' i:=(not j) or k;');
  4511. Add(' i:=j or false;');
  4512. Add(' i:=j and true;');
  4513. Add(' i:=j xor k;');
  4514. Add(' i:=j=k;');
  4515. Add(' i:=j<>k;');
  4516. ParseProgram;
  4517. end;
  4518. procedure TTestResolver.TestStringOperators;
  4519. begin
  4520. StartProgram(false);
  4521. Add([
  4522. 'var',
  4523. ' i,j:string;',
  4524. ' k:char;',
  4525. ' w:widechar;',
  4526. 'begin',
  4527. ' i:='''';',
  4528. ' i:=''''+'''';',
  4529. ' i:=k+'''';',
  4530. ' i:=''''+k;',
  4531. ' i:=''a''+j;',
  4532. ' i:=''abc''+j;',
  4533. ' k:=#65;',
  4534. ' k:=#$42;',
  4535. ' k:=''a'';',
  4536. ' k:='''''''';',
  4537. ' k:=j[1];',
  4538. ' k:=char(#10);',
  4539. ' w:=k;',
  4540. ' w:=#66;',
  4541. ' w:=#6666;',
  4542. ' w:=widechar(#10);',
  4543. ' w:=widechar(#$E0000);',
  4544. '']);
  4545. ParseProgram;
  4546. end;
  4547. procedure TTestResolver.TestWideCharOperators_DelphiUnicode;
  4548. begin
  4549. ResolverEngine.ExprEvaluator.DefaultStringCodePage:=CP_UTF16;
  4550. ResolverEngine.BaseTypeChar:=btWideChar;
  4551. ResolverEngine.BaseTypeString:=btUnicodeString;
  4552. StartProgram(false);
  4553. Add('var');
  4554. Add(' k:char;');
  4555. Add(' w:widechar;');
  4556. Add('begin');
  4557. Add(' w:=k;');
  4558. Add(' w:=#66;');
  4559. Add(' w:=#6666;');
  4560. Add(' w:=''ä'';');
  4561. ParseProgram;
  4562. end;
  4563. procedure TTestResolver.TestFloatOperators;
  4564. begin
  4565. StartProgram(false);
  4566. Add('var');
  4567. Add(' i,j,k:double;');
  4568. Add(' o,p:longint;');
  4569. Add('begin');
  4570. Add(' i:=1;');
  4571. Add(' i:=1+2;');
  4572. Add(' i:=1+2+3;');
  4573. Add(' i:=1-2;');
  4574. Add(' i:=j;');
  4575. Add(' i:=j+1;');
  4576. Add(' i:=-j+1;');
  4577. Add(' i:=j+k;');
  4578. Add(' i:=-j+k;');
  4579. Add(' i:=j*k;');
  4580. Add(' i:=10/3;');
  4581. Add(' i:=10.0/3;');
  4582. Add(' i:=10/3.0;');
  4583. Add(' i:=10.0/3.0;');
  4584. Add(' i:=j/k;');
  4585. Add(' i:=o/p;');
  4586. Add(' i:=10**3;');
  4587. Add(' i:=10.0**3;');
  4588. Add(' i:=10.0**3.0;');
  4589. Add(' i:=10**3.0;');
  4590. Add(' i:=j**k;');
  4591. Add(' i:=o**p;');
  4592. Add(' i:=(j+k)/3;');
  4593. ParseProgram;
  4594. end;
  4595. procedure TTestResolver.TestCAssignments;
  4596. begin
  4597. StartProgram(false);
  4598. Parser.Options:=Parser.Options+[po_cassignments];
  4599. Add('Type');
  4600. Add(' TFlag = (Flag1,Flag2);');
  4601. Add(' TFlags = set of TFlag;');
  4602. Add('var');
  4603. Add(' i: longint;');
  4604. Add(' c: char;');
  4605. Add(' s: string;');
  4606. Add(' d: double;');
  4607. Add(' f: TFlag;');
  4608. Add(' fs: TFlags;');
  4609. Add('begin');
  4610. Add(' i+=1;');
  4611. Add(' i-=2;');
  4612. Add(' i*=3;');
  4613. Add(' s+=''A'';');
  4614. Add(' s:=c;');
  4615. Add(' d+=4;');
  4616. Add(' d-=5;');
  4617. Add(' d*=6;');
  4618. Add(' d/=7;');
  4619. Add(' d+=8.5;');
  4620. Add(' d-=9.5;');
  4621. Add(' d*=10.5;');
  4622. Add(' d/=11.5;');
  4623. Add(' fs+=[f];');
  4624. Add(' fs-=[f];');
  4625. Add(' fs*=[f];');
  4626. Add(' fs+=[Flag1];');
  4627. Add(' fs-=[Flag1];');
  4628. Add(' fs*=[Flag1];');
  4629. Add(' fs+=[Flag1,Flag2];');
  4630. Add(' fs-=[Flag1,Flag2];');
  4631. Add(' fs*=[Flag1,Flag2];');
  4632. ParseProgram;
  4633. end;
  4634. procedure TTestResolver.TestTypeCastBaseTypes;
  4635. begin
  4636. StartProgram(false);
  4637. Add([
  4638. 'var',
  4639. ' si: smallint;',
  4640. ' i: longint;',
  4641. ' fs: single;',
  4642. ' d: double;',
  4643. ' b: boolean;',
  4644. ' c: char;',
  4645. ' s: string;',
  4646. 'begin',
  4647. ' d:=double({#a_read}i);',
  4648. ' i:=shortint({#b_read}i);',
  4649. ' i:=longint({#c_read}si);',
  4650. ' d:=double({#d_read}d);',
  4651. ' fs:=single({#e_read}d);',
  4652. ' d:=single({#f_read}d);',
  4653. ' b:=longbool({#g_read}b);',
  4654. ' b:=bytebool({#i_read}longbool({#h_read}b));',
  4655. ' d:=double({#j_read}i)/2.5;',
  4656. ' b:=boolean({#k_read}i);',
  4657. ' i:=longint({#l_read}b);',
  4658. ' d:=double({#m_read}i);',
  4659. ' c:=char({#n_read}c);',
  4660. ' c:=char({#o_read}i);',
  4661. ' c:=char(65);',
  4662. ' s:=string({#p_read}s);',
  4663. ' s:=string({#q_read}c);',
  4664. '']);
  4665. ParseProgram;
  4666. CheckAccessMarkers;
  4667. end;
  4668. procedure TTestResolver.TestTypeCastAliasBaseTypes;
  4669. begin
  4670. StartProgram(false);
  4671. Add('type');
  4672. Add(' integer = longint;');
  4673. Add(' TCaption = string;');
  4674. Add(' TYesNo = boolean;');
  4675. Add(' TFloat = double;');
  4676. Add(' TChar = char;');
  4677. Add('var');
  4678. Add(' i: longint;');
  4679. Add(' s: string;');
  4680. Add(' b: boolean;');
  4681. Add(' d: double;');
  4682. Add(' c: char;');
  4683. Add('begin');
  4684. Add(' i:=integer({#a_read}i);');
  4685. Add(' i:=integer({#h_read}b);');
  4686. Add(' s:=TCaption({#b_read}s);');
  4687. Add(' s:=TCaption({#g_read}c);');
  4688. Add(' b:=TYesNo({#c_read}b);');
  4689. Add(' b:=TYesNo({#d_read}i);');
  4690. Add(' d:=TFloat({#e_read}d);');
  4691. Add(' c:=TChar({#f_read}c);');
  4692. ParseProgram;
  4693. CheckAccessMarkers;
  4694. end;
  4695. procedure TTestResolver.TestTypeCastStrToIntFail;
  4696. begin
  4697. StartProgram(false);
  4698. Add('var');
  4699. Add(' s: string;');
  4700. Add(' i: longint;');
  4701. Add('begin');
  4702. Add(' i:=longint(s);');
  4703. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4704. end;
  4705. procedure TTestResolver.TestTypeCastStrToCharFail;
  4706. begin
  4707. StartProgram(false);
  4708. Add('var');
  4709. Add(' s: string;');
  4710. Add(' c: char;');
  4711. Add('begin');
  4712. Add(' c:=char(s);');
  4713. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4714. end;
  4715. procedure TTestResolver.TestTypeCastIntToStrFail;
  4716. begin
  4717. StartProgram(false);
  4718. Add('var');
  4719. Add(' s: string;');
  4720. Add(' i: longint;');
  4721. Add('begin');
  4722. Add(' s:=string(i);');
  4723. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4724. end;
  4725. procedure TTestResolver.TestTypeCastDoubleToStrFail;
  4726. begin
  4727. StartProgram(false);
  4728. Add('var');
  4729. Add(' s: string;');
  4730. Add(' d: double;');
  4731. Add('begin');
  4732. Add(' s:=string(d);');
  4733. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4734. end;
  4735. procedure TTestResolver.TestTypeCastDoubleToIntFail;
  4736. begin
  4737. StartProgram(false);
  4738. Add('var');
  4739. Add(' i: longint;');
  4740. Add(' d: double;');
  4741. Add('begin');
  4742. Add(' i:=longint(d);');
  4743. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4744. end;
  4745. procedure TTestResolver.TestTypeCastDoubleToBoolFail;
  4746. begin
  4747. StartProgram(false);
  4748. Add('var');
  4749. Add(' b: boolean;');
  4750. Add(' d: double;');
  4751. Add('begin');
  4752. Add(' b:=longint(d);');
  4753. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4754. end;
  4755. procedure TTestResolver.TestTypeCastBooleanToDoubleFail;
  4756. begin
  4757. StartProgram(false);
  4758. Add('var');
  4759. Add(' b: boolean;');
  4760. Add(' d: double;');
  4761. Add('begin');
  4762. Add(' d:=double(b);');
  4763. CheckResolverException(sIllegalTypeConversionTo,nIllegalTypeConversionTo);
  4764. end;
  4765. procedure TTestResolver.TestAssign_Access;
  4766. begin
  4767. StartProgram(false);
  4768. Parser.Options:=Parser.Options+[po_cassignments];
  4769. Add('var i: longint;');
  4770. Add('begin');
  4771. Add(' {#a1_assign}i:={#a2_read}i;');
  4772. Add(' {#b1_readandassign}i+={#b2_read}i;');
  4773. Add(' {#c1_readandassign}i-={#c2_read}i;');
  4774. Add(' {#d1_readandassign}i*={#d2_read}i;');
  4775. ParseProgram;
  4776. CheckAccessMarkers;
  4777. end;
  4778. procedure TTestResolver.TestAssignedIntFail;
  4779. begin
  4780. StartProgram(false);
  4781. Add('var i: longint;');
  4782. Add('begin');
  4783. Add(' if Assigned(i) then ;');
  4784. CheckResolverException('Incompatible type for arg no. 1: Got "Longint", expected "class or array"',
  4785. nIncompatibleTypeArgNo);
  4786. end;
  4787. procedure TTestResolver.TestHighLow;
  4788. begin
  4789. StartProgram(false);
  4790. Add([
  4791. 'const',
  4792. ' abc = ''abc'';',
  4793. 'var',
  4794. ' bo: boolean;',
  4795. ' by: byte;',
  4796. ' ch: char;',
  4797. ' s: string;',
  4798. ' i: longint = high(abc);',
  4799. 'begin',
  4800. ' for bo:=low(boolean) to high(boolean) do;',
  4801. ' for by:=low(byte) to high(byte) do;',
  4802. ' for ch:=low(char) to high(AnsiChar) do;',
  4803. ' for i:=low(s) to high(s) do;',
  4804. '']);
  4805. ParseProgram;
  4806. end;
  4807. procedure TTestResolver.TestStr_BaseTypes;
  4808. begin
  4809. StartProgram(false);
  4810. Add('var');
  4811. Add(' b: boolean;');
  4812. Add(' i: longint;');
  4813. Add(' i64: int64;');
  4814. Add(' s: single;');
  4815. Add(' d: double;');
  4816. Add(' aString: string;');
  4817. Add(' r: record end;');
  4818. Add('begin');
  4819. Add(' Str(b,{#a_var}aString);');
  4820. Add(' Str(b:1,aString);');
  4821. Add(' Str(b:i,aString);');
  4822. Add(' Str(i,aString);');
  4823. Add(' Str(i:2,aString);');
  4824. Add(' Str(i:i64,aString);');
  4825. Add(' Str(i64,aString);');
  4826. Add(' Str(i64:3,aString);');
  4827. Add(' Str(i64:i,aString);');
  4828. Add(' Str(s,aString);');
  4829. Add(' Str(d,aString);');
  4830. Add(' Str(d:4,aString);');
  4831. Add(' Str(d:4:5,aString);');
  4832. Add(' Str(d:4:i,aString);');
  4833. Add(' aString:=Str(b);');
  4834. Add(' aString:=Str(i:3);');
  4835. Add(' aString:=Str(d:3:4);');
  4836. Add(' aString:=Str(b,i,d);');
  4837. Add(' aString:=Str(s,''foo'');');
  4838. Add(' aString:=Str(i,{#assign_read}aString);');
  4839. Add(' while true do Str(i,{#whiledo_var}aString);');
  4840. Add(' repeat Str(i,{#repeat_var}aString); until true;');
  4841. Add(' if true then Str(i,{#ifthen_var}aString) else Str(i,{#ifelse_var}aString);');
  4842. Add(' for i:=0 to 0 do Str(i,{#fordo_var}aString);');
  4843. Add(' with r do Str(i,{#withdo_var}aString);');
  4844. Add(' case Str(s,''caseexpr'') of');
  4845. Add(' ''bar'': Str(i,{#casest_var}aString);');
  4846. Add(' else Str(i,{#caseelse_var}aString);');
  4847. Add(' end;');
  4848. ParseProgram;
  4849. CheckAccessMarkers;
  4850. end;
  4851. procedure TTestResolver.TestStr_StringFail;
  4852. begin
  4853. StartProgram(false);
  4854. Add('var');
  4855. Add(' aString: string;');
  4856. Add('begin');
  4857. Add(' Str(aString,aString);');
  4858. CheckResolverException('Incompatible type for arg no. 1: Got "String", expected "boolean, integer, enum value"',
  4859. nIncompatibleTypeArgNo);
  4860. end;
  4861. procedure TTestResolver.TestStr_CharFail;
  4862. begin
  4863. StartProgram(false);
  4864. Add('var');
  4865. Add(' c: char;');
  4866. Add(' aString: string;');
  4867. Add('begin');
  4868. Add(' Str(c,aString);');
  4869. CheckResolverException('Incompatible type for arg no. 1: Got "Char", expected "boolean, integer, enum value"',
  4870. nIncompatibleTypeArgNo);
  4871. end;
  4872. procedure TTestResolver.TestIncDec;
  4873. begin
  4874. StartProgram(false);
  4875. Add('var');
  4876. Add(' i: longint;');
  4877. Add('begin');
  4878. Add(' inc({#a_var}i);');
  4879. Add(' inc({#b_var}i,2);');
  4880. Add(' dec({#c_var}i);');
  4881. Add(' dec({#d_var}i,3);');
  4882. ParseProgram;
  4883. CheckAccessMarkers;
  4884. end;
  4885. procedure TTestResolver.TestIncStringFail;
  4886. begin
  4887. StartProgram(false);
  4888. Add('var');
  4889. Add(' i: string;');
  4890. Add('begin');
  4891. Add(' inc(i);');
  4892. CheckResolverException('Incompatible type for arg no. 1: Got "String", expected "integer"',nIncompatibleTypeArgNo);
  4893. end;
  4894. procedure TTestResolver.TestTypeInfo;
  4895. begin
  4896. StartProgram(false);
  4897. Add([
  4898. 'type',
  4899. ' integer = longint;',
  4900. ' TRec = record',
  4901. ' v: integer;',
  4902. ' end;',
  4903. ' TClass = class of TObject;',
  4904. ' TObject = class',
  4905. ' class function ClassType: TClass; virtual; abstract;',
  4906. ' end;',
  4907. 'var',
  4908. ' i: integer;',
  4909. ' s: string;',
  4910. ' p: pointer;',
  4911. ' r: TRec;',
  4912. ' o: TObject;',
  4913. ' c: TClass;',
  4914. 'begin',
  4915. ' p:=typeinfo(integer);',
  4916. ' p:=typeinfo(longint);',
  4917. ' p:=typeinfo(i);',
  4918. ' p:=typeinfo(s);',
  4919. ' p:=typeinfo(p);',
  4920. ' p:=typeinfo(r.v);',
  4921. ' p:=typeinfo(TObject.ClassType);',
  4922. ' p:=typeinfo(o.ClassType);',
  4923. ' p:=typeinfo(o);',
  4924. ' p:=typeinfo(c);',
  4925. ' p:=typeinfo(c.ClassType);',
  4926. '']);
  4927. ParseProgram;
  4928. end;
  4929. procedure TTestResolver.TestTypeInfo_FailRTTIDisabled;
  4930. begin
  4931. StartProgram(false);
  4932. Add([
  4933. '{$modeswitch OmitRTTI}',
  4934. 'type',
  4935. ' TObject = class',
  4936. ' end;',
  4937. 'var o: TObject;',
  4938. 'begin',
  4939. ' if typeinfo(o)=nil then ;',
  4940. '']);
  4941. CheckResolverException(sSymbolCannotBePublished,nSymbolCannotBePublished);
  4942. end;
  4943. procedure TTestResolver.TestGetTypeKind;
  4944. begin
  4945. StartProgram(true,[supTTypeKind]);
  4946. Add([
  4947. 'type',
  4948. ' integer = longint;',
  4949. ' TRec = record',
  4950. ' v: integer;',
  4951. ' end;',
  4952. ' TClass = class of TObject;',
  4953. ' TObject = class',
  4954. ' class function ClassType: TClass; virtual; abstract;',
  4955. ' end;',
  4956. 'var',
  4957. ' i: integer;',
  4958. ' s: string;',
  4959. ' p: pointer;',
  4960. ' r: TRec;',
  4961. ' o: TObject;',
  4962. ' c: TClass;',
  4963. ' k: TTypeKind;',
  4964. 'begin',
  4965. ' k:=gettypekind(integer);',
  4966. ' k:=gettypekind(longint);',
  4967. ' k:=gettypekind(i);',
  4968. ' k:=gettypekind(s);',
  4969. ' k:=gettypekind(p);',
  4970. ' k:=gettypekind(r.v);',
  4971. ' k:=gettypekind(TObject.ClassType);',
  4972. ' k:=gettypekind(o.ClassType);',
  4973. ' k:=gettypekind(o);',
  4974. ' k:=gettypekind(c);',
  4975. ' k:=gettypekind(c.ClassType);',
  4976. ' k:=gettypekind(k);',
  4977. '']);
  4978. ParseProgram;
  4979. end;
  4980. procedure TTestResolver.TestForLoop;
  4981. begin
  4982. StartProgram(false);
  4983. Add('var');
  4984. Add(' {#v1}v1,{#v2}v2,{#v3}v3:longint;');
  4985. Add('begin');
  4986. Add(' for {@v1}v1:=');
  4987. Add(' {@v2}v2');
  4988. Add(' to {@v3}v3 do ;');
  4989. ParseProgram;
  4990. end;
  4991. procedure TTestResolver.TestForLoop_NestedSameVarFail;
  4992. begin
  4993. StartProgram(false);
  4994. Add([
  4995. 'var i: byte;',
  4996. 'begin',
  4997. ' for i:=1 to 2 do',
  4998. ' for i:=1 to 2 do ;',
  4999. '']);
  5000. CheckResolverException('Illegal assignment to for-loop variable "i"',nIllegalAssignmentToForLoopVar);
  5001. end;
  5002. procedure TTestResolver.TestForLoop_AssignVarFail;
  5003. begin
  5004. StartProgram(false);
  5005. Add([
  5006. 'var i: byte;',
  5007. 'begin',
  5008. ' for i:=1 to 2 do',
  5009. ' i:=3;',
  5010. '']);
  5011. CheckResolverException('Illegal assignment to for-loop variable "i"',nIllegalAssignmentToForLoopVar);
  5012. end;
  5013. procedure TTestResolver.TestForLoop_PassVarFail;
  5014. begin
  5015. StartProgram(false);
  5016. Add([
  5017. 'procedure DoIt(var i: byte); external;',
  5018. 'var i: byte;',
  5019. 'begin',
  5020. ' for i:=1 to 2 do',
  5021. ' DoIt(i);',
  5022. '']);
  5023. CheckResolverException('Illegal assignment to for-loop variable "i"',nIllegalAssignmentToForLoopVar);
  5024. end;
  5025. procedure TTestResolver.TestForLoop_FieldFail;
  5026. begin
  5027. StartProgram(false);
  5028. Add([
  5029. 'type',
  5030. ' TObject = class',
  5031. ' Size: word;',
  5032. ' procedure Fly;',
  5033. ' end;',
  5034. 'procedure TObject.Fly;',
  5035. 'begin',
  5036. ' for Size:=1 to 2 do',
  5037. ' ;',
  5038. 'end;',
  5039. 'begin',
  5040. '']);
  5041. CheckResolverException(sForLoopControlVarMustBeSimpleLocalVar,nForLoopControlVarMustBeSimpleLocalVar);
  5042. end;
  5043. procedure TTestResolver.TestStatements;
  5044. begin
  5045. StartProgram(false);
  5046. Add([
  5047. 'var',
  5048. ' v1,v2,v3:longint;',
  5049. 'begin',
  5050. ' v1:=1;',
  5051. ' v2:=v1+v1*v1+v1 div v1;',
  5052. ' v3:=-v1;',
  5053. ' repeat',
  5054. ' v1:=v1+1;',
  5055. ' until v1>=5;',
  5056. ' while v1>=0 do',
  5057. ' v1:=v1-v2;',
  5058. ' for v1:=v2 to v3 do v2:=v1;',
  5059. ' if v1<v2 then v3:=v1 else v3:=v2;',
  5060. '']);
  5061. ParseProgram;
  5062. AssertEquals('3 declarations',3,PasProgram.ProgramSection.Declarations.Count);
  5063. end;
  5064. procedure TTestResolver.TestCaseOfInt;
  5065. begin
  5066. StartProgram(false);
  5067. Add('const');
  5068. Add(' {#c1}c1=1;');
  5069. Add(' {#c2}c2=2;');
  5070. Add(' {#c3}c3=3;');
  5071. Add(' {#c4}c4=4;');
  5072. Add(' {#c5}c5=5;');
  5073. Add(' {#c6}c6=6;');
  5074. Add('var');
  5075. Add(' {#v1}v1,{#v2}v2,{#v3}v3:longint;');
  5076. Add('begin');
  5077. Add(' Case {@v1}v1+{@v2}v2 of');
  5078. Add(' {@c1}c1:');
  5079. Add(' {@v2}v2:={@v3}v3;');
  5080. Add(' {@c2}c2,{@c3}c3: ;');
  5081. Add(' {@c4}c4..5: ;');
  5082. Add(' {@c5}c5+{@c6}c6: ;');
  5083. Add(' else');
  5084. Add(' {@v1}v1:=3;');
  5085. Add(' end;');
  5086. ParseProgram;
  5087. end;
  5088. procedure TTestResolver.TestCaseOfIntExtConst;
  5089. begin
  5090. Parser.Options:=Parser.Options+[po_ExtConstWithoutExpr];
  5091. StartProgram(false);
  5092. Add([
  5093. 'const e: longint; external;',
  5094. 'var i: longint;',
  5095. 'begin',
  5096. ' case i of',
  5097. ' 2: ;',
  5098. ' e: ;',
  5099. ' 1: ;',
  5100. ' end;',
  5101. '']);
  5102. ParseProgram;
  5103. end;
  5104. procedure TTestResolver.TestCaseIntDuplicateFail;
  5105. begin
  5106. StartProgram(false);
  5107. Add([
  5108. 'var i: longint;',
  5109. 'begin',
  5110. ' case i of',
  5111. ' 2: ;',
  5112. ' 1..3: ;',
  5113. ' end;',
  5114. '']);
  5115. CheckResolverException('Duplicate case value "1..3", other at afile.pp(5,3)',nDuplicateCaseValueXatY);
  5116. end;
  5117. procedure TTestResolver.TestCaseOfStringDuplicateFail;
  5118. begin
  5119. StartProgram(false);
  5120. Add([
  5121. 'var s: string;',
  5122. 'begin',
  5123. ' case s of',
  5124. ' ''a''#10''bc'': ;',
  5125. ' ''A''#10''BC'': ;',
  5126. ' ''a''#10''bc'': ;',
  5127. ' end;',
  5128. '']);
  5129. CheckResolverException('Duplicate case value "string", other at afile.pp(5,3)',nDuplicateCaseValueXatY);
  5130. end;
  5131. procedure TTestResolver.TestCaseOfStringRangeDuplicateFail;
  5132. begin
  5133. StartProgram(false);
  5134. Add([
  5135. 'var s: string;',
  5136. 'begin',
  5137. ' case s of',
  5138. ' ''c'': ;',
  5139. ' ''a''..''z'': ;',
  5140. ' end;',
  5141. '']);
  5142. CheckResolverException('Duplicate case value "string", other at afile.pp(5,3)',nDuplicateCaseValueXatY);
  5143. end;
  5144. procedure TTestResolver.TestCaseOfBaseType;
  5145. begin
  5146. StartProgram(false);
  5147. Add([
  5148. 'type',
  5149. ' TFlag = (red,green,blue);',
  5150. 'var',
  5151. ' i: longint;',
  5152. ' f: TFlag;',
  5153. ' b: boolean;',
  5154. ' c: char;',
  5155. ' s: string;',
  5156. 'begin',
  5157. ' case i of',
  5158. ' 1: ;',
  5159. ' 2..3: ;',
  5160. ' 4,5..6,7: ;',
  5161. ' else',
  5162. ' end;',
  5163. ' case f of',
  5164. ' red: ;',
  5165. ' green..blue: ;',
  5166. ' end;',
  5167. ' case b of',
  5168. ' true: ;',
  5169. ' false: ;',
  5170. ' end;',
  5171. ' case c of',
  5172. ' #0: ;',
  5173. ' #10,#13: ;',
  5174. ' ''0''..''9'',''a''..''z'': ;',
  5175. ' end;',
  5176. ' case s of',
  5177. ' #10: ;',
  5178. ' ''abc'': ;',
  5179. ' ''a''..''z'': ;',
  5180. ' end;']);
  5181. ParseProgram;
  5182. end;
  5183. procedure TTestResolver.TestCaseOfExprNonOrdFail;
  5184. begin
  5185. StartProgram(false);
  5186. Add('begin');
  5187. Add(' case longint of');
  5188. Add(' 1: ;');
  5189. Add(' end;');
  5190. CheckResolverException('ordinal expression expected, but Longint found',
  5191. nXExpectedButYFound);
  5192. end;
  5193. procedure TTestResolver.TestCaseOfIncompatibleValueFail;
  5194. begin
  5195. StartProgram(false);
  5196. Add('var i: longint;');
  5197. Add('begin');
  5198. Add(' case i of');
  5199. Add(' ''1'': ;');
  5200. Add(' end;');
  5201. CheckResolverException('Incompatible types: got "Char" expected "Longint"',
  5202. nIncompatibleTypesGotExpected);
  5203. end;
  5204. procedure TTestResolver.TestTryStatement;
  5205. begin
  5206. StartProgram(false);
  5207. Add('type');
  5208. Add(' TObject = class end;');
  5209. Add(' {#Exec}Exception = class end;');
  5210. Add('var');
  5211. Add(' {#v1}v1,{#e1}e:longint;');
  5212. Add('begin');
  5213. Add(' try');
  5214. Add(' {@v1}v1:={@e1}e;');
  5215. Add(' finally');
  5216. Add(' {@v1}v1:={@e1}e;');
  5217. Add(' end;');
  5218. Add(' try');
  5219. Add(' {@v1}v1:={@e1}e;');
  5220. Add(' except');
  5221. Add(' {@v1}v1:={@e1}e;');
  5222. Add(' raise;');
  5223. Add(' end;');
  5224. Add(' try');
  5225. Add(' {@v1}v1:={@e1}e;');
  5226. Add(' except');
  5227. Add(' on {#e2}{=Exec}E: Exception do');
  5228. Add(' if {@e2}e=nil then raise;');
  5229. Add(' on {#e3}{=Exec}E: Exception do');
  5230. Add(' raise {@e3}e;');
  5231. Add(' else');
  5232. Add(' {@v1}v1:={@e1}e;');
  5233. Add(' end;');
  5234. ParseProgram;
  5235. end;
  5236. procedure TTestResolver.TestTryExceptOnNonTypeFail;
  5237. begin
  5238. StartProgram(false);
  5239. Add('type TObject = class end;');
  5240. Add('var E: TObject;');
  5241. Add('begin');
  5242. Add(' try');
  5243. Add(' except');
  5244. Add(' on E do ;');
  5245. Add(' end;');
  5246. CheckParserException('Expected type, but got variable',PParser.nParserExpectedTypeButGot);
  5247. end;
  5248. procedure TTestResolver.TestTryExceptOnNonClassFail;
  5249. begin
  5250. StartProgram(false);
  5251. Add('begin');
  5252. Add(' try');
  5253. Add(' except');
  5254. Add(' on longint do ;');
  5255. Add(' end;');
  5256. CheckResolverException('class expected, but Longint found',nXExpectedButYFound);
  5257. end;
  5258. procedure TTestResolver.TestTryStatementMissingOnFail;
  5259. begin
  5260. StartProgram(true,[supTObject]);
  5261. Add([
  5262. 'procedure Run;',
  5263. 'begin',
  5264. ' try',
  5265. ' except',
  5266. ' on TObject do ;',
  5267. ' Run;',
  5268. ' end;',
  5269. 'end;',
  5270. 'begin',
  5271. '']);
  5272. CheckParserException('Expected "end" or "on"',nParserExpectToken2Error);
  5273. end;
  5274. procedure TTestResolver.TestRaiseNonVarFail;
  5275. begin
  5276. StartProgram(false);
  5277. Add('type TObject = class end;');
  5278. Add('begin');
  5279. Add(' raise TObject;');
  5280. CheckResolverException('variable expected, but class found',nXExpectedButYFound);
  5281. end;
  5282. procedure TTestResolver.TestRaiseNonClassFail;
  5283. begin
  5284. StartProgram(false);
  5285. Add('var');
  5286. Add(' E: longint;');
  5287. Add('begin');
  5288. Add(' raise E;');
  5289. CheckResolverException('class expected, but Longint found',nXExpectedButYFound);
  5290. end;
  5291. procedure TTestResolver.TestRaiseDescendant;
  5292. var
  5293. aMarker: PSrcMarker;
  5294. Elements: TFPList;
  5295. ActualNewInstance: Boolean;
  5296. i: Integer;
  5297. El: TPasElement;
  5298. Ref: TResolvedReference;
  5299. begin
  5300. StartProgram(false);
  5301. Add([
  5302. 'type',
  5303. ' TObject = class',
  5304. ' constructor Create(Msg: string); external name ''ext'';',
  5305. ' end;',
  5306. ' Exception = class end;',
  5307. ' EConvertError = class(Exception) end;',
  5308. 'function AssertConv(Msg: string = ''msg''): EConvertError;',
  5309. 'begin',
  5310. ' Result:=EConvertError.{#ass}Create(Msg);',
  5311. 'end;',
  5312. 'begin',
  5313. ' raise Exception.{#a}Create(''foo'');',
  5314. ' raise EConvertError.{#b}Create(''bar'');',
  5315. ' raise AssertConv(''c'');',
  5316. ' raise AssertConv;',
  5317. '']);
  5318. ParseProgram;
  5319. aMarker:=FirstSrcMarker;
  5320. while aMarker<>nil do
  5321. begin
  5322. //writeln('TTestResolver.TestRaiseDescendant ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  5323. Elements:=FindElementsAt(aMarker);
  5324. try
  5325. ActualNewInstance:=false;
  5326. for i:=0 to Elements.Count-1 do
  5327. begin
  5328. El:=TPasElement(Elements[i]);
  5329. //writeln('TTestResolver.TestRaiseDescendant ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  5330. if not (El.CustomData is TResolvedReference) then continue;
  5331. Ref:=TResolvedReference(El.CustomData);
  5332. if not (Ref.Declaration is TPasProcedure) then continue;
  5333. //writeln('TTestResolver.TestRaiseDescendant ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  5334. if (Ref.Declaration is TPasConstructor) then
  5335. ActualNewInstance:=rrfNewInstance in Ref.Flags;
  5336. break;
  5337. end;
  5338. if not ActualNewInstance then
  5339. RaiseErrorAtSrcMarker('expected newinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  5340. finally
  5341. Elements.Free;
  5342. end;
  5343. aMarker:=aMarker^.Next;
  5344. end;
  5345. end;
  5346. procedure TTestResolver.TestStatementsRefs;
  5347. begin
  5348. StartProgram(false);
  5349. Add('var');
  5350. Add(' {#v1}v1,{#v2}v2,{#v3}v3:longint;');
  5351. Add('begin');
  5352. Add(' {@v1}v1:=1;');
  5353. Add(' {@v2}v2:=');
  5354. Add(' {@v1}v1+');
  5355. Add(' {@v1}v1*{@v1}v1');
  5356. Add(' +{@v1}v1 div {@v1}v1;');
  5357. Add(' {@v3}v3:=');
  5358. Add(' -{@v1}v1;');
  5359. Add(' repeat');
  5360. Add(' {@v1}v1:=');
  5361. Add(' {@v1}v1+1;');
  5362. Add(' until {@v1}v1>=5;');
  5363. Add(' while {@v1}v1>=0 do');
  5364. Add(' {@v1}v1');
  5365. Add(' :={@v1}v1-{@v2}v2;');
  5366. Add(' if {@v1}v1<{@v2}v2 then');
  5367. Add(' {@v3}v3:={@v1}v1');
  5368. Add(' else {@v3}v3:=');
  5369. Add(' {@v2}v2;');
  5370. ParseProgram;
  5371. AssertEquals('3 declarations',3,PasProgram.ProgramSection.Declarations.Count);
  5372. end;
  5373. procedure TTestResolver.TestRepeatUntilNonBoolFail;
  5374. begin
  5375. StartProgram(false);
  5376. Add('begin');
  5377. Add(' repeat');
  5378. Add(' until 3;');
  5379. CheckResolverException('Boolean expected, but Longint found',nXExpectedButYFound);
  5380. end;
  5381. procedure TTestResolver.TestWhileDoNonBoolFail;
  5382. begin
  5383. StartProgram(false);
  5384. Add('begin');
  5385. Add(' while 3 do ;');
  5386. CheckResolverException('Boolean expected, but Longint found',nXExpectedButYFound);
  5387. end;
  5388. procedure TTestResolver.TestIfThen;
  5389. begin
  5390. StartProgram(false);
  5391. Add([
  5392. 'var b: boolean;',
  5393. 'begin',
  5394. ' if b then ;',
  5395. ' if b then else ;']);
  5396. ParseProgram;
  5397. end;
  5398. procedure TTestResolver.TestIfThenNonBoolFail;
  5399. begin
  5400. StartProgram(false);
  5401. Add('begin');
  5402. Add(' if 3 then ;');
  5403. CheckResolverException('Boolean expected, but Longint found',nXExpectedButYFound);
  5404. end;
  5405. procedure TTestResolver.TestIfAssignMissingSemicolonFail;
  5406. begin
  5407. StartProgram(false);
  5408. Add([
  5409. 'var',
  5410. ' v:longint;',
  5411. 'begin',
  5412. ' if true then v:=1',
  5413. ' v:=2']);
  5414. CheckParserException('Expected "Semicolon"',nParserExpectTokenError);
  5415. end;
  5416. procedure TTestResolver.TestForLoopVarNonVarFail;
  5417. begin
  5418. StartProgram(false);
  5419. Add('const i = 3;');
  5420. Add('begin');
  5421. Add(' for i:=1 to 2 do ;');
  5422. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  5423. end;
  5424. procedure TTestResolver.TestForLoopStartIncompFail;
  5425. begin
  5426. StartProgram(false);
  5427. Add('var i: char;');
  5428. Add('begin');
  5429. Add(' for i:=1 to 2 do ;');
  5430. CheckResolverException('Incompatible types: got "Longint" expected "Char"',
  5431. nIncompatibleTypesGotExpected);
  5432. end;
  5433. procedure TTestResolver.TestForLoopEndIncompFail;
  5434. begin
  5435. StartProgram(false);
  5436. Add('var i: longint;');
  5437. Add('begin');
  5438. Add(' for i:=1 to ''2'' do ;');
  5439. CheckResolverException('Incompatible types: got "Char" expected "Longint"',
  5440. nIncompatibleTypesGotExpected);
  5441. end;
  5442. procedure TTestResolver.TestSimpleStatement_VarFail;
  5443. begin
  5444. StartProgram(false);
  5445. Add('var i: longint;');
  5446. Add('begin');
  5447. Add(' i;');
  5448. CheckResolverException('Illegal expression',nIllegalExpression);
  5449. end;
  5450. procedure TTestResolver.TestLabelStatementFail;
  5451. begin
  5452. StartProgram(false);
  5453. Add('var i: longint;');
  5454. Add('begin');
  5455. Add(' i: i;');
  5456. CheckParserException('Expected ";"',nParserExpectTokenError);
  5457. end;
  5458. procedure TTestResolver.TestLabelStatementDelphiFail;
  5459. begin
  5460. StartProgram(false);
  5461. Add('{$mode delphi}');
  5462. Add('{$goto off}');
  5463. Add('var i: longint;');
  5464. Add('begin');
  5465. Add(' i: i;');
  5466. CheckParserException('Expected ";"',nParserExpectTokenError);
  5467. end;
  5468. procedure TTestResolver.TestUnitForwardOverloads;
  5469. begin
  5470. StartUnit(false);
  5471. Add([
  5472. 'interface',
  5473. 'procedure {#ADecl}DoIt(vI: longint);',
  5474. 'procedure {#BDecl}DoIt(vI, vJ: longint);',
  5475. 'implementation',
  5476. 'procedure {#EDecl}DoIt(vI, vJ, vK, vL, vM: longint); forward;',
  5477. 'procedure {#C}DoIt(vI, vJ, vK: longint); begin end;',
  5478. 'procedure {#AImpl}DoIt(vi: longint); begin end;',
  5479. 'procedure {#D}DoIt(vI, vJ, vK, vL: longint); begin end;',
  5480. 'procedure {#BImpl}DoIt(vi, vj: longint); begin end;',
  5481. 'procedure {#EImpl}DoIt(vi, vj, vk, vl, vm: longint); begin end;',
  5482. 'begin',
  5483. ' {@ADecl}DoIt(1);',
  5484. ' {@BDecl}DoIt(2,3);',
  5485. ' {@C}DoIt(4,5,6);',
  5486. ' {@D}DoIt(7,8,9,10);',
  5487. ' {@EDecl}DoIt(11,12,13,14,15);']);
  5488. ParseUnit;
  5489. end;
  5490. procedure TTestResolver.TestUnitIntfInitialization;
  5491. var
  5492. El, DeclEl, OtherUnit: TPasElement;
  5493. LocalVar: TPasVariable;
  5494. Assign1, Assign2, Assign3: TPasImplAssign;
  5495. Prim1, Prim2: TPrimitiveExpr;
  5496. BinExp: TBinaryExpr;
  5497. begin
  5498. StartUnit(true);
  5499. Add('interface');
  5500. Add('var exitCOde: string;');
  5501. Add('implementation');
  5502. Add('initialization');
  5503. Add(' ExitcodE:=''1'';');
  5504. Add(' afile.eXitCode:=''2'';');
  5505. Add(' System.exiTCode:=3;');
  5506. ParseUnit;
  5507. // interface
  5508. AssertEquals('1 intf declaration',1,Module.InterfaceSection.Declarations.Count);
  5509. El:=TPasElement(Module.InterfaceSection.Declarations[0]);
  5510. AssertEquals('local var',TPasVariable,El.ClassType);
  5511. LocalVar:=TPasVariable(El);
  5512. AssertEquals('local var exitcode','exitCOde',LocalVar.Name);
  5513. // initialization
  5514. AssertEquals('3 initialization statements',3,Module.InitializationSection.Elements.Count);
  5515. // check direct assignment to local var
  5516. El:=TPasElement(Module.InitializationSection.Elements[0]);
  5517. AssertEquals('direct assign',TPasImplAssign,El.ClassType);
  5518. Assign1:=TPasImplAssign(El);
  5519. AssertEquals('direct assign left',TPrimitiveExpr,Assign1.Left.ClassType);
  5520. Prim1:=TPrimitiveExpr(Assign1.Left);
  5521. AssertNotNull(Prim1.CustomData);
  5522. AssertEquals('direct assign left ref',TResolvedReference,Prim1.CustomData.ClassType);
  5523. DeclEl:=TResolvedReference(Prim1.CustomData).Declaration;
  5524. AssertSame('direct assign local var',LocalVar,DeclEl);
  5525. // check indirect assignment to local var: "afile.eXitCode"
  5526. El:=TPasElement(Module.InitializationSection.Elements[1]);
  5527. AssertEquals('indirect assign',TPasImplAssign,El.ClassType);
  5528. Assign2:=TPasImplAssign(El);
  5529. AssertEquals('indirect assign left',TBinaryExpr,Assign2.Left.ClassType);
  5530. BinExp:=TBinaryExpr(Assign2.Left);
  5531. AssertEquals('indirect assign first token',TPrimitiveExpr,BinExp.Left.ClassType);
  5532. Prim1:=TPrimitiveExpr(BinExp.Left);
  5533. AssertEquals('indirect assign first token','afile',Prim1.Value);
  5534. AssertNotNull(Prim1.CustomData);
  5535. AssertEquals('indirect assign unit ref resolved',TResolvedReference,Prim1.CustomData.ClassType);
  5536. DeclEl:=TResolvedReference(Prim1.CustomData).Declaration;
  5537. AssertSame('indirect assign unit ref',Module,DeclEl);
  5538. AssertEquals('indirect assign dot',eopSubIdent,BinExp.OpCode);
  5539. AssertEquals('indirect assign second token',TPrimitiveExpr,BinExp.Right.ClassType);
  5540. Prim2:=TPrimitiveExpr(BinExp.Right);
  5541. AssertEquals('indirect assign second token','eXitCode',Prim2.Value);
  5542. AssertNotNull(Prim2.CustomData);
  5543. AssertEquals('indirect assign var ref resolved',TResolvedReference,Prim2.CustomData.ClassType);
  5544. AssertEquals('indirect assign left ref',TResolvedReference,Prim2.CustomData.ClassType);
  5545. DeclEl:=TResolvedReference(Prim2.CustomData).Declaration;
  5546. AssertSame('indirect assign local var',LocalVar,DeclEl);
  5547. // check assignment to "system.ExitCode"
  5548. El:=TPasElement(Module.InitializationSection.Elements[2]);
  5549. AssertEquals('other unit assign',TPasImplAssign,El.ClassType);
  5550. Assign3:=TPasImplAssign(El);
  5551. AssertEquals('other unit assign left',TBinaryExpr,Assign3.Left.ClassType);
  5552. BinExp:=TBinaryExpr(Assign3.Left);
  5553. AssertEquals('othe unit assign first token',TPrimitiveExpr,BinExp.Left.ClassType);
  5554. Prim1:=TPrimitiveExpr(BinExp.Left);
  5555. AssertEquals('other unit assign first token','System',Prim1.Value);
  5556. AssertNotNull(Prim1.CustomData);
  5557. AssertEquals('other unit assign unit ref resolved',TResolvedReference,Prim1.CustomData.ClassType);
  5558. DeclEl:=TResolvedReference(Prim1.CustomData).Declaration;
  5559. OtherUnit:=DeclEl;
  5560. AssertEquals('other unit assign unit ref',TPasUsesUnit,DeclEl.ClassType);
  5561. AssertEquals('other unit assign unit ref system','system',lowercase(DeclEl.Name));
  5562. AssertEquals('other unit assign dot',eopSubIdent,BinExp.OpCode);
  5563. AssertEquals('other unit assign second token',TPrimitiveExpr,BinExp.Right.ClassType);
  5564. Prim2:=TPrimitiveExpr(BinExp.Right);
  5565. AssertEquals('other unit assign second token','exiTCode',Prim2.Value);
  5566. AssertNotNull(Prim2.CustomData);
  5567. AssertEquals('other unit assign var ref resolved',TResolvedReference,Prim2.CustomData.ClassType);
  5568. AssertEquals('other unit assign left ref',TResolvedReference,Prim2.CustomData.ClassType);
  5569. DeclEl:=TResolvedReference(Prim2.CustomData).Declaration;
  5570. AssertEquals('other unit assign var',TPasVariable,DeclEl.ClassType);
  5571. AssertEquals('other unit assign var exitcode','exitcode',lowercase(DeclEl.Name));
  5572. AssertSame('other unit assign var exitcode',(OtherUnit as TPasUsesUnit).Module,DeclEl.GetModule);
  5573. end;
  5574. procedure TTestResolver.TestUnitUseSystem;
  5575. begin
  5576. StartProgram(true);
  5577. Add('type number = system.integer;');
  5578. Add('begin');
  5579. Add(' if ExitCode=2 then ;');
  5580. ParseProgram;
  5581. end;
  5582. procedure TTestResolver.TestUnitUseIntf;
  5583. begin
  5584. AddModuleWithIntfImplSrc('unit2.pp',
  5585. LinesToStr([
  5586. 'type TListCallBack = procedure;',
  5587. 'var i: longint;',
  5588. 'procedure DoIt;',
  5589. '']),
  5590. LinesToStr([
  5591. 'procedure DoIt; begin end;']));
  5592. StartProgram(true);
  5593. Add('uses unit2;');
  5594. Add('type TListCB = unit2.tlistcallback;');
  5595. Add('begin');
  5596. Add(' if i=2 then');
  5597. Add(' DoIt;');
  5598. ParseProgram;
  5599. end;
  5600. procedure TTestResolver.TestUnitUseImplFail;
  5601. begin
  5602. AddModuleWithIntfImplSrc('unit2.pp',
  5603. LinesToStr([
  5604. '']),
  5605. LinesToStr([
  5606. 'procedure DoIt; begin end;']));
  5607. StartProgram(true);
  5608. Add('uses unit2;');
  5609. Add('begin');
  5610. Add(' DoIt;');
  5611. CheckResolverException('identifier not found "DoIt"',nIdentifierNotFound);
  5612. end;
  5613. procedure TTestResolver.TestUnit_DuplicateUsesFail;
  5614. begin
  5615. AddModuleWithIntfImplSrc('unit2.pp',
  5616. LinesToStr([
  5617. 'var i: longint;']),
  5618. LinesToStr([
  5619. '']));
  5620. StartProgram(true);
  5621. Add('uses unit2, unit2;');
  5622. Add('begin');
  5623. Add(' i:=3;');
  5624. CheckParserException('Duplicate identifier "unit2"',
  5625. nParserDuplicateIdentifier);
  5626. end;
  5627. procedure TTestResolver.TestUnit_DuplicateUsesIntfImplFail;
  5628. begin
  5629. AddModuleWithIntfImplSrc('unit2.pp',
  5630. LinesToStr([
  5631. 'type number = longint;']),
  5632. LinesToStr([
  5633. '']));
  5634. StartUnit(true);
  5635. Add([
  5636. 'interface',
  5637. 'uses unit2;',
  5638. 'var j: number;',
  5639. 'implementation',
  5640. 'uses unit2;',
  5641. 'initialization',
  5642. ' if number(3) then ;',
  5643. '']);
  5644. CheckParserException('Duplicate identifier "unit2" at token ";" in file afile.pp at line 6 column 11',
  5645. nParserDuplicateIdentifier);
  5646. end;
  5647. procedure TTestResolver.TestUnit_NestedFail;
  5648. begin
  5649. AddModuleWithIntfImplSrc('unit2.pp',
  5650. LinesToStr([
  5651. 'var i2: longint;']),
  5652. LinesToStr([
  5653. '']));
  5654. AddModuleWithIntfImplSrc('unit1.pp',
  5655. LinesToStr([
  5656. 'uses unit2;',
  5657. 'var j1: longint;']),
  5658. LinesToStr([
  5659. '']));
  5660. StartProgram(true);
  5661. Add([
  5662. 'uses unit1;',
  5663. 'begin',
  5664. ' if j1=0 then ;',
  5665. ' if i2=0 then ;',
  5666. '']);
  5667. CheckResolverException('identifier not found "i2"',nIdentifierNotFound);
  5668. end;
  5669. procedure TTestResolver.TestUnitUseDotted;
  5670. begin
  5671. AddModuleWithIntfImplSrc('ns1.unit2.pp',
  5672. LinesToStr([
  5673. 'var i2: longint;']),
  5674. LinesToStr([
  5675. '']));
  5676. AddModuleWithIntfImplSrc('ns2.ns2A.unit1.pp',
  5677. LinesToStr([
  5678. 'uses ns1.unit2;',
  5679. 'var j1: longint;']),
  5680. LinesToStr([
  5681. '']));
  5682. StartProgram(true);
  5683. Add([
  5684. 'uses ns2.ns2A.unit1;',
  5685. 'begin',
  5686. ' if j1=0 then ;',
  5687. '']);
  5688. ParseProgram;
  5689. end;
  5690. procedure TTestResolver.TestUnit_ProgramDefaultNamespace;
  5691. begin
  5692. MainFilename:='ns1.main1.pas';
  5693. AddModuleWithIntfImplSrc('ns1.unit2.pp',
  5694. LinesToStr([
  5695. 'var i2: longint;']),
  5696. LinesToStr([
  5697. '']));
  5698. AddModuleWithIntfImplSrc('ns1.unit1.pp',
  5699. LinesToStr([
  5700. 'uses unit2;',
  5701. 'var j1: longint;']),
  5702. LinesToStr([
  5703. '']));
  5704. StartProgram(true);
  5705. Add([
  5706. 'uses unit1;',
  5707. 'begin',
  5708. ' if j1=0 then ;',
  5709. '']);
  5710. ParseProgram;
  5711. end;
  5712. procedure TTestResolver.TestUnit_DottedIdentifier;
  5713. begin
  5714. MainFilename:='unitdots.main1.pas';
  5715. AddModuleWithIntfImplSrc('unitdots.unit1.pp',
  5716. LinesToStr([
  5717. 'type TColor = longint;',
  5718. 'var i1: longint;']),
  5719. LinesToStr([
  5720. '']));
  5721. AddModuleWithIntfImplSrc('unitdots.pp',
  5722. LinesToStr([
  5723. 'type TBright = longint;',
  5724. 'var j1: longint;']),
  5725. LinesToStr([
  5726. '']));
  5727. StartProgram(true);
  5728. Add([
  5729. 'uses unitdots.unit1, unitdots;',
  5730. 'type',
  5731. ' TPrgBright = unitdots.tbright;',
  5732. ' TPrgColor = unitdots.unit1.tcolor;',
  5733. ' TStrange = unitdots.main1.tprgcolor;',
  5734. 'var k1: longint;',
  5735. 'begin',
  5736. ' if unitdots.main1.k1=0 then ;',
  5737. ' if unitdots.j1=0 then ;',
  5738. ' if unitdots.unit1.i1=0 then ;',
  5739. '']);
  5740. ParseProgram;
  5741. end;
  5742. procedure TTestResolver.TestUnit_DottedPrg;
  5743. begin
  5744. MainFilename:='unitdots.main1.pas';
  5745. AddModuleWithIntfImplSrc('unitdots.unit1.pp',
  5746. LinesToStr([
  5747. 'type TColor = longint;',
  5748. 'var i1: longint;']),
  5749. LinesToStr([
  5750. '']));
  5751. StartProgram(true);
  5752. Add([
  5753. 'uses UnIt1;',
  5754. 'type',
  5755. ' TPrgColor = UNIT1.tcolor;',
  5756. ' TStrange = UnitDots.Main1.tprgcolor;',
  5757. 'var k1: longint;',
  5758. 'begin',
  5759. ' if unitdots.main1.k1=0 then ;',
  5760. ' if unit1.i1=0 then ;',
  5761. '']);
  5762. ParseProgram;
  5763. end;
  5764. procedure TTestResolver.TestUnit_DottedUnit;
  5765. begin
  5766. MainFilename:='unitdots.unit1.pas';
  5767. StartUnit(false);
  5768. Add([
  5769. 'interface',
  5770. 'var k1: longint;',
  5771. 'implementation',
  5772. 'initialization',
  5773. ' if unitDots.Unit1.k1=0 then ;',
  5774. '']);
  5775. ParseUnit;
  5776. end;
  5777. procedure TTestResolver.TestUnit_DottedExpr;
  5778. begin
  5779. MainFilename:='unitdots1.sub1.main1.pas';
  5780. AddModuleWithIntfImplSrc('unitdots2.sub2.unit2.pp',
  5781. LinesToStr([
  5782. 'procedure DoIt; external name ''$DoIt'';']),
  5783. LinesToStr([
  5784. '']));
  5785. AddModuleWithIntfImplSrc('unitdots3.sub3.unit3.pp',
  5786. LinesToStr([
  5787. 'procedure DoSome;']),
  5788. LinesToStr([
  5789. 'uses unitdots2.sub2.unit2;',
  5790. 'procedure DoSome;',
  5791. 'begin',
  5792. ' unitdots2.sub2.unit2.doit;',
  5793. 'end;']));
  5794. StartProgram(true);
  5795. Add([
  5796. 'uses unitdots3.sub3.unit3;',
  5797. 'begin',
  5798. ' unitdots3.sub3.unit3.dosome;',
  5799. '']);
  5800. ParseProgram;
  5801. end;
  5802. procedure TTestResolver.TestUnit_DottedSystem;
  5803. begin
  5804. AddModuleWithIntfImplSrc('System.SysUtils.pas',
  5805. LinesToStr([
  5806. 'type TFlag = word;'
  5807. ]),
  5808. ''
  5809. );
  5810. AddModuleWithIntfImplSrc('UnitA.pas',
  5811. LinesToStr([
  5812. ''
  5813. ]),
  5814. LinesToStr([
  5815. 'uses System.SysUtils;',
  5816. 'type TSize = TFlag;',
  5817. 'type TWidth = System.SysUtils.TFlag;',
  5818. 'type TBird = System.integer;',
  5819. 'type TEagle = integer;',
  5820. '']) );
  5821. StartProgram(true);
  5822. Add('uses UnitA;');
  5823. Add('begin');
  5824. ParseProgram;
  5825. end;
  5826. procedure TTestResolver.TestUnit_DuplicateDottedUsesFail;
  5827. begin
  5828. AddModuleWithIntfImplSrc('ns.unit2.pp',
  5829. LinesToStr([
  5830. 'var i: longint;']),
  5831. LinesToStr([
  5832. '']));
  5833. StartProgram(true);
  5834. Add('uses ns.unit2, ns.unit2;');
  5835. Add('begin');
  5836. Add(' i:=3;');
  5837. CheckParserException('Duplicate identifier "ns.unit2"',
  5838. nParserDuplicateIdentifier);
  5839. end;
  5840. procedure TTestResolver.TestUnit_DuplicateUsesDiffName;
  5841. begin
  5842. MainFilename:='unitdots.main1.pas';
  5843. AddModuleWithIntfImplSrc('unitdots.unit1.pp',
  5844. LinesToStr([
  5845. 'var j1: longint;']),
  5846. LinesToStr([
  5847. '']));
  5848. StartProgram(true);
  5849. Add([
  5850. 'uses unitdots.unit1, unit1;',
  5851. 'var k1: longint;',
  5852. 'begin',
  5853. ' if unitdots.main1.k1=0 then ;',
  5854. ' if unit1.j1=0 then ;',
  5855. ' if unitdots.unit1.j1=0 then ;',
  5856. '']);
  5857. ParseProgram;
  5858. end;
  5859. procedure TTestResolver.TestUnit_Unit1DotUnit2Fail;
  5860. begin
  5861. AddModuleWithIntfImplSrc('unit1.pp',
  5862. LinesToStr([
  5863. 'var i1: longint;']),
  5864. LinesToStr([
  5865. '']));
  5866. AddModuleWithIntfImplSrc('unit2.pp',
  5867. LinesToStr([
  5868. 'uses unit1;',
  5869. 'var j1: longint;']),
  5870. LinesToStr([
  5871. '']));
  5872. StartProgram(true);
  5873. Add([
  5874. 'uses unit2;',
  5875. 'begin',
  5876. ' if unit2.unit1.i1=0 then ;',
  5877. '']);
  5878. CheckResolverException('identifier not found "unit1"',
  5879. nIdentifierNotFound);
  5880. end;
  5881. procedure TTestResolver.TestUnit_InFilename;
  5882. begin
  5883. AddModuleWithIntfImplSrc('unit2.pp',
  5884. LinesToStr([
  5885. 'var i1: longint;']),
  5886. LinesToStr([
  5887. '']));
  5888. StartProgram(true);
  5889. Add([
  5890. 'uses foo in ''unit2.pp'';',
  5891. 'begin',
  5892. ' if foo.i1=0 then ;',
  5893. '']);
  5894. ParseProgram;
  5895. end;
  5896. procedure TTestResolver.TestUnit_InFilenameAliasDelphiFail;
  5897. begin
  5898. AddModuleWithIntfImplSrc('unit2.pp',
  5899. LinesToStr([
  5900. 'var i1: longint;']),
  5901. LinesToStr([
  5902. '']));
  5903. StartProgram(true);
  5904. Add([
  5905. '{$mode delphi}',
  5906. 'uses foo in ''unit2.pp'';',
  5907. 'begin',
  5908. ' if foo.i1=0 then ;',
  5909. '']);
  5910. CheckResolverException('foo expected, but unit2 found',nXExpectedButYFound);
  5911. end;
  5912. procedure TTestResolver.TestUnit_InFilenameInUnitDelphiFail;
  5913. begin
  5914. AddModuleWithIntfImplSrc('unit2.pp',
  5915. LinesToStr([
  5916. 'var i1: longint;']),
  5917. LinesToStr([
  5918. '']));
  5919. StartUnit(true);
  5920. Add([
  5921. '{$mode delphi}',
  5922. 'interface',
  5923. 'uses unit2 in ''unit2.pp'';',
  5924. 'implementation',
  5925. '']);
  5926. CheckParserException('Expected ";"',nParserExpectTokenError);
  5927. end;
  5928. procedure TTestResolver.TestUnit_MissingUnitErrorPos;
  5929. begin
  5930. AddModuleWithIntfImplSrc('unit2.pp',
  5931. LinesToStr([
  5932. 'var j1: longint;']),
  5933. LinesToStr([
  5934. '']));
  5935. StartProgram(true);
  5936. Add([
  5937. 'uses unit2, ;',
  5938. 'begin']);
  5939. CheckParserException('Expected "Identifier" at token ";" in file afile.pp at line 2 column 13',
  5940. nParserExpectTokenError);
  5941. end;
  5942. procedure TTestResolver.TestUnit_UnitNotFoundErrorPos;
  5943. begin
  5944. StartProgram(true);
  5945. Add([
  5946. 'uses foo ;',
  5947. 'begin']);
  5948. CheckResolverException('can''t find unit "foo" at afile.pp (2,6)',nCantFindUnitX);
  5949. end;
  5950. procedure TTestResolver.TestUnit_AccessIndirectUsedUnitFail;
  5951. begin
  5952. AddModuleWithIntfImplSrc('unit2.pp',
  5953. LinesToStr([
  5954. 'var i2: longint;']),
  5955. LinesToStr([
  5956. '']));
  5957. AddModuleWithIntfImplSrc('unit1.pp',
  5958. LinesToStr([
  5959. 'uses unit2;']),
  5960. LinesToStr([
  5961. '']));
  5962. StartProgram(true);
  5963. Add([
  5964. 'uses unit1;',
  5965. 'begin',
  5966. ' if unit2.i2=0 then ;',
  5967. '']);
  5968. CheckResolverException('identifier not found "unit2"',nIdentifierNotFound);
  5969. end;
  5970. procedure TTestResolver.TestUnit_Intf1Impl2Intf1;
  5971. begin
  5972. AddModuleWithIntfImplSrc('unit1.pp',
  5973. LinesToStr([
  5974. 'type number = longint;']),
  5975. LinesToStr([
  5976. 'uses afile;',
  5977. 'procedure DoIt;',
  5978. 'begin',
  5979. ' i:=3;',
  5980. 'end;']));
  5981. StartUnit(true);
  5982. Add([
  5983. 'interface',
  5984. 'uses unit1;',
  5985. 'var i: number;',
  5986. 'implementation']);
  5987. ParseUnit;
  5988. end;
  5989. procedure TTestResolver.TestUnit_Intf1Impl2Intf1_Duplicate;
  5990. begin
  5991. AddModuleWithIntfImplSrc('unit1.pp',
  5992. LinesToStr([
  5993. 'type number = longint;']),
  5994. LinesToStr([
  5995. 'uses afile;',
  5996. 'procedure DoIt;',
  5997. 'begin',
  5998. ' i:=3;',
  5999. 'end;']));
  6000. StartUnit(true);
  6001. Add([
  6002. 'interface',
  6003. 'uses unit1, foo in ''unit1.pp'';',
  6004. 'var i: number;',
  6005. 'implementation']);
  6006. ParseUnit;
  6007. end;
  6008. procedure TTestResolver.TestProcParam;
  6009. begin
  6010. StartProgram(false);
  6011. Add('type');
  6012. Add(' integer = longint;');
  6013. Add('procedure Proc1(a: integer);');
  6014. Add('begin');
  6015. Add(' a:=3;');
  6016. Add('end;');
  6017. Add('begin');
  6018. ParseProgram;
  6019. end;
  6020. procedure TTestResolver.TestProcParamAccess;
  6021. begin
  6022. StartProgram(false);
  6023. Add('type');
  6024. Add(' integer = longint;');
  6025. Add('procedure DoIt(vI: integer; const vJ: integer; var vK: integer);');
  6026. Add('var vL: integer;');
  6027. Add('begin');
  6028. Add(' vi:=vi+1;');
  6029. Add(' vl:=vj+1;');
  6030. Add(' vk:=vk+1;');
  6031. Add(' vl:=vl+1;');
  6032. Add(' DoIt(vi,vi,vi);');
  6033. Add(' DoIt(vj,vj,vl);');
  6034. Add(' DoIt(vk,vk,vk);');
  6035. Add(' DoIt(vl,vl,vl);');
  6036. Add('end;');
  6037. Add('var i: integer;');
  6038. Add('begin');
  6039. Add(' DoIt(i,i,i);');
  6040. Add(' DoIt(1,1,i);');
  6041. ParseProgram;
  6042. end;
  6043. procedure TTestResolver.TestProcParamConstRef;
  6044. begin
  6045. StartProgram(false);
  6046. Add([
  6047. 'procedure Run(constref a: word);',
  6048. 'begin',
  6049. 'end;',
  6050. 'begin']);
  6051. ParseProgram;
  6052. end;
  6053. procedure TTestResolver.TestFunctionResult;
  6054. begin
  6055. StartProgram(false);
  6056. Add('function Func1: longint;');
  6057. Add('begin');
  6058. Add(' Result:=3;');
  6059. Add(' Func1:=4; ');
  6060. Add('end;');
  6061. Add('begin');
  6062. ParseProgram;
  6063. end;
  6064. procedure TTestResolver.TestProcedureResultFail;
  6065. begin
  6066. StartProgram(false);
  6067. Add('procedure A: longint; begin end;');
  6068. Add('begin');
  6069. CheckParserException('Expected ";"',
  6070. nParserExpectTokenError);
  6071. end;
  6072. procedure TTestResolver.TestProc_ArgVarPrecisionLossFail;
  6073. begin
  6074. StartProgram(false);
  6075. Add([
  6076. 'type',
  6077. ' TColor = type longint;',
  6078. ' TByte = byte;',
  6079. 'procedure DoColor(var c: TColor); external;',
  6080. 'var',
  6081. ' b: TByte;',
  6082. 'begin',
  6083. ' DoColor(TColor(b));',
  6084. '']);
  6085. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  6086. end;
  6087. procedure TTestResolver.TestProc_ArgVarTypeAliasObjFPC;
  6088. begin
  6089. StartProgram(false);
  6090. Add([
  6091. 'type',
  6092. ' TColor = type longint;',
  6093. 'procedure DoColor(var c: TColor); external;',
  6094. 'procedure TakeColor(c: TColor); external;',
  6095. 'procedure DoInt(var i: longint); external;',
  6096. 'var',
  6097. ' i: longint;',
  6098. ' c: TColor;',
  6099. 'begin',
  6100. ' DoColor(c);',
  6101. ' DoColor(longint(c));',
  6102. ' DoColor(i);',
  6103. ' DoColor(TColor(i));',
  6104. ' TakeColor(c);',
  6105. ' TakeColor(longint(c));',
  6106. ' TakeColor(i);',
  6107. ' TakeColor(TColor(i));',
  6108. ' DoInt(i);',
  6109. ' DoInt(TColor(i));',
  6110. ' DoInt(c);',
  6111. ' DoInt(longint(c));',
  6112. '']);
  6113. ParseProgram;
  6114. end;
  6115. procedure TTestResolver.TestProc_ArgVarTypeAliasDelphi;
  6116. begin
  6117. StartProgram(false);
  6118. Add([
  6119. '{$mode delphi}',
  6120. 'type',
  6121. ' TColor = type longint;',
  6122. 'procedure DoColor(var c: TColor); external;',
  6123. 'procedure TakeColor(c: TColor); external;',
  6124. 'procedure DoInt(var i: longint); external;',
  6125. 'var',
  6126. ' i: longint;',
  6127. ' c: TColor;',
  6128. 'begin',
  6129. ' DoColor(c);',
  6130. ' DoColor(TColor(i));',
  6131. ' TakeColor(i);',
  6132. ' TakeColor(longint(c));',
  6133. ' DoInt(i);',
  6134. ' DoInt(longint(c));',
  6135. '']);
  6136. ParseProgram;
  6137. end;
  6138. procedure TTestResolver.TestProc_ArgVarTypeAliasDelphiMismatchFail;
  6139. begin
  6140. StartProgram(false);
  6141. Add([
  6142. '{$mode delphi}',
  6143. 'type',
  6144. ' TColor = type longint;',
  6145. 'procedure DoColor(var c: TColor); external;',
  6146. 'var',
  6147. ' i: longint;',
  6148. 'begin',
  6149. ' DoColor(i);',
  6150. '']);
  6151. CheckResolverException('Incompatible type for arg no. 1: Got "Longint", expected "TColor". Var param must match exactly.',
  6152. nIncompatibleTypeArgNoVarParamMustMatchExactly);
  6153. end;
  6154. procedure TTestResolver.TestProc_ArgAnonymouseRangeTypeFail;
  6155. begin
  6156. StartProgram(false);
  6157. Add([
  6158. 'procedure Fly(Speed: 1..2);',
  6159. 'begin end;',
  6160. 'begin']);
  6161. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  6162. end;
  6163. procedure TTestResolver.TestProc_ArgAnonymouseEnumTypeFail;
  6164. begin
  6165. StartProgram(false);
  6166. Add([
  6167. 'procedure Fly(Speed: (red, blue));',
  6168. 'begin end;',
  6169. 'begin']);
  6170. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  6171. end;
  6172. procedure TTestResolver.TestProc_ArgAnonymouseSetTypeFail;
  6173. begin
  6174. StartProgram(false);
  6175. Add([
  6176. 'procedure Fly(Speed: set of (red, blue));',
  6177. 'begin end;',
  6178. 'begin']);
  6179. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  6180. end;
  6181. procedure TTestResolver.TestProc_ArgAnonymousePointerTypeFail;
  6182. begin
  6183. StartProgram(false);
  6184. Add([
  6185. 'procedure Fly(Speed: ^word);',
  6186. 'begin end;',
  6187. 'begin']);
  6188. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  6189. end;
  6190. procedure TTestResolver.TestProc_ArgMissingSemicolonFail;
  6191. begin
  6192. StartProgram(false);
  6193. Add([
  6194. 'type TScalar = double;',
  6195. 'procedure SinCos (var sinus: TScalar var cosinus: TScalar);',
  6196. 'begin end;',
  6197. 'begin']);
  6198. CheckParserException('Expected ";" at token "var" in file afile.pp at line 3 column 38',nParserExpectTokenError);
  6199. end;
  6200. procedure TTestResolver.TestProcOverload;
  6201. var
  6202. El: TPasElement;
  6203. begin
  6204. StartProgram(false);
  6205. Add('function Func1(i: longint; j: longint = 0): longint; overload;');
  6206. Add('begin');
  6207. Add(' Result:=1;');
  6208. Add('end;');
  6209. Add('function Func1(s: string): longint; overload;');
  6210. Add('begin');
  6211. Add(' Result:=2;');
  6212. Add('end;');
  6213. Add('begin');
  6214. Add(' Func1(3);');
  6215. ParseProgram;
  6216. AssertEquals('2 declarations',2,PasProgram.ProgramSection.Declarations.Count);
  6217. El:=TPasElement(PasProgram.ProgramSection.Declarations[0]);
  6218. AssertEquals('is function',TPasFunction,El.ClassType);
  6219. AssertEquals('1 statement',1,PasProgram.InitializationSection.Elements.Count);
  6220. end;
  6221. procedure TTestResolver.TestProcOverloadImplDuplicateFail;
  6222. begin
  6223. StartUnit(false);
  6224. Add([
  6225. 'interface',
  6226. 'procedure DoIt(d: double);',
  6227. 'implementation',
  6228. 'procedure DoIt(d: double); begin end;',
  6229. 'procedure DoIt(d: double); begin end;',
  6230. 'end.']);
  6231. CheckResolverException('Duplicate identifier "DoIt" at afile.pp(5,15)',nDuplicateIdentifier);
  6232. end;
  6233. procedure TTestResolver.TestProcOverloadImplDuplicate2Fail;
  6234. begin
  6235. StartUnit(false);
  6236. Add([
  6237. 'interface',
  6238. 'implementation',
  6239. 'procedure DoIt(d: double); begin end;',
  6240. 'procedure DoIt(d: double); begin end;',
  6241. 'end.']);
  6242. CheckResolverException('Duplicate identifier "DoIt" at afile.pp(4,15)',nDuplicateIdentifier);
  6243. end;
  6244. procedure TTestResolver.TestProcOverloadOtherUnit;
  6245. begin
  6246. AddModuleWithIntfImplSrc('unit1.pp',
  6247. LinesToStr([
  6248. 'procedure DoIt(d: double);',
  6249. '']),
  6250. LinesToStr([
  6251. 'procedure DoIt(d: double); begin end;',
  6252. '']));
  6253. StartUnit(true);
  6254. Add([
  6255. 'interface',
  6256. 'implementation',
  6257. 'procedure DoIt(d: double); begin end;',
  6258. 'end.']);
  6259. ParseUnit;
  6260. end;
  6261. procedure TTestResolver.TestProcOverloadWithBaseTypes;
  6262. begin
  6263. StartProgram(false);
  6264. Add('function {#A}Func1(i: longint; j: longint = 0): longint; overload;');
  6265. Add('begin');
  6266. Add(' Result:=1;');
  6267. Add('end;');
  6268. Add('function {#B}Func1(s: string): longint; overload;');
  6269. Add('begin');
  6270. Add(' Result:=2;');
  6271. Add('end;');
  6272. Add('begin');
  6273. Add(' {@A}Func1(3);');
  6274. ParseProgram;
  6275. end;
  6276. procedure TTestResolver.TestProcOverloadWithBaseTypes2;
  6277. begin
  6278. StartProgram(false);
  6279. Add('procedure {#byte}DoIt(p: byte); external; var by: byte;');
  6280. Add('procedure {#shortint}DoIt(p: shortint); external; var shi: shortint;');
  6281. Add('procedure {#word}DoIt(p: word); external; var w: word;');
  6282. Add('procedure {#smallint}DoIt(p: smallint); external; var smi: smallint;');
  6283. Add('procedure {#longword}DoIt(p: longword); external; var lw: longword;');
  6284. Add('procedure {#longint}DoIt(p: longint); external; var li: longint;');
  6285. Add('procedure {#qword}DoIt(p: qword); external; var qw: qword;');
  6286. Add('procedure {#int64}DoIt(p: int64); external; var i6: int64;');
  6287. Add('procedure {#comp}DoIt(p: comp); external; var co: comp;');
  6288. Add('procedure {#boolean}DoIt(p: boolean); external; var bo: boolean;');
  6289. Add('procedure {#char}DoIt(p: char); external; var ch: char;');
  6290. Add('procedure {#widechar}DoIt(p: widechar); external; var wc: widechar;');
  6291. Add('procedure {#string}DoIt(p: string); external; var st: string;');
  6292. Add('procedure {#widestring}DoIt(p: widestring); external; var ws: widestring;');
  6293. Add('procedure {#shortstring}DoIt(p: shortstring); external; var ss: shortstring;');
  6294. Add('procedure {#unicodestring}DoIt(p: unicodestring); external; var us: unicodestring;');
  6295. Add('procedure {#rawbytestring}DoIt(p: rawbytestring); external; var rs: rawbytestring;');
  6296. Add('begin');
  6297. Add(' {@byte}DoIt(by);');
  6298. Add(' {@shortint}DoIt(shi);');
  6299. Add(' {@word}DoIt(w);');
  6300. Add(' {@smallint}DoIt(smi);');
  6301. Add(' {@longword}DoIt(lw);');
  6302. Add(' {@longint}DoIt(li);');
  6303. Add(' {@qword}DoIt(qw);');
  6304. Add(' {@int64}DoIt(i6);');
  6305. Add(' {@comp}DoIt(co);');
  6306. Add(' {@boolean}DoIt(bo);');
  6307. Add(' {@char}DoIt(ch);');
  6308. Add(' {@widechar}DoIt(wc);');
  6309. Add(' {@string}DoIt(st);');
  6310. Add(' {@widestring}DoIt(ws);');
  6311. Add(' {@shortstring}DoIt(ss);');
  6312. Add(' {@unicodestring}DoIt(us);');
  6313. Add(' {@rawbytestring}DoIt(rs);');
  6314. ParseProgram;
  6315. end;
  6316. procedure TTestResolver.TestProcOverloadWithDefaultArgs;
  6317. begin
  6318. StartProgram(false);
  6319. Add([
  6320. 'type float = type single;',
  6321. 'type integer = longint;',
  6322. 'procedure {#float}DoIt(s: float); external;',
  6323. 'procedure {#longint}DoIt(i: integer; Scale: float = 1.0); external;',
  6324. 'var i: integer;',
  6325. 'begin',
  6326. ' {@float}DoIt(1.0);',
  6327. ' {@longint}DoIt(2);',
  6328. ' {@longint}DoIt(i);',
  6329. '']);
  6330. ParseProgram;
  6331. end;
  6332. procedure TTestResolver.TestProcOverloadNearestHigherPrecision;
  6333. begin
  6334. StartProgram(false);
  6335. Add([
  6336. 'procedure {#longint}DoIt(i: longint); external;',
  6337. 'procedure DoIt(i: int64); external;',
  6338. 'var w: word;',
  6339. 'begin',
  6340. ' {@longint}DoIt(w);',
  6341. '']);
  6342. ParseProgram;
  6343. end;
  6344. procedure TTestResolver.TestProcOverloadForLoopIntDouble;
  6345. begin
  6346. StartProgram(false);
  6347. Add([
  6348. 'function {#int}Max(a,b: longint): longint; external; overload;',
  6349. 'function {#double}Max(a,b: double): double; external; overload;',
  6350. 'var',
  6351. ' i: longint;',
  6352. ' S: string;',
  6353. 'begin',
  6354. ' for i:=0 to Max(length(s),1) do ;',
  6355. '']);
  6356. ParseProgram;
  6357. end;
  6358. procedure TTestResolver.TestProcOverloadStringArgCount;
  6359. begin
  6360. StartProgram(false);
  6361. Add([
  6362. 'function {#a}StrToDate(const a: String): double; begin end;',
  6363. 'function {#b}StrToDate(const a: String; const b: string): double; begin end;',
  6364. 'function {#c}StrToDate(const a: String; const b: string; c: char): double; begin end;',
  6365. 'var d: double;',
  6366. 'begin',
  6367. ' d:={@a}StrToDate('''');',
  6368. ' d:={@b}StrToDate('''','''');',
  6369. ' d:={@c}StrToDate('''','''',''x'');',
  6370. '']);
  6371. ParseProgram;
  6372. end;
  6373. procedure TTestResolver.TestProcCallLowPrecision;
  6374. begin
  6375. StartProgram(false);
  6376. Add([
  6377. 'procedure {#longint}DoIt(i: longint); external;',
  6378. 'var i: int64;',
  6379. 'begin',
  6380. ' {@longint}DoIt(i);',
  6381. '']);
  6382. ParseProgram;
  6383. end;
  6384. procedure TTestResolver.TestProcOverloadUntyped;
  6385. begin
  6386. StartProgram(false);
  6387. Add([
  6388. 'procedure {#a}DoIt(a, b: longint); external;',
  6389. 'procedure {#b}DoIt(const a; b: longint); external;',
  6390. 'var',
  6391. ' a: longint;',
  6392. ' b: boolean;',
  6393. 'begin',
  6394. ' {@a}DoIt(a,a);',
  6395. ' {@b}DoIt(b,a);',
  6396. '']);
  6397. ParseProgram;
  6398. end;
  6399. procedure TTestResolver.TestProcOverloadMultiLowPrecisionFail;
  6400. begin
  6401. StartProgram(false);
  6402. Add([
  6403. 'procedure DoIt(i: longint); external;',
  6404. 'procedure DoIt(w: longword); external;',
  6405. 'var i: int64;',
  6406. 'begin',
  6407. ' DoIt(i);',
  6408. '']);
  6409. CheckResolverException('Can''t determine which overloaded function to call, afile.pp(3,15), afile.pp(2,15)',
  6410. nCantDetermineWhichOverloadedFunctionToCall);
  6411. end;
  6412. procedure TTestResolver.TestProcOverload_TypeAlias;
  6413. begin
  6414. StartProgram(false);
  6415. Add([
  6416. 'type',
  6417. ' TValue = type longint;',
  6418. ' TAliasValue = TValue;',
  6419. ' TColor = type TAliasValue;',
  6420. ' TAliasColor = TColor;',
  6421. 'procedure {#a}DoIt(i: TAliasValue); external;',
  6422. 'procedure {#b}DoIt(i: TAliasColor); external;',
  6423. 'procedure {#c}Fly(var i: TAliasValue); external;',
  6424. 'procedure {#d}Fly(var i: TAliasColor); external;',
  6425. 'var',
  6426. ' v: TAliasValue;',
  6427. ' c: TAliasColor;',
  6428. 'begin',
  6429. ' {@a}DoIt(v);',
  6430. ' {@a}DoIt(TAliasValue(c));',
  6431. ' {@a}DoIt(TValue(c));',
  6432. ' {@b}DoIt(c);',
  6433. ' {@b}DoIt(TAliasColor(v));',
  6434. ' {@b}DoIt(TColor(v));',
  6435. ' {@c}Fly(v);',
  6436. ' {@c}Fly(TAliasValue(c));',
  6437. ' {@c}Fly(TValue(c));',
  6438. ' {@d}Fly(c);',
  6439. ' {@d}Fly(TAliasColor(v));',
  6440. ' {@d}Fly(TColor(v));',
  6441. '']);
  6442. ParseProgram;
  6443. end;
  6444. procedure TTestResolver.TestProcOverload_TypeAliasLiteralFail;
  6445. begin
  6446. StartProgram(false);
  6447. Add([
  6448. 'type',
  6449. ' integer = word;',
  6450. ' TValue = type word;',
  6451. ' TAliasValue = TValue;',
  6452. 'procedure DoIt(i: integer); external;',
  6453. 'procedure DoIt(i: TAliasValue); external;',
  6454. 'begin',
  6455. ' DoIt(1);',
  6456. '']);
  6457. CheckResolverException('Can''t determine which overloaded function to call, afile.pp(7,15), afile.pp(6,15)',
  6458. nCantDetermineWhichOverloadedFunctionToCall);
  6459. end;
  6460. procedure TTestResolver.TestProcOverloadWithClassTypes;
  6461. begin
  6462. StartProgram(false);
  6463. Add('type');
  6464. Add(' {#TOBJ}TObject = class end;');
  6465. Add(' {#TA}TClassA = class end;');
  6466. Add(' {#TB}TClassB = class end;');
  6467. Add('procedure {#DoA}DoIt({=TA}p: TClassA); overload;');
  6468. Add('begin');
  6469. Add('end;');
  6470. Add('procedure {#DoB}DoIt({=TB}p: TClassB); overload;');
  6471. Add('begin');
  6472. Add('end;');
  6473. Add('var');
  6474. Add(' {#A}{=TA}A: TClassA;');
  6475. Add(' {#B}{=TB}B: TClassB;');
  6476. Add('begin');
  6477. Add(' {@DoA}DoIt({@A}A);');
  6478. Add(' {@DoB}DoIt({@B}B);');
  6479. ParseProgram;
  6480. end;
  6481. procedure TTestResolver.TestProcOverloadWithInhClassTypes;
  6482. begin
  6483. StartProgram(false);
  6484. Add('type');
  6485. Add(' {#TOBJ}TObject = class end;');
  6486. Add(' {#TA}TClassA = class end;');
  6487. Add(' {#TB}TClassB = class(TClassA) end;');
  6488. Add(' {#TC}TClassC = class(TClassB) end;');
  6489. Add('procedure {#DoA}DoIt({=TA}p: TClassA); overload;');
  6490. Add('begin');
  6491. Add('end;');
  6492. Add('procedure {#DoB}DoIt({=TB}p: TClassB); overload;');
  6493. Add('begin');
  6494. Add('end;');
  6495. Add('var');
  6496. Add(' {#A}{=TA}A: TClassA;');
  6497. Add(' {#B}{=TB}B: TClassB;');
  6498. Add(' {#C}{=TC}C: TClassC;');
  6499. Add('begin');
  6500. Add(' {@DoA}DoIt({@A}A);');
  6501. Add(' {@DoB}DoIt({@B}B);');
  6502. Add(' {@DoB}DoIt({@C}C);');
  6503. ParseProgram;
  6504. end;
  6505. procedure TTestResolver.TestProcOverloadWithInhAliasClassTypes;
  6506. begin
  6507. StartProgram(false);
  6508. Add([
  6509. 'type',
  6510. ' {#TOBJ}TObject = class end;',
  6511. ' {#TA}TClassA = class end;',
  6512. ' {#TB}{=TA}TClassB = TClassA;',
  6513. ' {#TC}TClassC = class(TClassB) end;',
  6514. 'procedure {#DoA}DoIt({=TA}p: TClassA); overload;',
  6515. 'begin',
  6516. 'end;',
  6517. 'procedure {#DoC}DoIt({=TC}p: TClassC); overload;',
  6518. 'begin',
  6519. 'end;',
  6520. 'var',
  6521. ' {#A}{=TA}A: TClassA;',
  6522. ' {#B}{=TB}B: TClassB;',
  6523. ' {#C}{=TC}C: TClassC;',
  6524. 'begin',
  6525. ' {@DoA}DoIt({@A}A);',
  6526. ' {@DoA}DoIt({@B}B);',
  6527. ' {@DoC}DoIt({@C}C);']);
  6528. ParseProgram;
  6529. end;
  6530. procedure TTestResolver.TestProcOverloadWithInterfaces;
  6531. begin
  6532. StartProgram(false);
  6533. Add([
  6534. '{$interfaces corba}',
  6535. 'type',
  6536. ' {#IUnk}IUnknown = interface end;',
  6537. ' {#IBird}IBird = interface(IUnknown) end;',
  6538. ' {#TObj}TObject = class end;',
  6539. ' {#TBird}TBird = class(IBird) end;',
  6540. 'procedure {#DoA}DoIt(o: TObject); overload; begin end;',
  6541. 'procedure {#DoB}DoIt(b: IBird); overload; begin end;',
  6542. 'var',
  6543. ' o: TObject;',
  6544. ' b: TBird;',
  6545. ' i: IBird;',
  6546. 'begin',
  6547. ' {@DoA}DoIt(o);',
  6548. ' {@DoA}DoIt(b);',
  6549. ' {@DoB}DoIt(i);',
  6550. '']);
  6551. ParseProgram;
  6552. end;
  6553. procedure TTestResolver.TestProcOverloadBaseTypeOtherUnit;
  6554. begin
  6555. AddModuleWithIntfImplSrc('unit2.pp',
  6556. LinesToStr([
  6557. 'procedure Val(var d: double);',
  6558. '']),
  6559. LinesToStr([
  6560. 'procedure Val(var d: double); begin end;',
  6561. 'procedure Val(var i: integer); begin end;',
  6562. '']));
  6563. StartProgram(true);
  6564. Add('uses unit2;');
  6565. Add('var');
  6566. Add(' d: double;');
  6567. Add(' i: integer;');
  6568. Add('begin');
  6569. Add(' Val(d);');
  6570. ParseProgram;
  6571. end;
  6572. procedure TTestResolver.TestProcOverloadBaseProcNoHint;
  6573. begin
  6574. StartProgram(false);
  6575. Add([
  6576. 'function Copy(s: string): string; overload;',
  6577. 'begin end;',
  6578. 'var',
  6579. ' A: array of longint;',
  6580. ' s: string;',
  6581. 'begin',
  6582. ' A:=Copy(A,1);',
  6583. ' s:=copy(s)']);
  6584. ParseProgram;
  6585. CheckResolverUnexpectedHints;
  6586. end;
  6587. procedure TTestResolver.TestProcOverload_UnitOrderFail;
  6588. begin
  6589. AddModuleWithIntfImplSrc('unit1.pp',
  6590. LinesToStr([
  6591. 'procedure Val(d: string);',
  6592. '']),
  6593. LinesToStr([
  6594. 'procedure Val(d: string); begin end;',
  6595. '']));
  6596. AddModuleWithIntfImplSrc('unit2.pp',
  6597. LinesToStr([
  6598. 'procedure Val(d: double);',
  6599. '']),
  6600. LinesToStr([
  6601. 'procedure Val(d: double); begin end;',
  6602. '']));
  6603. StartProgram(true);
  6604. Add([
  6605. 'uses unit1, unit2;',
  6606. 'var',
  6607. ' s: string;',
  6608. 'begin',
  6609. ' Val(s);']);
  6610. CheckResolverException(sIncompatibleTypeArgNo,nIncompatibleTypeArgNo);
  6611. end;
  6612. procedure TTestResolver.TestProcOverload_UnitSameSignature;
  6613. begin
  6614. AddModuleWithIntfImplSrc('unit1.pp',
  6615. LinesToStr([
  6616. 'procedure Val(d: string);',
  6617. '']),
  6618. LinesToStr([
  6619. 'procedure Val(d: string); begin end;',
  6620. '']));
  6621. StartProgram(true);
  6622. Add([
  6623. 'uses unit1;',
  6624. 'procedure Val(d: string);',
  6625. 'begin',
  6626. 'end;',
  6627. 'var',
  6628. ' s: string;',
  6629. 'begin',
  6630. ' Val(s);']);
  6631. ParseProgram;
  6632. end;
  6633. procedure TTestResolver.TestProcOverloadDelphiMissingNextOverload;
  6634. begin
  6635. StartProgram(false);
  6636. Add([
  6637. '{$mode delphi}',
  6638. 'procedure DoIt(i: longint); overload;',
  6639. 'begin end;',
  6640. 'procedure DoIt(s: string);',
  6641. 'begin end;',
  6642. 'begin']);
  6643. CheckResolverException(sOverloadedProcMissesOverload,nOverloadedProcMissesOverload);
  6644. end;
  6645. procedure TTestResolver.TestProcOverloadDelphiMissingPrevOverload;
  6646. begin
  6647. StartProgram(false);
  6648. Add([
  6649. '{$mode delphi}',
  6650. 'procedure DoIt(i: longint); ',
  6651. 'begin end;',
  6652. 'procedure DoIt(s: string); overload;',
  6653. 'begin end;',
  6654. 'begin']);
  6655. CheckResolverException(sPreviousDeclMissesOverload,nPreviousDeclMissesOverload);
  6656. end;
  6657. procedure TTestResolver.TestProcOverloadDelphiUnit;
  6658. begin
  6659. AddModuleWithIntfImplSrc('unit2.pp',
  6660. LinesToStr([
  6661. '{$mode delphi}',
  6662. 'procedure DoIt(s: string); overload;',
  6663. 'procedure DoIt(b: boolean); overload;',
  6664. '']),
  6665. LinesToStr([
  6666. 'procedure DoIt(s: string); begin end;',
  6667. 'procedure DoIt(b: boolean); begin end;',
  6668. '']));
  6669. StartProgram(true);
  6670. Add([
  6671. '{$mode delphi}',
  6672. 'uses unit2;',
  6673. 'procedure DoIt(i: longint); overload;',
  6674. 'begin end;',
  6675. 'begin',
  6676. ' DoIt(3);',
  6677. ' DoIt(true);',
  6678. ' DoIt(''foo'');',
  6679. '']);
  6680. ParseProgram;
  6681. end;
  6682. procedure TTestResolver.TestProcOverloadDelphiUnitNoOverloadFail;
  6683. begin
  6684. AddModuleWithIntfImplSrc('unit2.pp',
  6685. LinesToStr([
  6686. '{$mode delphi}',
  6687. 'procedure DoIt(b: boolean);',
  6688. '']),
  6689. LinesToStr([
  6690. 'procedure DoIt(b: boolean); begin end;',
  6691. '']));
  6692. StartProgram(true);
  6693. Add([
  6694. '{$mode delphi}',
  6695. 'uses unit2;',
  6696. 'procedure DoIt(i: longint); overload;',
  6697. 'begin end;',
  6698. 'begin',
  6699. ' DoIt(true);',
  6700. '']);
  6701. CheckResolverException(sIncompatibleTypeArgNo,nIncompatibleTypeArgNo);
  6702. end;
  6703. procedure TTestResolver.TestProcOverloadObjFPCUnitWithoutOverloadMod;
  6704. begin
  6705. AddModuleWithIntfImplSrc('unit2.pp',
  6706. LinesToStr([
  6707. '{$mode objfpc}',
  6708. 'procedure DoIt(s: string);',
  6709. 'procedure DoIt(b: boolean);',
  6710. '']),
  6711. LinesToStr([
  6712. 'procedure DoIt(s: string); begin end;',
  6713. 'procedure DoIt(b: boolean); begin end;',
  6714. '']));
  6715. StartProgram(true);
  6716. Add([
  6717. '{$mode objfpc}',
  6718. 'uses unit2;',
  6719. 'procedure DoIt(i: longint); overload;',
  6720. 'begin end;',
  6721. 'begin',
  6722. ' DoIt(3);',
  6723. ' DoIt(true);',
  6724. ' DoIt(''foo'');',
  6725. '']);
  6726. ParseProgram;
  6727. end;
  6728. procedure TTestResolver.TestProcOverloadDelphiWithObjFPC;
  6729. begin
  6730. AddModuleWithIntfImplSrc('unit2.pp',
  6731. LinesToStr([
  6732. '{$mode objfpc}',
  6733. 'procedure DoIt(s: string);',
  6734. 'procedure DoIt(b: boolean);',
  6735. '']),
  6736. LinesToStr([
  6737. 'procedure DoIt(s: string); begin end;',
  6738. 'procedure DoIt(b: boolean); begin end;',
  6739. '']));
  6740. StartProgram(true);
  6741. Add([
  6742. '{$mode delphi}',
  6743. 'uses unit2;',
  6744. 'begin',
  6745. ' DoIt(true);',
  6746. ' DoIt(''foo'');',
  6747. '']);
  6748. ParseProgram;
  6749. end;
  6750. procedure TTestResolver.TestProcOverloadDelphiOverride;
  6751. begin
  6752. StartProgram(false);
  6753. Add([
  6754. '{$mode delphi}',
  6755. 'type',
  6756. ' TObject = class end;',
  6757. ' TBird = class',
  6758. ' function {#a}GetValue: longint; overload; virtual;',
  6759. ' function {#b}GetValue(AValue: longint): longint; overload; virtual;',
  6760. ' end;',
  6761. ' TEagle = class(TBird)',
  6762. ' function {#c}GetValue: longint; overload; override;',
  6763. ' function {#d}GetValue(AValue: longint): longint; overload; override;',
  6764. ' end;',
  6765. ' TBear = class',
  6766. ' procedure DoIt;',
  6767. ' end;',
  6768. 'function TBird.GetValue: longint;',
  6769. 'begin',
  6770. ' if 3={@a}GetValue then ;',
  6771. ' if 4={@b}GetValue(5) then ;',
  6772. 'end;',
  6773. 'function TBird.GetValue(AValue: longint): longint;',
  6774. 'begin',
  6775. 'end;',
  6776. 'function TEagle.GetValue: longint;',
  6777. 'begin',
  6778. ' if 13={@c}GetValue then ;',
  6779. ' if 14={@d}GetValue(15) then ;',
  6780. ' if 15=inherited {@a}GetValue then ;',
  6781. ' if 16=inherited {@b}GetValue(17) then ;',
  6782. 'end;',
  6783. 'function TEagle.GetValue(AValue: longint): longint;',
  6784. 'begin',
  6785. 'end;',
  6786. 'procedure TBear.DoIt;',
  6787. 'var',
  6788. ' e: TEagle;',
  6789. 'begin',
  6790. ' if 23=e.{@c}GetValue then ;',
  6791. ' if 24=e.{@d}GetValue(25) then ;',
  6792. 'end;',
  6793. 'begin']);
  6794. ParseProgram;
  6795. end;
  6796. procedure TTestResolver.TestProcOverloadDelphiOverrideOne;
  6797. begin
  6798. StartProgram(false);
  6799. Add([
  6800. '{$mode delphi}',
  6801. 'type',
  6802. ' TObject = class',
  6803. ' constructor Create(b: boolean); virtual;',
  6804. ' end;',
  6805. ' TBird = class',
  6806. ' // add first an overload',
  6807. ' constructor Create(w: word); overload;',
  6808. ' // and then override the previous',
  6809. ' constructor Create(b: boolean); override; overload;',
  6810. ' end;',
  6811. ' TEagle = class(TBird)',
  6812. ' constructor Create(b: boolean); override; overload;',
  6813. ' end;',
  6814. 'constructor TObject.Create(b: boolean);',
  6815. 'begin',
  6816. 'end;',
  6817. 'constructor TBird.Create(w: word);',
  6818. 'begin',
  6819. 'end;',
  6820. 'constructor TBird.Create(b: boolean);',
  6821. 'begin',
  6822. 'end;',
  6823. 'constructor TEagle.Create(b: boolean);',
  6824. 'begin',
  6825. 'end;',
  6826. 'begin',
  6827. ' TBird.Create(false);',
  6828. ' TBird.Create(2);',
  6829. ' TEagle.Create(true);',
  6830. ' TEagle.Create(3);',
  6831. '']);
  6832. ParseProgram;
  6833. end;
  6834. procedure TTestResolver.TestProcDuplicate;
  6835. begin
  6836. StartProgram(false);
  6837. Add('type integer = longint;');
  6838. Add('procedure ProcA(i: longint);');
  6839. Add('begin');
  6840. Add('end;');
  6841. Add('procedure ProcA(i: integer);');
  6842. Add('begin');
  6843. Add('end;');
  6844. Add('begin');
  6845. CheckResolverException(sDuplicateIdentifier,nDuplicateIdentifier);
  6846. end;
  6847. procedure TTestResolver.TestNestedProc;
  6848. begin
  6849. StartProgram(false);
  6850. Add('function DoIt({#a1}a,{#d1}d: longint): longint;');
  6851. Add('var');
  6852. Add(' {#b1}b: longint;');
  6853. Add(' {#c1}c: longint;');
  6854. Add(' function {#Nesty1}Nesty({#a2}a: longint): longint; ');
  6855. Add(' var {#b2}b: longint;');
  6856. Add(' begin');
  6857. Add(' Result:={@a2}a');
  6858. Add(' +{@b2}b');
  6859. Add(' +{@c1}c');
  6860. Add(' +{@d1}d;');
  6861. Add(' Nesty:=3;');
  6862. Add(' DoIt:=4;');
  6863. Add(' end;');
  6864. Add('begin');
  6865. Add(' Result:={@a1}a');
  6866. Add(' +{@b1}b');
  6867. Add(' +{@c1}c;');
  6868. Add(' DoIt:=5;');
  6869. Add('end;');
  6870. Add('begin');
  6871. ParseProgram;
  6872. end;
  6873. procedure TTestResolver.TestNestedProc_ResultString;
  6874. var
  6875. aMarker: PSrcMarker;
  6876. Elements: TFPList;
  6877. i: Integer;
  6878. El: TPasElement;
  6879. Ref: TResolvedReference;
  6880. begin
  6881. StartProgram(false);
  6882. Add([
  6883. 'function DoIt: string;',
  6884. ' function Sub: char;',
  6885. ' begin',
  6886. ' {#a1}DoIt:=#65;',
  6887. ' {#a2}DoIt[1]:=#66;',
  6888. ' {#a3}DoIt;',
  6889. ' end;',
  6890. 'begin',
  6891. ' {#b1}DoIt:=#67;',
  6892. ' {#b2}DoIt[2]:=#68;',
  6893. ' {#b3}DoIt;',
  6894. 'end;',
  6895. 'begin']);
  6896. ParseProgram;
  6897. aMarker:=FirstSrcMarker;
  6898. while aMarker<>nil do
  6899. begin
  6900. //writeln('TTestResolver.TestNestedProc_ResultString ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  6901. Elements:=FindElementsAt(aMarker);
  6902. try
  6903. for i:=0 to Elements.Count-1 do
  6904. begin
  6905. El:=TPasElement(Elements[i]);
  6906. //writeln('TTestResolver.TestNestedProc_ResultString ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  6907. if not (El.CustomData is TResolvedReference) then continue;
  6908. Ref:=TResolvedReference(El.CustomData);
  6909. //writeln('TTestResolver.TestNestedProc_ResultString ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' Decl=',GetObjName(Ref.Declaration));
  6910. case aMarker^.Identifier of
  6911. 'a1','a2','b1','b2':
  6912. if not (Ref.Declaration is TPasResultElement) then
  6913. RaiseErrorAtSrcMarker('expected FuncResult at "#'+aMarker^.Identifier+', but was "'+GetObjName(Ref.Declaration)+'"',aMarker);
  6914. 'a3','b3':
  6915. if not (Ref.Declaration is TPasFunction) then
  6916. RaiseErrorAtSrcMarker('expected TPasFunction at "#'+aMarker^.Identifier+', but was "'+GetObjName(Ref.Declaration)+'"',aMarker);
  6917. end;
  6918. end;
  6919. finally
  6920. Elements.Free;
  6921. end;
  6922. aMarker:=aMarker^.Next;
  6923. end;
  6924. end;
  6925. procedure TTestResolver.TestFuncAssignFail;
  6926. begin
  6927. StartProgram(false);
  6928. Add([
  6929. 'function DoIt: boolean;',
  6930. 'begin',
  6931. 'end;',
  6932. 'begin',
  6933. ' DoIt:=true;']);
  6934. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  6935. end;
  6936. procedure TTestResolver.TestForwardProc;
  6937. begin
  6938. StartProgram(false);
  6939. Add('procedure {#A_forward}FuncA(i: longint); forward;');
  6940. Add('procedure {#B}FuncB(i: longint);');
  6941. Add('begin');
  6942. Add(' {@A_forward}FuncA(i);');
  6943. Add('end;');
  6944. Add('procedure {#A}FuncA(i: longint);');
  6945. Add('begin');
  6946. Add('end;');
  6947. Add('begin');
  6948. Add(' {@A_forward}FuncA(3);');
  6949. Add(' {@B}FuncB(3);');
  6950. ParseProgram;
  6951. end;
  6952. procedure TTestResolver.TestForwardProcUnresolved;
  6953. begin
  6954. StartProgram(false);
  6955. Add('procedure FuncA(i: longint); forward;');
  6956. Add('begin');
  6957. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  6958. end;
  6959. procedure TTestResolver.TestNestedForwardProc;
  6960. begin
  6961. StartProgram(false);
  6962. Add('procedure {#A}FuncA;');
  6963. Add(' procedure {#B_forward}ProcB(i: longint); forward;');
  6964. Add(' procedure {#C}ProcC(i: longint);');
  6965. Add(' begin');
  6966. Add(' {@B_forward}ProcB(i);');
  6967. Add(' end;');
  6968. Add(' procedure {#B}ProcB(i: longint);');
  6969. Add(' begin');
  6970. Add(' end;');
  6971. Add('begin');
  6972. Add(' {@B_forward}ProcB(3);');
  6973. Add(' {@C}ProcC(3);');
  6974. Add('end;');
  6975. Add('begin');
  6976. Add(' {@A}FuncA;');
  6977. ParseProgram;
  6978. end;
  6979. procedure TTestResolver.TestNestedForwardProcUnresolved;
  6980. begin
  6981. StartProgram(false);
  6982. Add('procedure FuncA;');
  6983. Add(' procedure ProcB(i: longint); forward;');
  6984. Add('begin');
  6985. Add('end;');
  6986. Add('begin');
  6987. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  6988. end;
  6989. procedure TTestResolver.TestForwardProcFuncMismatch;
  6990. begin
  6991. StartProgram(false);
  6992. Add('procedure DoIt; forward;');
  6993. Add('function DoIt: longint;');
  6994. Add('begin');
  6995. Add('end;');
  6996. Add('begin');
  6997. CheckResolverException('procedure expected, but function found',nXExpectedButYFound);
  6998. end;
  6999. procedure TTestResolver.TestForwardFuncResultMismatch;
  7000. begin
  7001. StartProgram(false);
  7002. Add('function DoIt: longint; forward;');
  7003. Add('function DoIt: string;');
  7004. Add('begin');
  7005. Add('end;');
  7006. Add('begin');
  7007. CheckResolverException('Result type mismatch, expected Longint, but found String',
  7008. nResultTypeMismatchExpectedButFound);
  7009. end;
  7010. procedure TTestResolver.TestForwardProcAssemblerMismatch;
  7011. begin
  7012. StartProgram(false);
  7013. Add('procedure Run; assembler; forward;');
  7014. Add('procedure Run;');
  7015. Add('begin');
  7016. Add('end;');
  7017. Add('begin');
  7018. CheckParserException('Expected "asm"',nParserExpectTokenError);
  7019. end;
  7020. procedure TTestResolver.TestUnitIntfProc;
  7021. begin
  7022. StartUnit(false);
  7023. Add('interface');
  7024. Add('procedure {#A_forward}FuncA({#Bar}Bar: longint);');
  7025. Add('implementation');
  7026. Add('procedure {#A}FuncA(bar: longint);');
  7027. Add('begin');
  7028. Add(' if {@Bar}bar=3 then ;');
  7029. Add('end;');
  7030. Add('initialization');
  7031. Add(' {@A_forward}FuncA(3);');
  7032. ParseUnit;
  7033. end;
  7034. procedure TTestResolver.TestUnitIntfProcUnresolved;
  7035. begin
  7036. StartUnit(false);
  7037. Add('interface');
  7038. Add('procedure {#A_forward}FuncA(i: longint);');
  7039. Add('implementation');
  7040. Add('initialization');
  7041. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  7042. end;
  7043. procedure TTestResolver.TestUnitIntfMismatchArgName;
  7044. begin
  7045. StartUnit(false);
  7046. Add('interface');
  7047. Add('procedure {#A_forward}ProcA(i: longint);');
  7048. Add('implementation');
  7049. Add('procedure {#A}ProcA(j: longint);');
  7050. Add('begin');
  7051. Add('end;');
  7052. CheckResolverException('function header "ProcA" doesn''t match forward : var name changes i => j',
  7053. nFunctionHeaderMismatchForwardVarName);
  7054. end;
  7055. procedure TTestResolver.TestProcOverloadIsNotFunc;
  7056. begin
  7057. StartUnit(false);
  7058. Add('interface');
  7059. Add('var ProcA: longint;');
  7060. Add('procedure {#A_Decl}ProcA(i: longint);');
  7061. Add('implementation');
  7062. Add('procedure {#A_Impl}ProcA(i: longint);');
  7063. Add('begin');
  7064. Add('end;');
  7065. CheckResolverException(sDuplicateIdentifier,nDuplicateIdentifier);
  7066. end;
  7067. procedure TTestResolver.TestProcCallMissingParams;
  7068. begin
  7069. StartProgram(false);
  7070. Add('procedure Proc1(a: longint);');
  7071. Add('begin');
  7072. Add('end;');
  7073. Add('begin');
  7074. Add(' Proc1;');
  7075. CheckResolverException('Wrong number of parameters specified for call to "Proc1"',
  7076. nWrongNumberOfParametersForCallTo);
  7077. end;
  7078. procedure TTestResolver.TestProcArgDefaultValue;
  7079. begin
  7080. StartProgram(false);
  7081. Add('const {#DefA}DefA = 3;');
  7082. Add('procedure Proc1(a: longint = {@DefA}DefA);');
  7083. Add('begin');
  7084. Add('end;');
  7085. Add('begin');
  7086. ParseProgram;
  7087. end;
  7088. procedure TTestResolver.TestProcArgDefaultValueTypeMismatch;
  7089. begin
  7090. StartProgram(false);
  7091. Add('procedure Proc1(a: string = 3);');
  7092. Add('begin');
  7093. Add('end;');
  7094. Add('begin');
  7095. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  7096. nIncompatibleTypesGotExpected);
  7097. end;
  7098. procedure TTestResolver.TestProcPassConstToVar;
  7099. begin
  7100. StartProgram(false);
  7101. Add('procedure DoSome(var i: longint); begin end;');
  7102. Add('procedure DoIt(const i: longint);');
  7103. Add('begin');
  7104. Add(' DoSome(i);');
  7105. Add('end;');
  7106. Add('begin');
  7107. CheckResolverException('Variable identifier expected',
  7108. nVariableIdentifierExpected);
  7109. end;
  7110. procedure TTestResolver.TestBuiltInProcCallMissingParams;
  7111. begin
  7112. StartProgram(false);
  7113. Add('begin');
  7114. Add(' length;');
  7115. CheckResolverException('Wrong number of parameters specified for call to "function Length(const String or Array): sizeint"',
  7116. nWrongNumberOfParametersForCallTo);
  7117. end;
  7118. procedure TTestResolver.TestAssignFunctionResult;
  7119. begin
  7120. StartProgram(false);
  7121. Add('function {#F1}F1: longint;');
  7122. Add('begin');
  7123. Add('end;');
  7124. Add('function {#F2}F2: longint;');
  7125. Add('begin');
  7126. Add('end;');
  7127. Add('var {#i}i: longint;');
  7128. Add('begin');
  7129. Add(' {@i}i:={@F1}F1();');
  7130. Add(' {@i}i:={@F1}F1()+{@F2}F2();');
  7131. Add(' {@i}i:={@F1}F1;');
  7132. Add(' {@i}i:={@F1}F1+{@F2}F2;');
  7133. ParseProgram;
  7134. end;
  7135. procedure TTestResolver.TestAssignProcResultFail;
  7136. begin
  7137. StartProgram(false);
  7138. Add('procedure {#P}P;');
  7139. Add('begin');
  7140. Add('end;');
  7141. Add('var {#i}i: longint;');
  7142. Add('begin');
  7143. Add(' {@i}i:={@P}P();');
  7144. CheckResolverException('Incompatible types: got "Procedure/Function" expected "Longint"',
  7145. nIncompatibleTypesGotExpected);
  7146. end;
  7147. procedure TTestResolver.TestFunctionResultInCondition;
  7148. begin
  7149. StartProgram(false);
  7150. Add('function {#F1}F1: longint;');
  7151. Add('begin');
  7152. Add('end;');
  7153. Add('function {#F2}F2: boolean;');
  7154. Add('begin');
  7155. Add('end;');
  7156. Add('var {#i}i: longint;');
  7157. Add('begin');
  7158. Add(' if {@F2}F2 then ;');
  7159. Add(' if {@i}i={@F1}F1() then ;');
  7160. ParseProgram;
  7161. end;
  7162. procedure TTestResolver.TestExit;
  7163. begin
  7164. StartProgram(false);
  7165. Add('procedure ProcA;');
  7166. Add('begin');
  7167. Add(' exit;');
  7168. Add('end;');
  7169. Add('function FuncB: longint;');
  7170. Add('begin');
  7171. Add(' exit;');
  7172. Add(' exit(3);');
  7173. Add('end;');
  7174. Add('function FuncC: string;');
  7175. Add('begin');
  7176. Add(' exit;');
  7177. Add(' exit(''a'');');
  7178. Add(' exit(''abc'');');
  7179. Add('end;');
  7180. Add('begin');
  7181. Add(' exit;');
  7182. Add(' exit(4);');
  7183. ParseProgram;
  7184. end;
  7185. procedure TTestResolver.TestBreak;
  7186. begin
  7187. StartProgram(false);
  7188. Add('var i: longint;');
  7189. Add('begin');
  7190. Add(' repeat');
  7191. Add(' break;');
  7192. Add(' until false;');
  7193. Add(' while true do');
  7194. Add(' break;');
  7195. Add(' for i:=0 to 1 do');
  7196. Add(' break;');
  7197. ParseProgram;
  7198. end;
  7199. procedure TTestResolver.TestContinue;
  7200. begin
  7201. StartProgram(false);
  7202. Add('var i: longint;');
  7203. Add('begin');
  7204. Add(' repeat');
  7205. Add(' continue;');
  7206. Add(' until false;');
  7207. Add(' while true do');
  7208. Add(' continue;');
  7209. Add(' for i:=0 to 1 do');
  7210. Add(' continue;');
  7211. ParseProgram;
  7212. end;
  7213. procedure TTestResolver.TestProcedureExternal;
  7214. begin
  7215. StartProgram(false);
  7216. Add('procedure {#ProcA}ProcA; external ''ExtProcA'';');
  7217. Add('function {#FuncB}FuncB: longint; external ''ExtFuncB'';');
  7218. Add('function {#FuncC}FuncC(d: double): string; external ''ExtFuncC'';');
  7219. Add('var');
  7220. Add(' i: longint;');
  7221. Add(' s: string;');
  7222. Add('begin');
  7223. Add(' {@ProcA}ProcA;');
  7224. Add(' i:={@FuncB}FuncB;');
  7225. Add(' i:={@FuncB}FuncB();');
  7226. Add(' s:={@FuncC}FuncC(1.2);');
  7227. ParseProgram;
  7228. end;
  7229. procedure TTestResolver.TestProc_UntypedParam_Forward;
  7230. begin
  7231. StartProgram(false);
  7232. Add('procedure {#ProcA}ProcA(var {#A}A); forward;');
  7233. Add('procedure {#ProcB}ProcB(const {#B}B); forward;');
  7234. Add('procedure {#ProcC}ProcC(out {#C}C); forward;');
  7235. //Add('procedure {#ProcD}ProcD(constref {#D}D); forward;');
  7236. Add('procedure ProcA(var A);');
  7237. Add('begin');
  7238. Add('end;');
  7239. Add('procedure ProcB(const B);');
  7240. Add('begin');
  7241. Add('end;');
  7242. Add('procedure ProcC(out C);');
  7243. Add('begin');
  7244. Add('end;');
  7245. //Add('procedure ProcD(constref D);');
  7246. //Add('begin');
  7247. //Add('end;');
  7248. Add('var i: longint;');
  7249. Add('begin');
  7250. Add(' {@ProcA}ProcA(i);');
  7251. Add(' {@ProcB}ProcB(i);');
  7252. Add(' {@ProcC}ProcC(i);');
  7253. //Add(' {@ProcD}ProcD(i);');
  7254. ParseProgram;
  7255. end;
  7256. procedure TTestResolver.TestProc_Varargs;
  7257. begin
  7258. StartProgram(false);
  7259. Add('procedure ProcA(i:longint); varargs; external;');
  7260. Add('procedure ProcB; varargs; external;');
  7261. Add('procedure ProcC(i: longint = 17); varargs; external;');
  7262. Add('begin');
  7263. Add(' ProcA(1);');
  7264. Add(' ProcA(1,2);');
  7265. Add(' ProcA(1,2.0);');
  7266. Add(' ProcA(1,2,3);');
  7267. Add(' ProcA(1,''2'');');
  7268. Add(' ProcA(2,'''');');
  7269. Add(' ProcA(3,false);');
  7270. Add(' ProcB;');
  7271. Add(' ProcB();');
  7272. Add(' ProcB(4);');
  7273. Add(' ProcB(''foo'');');
  7274. Add(' ProcC;');
  7275. Add(' ProcC();');
  7276. Add(' ProcC(4);');
  7277. Add(' ProcC(5,''foo'');');
  7278. ParseProgram;
  7279. end;
  7280. procedure TTestResolver.TestProc_VarargsOfT;
  7281. begin
  7282. StartProgram(false);
  7283. Add([
  7284. 'procedure ProcA(i:longint); varargs of word; external;',
  7285. 'procedure ProcB; varargs of boolean; external;',
  7286. 'procedure ProcC(i: longint = 17); varargs of double; external;',
  7287. 'begin',
  7288. ' ProcA(1);',
  7289. ' ProcA(2,3);',
  7290. ' ProcA(4,5,6);',
  7291. ' ProcB;',
  7292. ' ProcB();',
  7293. ' ProcB(false);',
  7294. ' ProcB(true,false);',
  7295. ' ProcC;',
  7296. ' ProcC();',
  7297. ' ProcC(7);',
  7298. ' ProcC(8,9.3);',
  7299. ' ProcC(8,9.3,1.3);',
  7300. '']);
  7301. ParseProgram;
  7302. end;
  7303. procedure TTestResolver.TestProc_VarargsOfTMismatch;
  7304. begin
  7305. StartProgram(false);
  7306. Add([
  7307. 'procedure ProcA(i:longint); varargs of word; external;',
  7308. 'begin',
  7309. ' ProcA(1,false);',
  7310. '']);
  7311. CheckResolverException('Incompatible type for arg no. 2: Got "Boolean", expected "Word"',nIncompatibleTypeArgNo);
  7312. end;
  7313. procedure TTestResolver.TestProc_ParameterExprAccess;
  7314. begin
  7315. StartProgram(false);
  7316. Add('type');
  7317. Add(' TRec = record');
  7318. Add(' a: longint;');
  7319. Add(' end;');
  7320. Add('procedure DoIt(i: longint; const j: longint; var k: longint; out l: longint);');
  7321. Add('begin');
  7322. Add(' DoIt({#loc1_read}i,{#loc2_read}i,{#loc3_var}i,{#loc4_out}i);');
  7323. Add('end;');
  7324. Add('var');
  7325. Add(' r: TRec;');
  7326. Add('begin');
  7327. Add(' DoIt({#r1_read}r.{#r_a1_read}a,');
  7328. Add(' {#r2_read}r.{#r_a2_read}a,');
  7329. Add(' {#r3_read}r.{#r_a3_var}a,');
  7330. Add(' {#r4_read}r.{#r_a4_out}a);');
  7331. Add(' with r do');
  7332. Add(' DoIt({#w_a1_read}a,');
  7333. Add(' {#w_a2_read}a,');
  7334. Add(' {#w_a3_var}a,');
  7335. Add(' {#w_a4_out}a);');
  7336. ParseProgram;
  7337. CheckAccessMarkers;
  7338. end;
  7339. procedure TTestResolver.TestProc_FunctionResult_DeclProc;
  7340. var
  7341. aMarker: PSrcMarker;
  7342. Elements: TFPList;
  7343. i: Integer;
  7344. El: TPasElement;
  7345. Ref: TResolvedReference;
  7346. ResultEl: TPasResultElement;
  7347. Proc: TPasProcedure;
  7348. ProcScope: TPasProcedureScope;
  7349. begin
  7350. StartProgram(false);
  7351. Add('type');
  7352. Add(' TObject = class');
  7353. Add(' function MethodA: longint;');
  7354. Add(' end;');
  7355. Add('function FuncA: longint; forward;');
  7356. Add('function TObject.MethodA: longint;');
  7357. Add('begin');
  7358. Add(' {#MethodA_Result}Result:=1;');
  7359. Add('end;');
  7360. Add('function FuncA: longint;');
  7361. Add(' function SubFuncA: longint; forward;');
  7362. Add(' function SubFuncB: longint;');
  7363. Add(' begin');
  7364. Add(' {#SubFuncB_Result}Result:=2;');
  7365. Add(' end;');
  7366. Add(' function SubFuncA: longint;');
  7367. Add(' begin');
  7368. Add(' {#SubFuncA_Result}Result:=3;');
  7369. Add(' end;');
  7370. Add('begin');
  7371. Add(' {#FuncA_Result}Result:=4;');
  7372. Add('end;');
  7373. Add('begin');
  7374. ParseProgram;
  7375. aMarker:=FirstSrcMarker;
  7376. while aMarker<>nil do
  7377. begin
  7378. //writeln('TTestResolver.TestProc_FunctionResult_DeclProc ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  7379. Elements:=FindElementsAt(aMarker);
  7380. try
  7381. for i:=0 to Elements.Count-1 do
  7382. begin
  7383. El:=TPasElement(Elements[i]);
  7384. //writeln('TTestResolver.TestProc_FunctionResult_DeclProc ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  7385. if not (El.CustomData is TResolvedReference) then continue;
  7386. Ref:=TResolvedReference(El.CustomData);
  7387. //writeln('TTestResolver.TestProc_FunctionResult_DeclProc ',GetObjName(Ref.Declaration));
  7388. if not (Ref.Declaration is TPasResultElement) then continue;
  7389. ResultEl:=TPasResultElement(Ref.Declaration);
  7390. Proc:=ResultEl.Parent.Parent as TPasProcedure;
  7391. ProcScope:=Proc.CustomData as TPasProcedureScope;
  7392. if ProcScope.DeclarationProc<>nil then
  7393. RaiseErrorAtSrcMarker('expected Result to resolve to declaration at "#'+aMarker^.Identifier+', but was implproc"',aMarker);
  7394. break;
  7395. end;
  7396. finally
  7397. Elements.Free;
  7398. end;
  7399. aMarker:=aMarker^.Next;
  7400. end;
  7401. end;
  7402. procedure TTestResolver.TestProc_TypeCastFunctionResult;
  7403. begin
  7404. StartProgram(false);
  7405. Add('function GetIt: longint; begin end;');
  7406. Add('var s: smallint;');
  7407. Add('begin');
  7408. Add(' s:=smallint(GetIt);');
  7409. ParseProgram;
  7410. end;
  7411. procedure TTestResolver.TestProc_ImplicitCalls;
  7412. var
  7413. aMarker: PSrcMarker;
  7414. Elements: TFPList;
  7415. ActualImplicitCallWithoutParams: Boolean;
  7416. i: Integer;
  7417. El: TPasElement;
  7418. Ref: TResolvedReference;
  7419. begin
  7420. StartProgram(false);
  7421. Add([
  7422. 'function b: longint;',
  7423. 'begin',
  7424. 'end;',
  7425. 'function GetStr: string;',
  7426. 'begin',
  7427. 'end;',
  7428. 'var',
  7429. ' a: longint;',
  7430. ' s: string;',
  7431. ' arr: array of longint;',
  7432. 'begin',
  7433. ' Inc(a,{#b1}b);',
  7434. ' Dec(a,{#b2}b);',
  7435. ' str({#b3}b,s);',
  7436. ' SetLength(arr,{#b4}b);',
  7437. ' Insert({#b5}b,arr,{#b6}b);',
  7438. ' Delete(arr,{#b7}b,{#b8}b);',
  7439. ' a:=length({#b9}GetStr);',
  7440. '']);
  7441. ParseProgram;
  7442. aMarker:=FirstSrcMarker;
  7443. while aMarker<>nil do
  7444. begin
  7445. //writeln('TTestResolver.TestProc_IncWithImplicitCall ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  7446. Elements:=FindElementsAt(aMarker);
  7447. try
  7448. ActualImplicitCallWithoutParams:=false;
  7449. for i:=0 to Elements.Count-1 do
  7450. begin
  7451. El:=TPasElement(Elements[i]);
  7452. //writeln('TTestResolver.TestProc_IncWithImplicitCall ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  7453. if not (El.CustomData is TResolvedReference) then continue;
  7454. Ref:=TResolvedReference(El.CustomData);
  7455. if not (Ref.Declaration is TPasProcedure) then continue;
  7456. //writeln('TTestResolver.TestProc_IncWithImplicitCall ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  7457. ActualImplicitCallWithoutParams:=rrfImplicitCallWithoutParams in Ref.Flags;
  7458. break;
  7459. end;
  7460. if not ActualImplicitCallWithoutParams then
  7461. RaiseErrorAtSrcMarker('expected implicit call at "#'+aMarker^.Identifier+', but got function ref"',aMarker);
  7462. finally
  7463. Elements.Free;
  7464. end;
  7465. aMarker:=aMarker^.Next;
  7466. end;
  7467. end;
  7468. procedure TTestResolver.TestProc_Absolute;
  7469. begin
  7470. StartProgram(false);
  7471. Add([
  7472. 'procedure DoIt(p: Pointer);',
  7473. 'var',
  7474. ' s: string absolute p;',
  7475. ' t: array of char absolute s;',
  7476. 'begin',
  7477. 'end;',
  7478. 'begin']);
  7479. ParseProgram;
  7480. end;
  7481. procedure TTestResolver.TestProc_LocalInit;
  7482. begin
  7483. StartProgram(false);
  7484. Add([
  7485. 'type TBytes = array of byte;',
  7486. 'procedure DoIt;',
  7487. 'const c = 4;',
  7488. 'var',
  7489. ' w: word = c;',
  7490. ' b: byte = 1+c;',
  7491. ' p: pointer = nil;',
  7492. ' buf: TBytes = nil;',
  7493. 'begin',
  7494. 'end;',
  7495. 'begin']);
  7496. ParseProgram;
  7497. end;
  7498. procedure TTestResolver.TestProc_ExtNamePropertyFail;
  7499. begin
  7500. StartProgram(false);
  7501. Add([
  7502. 'procedure Foo; external name ''});'' property;',
  7503. 'begin']);
  7504. CheckParserException('Expected ";" at token "property" in file afile.pp at line 2 column 36',
  7505. nParserExpectTokenError);
  7506. end;
  7507. procedure TTestResolver.TestAnonymousProc_Assign;
  7508. begin
  7509. StartProgram(false);
  7510. Add([
  7511. 'type',
  7512. ' TFunc = reference to function(x: word): word;',
  7513. 'var Func: TFunc;',
  7514. 'procedure DoIt(a: word);',
  7515. 'begin',
  7516. ' Func:=function(b:word): word',
  7517. ' begin',
  7518. ' Result:=a+b;',
  7519. ' exit(b);',
  7520. ' exit(Result);',
  7521. ' end;',// test semicolon
  7522. ' a:=3;',
  7523. 'end;',
  7524. 'begin',
  7525. ' Func:=function(c:word):word begin',
  7526. ' Result:=3+c;',
  7527. ' exit(c);',
  7528. ' exit(Result);',
  7529. ' end;']);
  7530. ParseProgram;
  7531. end;
  7532. procedure TTestResolver.TestAnonymousProc_AssignSemicolonFail;
  7533. begin
  7534. StartProgram(false);
  7535. Add([
  7536. 'type',
  7537. ' TProc = reference to procedure;',
  7538. 'procedure DoIt(a: word);',
  7539. 'var p: TProc;',
  7540. 'begin',
  7541. ' p:=procedure; begin end;',
  7542. ' a:=3;',
  7543. 'end;',
  7544. 'begin']);
  7545. CheckParserException('Expected "begin" at token ";" in file afile.pp at line 7 column 15',
  7546. nParserExpectTokenError);
  7547. end;
  7548. procedure TTestResolver.TestAnonymousProc_Assign_ReferenceToMissingFail;
  7549. begin
  7550. StartProgram(false);
  7551. Add([
  7552. 'type',
  7553. ' TProc = procedure;',
  7554. 'procedure DoIt;',
  7555. 'var p: TProc;',
  7556. 'begin',
  7557. ' p:=procedure(w: word) begin end;',
  7558. 'end;',
  7559. 'begin']);
  7560. CheckResolverException('procedural type modifier "reference to" mismatch',
  7561. nXModifierMismatchY);
  7562. end;
  7563. procedure TTestResolver.TestAnonymousProc_Assign_WrongParamListFail;
  7564. begin
  7565. StartProgram(false);
  7566. Add([
  7567. 'type',
  7568. ' TProc = reference to procedure;',
  7569. 'procedure DoIt;',
  7570. 'var p: TProc;',
  7571. 'begin',
  7572. ' p:=procedure(w: word) begin end;',
  7573. 'end;',
  7574. 'begin']);
  7575. CheckResolverException('Incompatible types, got 0 parameters, expected 1',
  7576. nIncompatibleTypesGotParametersExpected);
  7577. end;
  7578. procedure TTestResolver.TestAnonymousProc_Arg;
  7579. begin
  7580. StartProgram(false);
  7581. Add([
  7582. 'type',
  7583. ' TProc = reference to procedure;',
  7584. ' TFunc = reference to function(x: word): word;',
  7585. 'procedure DoMore(f,g: TProc);',
  7586. 'begin',
  7587. 'end;',
  7588. 'procedure DoIt(f: TFunc);',
  7589. 'begin',
  7590. ' DoIt(function(b:word): word',
  7591. ' begin',
  7592. ' Result:=1+b;',
  7593. ' end);',
  7594. ' DoMore(procedure begin end, procedure begin end);',
  7595. 'end;',
  7596. 'begin',
  7597. ' DoMore(procedure begin end, procedure begin end);',
  7598. '']);
  7599. ParseProgram;
  7600. end;
  7601. procedure TTestResolver.TestAnonymousProc_ArgSemicolonFail;
  7602. begin
  7603. StartProgram(false);
  7604. Add([
  7605. 'type',
  7606. ' TProc = reference to procedure;',
  7607. 'procedure DoIt(p: TProc);',
  7608. 'begin',
  7609. 'end;',
  7610. 'begin',
  7611. ' DoIt(procedure begin end;);']);
  7612. CheckParserException('Expected "," at token ";" in file afile.pp at line 8 column 27',
  7613. nParserExpectTokenError);
  7614. end;
  7615. procedure TTestResolver.TestAnonymousProc_EqualFail;
  7616. begin
  7617. StartProgram(false);
  7618. Add([
  7619. 'type',
  7620. ' TFunc = reference to function(x: word): word;',
  7621. 'procedure DoIt(f: TFunc);',
  7622. 'var w: word;',
  7623. 'begin',
  7624. ' if w=function(b:word): word',
  7625. ' begin',
  7626. ' Result:=1+b;',
  7627. ' end then ;',
  7628. 'end;',
  7629. 'begin']);
  7630. CheckResolverException('Incompatible types: got "Procedure/Function" expected "Word"',nIncompatibleTypesGotExpected);
  7631. end;
  7632. procedure TTestResolver.TestAnonymousProc_ConstFail;
  7633. begin
  7634. StartProgram(false);
  7635. Add([
  7636. 'type',
  7637. ' TProc = reference to procedure;',
  7638. 'const',
  7639. ' p: TProc = procedure begin end;',
  7640. 'begin']);
  7641. CheckParserException('Identifier expected at token "procedure" in file afile.pp at line 5 column 14',nParserExpectedIdentifier);
  7642. end;
  7643. procedure TTestResolver.TestAnonymousProc_Assembler;
  7644. begin
  7645. StartProgram(false);
  7646. Add([
  7647. 'type',
  7648. ' TProc = reference to procedure;',
  7649. ' TProcB = reference to procedure cdecl;',
  7650. 'procedure DoIt(p: TProc);',
  7651. 'var b: TProcB;',
  7652. 'begin',
  7653. ' p:=procedure assembler asm end;',
  7654. ' p:=procedure() assembler asm end;',
  7655. ' b:=procedure() cdecl assembler asm end;',
  7656. 'end;',
  7657. 'begin']);
  7658. ParseProgram;
  7659. end;
  7660. procedure TTestResolver.TestAnonymousProc_NameFail;
  7661. begin
  7662. StartProgram(false);
  7663. Add([
  7664. 'type',
  7665. ' TProc = reference to procedure;',
  7666. 'procedure DoIt(p: TProc);',
  7667. 'begin',
  7668. ' p:=procedure Bla() begin end;',
  7669. 'end;',
  7670. 'begin']);
  7671. CheckParserException(SParserSyntaxError,nParserSyntaxError);
  7672. end;
  7673. procedure TTestResolver.TestAnonymousProc_StatementFail;
  7674. begin
  7675. StartProgram(false);
  7676. Add([
  7677. 'procedure DoIt;',
  7678. 'begin',
  7679. ' procedure () begin end;',
  7680. 'end;',
  7681. 'begin']);
  7682. CheckParserException(SParserSyntaxError,nParserSyntaxError);
  7683. end;
  7684. procedure TTestResolver.TestAnonymousProc_Typecast_ObjFPC;
  7685. begin
  7686. StartProgram(false);
  7687. Add([
  7688. '{$mode ObjFPC}',
  7689. 'type',
  7690. ' TProc = reference to procedure(w: word);',
  7691. ' TArr = array of word;',
  7692. ' TFuncArr = reference to function: TArr;',
  7693. 'procedure DoIt(p: TProc);',
  7694. 'var',
  7695. ' w: word;',
  7696. ' a: TArr;',
  7697. 'begin',
  7698. ' p:=TProc(procedure(b: smallint) begin end);',
  7699. ' a:=TFuncArr(function: TArr begin end)();',
  7700. ' w:=TFuncArr(function: TArr begin end)()[3];',
  7701. 'end;',
  7702. 'begin']);
  7703. ParseProgram;
  7704. end;
  7705. procedure TTestResolver.TestAnonymousProc_Typecast_Delphi;
  7706. begin
  7707. StartProgram(false);
  7708. Add([
  7709. '{$mode Delphi}',
  7710. 'type',
  7711. ' TProc = reference to procedure(w: word);',
  7712. ' TArr = array of word;',
  7713. ' TFuncArr = reference to function: TArr;',
  7714. 'procedure DoIt(p: TProc);',
  7715. 'var',
  7716. ' w: word;',
  7717. ' a: TArr;',
  7718. 'begin',
  7719. ' p:=TProc(procedure(b: smallint) begin end);',
  7720. ' a:=TFuncArr(function: TArr begin end)();',
  7721. ' w:=TFuncArr(function: TArr begin end)()[3];',
  7722. 'end;',
  7723. 'begin']);
  7724. ParseProgram;
  7725. end;
  7726. procedure TTestResolver.TestAnonymousProc_TypecastToResultFail;
  7727. begin
  7728. StartProgram(false);
  7729. Add([
  7730. 'procedure DoIt;',
  7731. 'var i: longint;',
  7732. 'begin',
  7733. ' i:=longint(function(b: byte): byte begin end);',
  7734. 'end;',
  7735. 'begin']);
  7736. CheckResolverException('Illegal type conversion: "Procedure/Function" to "Longint"',
  7737. nIllegalTypeConversionTo);
  7738. end;
  7739. procedure TTestResolver.TestAnonymousProc_WithDo;
  7740. begin
  7741. StartProgram(false);
  7742. Add([
  7743. 'type',
  7744. ' TProc = reference to procedure(w: word);',
  7745. ' TObject = class end;',
  7746. ' TBird = class',
  7747. ' {#bool}b: boolean;',
  7748. ' end;',
  7749. 'procedure DoIt({#i}i: longint);',
  7750. 'var',
  7751. ' {#p}p: TProc;',
  7752. ' {#bird}bird: TBird;',
  7753. 'begin',
  7754. ' with {@bird}bird do',
  7755. ' {@p}p:=procedure({#w}w: word)',
  7756. ' begin',
  7757. ' {@bool}b:=true;',
  7758. ' {@bool}b:=({@w}w+{@i}i)>2;',
  7759. ' end;',
  7760. 'end;',
  7761. 'begin']);
  7762. ParseProgram;
  7763. end;
  7764. procedure TTestResolver.TestAnonymousProc_ExceptOn;
  7765. begin
  7766. StartProgram(false);
  7767. Add([
  7768. 'type',
  7769. ' TProc = reference to procedure;',
  7770. ' TObject = class end;',
  7771. ' Exception = class',
  7772. ' {#bool}b: boolean;',
  7773. ' end;',
  7774. 'procedure DoIt;',
  7775. 'var',
  7776. ' {#p}p: TProc;',
  7777. 'begin',
  7778. ' try',
  7779. ' except',
  7780. ' on {#E}E: Exception do',
  7781. ' {@p}p:=procedure',
  7782. ' begin',
  7783. ' {@E}E.{@bool}b:=true;',
  7784. ' end;',
  7785. ' end;',
  7786. 'end;',
  7787. 'begin']);
  7788. ParseProgram;
  7789. end;
  7790. procedure TTestResolver.TestAnonymousProc_Nested;
  7791. begin
  7792. StartProgram(false);
  7793. Add([
  7794. 'type',
  7795. ' TProc = reference to procedure;',
  7796. ' TObject = class',
  7797. ' i: byte;',
  7798. ' procedure DoIt;',
  7799. ' end;',
  7800. 'procedure TObject.DoIt;',
  7801. 'var',
  7802. ' p: TProc;',
  7803. ' procedure Sub;',
  7804. ' begin',
  7805. ' p:=procedure',
  7806. ' begin',
  7807. ' i:=3;',
  7808. ' Self.i:=4;',
  7809. ' p:=procedure',
  7810. ' procedure SubSub;',
  7811. ' begin',
  7812. ' i:=13;',
  7813. ' Self.i:=14;',
  7814. ' end;',
  7815. ' begin',
  7816. ' i:=13;',
  7817. ' Self.i:=14;',
  7818. ' end;',
  7819. ' end;',
  7820. ' end;',
  7821. 'begin',
  7822. 'end;',
  7823. 'begin']);
  7824. ParseProgram;
  7825. end;
  7826. procedure TTestResolver.TestAnonymousProc_ForLoop;
  7827. begin
  7828. StartProgram(false);
  7829. Add([
  7830. 'type TProc = reference to procedure;',
  7831. 'procedure Foo(p: TProc);',
  7832. 'begin',
  7833. 'end;',
  7834. 'procedure DoIt;',
  7835. 'var i: word;',
  7836. ' a: word;',
  7837. 'begin',
  7838. ' for i:=1 to 10 do begin',
  7839. ' Foo(procedure begin a:=3; end);',
  7840. ' end;',
  7841. 'end;',
  7842. 'begin',
  7843. ' DoIt;']);
  7844. ParseProgram;
  7845. end;
  7846. procedure TTestResolver.TestRecord;
  7847. begin
  7848. StartProgram(false);
  7849. Add('type');
  7850. Add(' {#TRec}TRec = record');
  7851. Add(' {#Size}Size: longint;');
  7852. Add(' end;');
  7853. Add('var');
  7854. Add(' {#r}{=TRec}r: TRec;');
  7855. Add('begin');
  7856. Add(' {@r}r.{@Size}Size:=3;');
  7857. ParseProgram;
  7858. end;
  7859. procedure TTestResolver.TestRecordVariant;
  7860. begin
  7861. StartProgram(false);
  7862. Add('type');
  7863. Add(' {#TRec}TRec = record');
  7864. Add(' {#Size}Size: longint;');
  7865. Add(' case {#vari}vari: longint of');
  7866. Add(' 0: ({#b}b: longint)');
  7867. Add(' end;');
  7868. Add('var');
  7869. Add(' {#r}{=TRec}r: TRec;');
  7870. Add('begin');
  7871. Add(' {@r}r.{@Size}Size:=3;');
  7872. Add(' {@r}r.{@vari}vari:=4;');
  7873. Add(' {@r}r.{@b}b:=5;');
  7874. ParseProgram;
  7875. end;
  7876. procedure TTestResolver.TestRecordVariantNested;
  7877. begin
  7878. StartProgram(false);
  7879. Add([
  7880. 'type',
  7881. ' {#TRec}TRec = record',
  7882. ' {#Size}Size: longint;',
  7883. ' case {#vari}vari: longint of',
  7884. ' 0: ({#b}b: longint)',
  7885. ' 1: ({#c}c:',
  7886. ' record',
  7887. ' {#d}d: longint;',
  7888. ' case {#e}e: longint of',
  7889. ' 0: ({#f}f: longint)',
  7890. ' end)',
  7891. ' end;',
  7892. 'var',
  7893. ' {#r}{=TRec}r: TRec;',
  7894. 'begin',
  7895. ' {@r}r.{@Size}Size:=3;',
  7896. ' {@r}r.{@vari}vari:=4;',
  7897. ' {@r}r.{@b}b:=5;',
  7898. ' {@r}r.{@c}c.{@d}d:=6;',
  7899. ' {@r}r.{@c}c.{@e}e:=7;',
  7900. ' {@r}r.{@c}c.{@f}f:=8;']);
  7901. ParseProgram;
  7902. end;
  7903. procedure TTestResolver.TestRecord_WriteConstParamFail;
  7904. begin
  7905. StartProgram(false);
  7906. Add('type');
  7907. Add(' TSmall = record');
  7908. Add(' Size: longint;');
  7909. Add(' end;');
  7910. Add('procedure DoIt(const S: TSmall);');
  7911. Add('begin');
  7912. Add(' S.Size:=3;');
  7913. Add('end;');
  7914. Add('begin');
  7915. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  7916. end;
  7917. procedure TTestResolver.TestRecord_WriteConstParam_WithDoFail;
  7918. begin
  7919. StartProgram(false);
  7920. Add('type');
  7921. Add(' TSmall = record');
  7922. Add(' Size: longint;');
  7923. Add(' end;');
  7924. Add('procedure DoIt(const S: TSmall);');
  7925. Add('begin');
  7926. Add(' with S do Size:=3;');
  7927. Add('end;');
  7928. Add('begin');
  7929. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  7930. end;
  7931. procedure TTestResolver.TestRecord_WriteNestedConstParamFail;
  7932. begin
  7933. StartProgram(false);
  7934. Add('type');
  7935. Add(' TSmall = record');
  7936. Add(' Size: longint;');
  7937. Add(' end;');
  7938. Add(' TBig = record');
  7939. Add(' Small: TSmall;');
  7940. Add(' end;');
  7941. Add('procedure DoIt(const B: TBig);');
  7942. Add('begin');
  7943. Add(' B.Small.Size:=3;');
  7944. Add('end;');
  7945. Add('begin');
  7946. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  7947. end;
  7948. procedure TTestResolver.TestRecord_WriteNestedConstParamWithDoFail;
  7949. begin
  7950. StartProgram(false);
  7951. Add('type');
  7952. Add(' TSmall = record');
  7953. Add(' Size: longint;');
  7954. Add(' end;');
  7955. Add(' TBig = record');
  7956. Add(' Small: TSmall;');
  7957. Add(' end;');
  7958. Add('procedure DoIt(const B: TBig);');
  7959. Add('begin');
  7960. Add(' with B do with Small do Size:=3;');
  7961. Add('end;');
  7962. Add('begin');
  7963. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  7964. end;
  7965. procedure TTestResolver.TestRecord_TypeCast;
  7966. begin
  7967. StartProgram(false);
  7968. Add([
  7969. 'type',
  7970. ' TAnimal = record',
  7971. ' Size: longint;',
  7972. ' end;',
  7973. ' TBird = record',
  7974. ' Length: longint;',
  7975. ' end;',
  7976. 'var',
  7977. ' a: TAnimal;',
  7978. ' b: TBird;',
  7979. 'begin',
  7980. ' b:=TBird(a);',
  7981. ' TAnimal(b).Size:=TBird(a).Length;',
  7982. ' ']);
  7983. ParseProgram;
  7984. end;
  7985. procedure TTestResolver.TestRecord_NewDispose;
  7986. begin
  7987. StartProgram(false);
  7988. Add([
  7989. 'type',
  7990. ' TBird = record',
  7991. ' Length: longint;',
  7992. ' end;',
  7993. ' PBird = ^TBird;',
  7994. 'var',
  7995. ' p: PBird;',
  7996. ' q: ^TBird;',
  7997. 'begin',
  7998. ' New(p);',
  7999. ' Dispose(p);',
  8000. ' New(q);',
  8001. ' Dispose(q);',
  8002. ' ']);
  8003. ParseProgram;
  8004. end;
  8005. procedure TTestResolver.TestRecord_Const;
  8006. begin
  8007. StartProgram(false);
  8008. Add([
  8009. 'type',
  8010. ' TPoint = record x, y: longint; end;',
  8011. 'const r: TPoint = (x:1; y:2);',
  8012. 'type',
  8013. ' TPasSourcePos = Record',
  8014. ' FileName: String;',
  8015. ' Row, Column: LongWord;',
  8016. ' end;',
  8017. 'const',
  8018. ' DefPasSourcePos: TPasSourcePos = (Filename:''''; Row:0; Column:0);',
  8019. 'begin',
  8020. '']);
  8021. ParseProgram;
  8022. end;
  8023. procedure TTestResolver.TestRecord_Const_DuplicateFail;
  8024. begin
  8025. StartProgram(false);
  8026. Add([
  8027. 'type',
  8028. ' TPoint = record x, y: longint; end;',
  8029. 'const r: TPoint = (x:1; x:2);',
  8030. 'begin',
  8031. '']);
  8032. CheckResolverException('Duplicate identifier "x" at afile.pp(4,20)',nDuplicateIdentifier);
  8033. end;
  8034. procedure TTestResolver.TestRecord_Const_ExprMismatchFail;
  8035. begin
  8036. StartProgram(false);
  8037. Add([
  8038. 'type',
  8039. ' TPoint = record x, y: longint; end;',
  8040. 'const r: TPoint = (x:1; x:2);',
  8041. 'begin',
  8042. '']);
  8043. CheckResolverException('Duplicate identifier "x" at afile.pp(4,20)',nDuplicateIdentifier);
  8044. end;
  8045. procedure TTestResolver.TestRecord_Const_MissingHint;
  8046. begin
  8047. StartProgram(false);
  8048. Add([
  8049. 'type',
  8050. ' TPoint = record x, y: longint; end;',
  8051. 'const r: TPoint = (x:1);',
  8052. 'begin',
  8053. '']);
  8054. ParseProgram;
  8055. CheckResolverHint(mtHint,nMissingFieldsX,'Missing fields: "y"');
  8056. end;
  8057. procedure TTestResolver.TestRecord_Const_UntypedFail;
  8058. begin
  8059. StartProgram(false);
  8060. Add([
  8061. 'const r = (x:1);',
  8062. 'begin',
  8063. '']);
  8064. CheckResolverException('Syntax error, "const" expected but "record values" found',nSyntaxErrorExpectedButFound);
  8065. end;
  8066. procedure TTestResolver.TestRecord_Const_NestedRecord;
  8067. begin
  8068. StartProgram(false);
  8069. Add([
  8070. 'type',
  8071. ' TPoint = record x, y: longint; end;',
  8072. ' TSrc = record',
  8073. ' Id: longint;',
  8074. ' XY: TPoint',
  8075. ' end;',
  8076. 'const r: TSrc = (Id:1; XY: (x:2; y:3));',
  8077. 'begin',
  8078. '']);
  8079. ParseProgram;
  8080. end;
  8081. procedure TTestResolver.TestRecord_Const_Variant;
  8082. begin
  8083. StartProgram(false);
  8084. Add([
  8085. 'type',
  8086. ' {#TRec}TRec = record',
  8087. ' {#Size}Size: longint;',
  8088. ' case {#vari}vari: longint of',
  8089. ' 0: ({#b}b: longint);',
  8090. ' 1: ({#c}c:',
  8091. ' record',
  8092. ' {#d}d: longint;',
  8093. ' case {#e}e: longint of',
  8094. ' 0: ({#f}f: longint)',
  8095. ' end)',
  8096. ' end;',
  8097. 'const',
  8098. ' {#r}r: TRec = (',
  8099. ' {@Size}Size:2;',
  8100. ' {@c}c:(',
  8101. ' {@d}d:3;',
  8102. ' {@f}f:4',
  8103. ' )',
  8104. ' );',
  8105. 'begin']);
  8106. ParseProgram;
  8107. end;
  8108. procedure TTestResolver.TestRecord_Default;
  8109. begin
  8110. StartProgram(false);
  8111. Add([
  8112. 'type',
  8113. ' TPoint = record x, y: longint; end;',
  8114. 'var',
  8115. ' i: longint;',
  8116. ' r: TPoint;',
  8117. 'begin',
  8118. ' i:=Default(longint);',
  8119. ' r:=Default(r);',
  8120. ' r:=Default(TPoint);',
  8121. '']);
  8122. ParseProgram;
  8123. end;
  8124. procedure TTestResolver.TestRecord_VarExternal;
  8125. begin
  8126. StartProgram(false);
  8127. Add([
  8128. '{$modeswitch externalclass}',
  8129. 'type',
  8130. ' TRec = record',
  8131. ' Id: longint external name ''$Id'';',
  8132. ' end;',
  8133. 'begin']);
  8134. ParseProgram;
  8135. end;
  8136. procedure TTestResolver.TestRecord_VarSelfFail;
  8137. begin
  8138. StartProgram(false);
  8139. Add([
  8140. 'type',
  8141. ' TRec = record',
  8142. ' r: Trec;',
  8143. ' end;',
  8144. 'begin']);
  8145. CheckResolverException('type "TRec" is not yet completely defined',nTypeXIsNotYetCompletelyDefined);
  8146. end;
  8147. procedure TTestResolver.TestAdvRecord;
  8148. begin
  8149. StartProgram(false);
  8150. Add([
  8151. '{$modeswitch advancedrecords}',
  8152. 'type',
  8153. ' TRec = record',
  8154. ' procedure DoIt;',
  8155. ' end;',
  8156. 'procedure TRec.DoIt;',
  8157. 'begin',
  8158. 'end;',
  8159. 'begin']);
  8160. ParseProgram;
  8161. end;
  8162. procedure TTestResolver.TestAdvRecord_Private;
  8163. begin
  8164. StartProgram(false);
  8165. Add([
  8166. '{$modeswitch advancedrecords}',
  8167. 'type',
  8168. ' TRec = record',
  8169. ' private',
  8170. ' a: byte;',
  8171. ' public',
  8172. ' b: byte;',
  8173. ' end;',
  8174. 'var',
  8175. ' r: TRec;',
  8176. 'begin',
  8177. ' r.a:=r.b;']);
  8178. ParseProgram;
  8179. end;
  8180. procedure TTestResolver.TestAdvRecord_StrictPrivate;
  8181. begin
  8182. StartProgram(false);
  8183. Add([
  8184. '{$modeswitch advancedrecords}',
  8185. 'type',
  8186. ' TRec = record',
  8187. ' strict private',
  8188. ' FSize: longword;',
  8189. ' function GetSize: longword;',
  8190. ' public',
  8191. ' property Size: longword read GetSize write FSize;',
  8192. ' end;',
  8193. 'function TRec.GetSize: longword;',
  8194. 'begin',
  8195. ' FSize:=GetSize;',
  8196. 'end;',
  8197. 'var',
  8198. ' r: TRec;',
  8199. 'begin',
  8200. ' r.Size:=r.Size;']);
  8201. ParseProgram;
  8202. end;
  8203. procedure TTestResolver.TestAdvRecord_StrictPrivateFail;
  8204. begin
  8205. StartProgram(false);
  8206. Add([
  8207. '{$modeswitch advancedrecords}',
  8208. 'type',
  8209. ' TRec = record',
  8210. ' strict private',
  8211. ' A: word;',
  8212. ' end;',
  8213. 'var',
  8214. ' r: TRec;',
  8215. 'begin',
  8216. ' r.a:=r.a;']);
  8217. CheckResolverException('Can''t access strict private member A',nCantAccessXMember);
  8218. end;
  8219. procedure TTestResolver.TestAdvRecord_MethodImplMissingFail;
  8220. begin
  8221. StartProgram(false);
  8222. Add([
  8223. '{$modeswitch advancedrecords}',
  8224. 'type',
  8225. ' TRec = record',
  8226. ' procedure SetSize(Value: word);',
  8227. ' end;',
  8228. 'begin',
  8229. '']);
  8230. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  8231. end;
  8232. procedure TTestResolver.TestAdvRecord_VarConst;
  8233. begin
  8234. StartProgram(false);
  8235. Add([
  8236. '{$modeswitch advancedrecords}',
  8237. 'type',
  8238. ' TRec = record',
  8239. ' type TInt = word;',
  8240. ' const',
  8241. ' C1 = 3;',
  8242. ' C2: TInt = 4;',
  8243. ' var',
  8244. ' V1: TInt;',
  8245. ' V2: TInt;',
  8246. ' class var',
  8247. ' VC: TInt;',
  8248. ' CA: array[1..C1] of TInt;',
  8249. ' procedure DoIt;',
  8250. ' end;',
  8251. 'procedure TRec.DoIt;',
  8252. 'begin',
  8253. ' C2:=Self.C2;',
  8254. ' V1:=VC;',
  8255. ' Self.V1:=Self.VC;',
  8256. ' VC:=V1;',
  8257. ' Self.VC:=Self.V1;',
  8258. 'end;',
  8259. 'var',
  8260. ' r: TRec;',
  8261. 'begin',
  8262. ' trec.C2:=trec.C2;',
  8263. ' r.V1:=r.VC;',
  8264. ' r.V1:=trec.VC;',
  8265. ' r.VC:=r.V1;',
  8266. ' trec.VC:=trec.c1;',
  8267. ' trec.ca[1]:=trec.c2;',
  8268. '']);
  8269. ParseProgram;
  8270. end;
  8271. procedure TTestResolver.TestAdvRecord_RecVal_ConstFail;
  8272. begin
  8273. StartProgram(false);
  8274. Add([
  8275. '{$modeswitch advancedrecords}',
  8276. 'type',
  8277. ' TRec = record',
  8278. ' V1: word;',
  8279. ' const',
  8280. ' C1 = 3;',
  8281. ' end;',
  8282. 'var',
  8283. ' r: TRec = (V1:2; C1: 4);',
  8284. 'begin',
  8285. '']);
  8286. CheckResolverException(sIdentifierXIsNotAnInstanceField,nIdentifierXIsNotAnInstanceField);
  8287. end;
  8288. procedure TTestResolver.TestAdvRecord_RecVal_ClassVarFail;
  8289. begin
  8290. StartProgram(false);
  8291. Add([
  8292. '{$modeswitch advancedrecords}',
  8293. 'type',
  8294. ' TRec = record',
  8295. ' V1: word;',
  8296. ' class var',
  8297. ' C1: word;',
  8298. ' end;',
  8299. 'var',
  8300. ' r: TRec = (V1:2; C1: 4);',
  8301. 'begin',
  8302. '']);
  8303. CheckResolverException(sIdentifierXIsNotAnInstanceField,nIdentifierXIsNotAnInstanceField);
  8304. end;
  8305. procedure TTestResolver.TestAdvRecord_LocalForwardType;
  8306. begin
  8307. StartProgram(false);
  8308. Add([
  8309. '{$modeswitch advancedrecords}',
  8310. 'type',
  8311. ' TRec = record',
  8312. ' type',
  8313. ' PInt = ^TInt;',
  8314. ' TInt = word;',
  8315. ' var i: PInt;',
  8316. ' end;',
  8317. 'var',
  8318. ' r: TRec;',
  8319. 'begin',
  8320. '']);
  8321. ParseProgram;
  8322. end;
  8323. procedure TTestResolver.TestAdvRecord_Constructor_NewInstance;
  8324. var
  8325. aMarker: PSrcMarker;
  8326. Elements: TFPList;
  8327. ActualNewInstance: Boolean;
  8328. i: Integer;
  8329. El: TPasElement;
  8330. Ref: TResolvedReference;
  8331. begin
  8332. StartProgram(false);
  8333. Add([
  8334. '{$modeswitch advancedrecords}',
  8335. 'type',
  8336. ' TRec = record',
  8337. ' constructor Create(w: word);',
  8338. ' class function DoSome: TRec; static;',
  8339. ' end;',
  8340. 'constructor TRec.Create(w: word);',
  8341. 'begin',
  8342. ' {#a}Create(1); // normal call',
  8343. ' TRec.{#b}Create(2); // new instance',
  8344. 'end;',
  8345. 'class function TRec.DoSome: TRec;',
  8346. 'begin',
  8347. ' Result:={#c}Create(3); // new instance',
  8348. 'end;',
  8349. 'var',
  8350. ' r: TRec;',
  8351. 'begin',
  8352. ' TRec.{#p}Create(4); // new object',
  8353. ' r:=TRec.{#q}Create(5); // new object',
  8354. ' with TRec do begin',
  8355. ' {#r}Create(6); // new object',
  8356. ' r:={#s}Create(7); // new object',
  8357. ' end;',
  8358. ' r.{#t}Create(8); // normal call',
  8359. ' r:=r.{#u}Create(9); // normal call',
  8360. ' with r do begin',
  8361. ' {#v}Create(10); // normal call',
  8362. ' r:={#w}Create(11); // normal call',
  8363. ' end;',
  8364. '']);
  8365. ParseProgram;
  8366. aMarker:=FirstSrcMarker;
  8367. while aMarker<>nil do
  8368. begin
  8369. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  8370. Elements:=FindElementsAt(aMarker);
  8371. try
  8372. ActualNewInstance:=false;
  8373. for i:=0 to Elements.Count-1 do
  8374. begin
  8375. El:=TPasElement(Elements[i]);
  8376. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  8377. if not (El.CustomData is TResolvedReference) then continue;
  8378. Ref:=TResolvedReference(El.CustomData);
  8379. if not (Ref.Declaration is TPasProcedure) then continue;
  8380. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  8381. if (Ref.Declaration is TPasConstructor) then
  8382. ActualNewInstance:=rrfNewInstance in Ref.Flags;
  8383. if rrfImplicitCallWithoutParams in Ref.Flags then
  8384. RaiseErrorAtSrcMarker('unexpected implicit call at "#'+aMarker^.Identifier+' ref"',aMarker);
  8385. break;
  8386. end;
  8387. case aMarker^.Identifier of
  8388. 'a','t','u','v','w':// should be normal call
  8389. if ActualNewInstance then
  8390. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got newinstance"',aMarker);
  8391. else // should be newinstance
  8392. if not ActualNewInstance then
  8393. RaiseErrorAtSrcMarker('expected newinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  8394. end;
  8395. finally
  8396. Elements.Free;
  8397. end;
  8398. aMarker:=aMarker^.Next;
  8399. end;
  8400. end;
  8401. procedure TTestResolver.TestAdvRecord_ConstructorNoParamsFail;
  8402. begin
  8403. StartProgram(false);
  8404. Add([
  8405. '{$modeswitch advancedrecords}',
  8406. 'type',
  8407. ' TRec = record',
  8408. ' constructor Create(w: word = 3);',
  8409. ' end;',
  8410. 'constructor TRec.Create(w: word);',
  8411. 'begin',
  8412. 'end;',
  8413. 'begin',
  8414. '']);
  8415. CheckResolverException(sParameterlessConstructorsNotAllowedInRecords,
  8416. nParameterlessConstructorsNotAllowedInRecords);
  8417. end;
  8418. procedure TTestResolver.TestAdvRecord_ClassConstructor;
  8419. begin
  8420. StartProgram(false);
  8421. Add([
  8422. '{$modeswitch advancedrecords}',
  8423. 'type',
  8424. ' TRec = record',
  8425. ' class var w: word;',
  8426. ' class procedure {#a}Create; static;',
  8427. ' class constructor Create;', // name clash is allowed!
  8428. ' end;',
  8429. 'class constructor TRec.Create;',
  8430. 'begin',
  8431. ' w:=w+1;',
  8432. 'end;',
  8433. 'class procedure TRec.Create; static;',
  8434. 'begin',
  8435. ' w:=w+1;',
  8436. 'end;',
  8437. 'begin',
  8438. ' TRec.{@a}Create;',
  8439. '']);
  8440. ParseProgram;
  8441. end;
  8442. procedure TTestResolver.TestAdvRecord_ClassConstructorParamsFail;
  8443. begin
  8444. StartProgram(false);
  8445. Add([
  8446. '{$modeswitch advancedrecords}',
  8447. 'type',
  8448. ' TRec = record',
  8449. ' class constructor Create(w: word);',
  8450. ' end;',
  8451. 'class constructor TRec.Create(w: word);',
  8452. 'begin',
  8453. 'end;',
  8454. 'begin',
  8455. '']);
  8456. CheckResolverException('class constructor cannot have parameters',nXCannotHaveParameters);
  8457. end;
  8458. procedure TTestResolver.TestAdvRecord_ClassConstructor_CallFail;
  8459. begin
  8460. StartProgram(false);
  8461. Add([
  8462. '{$modeswitch advancedrecords}',
  8463. 'type',
  8464. ' TRec = record',
  8465. ' class constructor Create;',
  8466. ' end;',
  8467. 'class constructor TRec.Create;',
  8468. 'begin',
  8469. 'end;',
  8470. 'begin',
  8471. ' TRec.Create;',
  8472. '']);
  8473. CheckResolverException('identifier not found "Create"',nIdentifierNotFound);
  8474. end;
  8475. procedure TTestResolver.TestAdvRecord_ClassConstructorDuplicateFail;
  8476. begin
  8477. StartProgram(false);
  8478. Add([
  8479. '{$modeswitch advancedrecords}',
  8480. 'type',
  8481. ' TRec = record',
  8482. ' class constructor Create;',
  8483. ' class constructor Init;',
  8484. ' end;',
  8485. 'class constructor TRec.Create;',
  8486. 'begin',
  8487. 'end;',
  8488. 'class constructor TRec.Init;',
  8489. 'begin',
  8490. 'end;',
  8491. 'begin',
  8492. '']);
  8493. CheckResolverException('Multiple class constructor in record TRec: Create and Init',
  8494. nMultipleXinTypeYNameZCAandB);
  8495. end;
  8496. procedure TTestResolver.TestAdvRecord_NestedRecordType;
  8497. begin
  8498. StartProgram(false);
  8499. Add([
  8500. '{$modeswitch advancedrecords}',
  8501. 'type',
  8502. ' TRec = record',
  8503. ' type',
  8504. ' TSub = record',
  8505. ' x: word;',
  8506. ' class var y: word;',
  8507. ' procedure DoSub;',
  8508. ' end;',
  8509. ' var',
  8510. ' Sub: TSub;',
  8511. ' procedure DoIt(const r: TRec);',
  8512. ' end;',
  8513. 'procedure TRec.TSub.DoSub;',
  8514. 'begin',
  8515. ' x:=3;',
  8516. 'end;',
  8517. 'procedure TRec.DoIt(const r: TRec);',
  8518. 'begin',
  8519. ' Sub.x:=4;',
  8520. ' r.Sub.y:=Sub.x;', // class var y is writable, even though r.Sub is not
  8521. 'end;',
  8522. 'var r: TRec;',
  8523. 'begin',
  8524. ' r.sub.x:=4;',
  8525. '']);
  8526. ParseProgram;
  8527. end;
  8528. procedure TTestResolver.TestAdvRecord_NestedArgConstFail;
  8529. begin
  8530. StartProgram(false);
  8531. Add([
  8532. '{$modeswitch advancedrecords}',
  8533. 'type',
  8534. ' TRec = record',
  8535. ' type',
  8536. ' TSub = record',
  8537. ' x: word;',
  8538. ' end;',
  8539. ' var',
  8540. ' Sub: TSub;',
  8541. ' procedure DoIt(const r: TRec);',
  8542. ' end;',
  8543. 'procedure TRec.DoIt(const r: TRec);',
  8544. 'begin',
  8545. ' r.Sub.x:=4;',
  8546. 'end;',
  8547. 'begin',
  8548. '']);
  8549. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  8550. end;
  8551. procedure TTestResolver.TestAdvRecord_Property;
  8552. begin
  8553. StartProgram(false);
  8554. Add([
  8555. '{$modeswitch advancedrecords}',
  8556. 'type',
  8557. ' TRec = record',
  8558. ' private',
  8559. ' FSize: word;',
  8560. ' function SizeStored: boolean;',
  8561. ' function GetWidth: word;',
  8562. ' procedure SetWidth(Value: word);',
  8563. ' public',
  8564. ' property Size: word read FSize write FSize stored SizeStored default 3;',
  8565. ' property Width: word read GetWidth write SetWidth;',
  8566. ' end;',
  8567. 'function TRec.SizeStored: boolean;',
  8568. 'begin',
  8569. 'end;',
  8570. 'function TRec.GetWidth: word;',
  8571. 'begin',
  8572. ' Result:=FSize;',
  8573. 'end;',
  8574. 'procedure TRec.SetWidth(Value: word);',
  8575. 'begin',
  8576. ' FSize:=Value;',
  8577. 'end;',
  8578. 'var r: TRec;',
  8579. 'begin',
  8580. ' r.Size:=r.Size;',
  8581. ' r.Width:=r.Width;',
  8582. '']);
  8583. ParseProgram;
  8584. end;
  8585. procedure TTestResolver.TestAdvRecord_ClassProperty;
  8586. begin
  8587. StartProgram(false);
  8588. Add([
  8589. '{$modeswitch advancedrecords}',
  8590. 'type',
  8591. ' TRec = record',
  8592. ' private',
  8593. ' class var FSize: word;',
  8594. ' class function GetWidth: word; static;',
  8595. ' class procedure SetWidth(Value: word); static;',
  8596. ' public',
  8597. ' class property Size: word read FSize write FSize;',
  8598. ' class property Width: word read GetWidth write SetWidth;',
  8599. ' end;',
  8600. 'class function TRec.GetWidth: word;',
  8601. 'begin',
  8602. ' Result:=FSize;',
  8603. 'end;',
  8604. 'class procedure TRec.SetWidth(Value: word);',
  8605. 'begin',
  8606. ' FSize:=Value;',
  8607. 'end;',
  8608. 'begin',
  8609. ' TRec.Size:=TRec.Size;',
  8610. ' TRec.Width:=TRec.Width;',
  8611. '']);
  8612. ParseProgram;
  8613. end;
  8614. procedure TTestResolver.TestAdvRecord_PropertyDefault;
  8615. begin
  8616. StartProgram(false);
  8617. Add([
  8618. '{$modeswitch advancedrecords}',
  8619. 'type',
  8620. ' TRec = record',
  8621. ' private',
  8622. ' function GetItems(Index: word): word;',
  8623. ' procedure SetItems(Index: word; Value: word);',
  8624. ' public',
  8625. ' property Items[Index: word]: word read GetItems write SetItems; default;',
  8626. ' end;',
  8627. ' TGlob = record',
  8628. ' private',
  8629. ' class function GetSizes(Index: word): word; static;',
  8630. ' class procedure SetSizes(Index: word; Value: word); static;',
  8631. ' public',
  8632. ' class property Sizes[Index: word]: word read GetSizes write SetSizes; default;',
  8633. ' end;',
  8634. 'function TRec.GetItems(Index: word): word;',
  8635. 'begin',
  8636. 'end;',
  8637. 'procedure TRec.SetItems(Index: word; Value: word);',
  8638. 'begin',
  8639. 'end;',
  8640. 'class function TGlob.GetSizes(Index: word): word;',
  8641. 'begin',
  8642. 'end;',
  8643. 'class procedure TGlob.SetSizes(Index: word; Value: word);',
  8644. 'begin',
  8645. 'end;',
  8646. 'var',
  8647. ' r: TRec;',
  8648. ' g: TGlob;',
  8649. 'begin',
  8650. ' r[1]:=r[2];',
  8651. ' TGlob[1]:=TGlob[2];',
  8652. '']);
  8653. ParseProgram;
  8654. end;
  8655. procedure TTestResolver.TestAdvRecord_RecordAsFuncResult;
  8656. begin
  8657. StartProgram(false);
  8658. Add([
  8659. '{$modeswitch advancedrecords}',
  8660. 'type',
  8661. ' {#A}TRec = record',
  8662. ' {#A_i}i: longint;',
  8663. ' class function {#A_CreateA}Create: TRec; static;',
  8664. ' class function {#A_CreateB}Create(i: longint): TRec; static;',
  8665. ' end;',
  8666. 'function {#F}F: TRec;',
  8667. 'begin',
  8668. ' Result:=default(TRec);',
  8669. 'end;',
  8670. 'class function TRec.Create: TRec;',
  8671. 'begin',
  8672. ' Result:=default(TRec);',
  8673. 'end;',
  8674. 'class function TRec.Create(i: longint): TRec;',
  8675. 'begin',
  8676. ' Result:=default(TRec);',
  8677. ' Result.i:=i;',
  8678. 'end;',
  8679. 'var',
  8680. ' {#v}{=A}v: TRec;',
  8681. 'begin',
  8682. ' {@v}v:={@F}F;',
  8683. ' {@v}v:={@F}F();',
  8684. ' if {@v}v={@F}F then ;',
  8685. ' if {@v}v={@F}F() then ;',
  8686. ' {@v}v:={@A}TRec.{@A_CreateA}Create;',
  8687. ' {@v}v:={@A}TRec.{@A_CreateA}Create();',
  8688. ' {@v}v:={@A}TRec.{@A_CreateB}Create(3);',
  8689. ' {@A}TRec.{@A_CreateA}Create . {@A_i}i:=4;',
  8690. ' {@A}TRec.{@A_CreateA}Create().{@A_i}i:=5;',
  8691. ' {@A}TRec.{@A_CreateB}Create(3).{@A_i}i:=6;']);
  8692. ParseProgram;
  8693. end;
  8694. procedure TTestResolver.TestAdvRecord_InheritedFail;
  8695. begin
  8696. StartProgram(false);
  8697. Add([
  8698. '{$modeswitch advancedrecords}',
  8699. 'type',
  8700. ' TRec = record',
  8701. ' procedure DoIt;',
  8702. ' end;',
  8703. 'procedure TRec.DoIt;',
  8704. 'begin',
  8705. ' inherited;',
  8706. 'end;',
  8707. 'begin',
  8708. '']);
  8709. CheckResolverException('The use of "inherited" is not allowed in a record',
  8710. nTheUseOfXisNotAllowedInARecord);
  8711. end;
  8712. procedure TTestResolver.TestAdvRecord_ForInEnumerator;
  8713. begin
  8714. StartProgram(false);
  8715. Add([
  8716. '{$modeswitch advancedrecords}',
  8717. 'type',
  8718. ' TObject = class end;',
  8719. ' TItem = TObject;',
  8720. ' TEnumerator = class',
  8721. ' FCurrent: TItem;',
  8722. ' property Current: TItem read FCurrent;',
  8723. ' function MoveNext: boolean;',
  8724. ' end;',
  8725. ' TBird = record',
  8726. ' function GetEnumerator: TEnumerator;',
  8727. ' end;',
  8728. 'function TEnumerator.MoveNext: boolean;',
  8729. 'begin',
  8730. 'end;',
  8731. 'function TBird.GetEnumerator: TEnumerator;',
  8732. 'begin',
  8733. 'end;',
  8734. 'var',
  8735. ' b: TBird;',
  8736. ' i: TItem;',
  8737. ' {#i2}i2: TItem;',
  8738. 'begin',
  8739. ' for i in b do {@i2}i2:=i;']);
  8740. ParseProgram;
  8741. end;
  8742. procedure TTestResolver.TestAdvRecord_InFunctionFail;
  8743. begin
  8744. StartProgram(false);
  8745. Add([
  8746. '{$modeswitch advancedrecords}',
  8747. 'procedure DoIt;',
  8748. 'type',
  8749. ' TBird = record',
  8750. ' class var i: word;',
  8751. ' end;',
  8752. 'var',
  8753. ' b: TBird;',
  8754. 'begin',
  8755. 'end;',
  8756. 'begin']);
  8757. CheckParserException(sErrRecordVariablesNotAllowed,nErrRecordVariablesNotAllowed);
  8758. end;
  8759. procedure TTestResolver.TestAdvRecord_SubClass;
  8760. begin
  8761. StartProgram(false);
  8762. Add([
  8763. '{$modeswitch AdvancedRecords}',
  8764. 'type',
  8765. ' TObject = class end;',
  8766. ' TPoint = record',
  8767. ' type',
  8768. ' TBird = class',
  8769. ' procedure DoIt;',
  8770. ' class procedure Glob;',
  8771. ' end;',
  8772. ' procedure DoIt(b: TBird);',
  8773. ' end;',
  8774. 'procedure TPoint.TBird.DoIt;',
  8775. 'begin',
  8776. 'end;',
  8777. 'class procedure TPoint.TBird.Glob;',
  8778. 'begin',
  8779. 'end;',
  8780. 'procedure TPoint.DoIt(b: TBird);',
  8781. 'begin',
  8782. 'end;',
  8783. 'begin',
  8784. '']);
  8785. ParseProgram;
  8786. end;
  8787. procedure TTestResolver.TestRecordAnonym_ResultTypeFail;
  8788. begin
  8789. StartProgram(false);
  8790. Add([
  8791. 'function Fly: record',
  8792. ' x: word;',
  8793. ' end;',
  8794. 'begin',
  8795. 'end;',
  8796. 'begin',
  8797. '']);
  8798. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  8799. end;
  8800. procedure TTestResolver.TestRecordAnonym_ArgumentFail;
  8801. begin
  8802. StartProgram(false);
  8803. Add([
  8804. 'procedure Fly(const r: record',
  8805. ' x: word;',
  8806. ' end);',
  8807. 'begin',
  8808. 'end;',
  8809. 'begin',
  8810. '']);
  8811. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  8812. end;
  8813. procedure TTestResolver.TestRecordAnonym_Advanced_ConstFail;
  8814. begin
  8815. StartProgram(false);
  8816. Add([
  8817. '{$modeswitch AdvancedRecords}',
  8818. 'var',
  8819. ' r: record',
  8820. ' const c = 3;',
  8821. ' var x: word;',
  8822. ' end;',
  8823. 'begin',
  8824. '']);
  8825. CheckParserException(SErrRecordConstantsNotAllowed,nErrRecordConstantsNotAllowed);
  8826. end;
  8827. procedure TTestResolver.TestRecordAnonym_Advanced_MethodFail;
  8828. begin
  8829. StartProgram(false);
  8830. Add([
  8831. '{$modeswitch AdvancedRecords}',
  8832. 'var',
  8833. ' r: record',
  8834. ' procedure Fly;',
  8835. ' end;',
  8836. 'begin',
  8837. '']);
  8838. CheckParserException(SErrRecordMethodsNotAllowed,nErrRecordMethodsNotAllowed);
  8839. end;
  8840. procedure TTestResolver.TestRecordAnonym_Advanced_TypeFail;
  8841. begin
  8842. StartProgram(false);
  8843. Add([
  8844. '{$modeswitch AdvancedRecords}',
  8845. 'var',
  8846. ' r: record',
  8847. ' type TFlag = word;',
  8848. ' end;',
  8849. 'begin',
  8850. '']);
  8851. CheckParserException(SErrRecordTypesNotAllowed,nErrRecordTypesNotAllowed);
  8852. end;
  8853. procedure TTestResolver.TestRecordAnonym_Advanced_PropertyFail;
  8854. begin
  8855. StartProgram(false);
  8856. Add([
  8857. '{$modeswitch AdvancedRecords}',
  8858. 'var',
  8859. ' r: record',
  8860. ' FSize: word;',
  8861. ' property Size: word read FSize;',
  8862. ' end;',
  8863. 'begin',
  8864. '']);
  8865. CheckParserException(SErrRecordPropertiesNotAllowed,nErrRecordPropertiesNotAllowed);
  8866. end;
  8867. procedure TTestResolver.TestRecordAnonym_Var;
  8868. begin
  8869. StartProgram(false);
  8870. Add([
  8871. 'var',
  8872. ' r: record',
  8873. ' x: word;',
  8874. ' end;',
  8875. 'begin',
  8876. ' r.x:=3;',
  8877. ' r.x:=r.x + 4;',
  8878. '']);
  8879. ParseProgram;
  8880. end;
  8881. procedure TTestResolver.TestRecordAnonym_Nested;
  8882. begin
  8883. StartProgram(false);
  8884. Add([
  8885. 'var',
  8886. ' r: record',
  8887. ' p: record',
  8888. ' x: word;',
  8889. ' end;',
  8890. ' end;',
  8891. 'begin',
  8892. ' r.p.x:=3;',
  8893. ' r.p.x:=r.p.x + 4;',
  8894. '']);
  8895. ParseProgram;
  8896. end;
  8897. procedure TTestResolver.TestRecordAnonym_Advanced_Visibility;
  8898. begin
  8899. StartProgram(false);
  8900. Add([
  8901. '{$modeswitch AdvancedRecords}',
  8902. 'var',
  8903. ' r: record',
  8904. ' private',
  8905. ' Size: word;',
  8906. ' public',
  8907. ' Color: word;',
  8908. ' end;',
  8909. 'begin',
  8910. ' r.Size:=3;',
  8911. ' r.Size:=r.Size+4;',
  8912. ' r.Color:=r.Color+5;',
  8913. '']);
  8914. ParseProgram;
  8915. end;
  8916. procedure TTestResolver.TestClass;
  8917. begin
  8918. StartProgram(false);
  8919. Add('type');
  8920. Add(' {#TOBJ}TObject = class');
  8921. Add(' {#B}b: longint;');
  8922. Add(' end;');
  8923. Add('var');
  8924. Add(' {#C}{=TOBJ}c: TObject;');
  8925. Add('begin');
  8926. Add(' {@C}c.{@b}b:=3;');
  8927. ParseProgram;
  8928. end;
  8929. procedure TTestResolver.TestClassDefaultInheritance;
  8930. begin
  8931. StartProgram(false);
  8932. Add('type');
  8933. Add(' {#TOBJ}TObject = class');
  8934. Add(' {#OBJ_b}b: longint;');
  8935. Add(' end;');
  8936. Add(' {#A}TClassA = class');
  8937. Add(' {#A_c}c: longint;');
  8938. Add(' end;');
  8939. Add('var');
  8940. Add(' {#V}{=A}v: TClassA;');
  8941. Add('begin');
  8942. Add(' {@V}v.{@A_c}c:=2;');
  8943. Add(' {@V}v.{@OBJ_b}b:=3;');
  8944. ParseProgram;
  8945. end;
  8946. procedure TTestResolver.TestClassTripleInheritance;
  8947. begin
  8948. StartProgram(false);
  8949. Add('type');
  8950. Add(' {#TOBJ}TObject = class');
  8951. Add(' {#OBJ_a}a: longint;');
  8952. Add(' {#OBJ_b}b: longint;');
  8953. Add(' end;');
  8954. Add(' {#A}TClassA = class');
  8955. Add(' {#A_c}c: longint;');
  8956. Add(' end;');
  8957. Add(' {#B}TClassB = class(TClassA)');
  8958. Add(' {#B_d}d: longint;');
  8959. Add(' end;');
  8960. Add('var');
  8961. Add(' {#V}{=B}v: TClassB;');
  8962. Add('begin');
  8963. Add(' {@V}v.{@B_d}d:=1;');
  8964. Add(' {@V}v.{@A_c}c:=2;');
  8965. Add(' {@V}v.{@OBJ_B}b:=3;');
  8966. Add(' {@V}v.{@Obj_a}a:=4;');
  8967. ParseProgram;
  8968. end;
  8969. procedure TTestResolver.TestClassInheritanceCycleFail;
  8970. begin
  8971. StartProgram(false);
  8972. Add([
  8973. 'type A = class(A)',
  8974. 'begin']);
  8975. CheckResolverException(sAncestorCycleDetected,nAncestorCycleDetected);
  8976. end;
  8977. procedure TTestResolver.TestClassDefaultVisibility;
  8978. var
  8979. Elements: TFPList;
  8980. El: TPasElement;
  8981. aMarker: PSrcMarker;
  8982. i: Integer;
  8983. begin
  8984. StartProgram(false);
  8985. Add([
  8986. 'type',
  8987. ' TObject = class',
  8988. ' {#B}b: longint;',
  8989. ' end;',
  8990. ' {$M+}',
  8991. ' TPersistent = class',
  8992. ' {#C}c: longint;',
  8993. ' end;',
  8994. ' {$M-}',
  8995. ' TPic = class',
  8996. ' {#D}d: longint;',
  8997. ' end;',
  8998. ' TComponent = class(TPersistent)',
  8999. ' {#E}e: longint;',
  9000. ' end;',
  9001. ' TControl = class(TComponent)',
  9002. ' {#F}f: longint;',
  9003. ' end;',
  9004. 'begin']);
  9005. ParseProgram;
  9006. aMarker:=FirstSrcMarker;
  9007. while aMarker<>nil do
  9008. begin
  9009. //writeln('TTestResolver.TestClassDefaultVisibility',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  9010. Elements:=FindElementsAt(aMarker);
  9011. try
  9012. for i:=0 to Elements.Count-1 do
  9013. begin
  9014. El:=TPasElement(Elements[i]);
  9015. //writeln('TTestResolver.TestClassDefaultVisibility ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  9016. if not (El is TPasVariable) then continue;
  9017. case aMarker^.Identifier of
  9018. 'B','D':
  9019. if El.Visibility<>visPublic then
  9020. RaiseErrorAtSrcMarker('expected visPublic at #'+aMarker^.Identifier+', but got '+VisibilityNames[El.Visibility],aMarker);
  9021. else
  9022. if El.Visibility<>visPublished then
  9023. RaiseErrorAtSrcMarker('expected visPublished at #'+aMarker^.Identifier+', but got '+VisibilityNames[El.Visibility],aMarker);
  9024. end;
  9025. break;
  9026. end;
  9027. finally
  9028. Elements.Free;
  9029. end;
  9030. aMarker:=aMarker^.Next;
  9031. end;
  9032. end;
  9033. procedure TTestResolver.TestClassForward;
  9034. begin
  9035. StartProgram(false);
  9036. Add('type');
  9037. Add(' TObject = class');
  9038. Add(' end;');
  9039. Add(' {#B_forward}TClassB = class;');
  9040. Add(' {#A}TClassA = class');
  9041. Add(' {#A_b}{=B_forward}b: TClassB;');
  9042. Add(' end;');
  9043. Add(' {#B}TClassB = class(TClassA)');
  9044. Add(' {#B_a}a: longint;');
  9045. Add(' {#B_d}d: longint;');
  9046. Add(' end;');
  9047. Add('var');
  9048. Add(' {#V}{=B}v: TClassB;');
  9049. Add('begin');
  9050. Add(' {@V}v.{@B_d}d:=1;');
  9051. Add(' {@V}v.{@B_a}a:=2;');
  9052. Add(' {@V}v.{@A_b}b:=nil;');
  9053. Add(' {@V}v.{@A_b}b.{@B_a}a:=3;');
  9054. ParseProgram;
  9055. end;
  9056. procedure TTestResolver.TestClassForwardAsAncestorFail;
  9057. begin
  9058. StartProgram(false);
  9059. Add('type');
  9060. Add(' TObject = class;');
  9061. Add(' TBird = class end;');
  9062. Add(' TObject = class');
  9063. Add(' end;');
  9064. Add('var');
  9065. Add(' v: TBird;');
  9066. Add('begin');
  9067. CheckResolverException('Can''t use forward declaration "TObject" as ancestor',
  9068. nCantUseForwardDeclarationAsAncestor);
  9069. end;
  9070. procedure TTestResolver.TestClassForwardNotResolved;
  9071. begin
  9072. StartProgram(false);
  9073. Add('type');
  9074. Add(' TObject = class');
  9075. Add(' end;');
  9076. Add(' TClassB = class;');
  9077. Add('var');
  9078. Add(' v: TClassB;');
  9079. Add('begin');
  9080. CheckResolverException(sForwardTypeNotResolved,
  9081. nForwardTypeNotResolved);
  9082. end;
  9083. procedure TTestResolver.TestClassForwardDuplicateFail;
  9084. begin
  9085. StartProgram(false);
  9086. Add([
  9087. 'type',
  9088. ' TObject = class;',
  9089. ' TObject = class;',
  9090. ' TObject = class',
  9091. ' end;',
  9092. 'begin']);
  9093. CheckResolverException('Duplicate identifier "TObject" at afile.pp(3,10)',nDuplicateIdentifier);
  9094. end;
  9095. procedure TTestResolver.TestClassForwardDelphiFail;
  9096. begin
  9097. StartProgram(false);
  9098. Add([
  9099. '{$mode delphi}',
  9100. 'type',
  9101. ' TObject = class end;',
  9102. ' TBird = class;',
  9103. 'const k = 1;',
  9104. 'type',
  9105. ' TBird = class',
  9106. ' end;',
  9107. 'begin']);
  9108. CheckResolverException('Forward type not resolved "TBird"',nForwardTypeNotResolved);
  9109. end;
  9110. procedure TTestResolver.TestClassForwardObjFPCProgram;
  9111. begin
  9112. StartProgram(false);
  9113. Add([
  9114. '{$mode objfpc}',
  9115. 'type',
  9116. ' TObject = class end;',
  9117. ' TBird = class;',
  9118. 'const k = 1;',
  9119. 'type',
  9120. ' TBird = class',
  9121. ' end;',
  9122. 'begin']);
  9123. ParseProgram;
  9124. end;
  9125. procedure TTestResolver.TestClassForwardObjFPCUnit;
  9126. begin
  9127. StartUnit(false);
  9128. Add([
  9129. '{$mode objfpc}',
  9130. 'interface',
  9131. 'type',
  9132. ' TObject = class end;',
  9133. ' TBird = class;',
  9134. 'const k = 1;',
  9135. 'type',
  9136. ' TBird = class',
  9137. ' end;',
  9138. 'implementation',
  9139. 'type',
  9140. ' TEagle = class;',
  9141. 'const c = 1;',
  9142. 'type',
  9143. ' TEagle = class',
  9144. ' end;',
  9145. '']);
  9146. ParseUnit;
  9147. end;
  9148. procedure TTestResolver.TestClassForwardNestedTypeFail;
  9149. begin
  9150. StartProgram(false);
  9151. Add([
  9152. 'type',
  9153. ' TObject = class',
  9154. ' end;',
  9155. ' TBird = class;',
  9156. ' TProc = procedure(a: TBird.TEnum);',
  9157. ' TBird = class',
  9158. ' type TEnum = (red,blue);',
  9159. ' end;',
  9160. 'begin',
  9161. '']);
  9162. CheckResolverException('identifier not found "TEnum"',nIdentifierNotFound);
  9163. end;
  9164. procedure TTestResolver.TestClass_Method;
  9165. begin
  9166. StartProgram(false);
  9167. Add('type');
  9168. Add(' TObject = class');
  9169. Add(' end;');
  9170. Add(' {#A}TClassA = class');
  9171. Add(' procedure {#A_ProcA_Decl}ProcA;');
  9172. Add(' end;');
  9173. Add('procedure TClassA.ProcA;');
  9174. Add('begin');
  9175. Add('end;');
  9176. Add('var');
  9177. Add(' {#V}{=A}v: TClassA;');
  9178. Add('begin');
  9179. Add(' {@V}v.{@A_ProcA_Decl}ProcA;');
  9180. ParseProgram;
  9181. end;
  9182. procedure TTestResolver.TestClass_ConstructorMissingDotFail;
  9183. begin
  9184. StartProgram(false);
  9185. Add([
  9186. 'type',
  9187. ' TObject = class',
  9188. ' constructor Create;',
  9189. ' end;',
  9190. 'constructor Create; begin end;',
  9191. 'begin',
  9192. '']);
  9193. CheckResolverException('full method name expected, but short name found',
  9194. nXExpectedButYFound);
  9195. end;
  9196. procedure TTestResolver.TestClass_MethodImplDuplicateFail;
  9197. begin
  9198. StartProgram(false);
  9199. Add([
  9200. 'type',
  9201. ' TObject = class',
  9202. ' procedure DoIt;',
  9203. ' end;',
  9204. 'procedure TObject.DoIt; begin end;',
  9205. 'procedure TObject.DoIt; begin end;',
  9206. 'begin',
  9207. '']);
  9208. CheckResolverException('Duplicate identifier "TObject.DoIt" at afile.pp(6,23) at afile.pp (7,23)',
  9209. nDuplicateIdentifier);
  9210. end;
  9211. procedure TTestResolver.TestClass_MethodWithoutClassFail;
  9212. begin
  9213. StartProgram(false);
  9214. Add('type');
  9215. Add(' TObject = class');
  9216. Add(' end;');
  9217. Add('procedure TClassA.ProcA;');
  9218. Add('begin');
  9219. Add('end;');
  9220. Add('begin');
  9221. CheckResolverException('class "TClassA" not found in this module',nClassXNotFoundInThisModule);
  9222. end;
  9223. procedure TTestResolver.TestClass_MethodInOtherUnitFail;
  9224. begin
  9225. AddModuleWithIntfImplSrc('unit1.pas',
  9226. LinesToStr([
  9227. 'type',
  9228. ' TObject = class',
  9229. ' public',
  9230. ' end;',
  9231. '']),
  9232. '');
  9233. StartProgram(true);
  9234. Add([
  9235. 'uses unit1;',
  9236. 'procedure TObject.DoIt;',
  9237. 'begin',
  9238. 'end;',
  9239. 'begin']);
  9240. CheckResolverException('class "TObject" not found in this module',
  9241. nClassXNotFoundInThisModule);
  9242. end;
  9243. procedure TTestResolver.TestClass_MethodWithParams;
  9244. begin
  9245. StartProgram(false);
  9246. Add('type');
  9247. Add(' {#A}TObject = class');
  9248. Add(' procedure {#ProcA_Decl}ProcA({#Bar}Bar: longint);');
  9249. Add(' end;');
  9250. Add('procedure tobject.proca(bar: longint);');
  9251. Add('begin');
  9252. Add(' if {@Bar}bar=3 then ;');
  9253. Add('end;');
  9254. Add('var');
  9255. Add(' {#V}{=A}Obj: TObject;');
  9256. Add('begin');
  9257. Add(' {@V}Obj.{@ProcA_Decl}ProcA(4);');
  9258. ParseProgram;
  9259. end;
  9260. procedure TTestResolver.TestClass_MethodUnresolvedPrg;
  9261. begin
  9262. StartProgram(false);
  9263. Add('type');
  9264. Add(' TObject = class');
  9265. Add(' end;');
  9266. Add(' TClassA = class');
  9267. Add(' procedure ProcA;');
  9268. Add(' end;');
  9269. Add('begin');
  9270. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  9271. end;
  9272. procedure TTestResolver.TestClass_MethodUnresolvedUnit;
  9273. begin
  9274. StartUnit(false);
  9275. Add('interface');
  9276. Add('type');
  9277. Add(' TObject = class');
  9278. Add(' end;');
  9279. Add(' TClassA = class');
  9280. Add(' procedure ProcA;');
  9281. Add(' end;');
  9282. Add('implementation');
  9283. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  9284. end;
  9285. procedure TTestResolver.TestClass_MethodAbstract;
  9286. begin
  9287. StartProgram(false);
  9288. Add('type');
  9289. Add(' TObject = class');
  9290. Add(' procedure ProcA; virtual; abstract;');
  9291. Add(' end;');
  9292. Add('begin');
  9293. ParseProgram;
  9294. end;
  9295. procedure TTestResolver.TestClass_MethodAbstractWithoutVirtualFail;
  9296. begin
  9297. StartProgram(false);
  9298. Add('type');
  9299. Add(' TObject = class');
  9300. Add(' procedure ProcA; abstract;');
  9301. Add(' end;');
  9302. Add('begin');
  9303. CheckResolverException('Invalid procedure modifier abstract without virtual',nInvalidXModifierY);
  9304. end;
  9305. procedure TTestResolver.TestClass_MethodAbstractHasBodyFail;
  9306. begin
  9307. StartProgram(false);
  9308. Add('type');
  9309. Add(' TObject = class');
  9310. Add(' procedure ProcA; virtual; abstract;');
  9311. Add(' end;');
  9312. Add('procedure TObject.ProcA;');
  9313. Add('begin');
  9314. Add('end;');
  9315. Add('begin');
  9316. CheckResolverException(sAbstractMethodsMustNotHaveImplementation,
  9317. nAbstractMethodsMustNotHaveImplementation);
  9318. end;
  9319. procedure TTestResolver.TestClass_MethodUnresolvedWithAncestor;
  9320. begin
  9321. StartProgram(false);
  9322. Add('type');
  9323. Add(' TObject = class');
  9324. Add(' procedure ProcA; virtual; abstract;');
  9325. Add(' end;');
  9326. Add(' TClassA = class');
  9327. Add(' procedure ProcA;');
  9328. Add(' end;');
  9329. Add('begin');
  9330. CheckResolverException(sForwardProcNotResolved,nForwardProcNotResolved);
  9331. end;
  9332. procedure TTestResolver.TestClass_ProcFuncMismatch;
  9333. begin
  9334. StartProgram(false);
  9335. Add('type');
  9336. Add(' TObject = class');
  9337. Add(' procedure DoIt;');
  9338. Add(' end;');
  9339. Add('function TObject.DoIt: longint;');
  9340. Add('begin');
  9341. Add('end;');
  9342. Add('begin');
  9343. CheckResolverException('procedure expected, but function found',
  9344. nXExpectedButYFound);
  9345. end;
  9346. procedure TTestResolver.TestClass_MethodOverload;
  9347. begin
  9348. StartProgram(false);
  9349. Add('type');
  9350. Add(' TObject = class');
  9351. Add(' procedure DoIt;');
  9352. Add(' procedure DoIt(i: longint);');
  9353. Add(' procedure DoIt(s: string);');
  9354. Add(' end;');
  9355. Add('procedure TObject.DoIt;');
  9356. Add('begin');
  9357. Add('end;');
  9358. Add('procedure TObject.DoIt(i: longint);');
  9359. Add('begin');
  9360. Add('end;');
  9361. Add('procedure TObject.DoIt(s: string);');
  9362. Add('begin');
  9363. Add('end;');
  9364. Add('begin');
  9365. ParseProgram;
  9366. end;
  9367. procedure TTestResolver.TestClass_MethodInvalidOverload;
  9368. begin
  9369. StartProgram(false);
  9370. Add('type');
  9371. Add(' TObject = class');
  9372. Add(' procedure DoIt(i: longint);');
  9373. Add(' procedure DoIt(k: longint);');
  9374. Add(' end;');
  9375. Add('procedure TObject.DoIt(i: longint);');
  9376. Add('begin');
  9377. Add('end;');
  9378. Add('procedure TObject.DoIt(k: longint);');
  9379. Add('begin');
  9380. Add('end;');
  9381. Add('begin');
  9382. CheckResolverException(sDuplicateIdentifier,nDuplicateIdentifier);
  9383. end;
  9384. procedure TTestResolver.TestClass_MethodOverride;
  9385. begin
  9386. StartProgram(false);
  9387. Add('type');
  9388. Add(' TObject = class');
  9389. Add(' procedure {#TOBJ_ProcA}ProcA; virtual; abstract;');
  9390. Add(' end;');
  9391. Add(' {#A}TClassA = class');
  9392. Add(' procedure {#A_ProcA}ProcA; override;');
  9393. Add(' end;');
  9394. Add('procedure TClassA.ProcA;');
  9395. Add('begin');
  9396. Add('end;');
  9397. Add('var');
  9398. Add(' {#V}{=A}v: TClassA;');
  9399. Add('begin');
  9400. Add(' {@V}v.{@A_ProcA}ProcA;');
  9401. ParseProgram;
  9402. end;
  9403. procedure TTestResolver.TestClass_MethodOverride2;
  9404. begin
  9405. StartProgram(false);
  9406. Add('type');
  9407. Add(' TObject = class');
  9408. Add(' procedure {#TOBJ_ProcA}ProcA; virtual; abstract;');
  9409. Add(' end;');
  9410. Add(' {#A}TClassA = class');
  9411. Add(' procedure {#A_ProcA}ProcA; override;');
  9412. Add(' end;');
  9413. Add(' {#B}TClassB = class');
  9414. Add(' procedure {#B_ProcA}ProcA; override;');
  9415. Add(' end;');
  9416. Add('procedure TClassA.ProcA;');
  9417. Add('begin');
  9418. Add('end;');
  9419. Add('procedure TClassB.ProcA;');
  9420. Add('begin');
  9421. Add('end;');
  9422. Add('var');
  9423. Add(' {#V}{=B}v: TClassB;');
  9424. Add('begin');
  9425. Add(' {@V}v.{@B_ProcA}ProcA;');
  9426. ParseProgram;
  9427. end;
  9428. procedure TTestResolver.TestClass_MethodOverrideAndOverload;
  9429. begin
  9430. StartProgram(false);
  9431. Add([
  9432. '{$mode delphi}',
  9433. 'type',
  9434. ' TObject = class',
  9435. ' public',
  9436. ' procedure Fly(b: boolean); virtual; abstract; overload;',
  9437. ' procedure Fly(c: word); virtual; abstract; overload;',
  9438. ' end;',
  9439. ' TBird = class(TObject)',
  9440. ' public',
  9441. ' procedure Fly(b: boolean); override;',
  9442. ' procedure Fly(c: word); override;',
  9443. ' procedure Fly(s: string); overload;',
  9444. ' end;',
  9445. 'procedure TBird.Fly(b: boolean);',
  9446. 'begin end;',
  9447. 'procedure TBird.Fly(c: word);',
  9448. 'begin end;',
  9449. 'procedure TBird.Fly(s: string);',
  9450. 'begin end;',
  9451. 'var',
  9452. ' b: TBird;',
  9453. 'begin',
  9454. ' b.Fly(true);',
  9455. ' b.Fly(1);',
  9456. 'end.',
  9457. '']);
  9458. ParseProgram;
  9459. end;
  9460. procedure TTestResolver.TestClass_MethodOverrideTwiceAndOverload;
  9461. begin
  9462. StartProgram(false);
  9463. Add([
  9464. '{$mode delphi}',
  9465. 'type',
  9466. ' TObject = class end;',
  9467. ' TAnimal = class',
  9468. ' procedure {#a}Fly(AValue: TAnimal); overload; virtual;',
  9469. ' end;',
  9470. ' TBird = class(TAnimal)',
  9471. ' procedure {#b}Fly(w: word); overload; virtual;',
  9472. ' procedure {#c}Fly(AValue: TAnimal); overload; override;',
  9473. ' end;',
  9474. ' TEagle = class(TBird)',
  9475. ' procedure {#d}Fly(b: boolean); overload; virtual;',
  9476. ' procedure {#e}Fly(AValue: TAnimal); overload; override;',
  9477. ' end;',
  9478. 'procedure TAnimal.Fly(AValue: TAnimal);',
  9479. 'begin',
  9480. 'end;',
  9481. 'procedure TBird.Fly(w: word);',
  9482. 'begin',
  9483. 'end;',
  9484. 'procedure TBird.Fly(AValue: TAnimal);',
  9485. 'begin',
  9486. ' {@c}Fly(Self);',
  9487. ' {@b}Fly(3);',
  9488. ' inherited {@a}Fly(Self);',
  9489. 'end;',
  9490. 'procedure TEagle.Fly(b: boolean);',
  9491. 'begin',
  9492. 'end;',
  9493. 'procedure TEagle.Fly(AValue: TAnimal);',
  9494. 'begin',
  9495. ' {@e}Fly(Self);',
  9496. ' {@b}Fly(13);',
  9497. ' {@d}Fly(true);',
  9498. ' inherited {@c}Fly(Self);',
  9499. ' inherited {@b}Fly(17);',
  9500. 'end;',
  9501. 'var',
  9502. ' e: TEagle;',
  9503. 'begin',
  9504. ' e.{@e}Fly(e);',
  9505. ' e.{@b}Fly(25);',
  9506. ' e.{@d}Fly(true);',
  9507. '']);
  9508. ParseProgram;
  9509. end;
  9510. procedure TTestResolver.TestClass_MethodOverrideFixCase;
  9511. procedure CheckOverrideName(aLabel: string);
  9512. var
  9513. Elements: TFPList;
  9514. i: Integer;
  9515. El: TPasElement;
  9516. Scope: TPasProcedureScope;
  9517. begin
  9518. Elements:=FindElementsAtSrcLabel(aLabel);
  9519. try
  9520. for i:=0 to Elements.Count-1 do
  9521. begin
  9522. El:=TPasElement(Elements[i]);
  9523. if not (El is TPasProcedure) then continue;
  9524. Scope:=El.CustomData as TPasProcedureScope;
  9525. if Scope.OverriddenProc=nil then
  9526. Fail('Scope.OverriddenProc=nil');
  9527. AssertEquals('Proc Name and Proc.Scope.OverriddenProc.Name',El.Name,Scope.OverriddenProc.Name);
  9528. end;
  9529. finally
  9530. Elements.Free;
  9531. end;
  9532. end;
  9533. begin
  9534. ResolverEngine.Options:=ResolverEngine.Options+[proFixCaseOfOverrides];
  9535. StartProgram(false);
  9536. Add('type');
  9537. Add(' TObject = class');
  9538. Add(' procedure {#TOBJ_ProcA}ProcA; virtual; abstract;');
  9539. Add(' end;');
  9540. Add(' {#A}TClassA = class');
  9541. Add(' procedure {#A_ProcA}proca; override;');
  9542. Add(' end;');
  9543. Add(' {#B}TClassB = class');
  9544. Add(' procedure {#B_ProcA}prOca; override;');
  9545. Add(' end;');
  9546. Add('procedure tclassa.proca;');
  9547. Add('begin');
  9548. Add('end;');
  9549. Add('procedure tclassb.proca;');
  9550. Add('begin');
  9551. Add('end;');
  9552. Add('var');
  9553. Add(' {#V}{=B}v: TClassB;');
  9554. Add('begin');
  9555. Add(' {@V}v.{@B_ProcA}ProcA;');
  9556. ParseProgram;
  9557. CheckOverrideName('A_ProcA');
  9558. CheckOverrideName('B_ProcA');
  9559. end;
  9560. procedure TTestResolver.TestClass_MethodOverrideSameResultType;
  9561. begin
  9562. AddModuleWithIntfImplSrc('unit2.pp',
  9563. LinesToStr([
  9564. 'type',
  9565. ' TObject = class',
  9566. ' public',
  9567. ' function ProcA(const s: string): string; virtual; abstract;',
  9568. ' end;',
  9569. '']),
  9570. LinesToStr([
  9571. ''])
  9572. );
  9573. StartProgram(true);
  9574. Add('uses unit2;');
  9575. Add('type');
  9576. Add(' TCar = class');
  9577. Add(' public');
  9578. Add(' function ProcA(const s: string): string; override;');
  9579. Add(' end;');
  9580. Add('function TCar.ProcA(const s: string): string; begin end;');
  9581. Add('begin');
  9582. ParseProgram;
  9583. end;
  9584. procedure TTestResolver.TestClass_MethodOverrideDiffResultTypeFail;
  9585. begin
  9586. StartProgram(false);
  9587. Add('type');
  9588. Add(' TObject = class');
  9589. Add(' public');
  9590. Add(' function ProcA(const s: string): string; virtual; abstract;');
  9591. Add(' end;');
  9592. Add(' TCar = class');
  9593. Add(' public');
  9594. Add(' function ProcA(const s: string): longint; override;');
  9595. Add(' end;');
  9596. Add('function TCar.ProcA(const s: string): longint; begin end;');
  9597. Add('begin');
  9598. CheckResolverException('Result type mismatch, expected String, but found Longint',
  9599. nResultTypeMismatchExpectedButFound);
  9600. end;
  9601. procedure TTestResolver.TestClass_MethodOverrideDiffVarName;
  9602. begin
  9603. StartProgram(false);
  9604. Add([
  9605. 'type',
  9606. ' TObject = class',
  9607. ' procedure DoIt(aName: string); virtual; abstract;',
  9608. ' end;',
  9609. ' TCar = class',
  9610. ' procedure DoIt(aCaption: string); override;',
  9611. ' end;',
  9612. 'procedure TCar.DoIt(aCaption: string); begin end;',
  9613. 'begin'
  9614. ]);
  9615. ParseProgram;
  9616. end;
  9617. procedure TTestResolver.TestClass_MethodOverloadMissingInDelphi;
  9618. begin
  9619. StartProgram(false);
  9620. Add([
  9621. '{$mode delphi}',
  9622. 'type',
  9623. ' TObject = class',
  9624. ' procedure DoIt(i: longint); virtual; abstract;',
  9625. ' procedure DoIt(s: string); virtual; abstract;',
  9626. ' end;',
  9627. 'begin'
  9628. ]);
  9629. CheckResolverException(sPreviousDeclMissesOverload,nPreviousDeclMissesOverload);
  9630. end;
  9631. procedure TTestResolver.TestClass_MethodOverloadAncestor;
  9632. begin
  9633. StartProgram(false);
  9634. Add('type');
  9635. Add(' TObject = class');
  9636. Add(' procedure {#A1}DoIt;');
  9637. Add(' procedure {#B1}DoIt(i: longint);');
  9638. Add(' end;');
  9639. Add(' TCar = class');
  9640. Add(' procedure {#A2}DoIt;');
  9641. Add(' procedure {#B2}DoIt(i: longint);');
  9642. Add(' end;');
  9643. Add('procedure TObject.DoIt; begin end;');
  9644. Add('procedure TObject.DoIt(i: longint); begin end;');
  9645. Add('procedure TCar.DoIt;');
  9646. Add('begin');
  9647. Add(' {@A2}DoIt;');
  9648. Add(' {@B2}DoIt(1);');
  9649. Add(' inherited {@A1}DoIt;');
  9650. Add(' inherited {@B1}DoIt(2);');
  9651. Add('end;');
  9652. Add('procedure TCar.DoIt(i: longint); begin end;');
  9653. Add('begin');
  9654. ParseProgram;
  9655. end;
  9656. procedure TTestResolver.TestClass_MethodOverloadUnit;
  9657. begin
  9658. StartProgram(true);
  9659. Add([
  9660. 'type',
  9661. ' TObject = class',
  9662. ' procedure Copy(s: string);',
  9663. ' end;',
  9664. 'procedure TObject.Copy(s: string);',
  9665. 'var a: array of longint;',
  9666. 'begin',
  9667. ' a:=system.Copy(a,1,3);',
  9668. 'end;',
  9669. 'begin']);
  9670. ParseProgram;
  9671. CheckResolverUnexpectedHints;
  9672. end;
  9673. procedure TTestResolver.TestClass_HintMethodHidesNonVirtualMethod;
  9674. begin
  9675. StartProgram(false);
  9676. Add([
  9677. 'type',
  9678. ' TObject = class',
  9679. ' procedure DoIt(p: pointer);',
  9680. ' end;',
  9681. ' TBird = class',
  9682. ' procedure DoIt(i: longint);',
  9683. ' end;',
  9684. 'procedure TObject.DoIt(p: pointer);',
  9685. 'begin',
  9686. ' if p=nil then ;',
  9687. 'end;',
  9688. 'procedure TBird.DoIt(i: longint); begin end;',
  9689. 'var b: TBird;',
  9690. 'begin',
  9691. ' b.DoIt(3);']);
  9692. ParseProgram;
  9693. CheckResolverHint(mtHint,nFunctionHidesIdentifier_NonVirtualMethod,
  9694. 'function hides identifier at "afile.pp(4,19)". Use overload or reintroduce');
  9695. end;
  9696. procedure TTestResolver.
  9697. TestClass_HintMethodHidesNonVirtualMethodWithoutBody_NoHint;
  9698. begin
  9699. AddModuleWithIntfImplSrc('unit2.pas',
  9700. LinesToStr([
  9701. 'type',
  9702. ' TObject = class',
  9703. ' public',
  9704. ' procedure DoIt(p: pointer);',
  9705. ' end;',
  9706. '']),
  9707. LinesToStr([
  9708. 'procedure TObject.DoIt(p: pointer);',
  9709. 'begin',
  9710. 'end;',
  9711. '']) );
  9712. StartProgram(true);
  9713. Add([
  9714. 'uses unit2;',
  9715. 'type',
  9716. ' TBird = class',
  9717. ' procedure DoIt(i: longint);',
  9718. ' end;',
  9719. 'procedure TBird.DoIt(i: longint); begin end;',
  9720. 'var b: TBird;',
  9721. 'begin',
  9722. ' b.DoIt(3);']);
  9723. ParseProgram;
  9724. CheckResolverUnexpectedHints(true);
  9725. end;
  9726. procedure TTestResolver.TestClass_NoHintMethodHidesPrivateMethod;
  9727. begin
  9728. AddModuleWithIntfImplSrc('unit2.pas',
  9729. LinesToStr([
  9730. 'type',
  9731. ' TObject = class',
  9732. ' private',
  9733. ' procedure DoIt(p: pointer);',
  9734. ' end;',
  9735. '']),
  9736. LinesToStr([
  9737. 'procedure TObject.DoIt(p: pointer);',
  9738. 'begin',
  9739. ' if p=nil then ;',
  9740. 'end;',
  9741. '']) );
  9742. StartProgram(true);
  9743. Add([
  9744. 'uses unit2;',
  9745. 'type',
  9746. ' TAnimal = class',
  9747. ' strict private',
  9748. ' procedure Fly(p: pointer);',
  9749. ' end;',
  9750. ' TBird = class(TAnimal)',
  9751. ' procedure DoIt(i: longint);',
  9752. ' procedure Fly(b: boolean);',
  9753. ' end;',
  9754. 'procedure TAnimal.Fly(p: pointer);',
  9755. 'begin',
  9756. ' if p=nil then ;',
  9757. 'end;',
  9758. 'procedure TBird.DoIt(i: longint); begin end;',
  9759. 'procedure TBird.Fly(b: boolean); begin end;',
  9760. 'var b: TBird;',
  9761. 'begin',
  9762. ' b.DoIt(3);']);
  9763. ParseProgram;
  9764. CheckResolverUnexpectedHints;
  9765. end;
  9766. procedure TTestResolver.TestClass_MethodReintroduce;
  9767. begin
  9768. StartProgram(false);
  9769. Add([
  9770. 'type',
  9771. ' TObject = class',
  9772. ' procedure DoIt(p: pointer); virtual; abstract;',
  9773. ' end;',
  9774. ' TBird = class',
  9775. ' procedure DoIt(i: longint); virtual; abstract; reintroduce;',
  9776. ' procedure DoIt(s: string); virtual; abstract;',
  9777. ' end;',
  9778. 'begin']);
  9779. ParseProgram;
  9780. CheckResolverUnexpectedHints;
  9781. end;
  9782. procedure TTestResolver.TestClass_MethodOverloadArrayOfTClass;
  9783. begin
  9784. StartProgram(false);
  9785. Add([
  9786. 'type',
  9787. ' TClass = class of TObject;',
  9788. ' TObject = class',
  9789. ' constructor {#A}Builder(AClass: TClass; AName: string); reintroduce; overload; virtual;',
  9790. ' constructor {#B}Builder(AClass: TClass); reintroduce; overload; virtual;',
  9791. ' constructor {#C}Builder(AClassArray: Array of TClass); reintroduce; overload; virtual;',
  9792. ' constructor {#D}Builder(AName: string); reintroduce; overload; virtual;',
  9793. ' constructor {#E}Builder; reintroduce; overload; virtual;',
  9794. ' class var ClassName: string;',
  9795. ' end;',
  9796. ' TTestCase = class end;',
  9797. 'constructor TObject.Builder(AClass: TClass; AName: string);',
  9798. 'begin',
  9799. ' Builder(AClass);',
  9800. 'end;',
  9801. 'constructor TObject.Builder(AClass: TClass);',
  9802. 'begin',
  9803. ' Builder(AClass.ClassName);',
  9804. 'end;',
  9805. 'constructor TObject.Builder(AClassArray: Array of TClass);',
  9806. 'var',
  9807. ' i: longint;',
  9808. 'begin',
  9809. ' Builder;',
  9810. ' for i := Low(AClassArray) to High(AClassArray) do',
  9811. ' if Assigned(AClassArray[i]) then ;',
  9812. 'end;',
  9813. 'constructor TObject.Builder(AName: string);',
  9814. 'begin',
  9815. ' Builder();',
  9816. 'end;',
  9817. 'constructor TObject.Builder;',
  9818. 'begin',
  9819. 'end;',
  9820. 'var',
  9821. ' o: TObject;',
  9822. 'begin',
  9823. ' o.{@A}Builder(TTestCase,''first'');',
  9824. ' o.{@B}Builder(TTestCase);',
  9825. ' o.{@C}Builder([]);',
  9826. ' o.{@C}Builder([TTestCase]);',
  9827. ' o.{@C}Builder([TObject,TTestCase]);',
  9828. ' o.{@D}Builder(''fourth'');',
  9829. ' o.{@E}Builder();',
  9830. ' o.{@E}Builder;',
  9831. '']);
  9832. ParseProgram;
  9833. end;
  9834. procedure TTestResolver.TestClass_ConstructorHidesAncestorWarning;
  9835. begin
  9836. StartProgram(false);
  9837. Add([
  9838. 'type',
  9839. ' TObject = class',
  9840. ' constructor Create(o: tobject); virtual; abstract;',
  9841. ' end;',
  9842. ' TBird = class',
  9843. ' constructor Create(s: string); virtual; abstract;',
  9844. ' end;',
  9845. 'begin',
  9846. '']);
  9847. ParseProgram;
  9848. CheckResolverHint(mtWarning,nMethodHidesMethodOfBaseType,
  9849. 'Method "Create" hides method of base type "TObject" at afile.pp(4,23)');
  9850. CheckResolverUnexpectedHints;
  9851. end;
  9852. procedure TTestResolver.TestClass_ConstructorOverride;
  9853. begin
  9854. StartProgram(false);
  9855. Add([
  9856. 'type',
  9857. ' TObject = class',
  9858. ' constructor Create(o: tobject); virtual;',
  9859. ' end;',
  9860. ' TBird = class',
  9861. ' constructor Create(o: tobject); override;',
  9862. ' end;',
  9863. ' TEagle = class(TBird)',
  9864. ' constructor Create(o: tobject); override;',
  9865. ' end;',
  9866. 'constructor tobject.Create(o: tobject); begin end;',
  9867. 'constructor tbird.Create(o: tobject); begin end;',
  9868. 'constructor teagle.Create(o: tobject); begin end;',
  9869. 'var o: TEagle;',
  9870. 'begin',
  9871. ' o:=TEagle.Create(nil);',
  9872. ' o:=TEagle.Create(o);',
  9873. '']);
  9874. ParseProgram;
  9875. end;
  9876. procedure TTestResolver.TestClass_ConstructorAccessHiddenAncestorFail;
  9877. begin
  9878. StartProgram(false);
  9879. Add([
  9880. 'type',
  9881. ' TObject = class',
  9882. ' constructor Create(o: tobject);',
  9883. ' end;',
  9884. ' TBird = class',
  9885. ' constructor Create(i: longint); reintroduce;',
  9886. ' end;',
  9887. 'constructor tobject.Create(o: tobject); begin end;',
  9888. 'constructor tbird.Create(i: longint); begin end;',
  9889. 'var o: TBird;',
  9890. 'begin',
  9891. ' o:=TBird.Create(nil);',
  9892. '']);
  9893. CheckResolverException('Incompatible type for arg no. 1: Got "Nil", expected "Longint"',
  9894. nIncompatibleTypeArgNo);
  9895. end;
  9896. procedure TTestResolver.TestClass_ConstructorNoteAbstractMethods;
  9897. begin
  9898. StartProgram(false);
  9899. Add([
  9900. 'type',
  9901. ' TObject = class',
  9902. ' procedure DoIt; virtual; abstract;',
  9903. ' constructor Create; virtual;',
  9904. ' end;',
  9905. 'constructor TObject.Create;',
  9906. 'begin',
  9907. 'end;',
  9908. 'begin',
  9909. ' TObject.Create;']);
  9910. ParseProgram;
  9911. CheckResolverHint(mtWarning,nConstructingClassXWithAbstractMethodY,'Constructing a class "TObject" with abstract method "DoIt"');
  9912. CheckResolverUnexpectedHints;
  9913. end;
  9914. procedure TTestResolver.TestClass_ConstructorNoNoteAbstractMethods;
  9915. begin
  9916. StartProgram(false);
  9917. Add([
  9918. 'type',
  9919. ' TObject = class',
  9920. ' procedure DoIt; virtual; abstract;',
  9921. ' constructor Create;',
  9922. ' end;',
  9923. ' TClass = class of TObject;',
  9924. 'constructor TObject.Create;',
  9925. 'begin',
  9926. 'end;',
  9927. 'var c: TClass;',
  9928. 'begin',
  9929. ' c.Create;',
  9930. ' with c do Create;',
  9931. '']);
  9932. ParseProgram;
  9933. CheckResolverUnexpectedHints;
  9934. end;
  9935. procedure TTestResolver.TestClass_MethodScope;
  9936. begin
  9937. StartProgram(false);
  9938. Add('type');
  9939. Add(' TObject = class');
  9940. Add(' end;');
  9941. Add(' {#A}TClassA = class');
  9942. Add(' {#A_A}A: longint;');
  9943. Add(' procedure {#A_ProcB}ProcB;');
  9944. Add(' end;');
  9945. Add('procedure TClassA.ProcB;');
  9946. Add('begin');
  9947. Add(' {@A_A}A:=3;');
  9948. Add('end;');
  9949. Add('begin');
  9950. ParseProgram;
  9951. end;
  9952. procedure TTestResolver.TestClass_IdentifierSelf;
  9953. begin
  9954. StartProgram(false);
  9955. Add('type');
  9956. Add(' TObject = class');
  9957. Add(' {#C}C: longint;');
  9958. Add(' end;');
  9959. Add(' {#A}TClassA = class');
  9960. Add(' {#B}B: longint;');
  9961. Add(' procedure {#A_ProcB}ProcB;');
  9962. Add(' end;');
  9963. Add('procedure TClassA.ProcB;');
  9964. Add('begin');
  9965. Add(' {@B}B:=1;');
  9966. Add(' {@C}C:=2;');
  9967. Add(' Self.{@B}B:=3;');
  9968. Add('end;');
  9969. Add('begin');
  9970. ParseProgram;
  9971. end;
  9972. procedure TTestResolver.TestClassCallInherited;
  9973. begin
  9974. StartProgram(false);
  9975. Add([
  9976. 'type',
  9977. ' TObject = class',
  9978. ' procedure {#TOBJ_ProcA}ProcA(vI: longint); virtual;',
  9979. ' procedure {#TOBJ_ProcB}ProcB(vJ: longint); virtual;',
  9980. ' end;',
  9981. ' {#A}TClassA = class',
  9982. ' procedure {#A_ProcA}ProcA({#i1}vI: longint); override;',
  9983. ' procedure {#A_ProcB}ProcB(vJ: longint); override;',
  9984. ' procedure {#A_ProcC}ProcC; virtual;',
  9985. ' end;',
  9986. 'procedure TObject.ProcA(vi: longint);',
  9987. 'begin',
  9988. ' inherited; // ignore, do not raise error',
  9989. 'end;',
  9990. 'procedure TObject.ProcB(vj: longint);',
  9991. 'begin',
  9992. 'end;',
  9993. 'procedure TClassA.ProcA(vi: longint);',
  9994. 'begin',
  9995. ' {@A_ProcA}ProcA({@i1}vI);',
  9996. ' {@TOBJ_ProcA}inherited;',
  9997. ' inherited {@TOBJ_ProcA}ProcA({@i1}vI);',
  9998. ' {@A_ProcB}ProcB({@i1}vI);',
  9999. ' inherited {@TOBJ_ProcB}ProcB({@i1}vI);',
  10000. 'end;',
  10001. 'procedure TClassA.ProcB(vJ: longint);',
  10002. 'begin',
  10003. 'end;',
  10004. 'procedure TClassA.ProcC;',
  10005. 'begin',
  10006. ' inherited; // ignore, do not raise error',
  10007. 'end;',
  10008. 'begin']);
  10009. ParseProgram;
  10010. CheckResolverUnexpectedHints;
  10011. end;
  10012. procedure TTestResolver.TestClassCallInheritedNoParamsAbstractFail;
  10013. begin
  10014. StartProgram(false);
  10015. Add('type');
  10016. Add(' TObject = class');
  10017. Add(' procedure ProcA; virtual; abstract;');
  10018. Add(' end;');
  10019. Add(' TClassA = class');
  10020. Add(' procedure ProcA; override;');
  10021. Add(' end;');
  10022. Add('procedure TClassA.ProcA;');
  10023. Add('begin');
  10024. Add(' inherited;');
  10025. Add('end;');
  10026. Add('begin');
  10027. CheckResolverException('Abstract methods cannot be called directly',
  10028. nAbstractMethodsCannotBeCalledDirectly);
  10029. end;
  10030. procedure TTestResolver.TestClassCallInheritedWithParamsAbstractFail;
  10031. begin
  10032. StartProgram(false);
  10033. Add('type');
  10034. Add(' TObject = class');
  10035. Add(' procedure ProcA(c: char); virtual; abstract;');
  10036. Add(' end;');
  10037. Add(' TClassA = class');
  10038. Add(' procedure ProcA(c: char); override;');
  10039. Add(' end;');
  10040. Add('procedure TClassA.ProcA(c: char);');
  10041. Add('begin');
  10042. Add(' inherited ProcA(c);');
  10043. Add('end;');
  10044. Add('begin');
  10045. CheckResolverException('Abstract methods cannot be called directly',
  10046. nAbstractMethodsCannotBeCalledDirectly);
  10047. end;
  10048. procedure TTestResolver.TestClassCallInheritedConstructor;
  10049. begin
  10050. StartProgram(false);
  10051. Add('type');
  10052. Add(' TObject = class');
  10053. Add(' constructor {#TOBJ_CreateA}Create(vI: longint); virtual;');
  10054. Add(' end;');
  10055. Add(' {#A}TClassA = class');
  10056. Add(' constructor {#A_CreateA}Create({#i1}vI: longint); override;');
  10057. Add(' end;');
  10058. Add('constructor TObject.Create(vI: longint);');
  10059. Add('begin');
  10060. Add(' inherited; // ignore and do not raise error');
  10061. Add('end;');
  10062. Add('constructor TClassA.Create(vI: longint);');
  10063. Add('begin');
  10064. Add(' {@A_CreateA}Create({@i1}vI);');
  10065. Add(' {@TOBJ_CreateA}inherited;');
  10066. Add(' inherited {@TOBJ_CreateA}Create({@i1}vI);');
  10067. Add('end;');
  10068. Add('begin');
  10069. ParseProgram;
  10070. end;
  10071. procedure TTestResolver.TestClassCallInheritedNested;
  10072. begin
  10073. StartProgram(false);
  10074. Add([
  10075. 'type',
  10076. ' TObject = class',
  10077. ' function DoIt: longint; virtual;',
  10078. ' end;',
  10079. ' TBird = class',
  10080. ' function DoIt: longint; override;',
  10081. ' end;',
  10082. 'function tobject.doit: longint;',
  10083. 'begin',
  10084. 'end;',
  10085. 'function tbird.doit: longint;',
  10086. ' procedure Sub;',
  10087. ' begin',
  10088. ' inherited;',
  10089. ' inherited DoIt;',
  10090. ' if inherited DoIt=4 then ;',
  10091. ' end;',
  10092. 'begin',
  10093. ' Sub;',
  10094. ' inherited;',
  10095. ' inherited DoIt;',
  10096. ' if inherited DoIt=14 then ;',
  10097. ' with Self do inherited;',
  10098. ' with Self do inherited DoIt;',
  10099. 'end;',
  10100. 'begin',
  10101. '']);
  10102. ParseProgram;
  10103. end;
  10104. procedure TTestResolver.TestClassCallInheritedAs;
  10105. begin
  10106. StartProgram(false);
  10107. Add([
  10108. 'type',
  10109. ' TObject = class',
  10110. ' function GetSome: TObject; virtual;',
  10111. ' end;',
  10112. ' TBird = class',
  10113. ' function GetIt: TBird;',
  10114. ' end;',
  10115. 'function TObject.GetSome: TObject;',
  10116. 'begin',
  10117. 'end;',
  10118. 'function TBird.GetIt: TBird;',
  10119. 'begin',
  10120. ' Result:=inherited GetSome as TBird;',
  10121. 'end;',
  10122. 'begin']);
  10123. ParseProgram;
  10124. end;
  10125. procedure TTestResolver.TestClassAssignNil;
  10126. begin
  10127. StartProgram(false);
  10128. Add('type');
  10129. Add(' {#TOBJ}TObject = class');
  10130. Add(' end;');
  10131. Add(' {#A}TClassA = class');
  10132. Add(' {#FSub}FSub: TClassA;');
  10133. Add(' property {#Sub}Sub: TClassA read {@FSub}FSub write {@FSub}FSub;');
  10134. Add(' end;');
  10135. Add('var');
  10136. Add(' {#v}{=A}v: TClassA;');
  10137. Add('begin');
  10138. Add(' {@v}v:=nil;');
  10139. Add(' if {@v}v=nil then ;');
  10140. Add(' if nil={@v}v then ;');
  10141. Add(' if {@v}v<>nil then ;');
  10142. Add(' if nil<>{@v}v then ;');
  10143. Add(' {@v}v.{@FSub}FSub:=nil;');
  10144. Add(' if {@v}v.{@FSub}FSub=nil then ;');
  10145. Add(' if {@v}v.{@FSub}FSub<>nil then ;');
  10146. Add(' {@v}v.{@Sub}Sub:=nil;');
  10147. Add(' if {@v}v.{@Sub}Sub=nil then ;');
  10148. Add(' if {@v}v.{@Sub}Sub<>nil then ;');
  10149. ParseProgram;
  10150. end;
  10151. procedure TTestResolver.TestClassAssign;
  10152. begin
  10153. StartProgram(false);
  10154. Add('type');
  10155. Add(' {#TOBJ}TObject = class');
  10156. Add(' end;');
  10157. Add(' {#A}TClassA = class');
  10158. Add(' {#FSub}FSub: TClassA;');
  10159. Add(' property {#Sub}Sub: TClassA read {@FSub}FSub write {@FSub}FSub;');
  10160. Add(' end;');
  10161. Add('var');
  10162. Add(' {#o}{=TOBJ}o: TObject;');
  10163. Add(' {#v}{=A}v: TClassA;');
  10164. Add(' {#p}{=A}p: TClassA;');
  10165. Add('begin');
  10166. Add(' {@o}o:={@v}v;');
  10167. Add(' {@v}v:={@p}p;');
  10168. Add(' if {@v}v={@p}p then ;');
  10169. Add(' if {@v}v={@o}o then ;');
  10170. Add(' if {@o}o={@o}o then ;');
  10171. Add(' if {@o}o={@v}v then ;');
  10172. Add(' if {@v}v<>{@p}p then ;');
  10173. Add(' if {@v}v<>{@o}o then ;');
  10174. Add(' if {@o}o<>{@o}o then ;');
  10175. Add(' if {@o}o<>{@v}v then ;');
  10176. Add(' {@v}v.{@FSub}FSub:={@p}p;');
  10177. Add(' {@p}p:={@v}v.{@FSub}FSub;');
  10178. Add(' {@o}o:={@v}v.{@FSub}FSub;');
  10179. Add(' {@v}v.{@Sub}Sub:={@p}p;');
  10180. Add(' {@p}p:={@v}v.{@Sub}Sub;');
  10181. Add(' {@o}o:={@v}v.{@Sub}Sub;');
  10182. ParseProgram;
  10183. end;
  10184. procedure TTestResolver.TestClassNilAsParam;
  10185. begin
  10186. StartProgram(false);
  10187. Add('type');
  10188. Add(' {#TOBJ}TObject = class');
  10189. Add(' end;');
  10190. Add('procedure ProcP(o: TObject);');
  10191. Add('begin end;');
  10192. Add('begin');
  10193. Add(' ProcP(nil);');
  10194. ParseProgram;
  10195. end;
  10196. procedure TTestResolver.TestClass_Operators_Is_As;
  10197. begin
  10198. StartProgram(false);
  10199. Add('type');
  10200. Add(' {#TOBJ}TObject = class');
  10201. Add(' end;');
  10202. Add(' {#A}TClassA = class');
  10203. Add(' {#Sub}Sub: TClassA;');
  10204. Add(' end;');
  10205. Add('var');
  10206. Add(' {#o}{=TOBJ}o: TObject;');
  10207. Add(' {#v}{=A}v: TClassA;');
  10208. Add('begin');
  10209. Add(' if {@o}o is {@A}TClassA then;');
  10210. Add(' if {@v}v is {@A}TClassA then;');
  10211. Add(' if {@v}v is {@TOBJ}TObject then;');
  10212. Add(' if {@v}v.{@Sub}Sub is {@A}TClassA then;');
  10213. Add(' {@v}v:={@o}o as {@A}TClassA;');
  10214. ParseProgram;
  10215. end;
  10216. procedure TTestResolver.TestClass_OperatorIsOnNonTypeFail;
  10217. begin
  10218. StartProgram(false);
  10219. Add('type');
  10220. Add(' {#TOBJ}TObject = class');
  10221. Add(' end;');
  10222. Add(' {#A}TClassA = class');
  10223. Add(' end;');
  10224. Add('var');
  10225. Add(' {#o}{=TOBJ}o: TObject;');
  10226. Add(' {#v}{=A}v: TClassA;');
  10227. Add('begin');
  10228. Add(' if {@o}o is {@v}v then;');
  10229. CheckResolverException('class type expected, but class found',
  10230. nXExpectedButYFound);
  10231. end;
  10232. procedure TTestResolver.TestClass_OperatorAsOnNonDescendantFail;
  10233. begin
  10234. StartProgram(false);
  10235. Add('type');
  10236. Add(' {#TOBJ}TObject = class');
  10237. Add(' end;');
  10238. Add(' {#A}TClassA = class');
  10239. Add(' end;');
  10240. Add('var');
  10241. Add(' {#o}{=TOBJ}o: TObject;');
  10242. Add(' {#v}{=A}v: TClassA;');
  10243. Add('begin');
  10244. Add(' {@o}o:={@v}v as {@TObj}TObject;');
  10245. CheckResolverException('Types are not related: "TClassA" and "class TObject" at afile.pp (11,16)',nTypesAreNotRelatedXY);
  10246. end;
  10247. procedure TTestResolver.TestClass_OperatorAsOnNonTypeFail;
  10248. begin
  10249. StartProgram(false);
  10250. Add('type');
  10251. Add(' {#TOBJ}TObject = class');
  10252. Add(' end;');
  10253. Add(' {#A}TClassA = class');
  10254. Add(' end;');
  10255. Add('var');
  10256. Add(' {#o}{=TOBJ}o: TObject;');
  10257. Add(' {#v}{=A}v: TClassA;');
  10258. Add('begin');
  10259. Add(' {@o}o:={@v}v as {@o}o;');
  10260. CheckResolverException('class expected, but o found',
  10261. nXExpectedButYFound);
  10262. end;
  10263. procedure TTestResolver.TestClassAsFuncResult;
  10264. begin
  10265. StartProgram(false);
  10266. Add([
  10267. 'type',
  10268. ' {#TOBJ}TObject = class',
  10269. ' end;',
  10270. ' {#A}TClassA = class',
  10271. ' {#A_i}i: longint;',
  10272. ' constructor {#A_CreateA}Create;',
  10273. ' constructor {#A_CreateB}Create(i: longint);',
  10274. ' end;',
  10275. 'function {#F}F: TClassA;',
  10276. 'begin',
  10277. ' Result:=nil;',
  10278. 'end;',
  10279. 'constructor TClassA.Create;',
  10280. 'begin',
  10281. 'end;',
  10282. 'constructor TClassA.Create(i: longint);',
  10283. 'begin',
  10284. 'end;',
  10285. 'var',
  10286. ' {#o}{=TOBJ}o: TObject;',
  10287. ' {#v}{=A}v: TClassA;',
  10288. 'begin',
  10289. ' {@o}o:={@F}F;',
  10290. ' {@o}o:={@F}F();',
  10291. ' {@v}v:={@F}F;',
  10292. ' {@v}v:={@F}F();',
  10293. ' if {@o}o={@F}F then ;',
  10294. ' if {@o}o={@F}F() then ;',
  10295. ' if {@v}v={@F}F then ;',
  10296. ' if {@v}v={@F}F() then ;',
  10297. ' {@v}v:={@A}TClassA.{@A_CreateA}Create;',
  10298. ' {@v}v:={@A}TClassA.{@A_CreateA}Create();',
  10299. ' {@v}v:={@A}TClassA.{@A_CreateB}Create(3);',
  10300. ' {@A}TClassA.{@A_CreateA}Create.{@A_i}i:=3;',
  10301. ' {@A}TClassA.{@A_CreateA}Create().{@A_i}i:=3;',
  10302. ' {@A}TClassA.{@A_CreateB}Create(3).{@A_i}i:=3;']);
  10303. ParseProgram;
  10304. end;
  10305. procedure TTestResolver.TestClassTypeCast;
  10306. begin
  10307. StartProgram(false);
  10308. Add('type');
  10309. Add(' {#TOBJ}TObject = class');
  10310. Add(' end;');
  10311. Add(' {#A}TClassA = class');
  10312. Add(' id: longint;');
  10313. Add(' end;');
  10314. Add('procedure ProcA(var a: TClassA);');
  10315. Add('begin');
  10316. Add('end;');
  10317. Add('var');
  10318. Add(' {#o}{=TOBJ}o: TObject;');
  10319. Add(' {#v}{=A}v: TClassA;');
  10320. Add('begin');
  10321. Add(' {@o}o:={@v}v;');
  10322. Add(' {@o}o:=TObject({@o}o);');
  10323. Add(' {@v}v:=TClassA({@o}o);');
  10324. Add(' {@v}v:=TClassA(TObject({@o}o));');
  10325. Add(' {@v}v:=TClassA({@v}v);');
  10326. Add(' {@v}v:=v as TClassA;');
  10327. Add(' {@v}v:=o as TClassA;');
  10328. Add(' ProcA({@v}v);');
  10329. Add(' ProcA(TClassA({@o}o));');
  10330. Add(' if TClassA({@o}o).id=3 then ;');
  10331. Add(' if (o as TClassA).id=3 then ;');
  10332. Add(' o:=TObject(nil);');
  10333. ParseProgram;
  10334. end;
  10335. procedure TTestResolver.TestClassTypeCastUnrelatedWarn;
  10336. begin
  10337. StartProgram(false);
  10338. Add([
  10339. 'type',
  10340. ' {#TOBJ}TObject = class',
  10341. ' end;',
  10342. ' {#A}TClassA = class',
  10343. ' id: longint;',
  10344. ' end;',
  10345. ' {#B}TClassB = class',
  10346. ' Name: string;',
  10347. ' end;',
  10348. 'var',
  10349. ' {#o}{=TOBJ}o: TObject;',
  10350. ' {#va}{=A}va: TClassA;',
  10351. ' {#vb}{=B}vb: TClassB;',
  10352. 'begin',
  10353. ' {@vb}vb:=TClassB({@va}va);']);
  10354. ParseProgram;
  10355. CheckResolverHint(mtWarning,nClassTypesAreNotRelatedXY,'Class types "TClassA" and "TClassB" are not related');
  10356. CheckResolverUnexpectedHints;
  10357. end;
  10358. procedure TTestResolver.TestClass_TypeCastSelf;
  10359. begin
  10360. StartProgram(false);
  10361. Add('type');
  10362. Add(' TObject = class');
  10363. Add(' constructor Create;');
  10364. Add(' procedure ProcA;');
  10365. Add(' end;');
  10366. Add(' TClassA = class');
  10367. Add(' id: longint;');
  10368. Add(' end;');
  10369. Add('constructor TObject.Create;');
  10370. Add('begin');
  10371. Add(' TClassA(Self).id:=3;');
  10372. Add(' if TClassA(Self).id=4 then;');
  10373. Add(' if 5=TClassA(Self).id then;');
  10374. Add('end;');
  10375. Add('procedure TObject.ProcA;');
  10376. Add('begin');
  10377. Add(' TClassA(Self).id:=3;');
  10378. Add(' if TClassA(Self).id=4 then;');
  10379. Add(' if 5=TClassA(Self).id then;');
  10380. Add('end;');
  10381. Add('begin');
  10382. ParseProgram;
  10383. end;
  10384. procedure TTestResolver.TestClass_TypeCaseMultipleParamsFail;
  10385. begin
  10386. StartProgram(false);
  10387. Add('type');
  10388. Add(' TObject = class');
  10389. Add(' i: longint;');
  10390. Add(' end;');
  10391. Add('var o: TObject;');
  10392. Add('begin');
  10393. Add(' o.i:=TObject(o,o).i;');
  10394. CheckResolverException('wrong number of parameters for type cast to TObject',
  10395. nWrongNumberOfParametersForTypeCast);
  10396. end;
  10397. procedure TTestResolver.TestClass_TypeCastAssign;
  10398. begin
  10399. StartProgram(false);
  10400. Add('type');
  10401. Add(' TObject = class');
  10402. Add(' end;');
  10403. Add(' TCar = class');
  10404. Add(' end;');
  10405. Add('procedure DoIt(a: TCar; const b: TCar; var c: TCar; out d: TCar); begin end;');
  10406. Add('var');
  10407. Add(' o: TObject;');
  10408. Add(' c: TCar;');
  10409. Add('begin');
  10410. Add(' TCar({#a_assign}o):=nil;');
  10411. Add(' TCar({#b_assign}o):=c;');
  10412. Add(' DoIt(TCar({#c1_read}o),TCar({#c2_read}o),TCar({#c3_var}o),TCar({#c4_out}o));');
  10413. ParseProgram;
  10414. CheckAccessMarkers;
  10415. end;
  10416. procedure TTestResolver.TestClass_AccessMemberViaClassFail;
  10417. begin
  10418. StartProgram(false);
  10419. Add('type');
  10420. Add(' TObject = class');
  10421. Add(' i: longint;');
  10422. Add(' end;');
  10423. Add('begin');
  10424. Add(' if TObject.i=7 then ;');
  10425. CheckResolverException(sInstanceMemberXInaccessible,
  10426. nInstanceMemberXInaccessible);
  10427. end;
  10428. procedure TTestResolver.TestClass_FuncReturningObjectMember;
  10429. begin
  10430. StartProgram(false);
  10431. Add('type');
  10432. Add(' TObject = class');
  10433. Add(' i: longint;');
  10434. Add(' end;');
  10435. Add('function FuncO: TObject;');
  10436. Add('begin');
  10437. Add('end;');
  10438. Add('begin');
  10439. Add(' FuncO.i:=3;');
  10440. Add(' if FuncO.i=4 then ;');
  10441. Add(' if 5=FuncO.i then ;');
  10442. ParseProgram;
  10443. end;
  10444. procedure TTestResolver.TestClass_StaticWithoutClassFail;
  10445. begin
  10446. StartProgram(false);
  10447. Add('type');
  10448. Add(' TObject = class');
  10449. Add(' procedure ProcA; static;');
  10450. Add(' end;');
  10451. Add('procedure TObject.ProcA; begin end;');
  10452. Add('begin');
  10453. CheckResolverException('Invalid procedure modifier static',
  10454. nInvalidXModifierY);
  10455. end;
  10456. procedure TTestResolver.TestClass_SelfInStaticFail;
  10457. begin
  10458. StartProgram(false);
  10459. Add('type');
  10460. Add(' TObject = class');
  10461. Add(' class procedure ProcA; static;');
  10462. Add(' end;');
  10463. Add('class procedure TObject.ProcA;');
  10464. Add('begin');
  10465. Add(' if Self=nil then ;');
  10466. Add('end;');
  10467. Add('begin');
  10468. CheckResolverException('identifier not found "Self"',nIdentifierNotFound);
  10469. end;
  10470. procedure TTestResolver.TestClass_SelfDotInStaticFail;
  10471. begin
  10472. StartProgram(false);
  10473. Add('type');
  10474. Add(' TObject = class');
  10475. Add(' class var FLeft: word;');
  10476. Add(' class function DoIt: word; static;');
  10477. Add(' class property Left: word read FLeft;');
  10478. Add(' end;');
  10479. Add('class function TObject.DoIt: word;');
  10480. Add('begin');
  10481. Add(' Result:=Self.Left;');
  10482. Add('end;');
  10483. Add('begin');
  10484. CheckResolverException('identifier not found "Self"',nIdentifierNotFound);
  10485. end;
  10486. procedure TTestResolver.TestClass_ProcStaticMismatchFail;
  10487. begin
  10488. StartProgram(false);
  10489. Add([
  10490. 'type',
  10491. ' TObject = class',
  10492. ' procedure Run;',
  10493. ' end;',
  10494. 'procedure TObject.Run; static;',
  10495. 'begin',
  10496. 'end;',
  10497. 'begin']);
  10498. CheckResolverException('Directive "static" not allowed here',nDirectiveXNotAllowedHere);
  10499. end;
  10500. procedure TTestResolver.TestClass_PrivateProtectedInSameUnit;
  10501. begin
  10502. StartProgram(false);
  10503. Add('type');
  10504. Add(' TObject = class');
  10505. Add(' strict private {#vstrictprivate}vstrictprivate: longint;');
  10506. Add(' strict protected {#vstrictprotected}vstrictprotected: longint;');
  10507. Add(' private {#vprivate}vprivate: longint;');
  10508. Add(' protected {#vprotected}vprotected: longint;');
  10509. Add(' public {#vpublic}vpublic: longint;');
  10510. Add(' procedure ProcA;');
  10511. Add(' automated {#vautomated}vautomated: longint;');
  10512. Add(' published {#vpublished}vpublished: longint;');
  10513. Add(' end;');
  10514. Add('procedure TObject.ProcA;');
  10515. Add('begin');
  10516. Add(' if {@vstrictprivate}vstrictprivate=1 then ;');
  10517. Add(' if {@vstrictprotected}vstrictprotected=2 then ;');
  10518. Add(' if {@vprivate}vprivate=3 then ;');
  10519. Add(' if {@vprotected}vprotected=4 then ;');
  10520. Add(' if {@vpublic}vpublic=5 then ;');
  10521. Add(' if {@vautomated}vautomated=6 then ;');
  10522. Add(' if {@vpublished}vpublished=7 then ;');
  10523. Add('end;');
  10524. Add('var');
  10525. Add(' o: TObject;');
  10526. Add('begin');
  10527. Add(' if o.vprivate=10 then ;');
  10528. Add(' if o.vprotected=11 then ;');
  10529. Add(' if o.vpublic=12 then ;');
  10530. Add(' if o.vautomated=13 then ;');
  10531. Add(' if o.vpublished=14 then ;');
  10532. ParseProgram;
  10533. end;
  10534. procedure TTestResolver.TestClass_PrivateInMainBeginFail;
  10535. begin
  10536. AddModuleWithSrc('unit1.pas',
  10537. LinesToStr([
  10538. 'unit unit1;',
  10539. 'interface',
  10540. 'type',
  10541. ' TObject = class',
  10542. ' private v: longint;',
  10543. ' end;',
  10544. 'implementation',
  10545. 'end.'
  10546. ]));
  10547. StartProgram(true);
  10548. Add('uses unit1;');
  10549. Add('var');
  10550. Add(' o: TObject;');
  10551. Add('begin');
  10552. Add(' if o.v=3 then ;');
  10553. CheckResolverException('Can''t access private member v',
  10554. nCantAccessXMember);
  10555. end;
  10556. procedure TTestResolver.TestClass_PrivateInDescendantFail;
  10557. begin
  10558. AddModuleWithSrc('unit1.pas',
  10559. LinesToStr([
  10560. 'unit unit1;',
  10561. 'interface',
  10562. 'type',
  10563. ' TObject = class',
  10564. ' private v: longint;',
  10565. ' end;',
  10566. 'implementation',
  10567. 'end.'
  10568. ]));
  10569. StartProgram(true);
  10570. Add('uses unit1;');
  10571. Add('type');
  10572. Add(' TClassA = class(TObject)');
  10573. Add(' procedure ProcA;');
  10574. Add(' end;');
  10575. Add('procedure TClassA.ProcA;');
  10576. Add('begin');
  10577. Add(' if v=3 then ;');
  10578. Add('end;');
  10579. Add('begin');
  10580. CheckResolverException('Can''t access private member v',
  10581. nCantAccessXMember);
  10582. end;
  10583. procedure TTestResolver.TestClass_ProtectedInDescendant;
  10584. begin
  10585. AddModuleWithSrc('unit1.pas',
  10586. LinesToStr([
  10587. 'unit unit1;',
  10588. 'interface',
  10589. 'type',
  10590. ' TObject = class',
  10591. ' protected vprotected: longint;',
  10592. ' strict protected vstrictprotected: longint;',
  10593. ' end;',
  10594. 'implementation',
  10595. 'end.'
  10596. ]));
  10597. StartProgram(true);
  10598. Add([
  10599. 'uses unit1;',
  10600. 'type',
  10601. ' TClassA = class(TObject)',
  10602. ' procedure ProcA;',
  10603. ' end;',
  10604. ' TClassB = class(TObject)',
  10605. ' procedure ProcB;',
  10606. ' end;',
  10607. 'procedure TClassA.ProcA;',
  10608. 'begin',
  10609. ' if vprotected=3 then ;',
  10610. ' if vstrictprotected=4 then ;',
  10611. ' if self.vprotected=5 then;',
  10612. ' if self.vstrictprotected=6 then;',
  10613. ' with self do if vprotected=7 then;',
  10614. ' with self do if vstrictprotected=8 then;',
  10615. 'end;',
  10616. 'procedure TClassB.ProcB;',
  10617. 'var A: TClassA;',
  10618. 'begin',
  10619. ' if A.vprotected=9 then;',
  10620. ' with A do if vprotected=10 then;',
  10621. 'end;',
  10622. 'var A: TClassA;',
  10623. 'begin',
  10624. ' A.vprotected:=11;',
  10625. ' with A do vprotected:=12;',
  10626. ' // error: A.vstrictprotected:=13; ']);
  10627. ParseProgram;
  10628. end;
  10629. procedure TTestResolver.TestClass_StrictPrivateInMainBeginFail;
  10630. begin
  10631. StartProgram(false);
  10632. Add('type');
  10633. Add(' TObject = class');
  10634. Add(' strict private v: longint;');
  10635. Add(' end;');
  10636. Add('var');
  10637. Add(' o: TObject;');
  10638. Add('begin');
  10639. Add(' if o.v=3 then ;');
  10640. CheckResolverException('Can''t access strict private member v',
  10641. nCantAccessXMember);
  10642. end;
  10643. procedure TTestResolver.TestClass_StrictProtectedInMainBeginFail;
  10644. begin
  10645. StartProgram(false);
  10646. Add('type');
  10647. Add(' TObject = class');
  10648. Add(' strict protected v: longint;');
  10649. Add(' end;');
  10650. Add('var');
  10651. Add(' o: TObject;');
  10652. Add('begin');
  10653. Add(' if o.v=3 then ;');
  10654. CheckResolverException('Can''t access strict protected member v',
  10655. nCantAccessXMember);
  10656. end;
  10657. procedure TTestResolver.TestClass_Constructor_NewInstance;
  10658. var
  10659. aMarker: PSrcMarker;
  10660. Elements: TFPList;
  10661. i: Integer;
  10662. El: TPasElement;
  10663. Ref: TResolvedReference;
  10664. ActualNewInstance, ActualImplicitCallWithoutParams: Boolean;
  10665. begin
  10666. StartProgram(false);
  10667. Add([
  10668. 'type',
  10669. ' TObject = class',
  10670. ' constructor Create;',
  10671. ' class function DoSome: TObject;',
  10672. ' end;',
  10673. 'constructor TObject.Create;',
  10674. 'begin',
  10675. ' {#a}Create; // normal call',
  10676. ' TObject.{#b}Create; // new instance',
  10677. 'end;',
  10678. 'class function TObject.DoSome: TObject;',
  10679. 'begin',
  10680. ' Result:={#c}Create; // new instance',
  10681. 'end;',
  10682. 'var',
  10683. ' o: TObject;',
  10684. 'begin',
  10685. ' TObject.{#p}Create; // new object',
  10686. ' o:=TObject.{#q}Create; // new object',
  10687. ' o.{#r}Create; // normal call',
  10688. ' o:=o.{#s}Create; // normal call',
  10689. '']);
  10690. ParseProgram;
  10691. aMarker:=FirstSrcMarker;
  10692. while aMarker<>nil do
  10693. begin
  10694. //writeln('TTestResolver.TestClass_Constructor_NewInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  10695. Elements:=FindElementsAt(aMarker);
  10696. try
  10697. ActualNewInstance:=false;
  10698. ActualImplicitCallWithoutParams:=false;
  10699. for i:=0 to Elements.Count-1 do
  10700. begin
  10701. El:=TPasElement(Elements[i]);
  10702. //writeln('TTestResolver.TestClass_Constructor_NewInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  10703. if not (El.CustomData is TResolvedReference) then continue;
  10704. Ref:=TResolvedReference(El.CustomData);
  10705. if not (Ref.Declaration is TPasProcedure) then continue;
  10706. //writeln('TTestResolver.TestClass_Constructor_NewInstance ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  10707. if (Ref.Declaration is TPasConstructor) then
  10708. ActualNewInstance:=rrfNewInstance in Ref.Flags;
  10709. ActualImplicitCallWithoutParams:=rrfImplicitCallWithoutParams in Ref.Flags;
  10710. break;
  10711. end;
  10712. if not ActualImplicitCallWithoutParams then
  10713. RaiseErrorAtSrcMarker('expected implicit call at "#'+aMarker^.Identifier+', but got function ref"',aMarker);
  10714. case aMarker^.Identifier of
  10715. 'a','r','s':// should be normal call
  10716. if ActualNewInstance then
  10717. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got newinstance"',aMarker);
  10718. else // should be newinstance
  10719. if not ActualNewInstance then
  10720. RaiseErrorAtSrcMarker('expected newinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  10721. end;
  10722. finally
  10723. Elements.Free;
  10724. end;
  10725. aMarker:=aMarker^.Next;
  10726. end;
  10727. end;
  10728. procedure TTestResolver.TestClass_Destructor_FreeInstance;
  10729. var
  10730. aMarker: PSrcMarker;
  10731. Elements: TFPList;
  10732. i: Integer;
  10733. El: TPasElement;
  10734. Ref: TResolvedReference;
  10735. ActualFreeInstance, ActualImplicitCallWithoutParams: Boolean;
  10736. begin
  10737. StartProgram(false);
  10738. Add('type');
  10739. Add(' TObject = class');
  10740. Add(' destructor Destroy; virtual;');
  10741. Add(' end;');
  10742. Add(' TChild = class(TObject)');
  10743. Add(' destructor DestroyOther;');
  10744. Add(' end;');
  10745. Add('destructor TObject.Destroy;');
  10746. Add('begin');
  10747. Add('end;');
  10748. Add('destructor TChild.DestroyOther;');
  10749. Add('begin');
  10750. Add(' {#a}Destroy; // free instance');
  10751. Add(' inherited {#b}Destroy; // normal call');
  10752. Add('end;');
  10753. Add('var');
  10754. Add(' c: TChild;');
  10755. Add('begin');
  10756. Add(' c.{#c}Destroy; // free instance');
  10757. Add(' c.{#d}DestroyOther; // free instance');
  10758. ParseProgram;
  10759. aMarker:=FirstSrcMarker;
  10760. while aMarker<>nil do
  10761. begin
  10762. //writeln('TTestResolver.TestClass_Destructor_FreeInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  10763. Elements:=FindElementsAt(aMarker);
  10764. try
  10765. ActualFreeInstance:=false;
  10766. ActualImplicitCallWithoutParams:=false;
  10767. for i:=0 to Elements.Count-1 do
  10768. begin
  10769. El:=TPasElement(Elements[i]);
  10770. //writeln('TTestResolver.TestClass_Destructor_FreeInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  10771. if not (El.CustomData is TResolvedReference) then continue;
  10772. Ref:=TResolvedReference(El.CustomData);
  10773. if not (Ref.Declaration is TPasProcedure) then continue;
  10774. //writeln('TTestResolver.TestClass_Destructor_FreeInstance ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  10775. if (Ref.Declaration is TPasDestructor) then
  10776. ActualFreeInstance:=rrfFreeInstance in Ref.Flags;
  10777. ActualImplicitCallWithoutParams:=rrfImplicitCallWithoutParams in Ref.Flags;
  10778. break;
  10779. end;
  10780. if not ActualImplicitCallWithoutParams then
  10781. RaiseErrorAtSrcMarker('expected implicit call at "#'+aMarker^.Identifier+', but got function ref"',aMarker);
  10782. case aMarker^.Identifier of
  10783. 'b':// should be normal call
  10784. if ActualFreeInstance then
  10785. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got freeinstance"',aMarker);
  10786. else // should be freeinstance
  10787. if not ActualFreeInstance then
  10788. RaiseErrorAtSrcMarker('expected freeinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  10789. end;
  10790. finally
  10791. Elements.Free;
  10792. end;
  10793. aMarker:=aMarker^.Next;
  10794. end;
  10795. end;
  10796. procedure TTestResolver.TestClass_ConDestructor_CallInherited;
  10797. var
  10798. aMarker: PSrcMarker;
  10799. Elements: TFPList;
  10800. i: Integer;
  10801. El: TPasElement;
  10802. Ref: TResolvedReference;
  10803. begin
  10804. StartProgram(false);
  10805. Add('type');
  10806. Add(' TObject = class');
  10807. Add(' constructor Create;');
  10808. Add(' destructor Destroy; virtual;');
  10809. Add(' end;');
  10810. Add(' TChild = class(TObject)');
  10811. Add(' constructor Create;');
  10812. Add(' destructor Destroy; override;');
  10813. Add(' end;');
  10814. Add('constructor TObject.Create;');
  10815. Add('begin');
  10816. Add('end;');
  10817. Add('destructor TObject.Destroy;');
  10818. Add('begin');
  10819. Add('end;');
  10820. Add('constructor TChild.Create;');
  10821. Add('begin');
  10822. Add(' {#c}inherited; // normal call');
  10823. Add('end;');
  10824. Add('destructor TChild.Destroy;');
  10825. Add('begin');
  10826. Add(' {#d}inherited; // normal call');
  10827. Add('end;');
  10828. Add('begin');
  10829. ParseProgram;
  10830. aMarker:=FirstSrcMarker;
  10831. while aMarker<>nil do
  10832. begin
  10833. //writeln('TTestResolver.TestClass_ConDestructor_Inherited ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  10834. Elements:=FindElementsAt(aMarker);
  10835. try
  10836. for i:=0 to Elements.Count-1 do
  10837. begin
  10838. El:=TPasElement(Elements[i]);
  10839. //writeln('TTestResolver.TestClass_ConDestructor_Inherited ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  10840. if not (El.CustomData is TResolvedReference) then continue;
  10841. Ref:=TResolvedReference(El.CustomData);
  10842. if not (Ref.Declaration is TPasProcedure) then continue;
  10843. //writeln('TTestResolver.TestClass_ConDestructor_Inherited ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  10844. if rrfNewInstance in Ref.Flags then
  10845. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got newinstance"',aMarker);
  10846. if rrfFreeInstance in Ref.Flags then
  10847. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got freeinstance"',aMarker);
  10848. break;
  10849. end;
  10850. finally
  10851. Elements.Free;
  10852. end;
  10853. aMarker:=aMarker^.Next;
  10854. end;
  10855. end;
  10856. procedure TTestResolver.TestClass_Constructor_Inherited;
  10857. begin
  10858. StartProgram(false);
  10859. Add('type');
  10860. Add(' {#TOBJ}TObject = class');
  10861. Add(' constructor Create;');
  10862. Add(' destructor Destroy;');
  10863. Add(' procedure DoIt;');
  10864. Add(' end;');
  10865. Add(' {#TClassA}TClassA = class');
  10866. Add(' Sub: TObject;');
  10867. Add(' end;');
  10868. Add('constructor TObject.Create; begin end;');
  10869. Add('destructor TObject.Destroy; begin end;');
  10870. Add('procedure TObject.DoIt; begin end;');
  10871. Add('var a: TClassA;');
  10872. Add('begin');
  10873. Add(' a:=TClassA.Create;');
  10874. Add(' a.DoIt;');
  10875. Add(' a.Destroy;');
  10876. Add(' if TClassA.Create.Sub=nil then ;');
  10877. Add(' with TClassA.Create do Sub:=nil;');
  10878. Add(' with TClassA do a:=Create;');
  10879. Add(' with TClassA do Create.Sub:=nil;');
  10880. ParseProgram;
  10881. end;
  10882. procedure TTestResolver.TestClass_SubObject;
  10883. begin
  10884. StartProgram(false);
  10885. Add('type');
  10886. Add(' {#TOBJ}TObject = class');
  10887. Add(' {#Sub}Sub: TObject;');
  10888. Add(' procedure DoIt(p: longint);');
  10889. Add(' function GetIt(p: longint): TObject;');
  10890. Add(' end;');
  10891. Add('procedure TObject.DoIt(p: longint); begin end;');
  10892. Add('function TObject.GetIt(p: longint): TObject; begin end;');
  10893. Add('var o: TObject;');
  10894. Add('begin');
  10895. Add(' o.Sub:=nil;');
  10896. Add(' o.Sub.Sub:=nil;');
  10897. Add(' if o.Sub=nil then ;');
  10898. Add(' if o.Sub=o.Sub.Sub then ;');
  10899. Add(' o.Sub.DoIt(3);');
  10900. Add(' o.Sub.GetIt(4);');
  10901. Add(' o.Sub.GetIt(5).DoIt(6);');
  10902. Add(' o.Sub.GetIt(7).Sub.DoIt(8);');
  10903. ParseProgram;
  10904. end;
  10905. procedure TTestResolver.TestClass_WithDoClassInstance;
  10906. var
  10907. aMarker: PSrcMarker;
  10908. Elements: TFPList;
  10909. ActualRefWith: Boolean;
  10910. i: Integer;
  10911. El: TPasElement;
  10912. Ref: TResolvedReference;
  10913. begin
  10914. StartProgram(false);
  10915. Add('type');
  10916. Add(' TObject = class');
  10917. Add(' FInt: longint;');
  10918. Add(' FObj: TObject;');
  10919. Add(' FArr: array of longint;');
  10920. Add(' constructor Create;');
  10921. Add(' function GetSize: longint;');
  10922. Add(' procedure SetSize(Value: longint);');
  10923. Add(' function GetItems(Index: longint): longint;');
  10924. Add(' procedure SetItems(Index, Value: longint);');
  10925. Add(' property Size: longint read GetSize write SetSize;');
  10926. Add(' property Items[Index: longint]: longint read GetItems write SetItems;');
  10927. Add(' end;');
  10928. Add('constructor TObject.Create; begin end;');
  10929. Add('function TObject.GetSize: longint; begin end;');
  10930. Add('procedure TObject.SetSize(Value: longint); begin end;');
  10931. Add('function TObject.GetItems(Index: longint): longint; begin end;');
  10932. Add('procedure TObject.SetItems(Index, Value: longint); begin end;');
  10933. Add('var');
  10934. Add(' Obj: TObject;');
  10935. Add(' i: longint;');
  10936. Add('begin');
  10937. Add(' with TObject.Create do begin');
  10938. Add(' {#A}FInt:=3;');
  10939. Add(' i:={#B}FInt;');
  10940. Add(' i:={#C}GetSize;');
  10941. Add(' i:={#D}GetSize();');
  10942. Add(' {#E}SetSize(i);');
  10943. Add(' i:={#F}Size;');
  10944. Add(' {#G}Size:=i;');
  10945. Add(' i:={#H}Items[i];');
  10946. Add(' {#I}Items[i]:=i;');
  10947. Add(' i:={#J}FArr[i];');
  10948. Add(' {#K}FArr[i]:=i;');
  10949. Add(' end;');
  10950. ParseProgram;
  10951. aMarker:=FirstSrcMarker;
  10952. while aMarker<>nil do
  10953. begin
  10954. //writeln('TTestResolver.TestClass_WithClassInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  10955. Elements:=FindElementsAt(aMarker);
  10956. try
  10957. ActualRefWith:=false;
  10958. for i:=0 to Elements.Count-1 do
  10959. begin
  10960. El:=TPasElement(Elements[i]);
  10961. //writeln('TTestResolver.TestClass_WithClassInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  10962. if not (El.CustomData is TResolvedReference) then continue;
  10963. Ref:=TResolvedReference(El.CustomData);
  10964. if Ref.WithExprScope=nil then continue;
  10965. ActualRefWith:=true;
  10966. break;
  10967. end;
  10968. if not ActualRefWith then
  10969. RaiseErrorAtSrcMarker('expected Ref.WithExprScope<>nil at "#'+aMarker^.Identifier+', but got nil"',aMarker);
  10970. finally
  10971. Elements.Free;
  10972. end;
  10973. aMarker:=aMarker^.Next;
  10974. end;
  10975. end;
  10976. procedure TTestResolver.TestClass_ProcedureExternal;
  10977. begin
  10978. StartProgram(false);
  10979. Add('type');
  10980. Add(' TObject = class');
  10981. Add(' procedure DoIt; external ''somewhere'';');
  10982. Add(' end;');
  10983. Add('begin');
  10984. ParseProgram;
  10985. end;
  10986. procedure TTestResolver.TestClass_ReintroducePublicVarObjFPCFail;
  10987. begin
  10988. StartProgram(false);
  10989. Add([
  10990. 'type',
  10991. ' TObject = class',
  10992. ' public',
  10993. ' Some: longint;',
  10994. ' end;',
  10995. ' TCar = class(tobject)',
  10996. ' public',
  10997. ' Some: longint;',
  10998. ' end;',
  10999. 'begin']);
  11000. CheckResolverException('Duplicate identifier "Some" at afile.pp(5,5)',nDuplicateIdentifier);
  11001. end;
  11002. procedure TTestResolver.TestClass_ReintroducePublicVarDelphi;
  11003. begin
  11004. StartProgram(false);
  11005. Add([
  11006. '{$mode delphi}',
  11007. 'type',
  11008. ' TObject = class',
  11009. ' public',
  11010. ' {#Obj_Some}Some: longint;',
  11011. ' {#Obj_Foo}Foo: word;',
  11012. ' function {#Obj_Bar}Bar: string;',
  11013. ' end;',
  11014. ' TCar = class(tobject)',
  11015. ' public',
  11016. ' {#Car_Some}Some: double;',
  11017. ' function {#Car_Foo}Foo: boolean;',
  11018. ' {#Car_Bar}Bar: single;',
  11019. ' end;',
  11020. 'function TObject.Bar: string;',
  11021. 'begin',
  11022. 'end;',
  11023. 'function TCar.Foo: boolean;',
  11024. 'begin',
  11025. ' {@Car_Some}Some:=3.3;',
  11026. ' {@Car_Bar}Bar:=4.3;',
  11027. ' inherited {@Obj_Bar}Bar;',
  11028. ' inherited {@Obj_Bar}Bar();',
  11029. ' inherited {@Obj_Foo}Foo := 4;',
  11030. ' if inherited {@Obj_Some}Some = 5 then ;',
  11031. 'end;',
  11032. 'var C: TCar;',
  11033. 'begin',
  11034. ' C.Some:=1.3;']);
  11035. ParseProgram;
  11036. end;
  11037. procedure TTestResolver.TestClass_ReintroducePrivateVar;
  11038. begin
  11039. StartProgram(false);
  11040. Add('type');
  11041. Add(' TObject = class');
  11042. Add(' strict private');
  11043. Add(' Some: longint;');
  11044. Add(' end;');
  11045. Add(' TCar = class(tobject)');
  11046. Add(' public');
  11047. Add(' Some: longint;');
  11048. Add(' end;');
  11049. Add('begin');
  11050. ParseProgram;
  11051. end;
  11052. procedure TTestResolver.TestClass_ReintroduceProc;
  11053. begin
  11054. StartProgram(false);
  11055. Add('type');
  11056. Add(' TObject = class');
  11057. Add(' strict private');
  11058. Add(' Some: longint;');
  11059. Add(' end;');
  11060. Add(' TMobile = class');
  11061. Add(' strict private');
  11062. Add(' Some: string;');
  11063. Add(' end;');
  11064. Add(' TCar = class(tmobile)');
  11065. Add(' procedure {#A}Some;');
  11066. Add(' procedure {#B}Some(vA: longint);');
  11067. Add(' end;');
  11068. Add('procedure tcar.some;');
  11069. Add('begin');
  11070. Add(' {@A}Some;');
  11071. Add(' {@B}Some(1);');
  11072. Add('end;');
  11073. Add('procedure tcar.some(va: longint); begin end;');
  11074. Add('begin');
  11075. ParseProgram;
  11076. end;
  11077. procedure TTestResolver.TestClass_UntypedParam_TypeCast;
  11078. begin
  11079. StartProgram(false);
  11080. Add('type');
  11081. Add(' TObject = class end;');
  11082. Add('procedure {#ProcA}ProcA(var {#A}A);');
  11083. Add('begin');
  11084. Add(' TObject({@A}A):=TObject({@A}A);');
  11085. Add(' if TObject({@A}A)=nil then ;');
  11086. Add(' if nil=TObject({@A}A) then ;');
  11087. Add('end;');
  11088. Add('procedure {#ProcB}ProcB(const {#B}B);');
  11089. Add('begin');
  11090. Add(' if TObject({@B}B)=nil then ;');
  11091. Add(' if nil=TObject({@B}B) then ;');
  11092. Add('end;');
  11093. Add('var o: TObject;');
  11094. Add('begin');
  11095. Add(' {@ProcA}ProcA(o);');
  11096. Add(' {@ProcB}ProcB(o);');
  11097. ParseProgram;
  11098. end;
  11099. procedure TTestResolver.TestClass_Sealed;
  11100. begin
  11101. StartProgram(false);
  11102. Add('type');
  11103. Add(' TObject = class sealed');
  11104. Add(' end;');
  11105. Add('begin');
  11106. ParseProgram;
  11107. end;
  11108. procedure TTestResolver.TestClass_SealedDescendFail;
  11109. begin
  11110. StartProgram(false);
  11111. Add('type');
  11112. Add(' TObject = class sealed');
  11113. Add(' end;');
  11114. Add(' TNop = class(TObject)');
  11115. Add(' end;');
  11116. Add('begin');
  11117. CheckResolverException(sCannotCreateADescendantOfTheSealedXY,
  11118. nCannotCreateADescendantOfTheSealedXY);
  11119. end;
  11120. procedure TTestResolver.TestClass_Abstract;
  11121. begin
  11122. StartProgram(false);
  11123. Add([
  11124. 'type',
  11125. ' TObject = class',
  11126. ' constructor Create;',
  11127. ' end;',
  11128. ' TNop = class abstract(TObject)',
  11129. ' end;',
  11130. ' TBird = class(TNop)',
  11131. ' constructor Create(w: word);',
  11132. ' end;',
  11133. 'constructor TObject.Create;',
  11134. 'begin',
  11135. 'end;',
  11136. 'constructor TBird.Create(w: word);',
  11137. 'begin',
  11138. ' inherited Create;',
  11139. 'end;',
  11140. 'begin',
  11141. ' TBird.Create;']);
  11142. ParseProgram;
  11143. CheckResolverUnexpectedHints;
  11144. end;
  11145. procedure TTestResolver.TestClass_AbstractCreateFail;
  11146. begin
  11147. StartProgram(false);
  11148. Add([
  11149. 'type',
  11150. ' TObject = class',
  11151. ' constructor Create;',
  11152. ' end;',
  11153. ' TNop = class abstract(TObject)',
  11154. ' end;',
  11155. 'constructor TObject.Create;',
  11156. 'begin',
  11157. 'end;',
  11158. 'begin',
  11159. ' TNop.Create;']);
  11160. ParseProgram;
  11161. CheckResolverHint(mtWarning,nCreatingAnInstanceOfAbstractClassY,
  11162. 'Creating an instance of abstract class "TNop"');
  11163. end;
  11164. procedure TTestResolver.TestClass_VarExternal;
  11165. begin
  11166. StartProgram(false);
  11167. Add('{$modeswitch externalclass}');
  11168. Add('type');
  11169. Add(' TExtA = class external name ''ExtA''');
  11170. Add(' Id: longint external name ''$Id'';');
  11171. Add(' Data: longint external name ''$Data'';');
  11172. Add(' end;');
  11173. Add('begin');
  11174. ParseProgram;
  11175. end;
  11176. procedure TTestResolver.TestClass_WarnOverrideLowerVisibility;
  11177. begin
  11178. StartProgram(false);
  11179. Add('type');
  11180. Add(' TObject = class');
  11181. Add(' strict protected');
  11182. Add(' procedure DoStrictProtected; virtual; abstract;');
  11183. Add(' protected');
  11184. Add(' procedure DoProtected; virtual; abstract;');
  11185. Add(' public');
  11186. Add(' procedure DoPublic; virtual; abstract;');
  11187. Add(' published');
  11188. Add(' procedure DoPublished; virtual; abstract;');
  11189. Add(' end;');
  11190. Add(' TBird = class(TObject)');
  11191. Add(' private');
  11192. Add(' procedure DoStrictProtected; override;');
  11193. Add(' procedure DoProtected; override;');
  11194. Add(' protected');
  11195. Add(' procedure DoPublic; override;');
  11196. Add(' procedure DoPublished; override;');
  11197. Add(' end;');
  11198. Add('procedure TBird.DoStrictProtected; begin end;');
  11199. Add('procedure TBird.DoProtected; begin end;');
  11200. Add('procedure TBird.DoPublic; begin end;');
  11201. Add('procedure TBird.DoPublished; begin end;');
  11202. Add('begin');
  11203. ParseProgram;
  11204. CheckResolverHint(mtNote,nVirtualMethodXHasLowerVisibility,
  11205. 'Virtual method "DoStrictProtected" has a lower visibility (private) than parent class TObject (strict protected)');
  11206. CheckResolverHint(mtNote,nVirtualMethodXHasLowerVisibility,
  11207. 'Virtual method "DoProtected" has a lower visibility (private) than parent class TObject (protected)');
  11208. CheckResolverHint(mtNote,nVirtualMethodXHasLowerVisibility,
  11209. 'Virtual method "DoPublic" has a lower visibility (protected) than parent class TObject (public)');
  11210. CheckResolverHint(mtNote,nVirtualMethodXHasLowerVisibility,
  11211. 'Virtual method "DoPublished" has a lower visibility (protected) than parent class TObject (published)');
  11212. CheckResolverUnexpectedHints;
  11213. end;
  11214. procedure TTestResolver.TestClass_Const;
  11215. begin
  11216. StartProgram(false);
  11217. Add([
  11218. 'type',
  11219. ' integer = longint;',
  11220. ' TClass = class of TObject;',
  11221. ' TObject = class',
  11222. ' strict private const',
  11223. ' Prefix = ''binary'';',
  11224. ' PrefixLength = Length(Prefix);',
  11225. ' public',
  11226. ' const cI: integer = 3;',
  11227. ' procedure DoIt;',
  11228. ' class procedure DoMore;',
  11229. ' end;',
  11230. 'procedure tobject.doit;',
  11231. 'begin',
  11232. ' if cI=4 then;',
  11233. ' if 5=cI then;',
  11234. ' if Self.cI=6 then;',
  11235. ' if 7=Self.cI then;',
  11236. ' with Self do begin',
  11237. ' if cI=11 then;',
  11238. ' if 12=cI then;',
  11239. ' end;',
  11240. 'end;',
  11241. 'class procedure tobject.domore;',
  11242. 'begin',
  11243. ' if cI=8 then;',
  11244. ' if Self.cI=9 then;',
  11245. ' if 10=cI then;',
  11246. ' if 11=Self.cI then;',
  11247. ' with Self do begin',
  11248. ' if cI=13 then;',
  11249. ' if 14=cI then;',
  11250. ' end;',
  11251. 'end;',
  11252. 'var',
  11253. ' Obj: TObject;',
  11254. ' Cla: TClass;',
  11255. 'begin',
  11256. ' if TObject.cI=21 then ;',
  11257. ' if Obj.cI=22 then ;',
  11258. ' if Cla.cI=23 then ;',
  11259. ' with obj do if ci=24 then;',
  11260. ' with TObject do if ci=25 then;',
  11261. ' with Cla do if ci=26 then;']);
  11262. ParseProgram;
  11263. CheckResolverUnexpectedHints;
  11264. end;
  11265. procedure TTestResolver.TestClass_ClassMissingVarFail;
  11266. begin
  11267. StartProgram(false);
  11268. Add([
  11269. 'type',
  11270. ' TObject = class',
  11271. ' class c: word;',
  11272. ' end;',
  11273. 'begin']);
  11274. CheckParserException('Expected "Procedure" or "Function"',nParserExpectToken2Error);
  11275. end;
  11276. procedure TTestResolver.TestClass_ClassConstFail;
  11277. begin
  11278. StartProgram(false);
  11279. Add([
  11280. 'type',
  11281. ' TObject = class',
  11282. ' class const c = 1;',
  11283. ' end;',
  11284. 'begin']);
  11285. CheckParserException(sParserExpectToken2Error,nParserExpectToken2Error);
  11286. end;
  11287. procedure TTestResolver.TestClass_Enumerator;
  11288. begin
  11289. StartProgram(false);
  11290. Add([
  11291. 'type',
  11292. ' TObject = class end;',
  11293. ' TItem = TObject;',
  11294. ' TEnumerator = class',
  11295. ' FCurrent: TItem;',
  11296. ' property Current: TItem read FCurrent;',
  11297. ' function MoveNext: boolean;',
  11298. ' end;',
  11299. ' TBird = class',
  11300. ' function GetEnumerator: TEnumerator;',
  11301. ' end;',
  11302. 'function TEnumerator.MoveNext: boolean;',
  11303. 'begin',
  11304. 'end;',
  11305. 'function TBird.GetEnumerator: TEnumerator;',
  11306. 'begin',
  11307. 'end;',
  11308. 'var',
  11309. ' b: TBird;',
  11310. ' i: TItem;',
  11311. ' {#i2}i2: TItem;',
  11312. 'begin',
  11313. ' for i in b do {@i2}i2:=i;']);
  11314. ParseProgram;
  11315. end;
  11316. procedure TTestResolver.TestClass_EnumeratorFunc;
  11317. begin
  11318. StartProgram(false);
  11319. Add([
  11320. 'type',
  11321. ' TObject = class end;',
  11322. ' TItem = longint;',
  11323. ' TEnumerator = class',
  11324. ' FCurrent: TItem;',
  11325. ' property Current: TItem read FCurrent;',
  11326. ' function MoveNext: boolean;',
  11327. ' function GetEnumerator: TEnumerator;',
  11328. ' end;',
  11329. 'function TEnumerator.MoveNext: boolean;',
  11330. 'begin',
  11331. 'end;',
  11332. 'function TEnumerator.GetEnumerator: TEnumerator;',
  11333. 'begin',
  11334. 'end;',
  11335. 'function GetIt: TEnumerator;',
  11336. 'begin',
  11337. 'end;',
  11338. 'var',
  11339. ' i, i2: TItem;',
  11340. 'begin',
  11341. ' for i in GetIt do i2:=i;']);
  11342. ParseProgram;
  11343. end;
  11344. procedure TTestResolver.TestClass_ForInPropertyStaticArray;
  11345. begin
  11346. StartProgram(false);
  11347. Add([
  11348. 'type',
  11349. ' TMonthNameArray = array [1..12] of string;',
  11350. ' TMonthNames = TMonthNameArray;',
  11351. ' TObject = class',
  11352. ' private',
  11353. ' function GetLongMonthNames: TMonthNames; virtual; abstract;',
  11354. ' public',
  11355. ' Property LongMonthNames : TMonthNames Read GetLongMonthNames;',
  11356. ' end;',
  11357. 'var f: TObject;',
  11358. ' Month: string;',
  11359. 'begin',
  11360. ' for Month in f.LongMonthNames do ;',
  11361. '']);
  11362. ParseProgram;
  11363. end;
  11364. procedure TTestResolver.TestClass_TypeAlias;
  11365. begin
  11366. StartProgram(false);
  11367. Add([
  11368. 'type',
  11369. ' TObject = class',
  11370. ' end;',
  11371. ' TBird = type TObject;',
  11372. 'var',
  11373. ' o: TObject;',
  11374. ' b: TBird;',
  11375. 'begin',
  11376. ' o:=b;',
  11377. '']);
  11378. ParseProgram;
  11379. end;
  11380. procedure TTestResolver.TestClass_Message;
  11381. begin
  11382. StartProgram(false);
  11383. Add([
  11384. 'const',
  11385. ' FlyId = 2;',
  11386. ' RunStr = ''Fast'';',
  11387. 'type',
  11388. ' TObject = class',
  11389. ' procedure Fly(var msg); message 3+FlyId;',
  11390. ' procedure Run(var msg); virtual; abstract; message ''prefix''+RunStr;',
  11391. ' end;',
  11392. 'procedure TObject.Fly(var msg);',
  11393. 'begin',
  11394. 'end;',
  11395. 'begin',
  11396. '']);
  11397. ParseProgram;
  11398. end;
  11399. procedure TTestResolver.TestClass_Message_MissingParamFail;
  11400. begin
  11401. StartProgram(false);
  11402. Add([
  11403. 'type',
  11404. ' TObject = class',
  11405. ' procedure Fly; message 3;',
  11406. ' end;',
  11407. 'procedure TObject.Fly;',
  11408. 'begin',
  11409. 'end;',
  11410. 'begin',
  11411. '']);
  11412. CheckResolverException(sMessageHandlersInvalidParams,nMessageHandlersInvalidParams);
  11413. end;
  11414. procedure TTestResolver.TestClass_ExtRTTI_Explicit;
  11415. begin
  11416. Parser.Options:=Parser.Options+[po_CheckDirectiveRTTI];
  11417. StartProgram(false);
  11418. Add([
  11419. 'type',
  11420. ' {$RTTI explicit Fields([vcProtected,vcPublic])}',
  11421. ' {#rtti_TObject explicit Fields([vcProtected,vcPublic])}TObject = class',
  11422. ' end;',
  11423. ' {$RTTI explicit Fields([vcPrivate,vcProtected])}',
  11424. ' {#rtti_TAnimal explicit Fields([vcPrivate,vcProtected])}TAnimal = class',
  11425. ' end;',
  11426. ' {$RTTI inherit Fields([vcPublic])}',
  11427. ' {#rtti_TBird inherit Fields([vcPrivate,vcProtected,vcPublic])}TBird = class(TAnimal)',
  11428. ' end;',
  11429. 'begin',
  11430. '']);
  11431. ParseProgram;
  11432. CheckRTTIVisibilityMarkers;
  11433. end;
  11434. procedure TTestResolver.TestClass_PublishedClassVarFail;
  11435. begin
  11436. StartProgram(false);
  11437. Add('type');
  11438. Add(' TObject = class');
  11439. Add(' published');
  11440. Add(' class var Id: longint;');
  11441. Add(' end;');
  11442. Add('begin');
  11443. CheckResolverException(sSymbolCannotBePublished,nSymbolCannotBePublished);
  11444. end;
  11445. procedure TTestResolver.TestClass_PublishedClassPropertyFail;
  11446. begin
  11447. StartProgram(false);
  11448. Add('type');
  11449. Add(' TObject = class');
  11450. Add(' class var FA: longint;');
  11451. Add(' published');
  11452. Add(' class property A: longint read FA;');
  11453. Add(' end;');
  11454. Add('begin');
  11455. CheckResolverException('Invalid published property modifier "class"',
  11456. nInvalidXModifierY);
  11457. end;
  11458. procedure TTestResolver.TestClass_PublishedClassFunctionFail;
  11459. begin
  11460. StartProgram(false);
  11461. Add('type');
  11462. Add(' TObject = class');
  11463. Add(' published');
  11464. Add(' class procedure DoIt;');
  11465. Add(' end;');
  11466. Add('class procedure TObject.DoIt; begin end;');
  11467. Add('begin');
  11468. CheckResolverException(sSymbolCannotBePublished,nSymbolCannotBePublished);
  11469. end;
  11470. procedure TTestResolver.TestClass_PublishedOverloadFail;
  11471. begin
  11472. StartProgram(false);
  11473. Add('type');
  11474. Add(' TObject = class');
  11475. Add(' published');
  11476. Add(' procedure DoIt;');
  11477. Add(' procedure DoIt(i: longint);');
  11478. Add(' end;');
  11479. Add('procedure TObject.DoIt; begin end;');
  11480. Add('procedure TObject.DoIt(i: longint); begin end;');
  11481. Add('begin');
  11482. CheckResolverException(sDuplicatePublishedMethodXAtY,nDuplicatePublishedMethodXAtY);
  11483. end;
  11484. procedure TTestResolver.TestNestedClass;
  11485. begin
  11486. StartProgram(false);
  11487. Add([
  11488. 'type',
  11489. ' TObject = class end;',
  11490. ' TBear = class',
  11491. ' type',
  11492. ' TNumber = byte;',
  11493. ' TLeg = class',
  11494. ' constructor Create(i: TNumber);',
  11495. ' function {#Walk}Walk(i: TNumber): TLeg;',
  11496. ' end;',
  11497. ' procedure Move(i: TNumber);',
  11498. ' end;',
  11499. 'procedure TBear.Move(i: TNumber);',
  11500. 'var Leg: TLeg;',
  11501. 'begin',
  11502. ' Leg:=TLeg.Create(i);',
  11503. ' Leg:=TBear.TLeg.Create(i);',
  11504. 'end;',
  11505. 'constructor tBear.tLeg.Create(i: TNumber);',
  11506. 'begin',
  11507. ' {@Walk}Walk(i);',
  11508. ' Self.{@Walk}Walk(i);',
  11509. 'end;',
  11510. 'function tBear.tLeg.walk(i: TNumber): TLeg;',
  11511. 'begin',
  11512. ' Result:=Walk(3);',
  11513. 'end;',
  11514. 'var Leg: TBear.TLeg;',
  11515. 'begin',
  11516. ' Leg:=TBear.TLeg.Create(2);',
  11517. ' Leg:=Leg.Walk(3);',
  11518. '']);
  11519. ParseProgram;
  11520. end;
  11521. procedure TTestResolver.TestNestedClass_Forward;
  11522. begin
  11523. StartProgram(false);
  11524. Add([
  11525. 'type',
  11526. ' TObject = class',
  11527. ' type',
  11528. ' TArm = class;',
  11529. ' TLeg = class',
  11530. ' procedure Send(Arm: TArm);',
  11531. ' end;',
  11532. ' TArm = class',
  11533. ' i: byte;',
  11534. ' end;',
  11535. ' end;',
  11536. 'procedure tObject.tLeg.send(Arm: TArm);',
  11537. 'begin',
  11538. ' Arm.i:=3;',
  11539. 'end;',
  11540. 'var',
  11541. ' Leg: TObject.TLeg;',
  11542. ' Arm: TObject.TArm;',
  11543. 'begin',
  11544. ' Leg.Send(Arm);',
  11545. '']);
  11546. ParseProgram;
  11547. end;
  11548. procedure TTestResolver.TestNestedClass_StrictPrivateFail;
  11549. begin
  11550. StartProgram(false);
  11551. Add([
  11552. 'type',
  11553. ' TObject = class',
  11554. ' strict private type',
  11555. ' TArm = class',
  11556. ' i: byte;',
  11557. ' end;',
  11558. ' end;',
  11559. 'var',
  11560. ' Arm: TObject.TArm;',
  11561. 'begin',
  11562. '']);
  11563. CheckResolverException('Can''t access strict private member TArm',nCantAccessXMember);
  11564. end;
  11565. procedure TTestResolver.TestNestedClass_AccessStrictPrivate;
  11566. begin
  11567. StartProgram(false);
  11568. Add([
  11569. 'type',
  11570. ' TObject = class',
  11571. ' public type',
  11572. ' TWing = class',
  11573. ' procedure Fly;',
  11574. ' end;',
  11575. ' strict private',
  11576. ' class var i: longint;',
  11577. ' end;',
  11578. 'procedure TObject.TWing.Fly;',
  11579. 'begin',
  11580. ' i:=3;',
  11581. 'end;',
  11582. 'begin']);
  11583. ParseProgram;
  11584. end;
  11585. procedure TTestResolver.TestNestedClass_AccessParent;
  11586. begin
  11587. StartUnit(false);
  11588. Add([
  11589. 'interface',
  11590. 'type',
  11591. ' TObject = class',
  11592. ' end;',
  11593. ' TLimb = class',
  11594. ' {#tlimb_d}d: longint;',
  11595. ' end;',
  11596. ' TAnt = boolean;',
  11597. ' TBird = class',
  11598. ' public type',
  11599. ' TBody = class',
  11600. ' public type',
  11601. ' TAnt = word;',
  11602. ' TWing = class(TLimb)',
  11603. ' {#ant}ant: TAnt;',
  11604. ' procedure Fly(i: longint);',
  11605. ' end;',
  11606. ' public',
  11607. ' class var {#tbody_a}a, {#tbody_b}b, {#tbody_d}d, {#tbody_e}e: longint;',
  11608. ' end;',
  11609. ' public',
  11610. ' class var {#tbird_a}a, {#tbird_b}b, {#tbird_c}c, {#tbird_d}d, {#tbird_e}e: longint;',
  11611. ' end;',
  11612. 'var {#intf_a}a, {#intf_d}d: longint;',
  11613. 'implementation',
  11614. 'var {#impl_e}e: longint;',
  11615. 'procedure TBird.TBody.TWing.Fly(i: longint);',
  11616. 'begin',
  11617. ' {@ant}ant:=2;',
  11618. ' {@intf_a}a:=3;',
  11619. ' {@tbody_b}b:=4;',
  11620. ' {@tbird_c}c:=5;',
  11621. ' {@tlimb_d}d:=6;',
  11622. ' {@impl_e}e:=7;',
  11623. 'end;',
  11624. '']);
  11625. ParseUnit;
  11626. end;
  11627. procedure TTestResolver.TestNestedClass_BodyAccessParentVarFail;
  11628. begin
  11629. StartProgram(false);
  11630. Add([
  11631. 'type',
  11632. ' TObject = class end;',
  11633. ' TBird = class',
  11634. ' public type',
  11635. ' TWing = class',
  11636. ' procedure Fly;',
  11637. ' end;',
  11638. ' public',
  11639. ' var i: longint;',
  11640. ' end;',
  11641. 'procedure TBird.TWing.Fly;',
  11642. 'begin',
  11643. ' i:=3;',
  11644. 'end;',
  11645. 'begin']);
  11646. CheckResolverException('Instance member "i" inaccessible here',nInstanceMemberXInaccessible);
  11647. end;
  11648. procedure TTestResolver.TestNestedClass_PropertyAccessParentVarFail;
  11649. begin
  11650. StartProgram(false);
  11651. Add([
  11652. 'type',
  11653. ' TObject = class end;',
  11654. ' TBird = class',
  11655. ' fSize: word;',
  11656. ' public type',
  11657. ' TWing = class',
  11658. ' property Size: word read fSize;',
  11659. ' end;',
  11660. ' end;',
  11661. 'begin']);
  11662. CheckResolverException('identifier not found "fSize"',nIdentifierNotFound);
  11663. end;
  11664. procedure TTestResolver.TestExternalClass;
  11665. begin
  11666. StartProgram(false);
  11667. Add('type');
  11668. Add('{$modeswitch externalclass}');
  11669. Add(' TExtA = class external ''namespace'' name ''symbol''');
  11670. Add(' Id: longint;');
  11671. Add(' end;');
  11672. Add('begin');
  11673. ParseProgram;
  11674. end;
  11675. procedure TTestResolver.TestExternalClass_Descendant;
  11676. begin
  11677. StartProgram(false);
  11678. Add('type');
  11679. Add('{$modeswitch externalclass}');
  11680. Add(' TExtA = class external ''namespace'' name ''symbol''');
  11681. Add(' Id: longint;');
  11682. Add(' end;');
  11683. Add(' TExtB = class external ''namespace'' name ''symbol''(TExtA)');
  11684. Add(' end;');
  11685. Add('begin');
  11686. ParseProgram;
  11687. end;
  11688. procedure TTestResolver.TestExternalClass_HintMethodHidesNonVirtualMethodExact;
  11689. begin
  11690. StartProgram(false);
  11691. Add([
  11692. '{$modeswitch externalclass}',
  11693. 'type',
  11694. ' TJSObject = class external name ''JSObject''',
  11695. ' procedure DoIt(p: pointer);',
  11696. ' end;',
  11697. ' TBird = class external name ''Bird''(TJSObject)',
  11698. ' procedure DoIt(p: pointer);',
  11699. ' end;',
  11700. 'procedure TJSObject.DoIt(p: pointer);',
  11701. 'begin',
  11702. ' if p=nil then ;',
  11703. 'end;',
  11704. 'procedure TBird.DoIt(p: pointer); begin end;',
  11705. 'var b: TBird;',
  11706. 'begin',
  11707. ' b.DoIt(nil);']);
  11708. ParseProgram;
  11709. CheckResolverHint(mtHint,nMethodHidesNonVirtualMethodExactly,
  11710. 'method hides identifier at "afile.pp(5,19)". Use reintroduce');
  11711. end;
  11712. procedure TTestResolver.TestClassOf;
  11713. begin
  11714. StartProgram(false);
  11715. Add([
  11716. 'type',
  11717. ' {#TClass}{=TObj}TClass = class of TObject;',
  11718. ' {#TOBJ}TObject = class',
  11719. ' ClassType: TClass; ',
  11720. ' end;',
  11721. 'type',
  11722. ' {#TMobile}TMobile = class',
  11723. ' end;',
  11724. ' {#TMobiles}{=TMobile}TMobiles = class of TMobile;',
  11725. 'type',
  11726. ' {#TCars}{=TCar}TCars = class of TCar;',
  11727. ' {#TShips}{=TShip}TShips = class of TShip;',
  11728. ' {#TCar}TCar = class(TMobile)',
  11729. ' end;',
  11730. ' {#TShip}TShip = class(TMobile)',
  11731. ' end;',
  11732. 'var',
  11733. ' o: TObject;',
  11734. ' c: TClass;',
  11735. ' mobile: TMobile;',
  11736. ' mobiletype: TMobiles;',
  11737. ' car: TCar;',
  11738. ' cartype: TCars;',
  11739. ' ship: TShip;',
  11740. ' shiptype: TShips;',
  11741. ' p: pointer;',
  11742. 'begin',
  11743. ' c:=nil;',
  11744. ' c:=o.ClassType;',
  11745. ' if c=nil then;',
  11746. ' if nil=c then;',
  11747. ' if c=o.ClassType then ;',
  11748. ' if c<>o.ClassType then ;',
  11749. ' if Assigned(o) then ;',
  11750. ' if Assigned(o.ClassType) then ;',
  11751. ' if Assigned(c) then ;',
  11752. ' mobiletype:=TMobile;',
  11753. ' mobiletype:=TCar;',
  11754. ' mobiletype:=TShip;',
  11755. ' mobiletype:=cartype;',
  11756. ' if mobiletype=nil then ;',
  11757. ' if nil=mobiletype then ;',
  11758. ' if mobiletype=TShip then ;',
  11759. ' if TShip=mobiletype then ;',
  11760. ' if mobiletype<>TShip then ;',
  11761. ' if mobile is mobiletype then ;',
  11762. ' if car is mobiletype then ;',
  11763. ' if mobile is cartype then ;',
  11764. ' p:=c;',
  11765. ' if p=c then ;',
  11766. ' if c=p then ;',
  11767. '']);
  11768. ParseProgram;
  11769. end;
  11770. procedure TTestResolver.TestClassOfAlias;
  11771. begin
  11772. StartProgram(false);
  11773. Add([
  11774. 'type',
  11775. ' TObject = class',
  11776. ' end;',
  11777. ' TBird = TObject;',
  11778. ' TBirds = class of TBird;',
  11779. ' TEagles = TBirds;',
  11780. 'var',
  11781. ' o: TBird;',
  11782. ' c: TEagles;',
  11783. 'begin',
  11784. ' c:=TObject;',
  11785. ' c:=TBird;',
  11786. ' if c=TObject then ;',
  11787. ' if c=TBird then ;',
  11788. ' if o is c then ;',
  11789. '']);
  11790. ParseProgram;
  11791. end;
  11792. procedure TTestResolver.TestClassOfNonClassFail;
  11793. begin
  11794. StartProgram(false);
  11795. Add('type');
  11796. Add(' TCars = class of longint;');
  11797. Add('begin');
  11798. CheckResolverException('Incompatible types: got "Longint" expected "class"',
  11799. nIncompatibleTypesGotExpected);
  11800. end;
  11801. procedure TTestResolver.TestClassOfAssignClassOfFail;
  11802. begin
  11803. StartProgram(false);
  11804. Add([
  11805. 'type',
  11806. ' TObject = class end;',
  11807. ' TClass = class of TObject;',
  11808. 'var c: TClass;',
  11809. 'begin',
  11810. ' c:=TClass;']);
  11811. CheckResolverException('Incompatible types: got "type class-of" expected "class of TObject"',
  11812. nIncompatibleTypesGotExpected);
  11813. end;
  11814. procedure TTestResolver.TestClassOfIsOperatorFail;
  11815. begin
  11816. StartProgram(false);
  11817. Add('type');
  11818. Add(' TObject = class end;');
  11819. Add(' TCar = class end;');
  11820. Add(' TCars = class of TCar;');
  11821. Add('var cars: TCars;');
  11822. Add('begin');
  11823. Add(' if cars is TCars then ;');
  11824. CheckResolverException('left side of is-operator expects a class, but got "class of"',
  11825. nLeftSideOfIsOperatorExpectsAClassButGot);
  11826. end;
  11827. procedure TTestResolver.TestClassOfAsOperatorFail;
  11828. begin
  11829. StartProgram(false);
  11830. Add('type');
  11831. Add(' TObject = class end;');
  11832. Add(' TCar = class end;');
  11833. Add(' TCars = class of TCar;');
  11834. Add('var');
  11835. Add(' o: TObject;');
  11836. Add(' cars: TCars;');
  11837. Add('begin');
  11838. Add(' cars:=cars as TCars;');
  11839. CheckResolverException('Operator is not overloaded: "TCars" as "class of TCars"',
  11840. nOperatorIsNotOverloadedAOpB);
  11841. end;
  11842. procedure TTestResolver.TestClassOfIsOperator;
  11843. begin
  11844. StartProgram(false);
  11845. ResolverEngine.Options:=ResolverEngine.Options+[proClassOfIs];
  11846. Add('type');
  11847. Add(' TObject = class end;');
  11848. Add(' TClass = class of TObject;');
  11849. Add(' TCar = class end;');
  11850. Add(' TCars = class of TCar;');
  11851. Add('var C: TClass;');
  11852. Add(' D: TCars;');
  11853. Add('begin');
  11854. Add(' if C is TCar then;');
  11855. Add(' if C is TCars then;');
  11856. Add(' if C is D then ;');
  11857. ParseProgram;
  11858. end;
  11859. procedure TTestResolver.TestClass_ClassVar;
  11860. begin
  11861. StartProgram(false);
  11862. Add('type');
  11863. Add(' TObject = class');
  11864. Add(' class var GlobalId: longint;');
  11865. Add(' end;');
  11866. Add(' TObjectClass = class of TObject;');
  11867. Add('var');
  11868. Add(' o: TObject;');
  11869. Add(' oc: TObjectClass;');
  11870. Add('begin');
  11871. Add(' o.GlobalId:=3;');
  11872. Add(' if o.GlobalId=4 then ;');
  11873. Add(' if 5=o.GlobalId then ;');
  11874. Add(' TObject.GlobalId:=6;');
  11875. Add(' if TObject.GlobalId=7 then ;');
  11876. Add(' if 8=TObject.GlobalId then ;');
  11877. Add(' oc.GlobalId:=9;');
  11878. Add(' if oc.GlobalId=10 then ;');
  11879. Add(' if 11=oc.GlobalId then ;');
  11880. ParseProgram;
  11881. end;
  11882. procedure TTestResolver.TestClassOfDotClassVar;
  11883. begin
  11884. StartProgram(false);
  11885. Add('type');
  11886. Add(' TObject = class');
  11887. Add(' class var Id: longint;');
  11888. Add(' end;');
  11889. Add(' TObjectClass = class of TObject;');
  11890. Add('var');
  11891. Add(' oc: TObjectClass;');
  11892. Add('begin');
  11893. Add(' oc.Id:=3;');
  11894. Add(' if oc.Id=4 then ;');
  11895. Add(' if 5=oc.Id then ;');
  11896. Add(' TObject.Id:=3;');
  11897. Add(' if TObject.Id=4 then ;');
  11898. Add(' if 5=TObject.Id then ;');
  11899. ParseProgram;
  11900. end;
  11901. procedure TTestResolver.TestClassOfDotVarFail;
  11902. begin
  11903. StartProgram(false);
  11904. Add('type');
  11905. Add(' TObject = class');
  11906. Add(' Id: longint;');
  11907. Add(' end;');
  11908. Add(' TObjectClass = class of TObject;');
  11909. Add('var');
  11910. Add(' oc: TObjectClass;');
  11911. Add('begin');
  11912. Add(' oc.Id:=3;');
  11913. CheckResolverException(sInstanceMemberXInaccessible,
  11914. nInstanceMemberXInaccessible);
  11915. end;
  11916. procedure TTestResolver.TestClassOfDotClassProc;
  11917. begin
  11918. StartProgram(false);
  11919. Add('type');
  11920. Add(' TObject = class');
  11921. Add(' class procedure ProcA;');
  11922. Add(' class function FuncB: longint;');
  11923. Add(' class procedure ProcC(i: longint);');
  11924. Add(' class function FuncD(i: longint): longint;');
  11925. Add(' end;');
  11926. Add(' TObjectClass = class of TObject;');
  11927. Add('class procedure TObject.ProcA; begin end;');
  11928. Add('class function TObject.FuncB: longint; begin end;');
  11929. Add('class procedure TObject.ProcC(i: longint); begin end;');
  11930. Add('class function TObject.FuncD(i: longint): longint; begin end;');
  11931. Add('var');
  11932. Add(' o: TObject;');
  11933. Add(' oc: TObjectClass;');
  11934. Add('begin');
  11935. Add(' o.ProcA;');
  11936. Add(' oc.ProcA;');
  11937. Add(' TObject.ProcA;');
  11938. Add(' o.FuncB;');
  11939. Add(' o.FuncB();');
  11940. Add(' oc.FuncB;');
  11941. Add(' oc.FuncB();');
  11942. Add(' TObject.FuncB;');
  11943. Add(' TObject.FuncB();');
  11944. Add(' if oc.FuncB=3 then ;');
  11945. Add(' if oc.FuncB()=4 then ;');
  11946. Add(' if 5=oc.FuncB then ;');
  11947. Add(' if 6=oc.FuncB() then ;');
  11948. Add(' oc.ProcC(7);');
  11949. Add(' TObject.ProcC(8);');
  11950. Add(' oc.FuncD(7);');
  11951. Add(' TObject.FuncD(8);');
  11952. Add(' if oc.FuncD(9)=10 then ;');
  11953. Add(' if 11=oc.FuncD(12) then ;');
  11954. Add(' if TObject.FuncD(13)=14 then ;');
  11955. Add(' if 15=TObject.FuncD(16) then ;');
  11956. ParseProgram;
  11957. end;
  11958. procedure TTestResolver.TestClassOfDotProcFail;
  11959. begin
  11960. StartProgram(false);
  11961. Add('type');
  11962. Add(' TObject = class');
  11963. Add(' procedure ProcA;');
  11964. Add(' end;');
  11965. Add(' TObjectClass = class of TObject;');
  11966. Add('procedure TObject.ProcA; begin end;');
  11967. Add('var');
  11968. Add(' oc: TObjectClass;');
  11969. Add('begin');
  11970. Add(' oc.ProcA;');
  11971. CheckResolverException(sInstanceMemberXInaccessible,
  11972. nInstanceMemberXInaccessible);
  11973. end;
  11974. procedure TTestResolver.TestClassOfDotClassProperty;
  11975. begin
  11976. StartProgram(false);
  11977. Add('type');
  11978. Add(' TObject = class');
  11979. Add(' class var FA: longint;');
  11980. Add(' class function GetA: longint; static;');
  11981. Add(' class procedure SetA(Value: longint); static;');
  11982. Add(' class property A1: longint read FA write SetA;');
  11983. Add(' class property A2: longint read GetA write FA;');
  11984. Add(' end;');
  11985. Add(' TObjectClass = class of TObject;');
  11986. Add('class function TObject.GetA: longint; begin end;');
  11987. Add('class procedure TObject.SetA(Value: longint); begin end;');
  11988. Add('var');
  11989. Add(' o: TObject;');
  11990. Add(' oc: TObjectClass;');
  11991. Add('begin');
  11992. Add(' o.A1:=3;');
  11993. Add(' if o.A1=4 then ;');
  11994. Add(' if 5=o.A1 then ;');
  11995. Add(' oc.A1:=6;');
  11996. Add(' if oc.A1=7 then ;');
  11997. Add(' if 8=oc.A1 then ;');
  11998. Add(' TObject.A1:=9;');
  11999. Add(' if TObject.A1=10 then ;');
  12000. Add(' if 11=TObject.A1 then ;');
  12001. ParseProgram;
  12002. end;
  12003. procedure TTestResolver.TestClassOfDotPropertyFail;
  12004. begin
  12005. StartProgram(false);
  12006. Add('type');
  12007. Add(' TObject = class');
  12008. Add(' FA: longint;');
  12009. Add(' property A: longint read FA;');
  12010. Add(' end;');
  12011. Add(' TObjectClass = class of TObject;');
  12012. Add('var');
  12013. Add(' oc: TObjectClass;');
  12014. Add('begin');
  12015. Add(' if oc.A=3 then ;');
  12016. CheckResolverException(sInstanceMemberXInaccessible,
  12017. nInstanceMemberXInaccessible);
  12018. end;
  12019. procedure TTestResolver.TestClass_ClassProcSelf;
  12020. begin
  12021. StartProgram(false);
  12022. Add('type');
  12023. Add(' TObject = class');
  12024. Add(' class var GlobalId: longint;');
  12025. Add(' class procedure ProcA;');
  12026. Add(' end;');
  12027. Add(' TClass = class of TObject;');
  12028. Add('class procedure TObject.ProcA;');
  12029. Add('var c: TClass;');
  12030. Add('begin');
  12031. Add(' if Self=nil then ;');
  12032. Add(' if Self.GlobalId=3 then ;');
  12033. Add(' if 4=Self.GlobalId then ;');
  12034. Add(' Self.GlobalId:=5;');
  12035. Add(' c:=Self;');
  12036. Add(' c:=TClass(Self);');
  12037. Add(' if Self=c then ;');
  12038. Add('end;');
  12039. Add('begin');
  12040. ParseProgram;
  12041. end;
  12042. procedure TTestResolver.TestClass_ClassProcSelfTypeCastFail;
  12043. begin
  12044. StartProgram(false);
  12045. Add('type');
  12046. Add(' TObject = class');
  12047. Add(' class procedure ProcA;');
  12048. Add(' end;');
  12049. Add('class procedure TObject.ProcA;');
  12050. Add('begin');
  12051. Add(' if TObject(Self)=nil then ;');
  12052. Add('end;');
  12053. Add('begin');
  12054. CheckResolverException('Illegal type conversion: "Self" to "class TObject"',
  12055. nIllegalTypeConversionTo);
  12056. end;
  12057. procedure TTestResolver.TestClass_ClassMembers;
  12058. begin
  12059. StartProgram(false);
  12060. Add('type');
  12061. Add(' TObject = class');
  12062. Add(' end;');
  12063. Add(' TMobile = class');
  12064. Add(' public');
  12065. Add(' MobileId: longint;');
  12066. Add(' class var LastVal: longint;');
  12067. Add(' constructor Create; virtual;');
  12068. Add(' class procedure ClProcA;');
  12069. Add(' class function ClFuncB: longint;');
  12070. Add(' class function StFuncC: longint; static;');
  12071. Add(' class property ClMobileId: longint read StFuncC write LastVal;');
  12072. Add(' end;');
  12073. Add(' TMobiles = class of TMobile;');
  12074. Add(' TCars = class of TCar;');
  12075. Add(' TCar = class(TMobile)');
  12076. Add(' public');
  12077. Add(' CarId: longint;');
  12078. Add(' class var LastCarVal: longint;');
  12079. Add(' constructor Create; override;');
  12080. Add(' end;');
  12081. Add('constructor TMobile.Create;');
  12082. Add('begin');
  12083. Add(' Self.MobileId:=7;');
  12084. Add(' LastVal:=LastVal+ClMobileId+1;');
  12085. Add(' ClMobileId:=MobileId+3;');
  12086. Add(' TCar(Self).CarId:=4;');
  12087. Add('end;');
  12088. Add('class procedure TMobile.ClProcA;');
  12089. Add('var');
  12090. Add(' m: TMobiles;');
  12091. Add('begin');
  12092. Add(' LastVal:=9;');
  12093. Add(' Self.LastVal:=ClFuncB+ClMobileId;');
  12094. Add(' m:=Self;');
  12095. Add(' if m=Self then ;');
  12096. Add('end;');
  12097. Add('class function TMobile.ClFuncB: longint;');
  12098. Add('begin');
  12099. Add(' if LastVal=3 then ;');
  12100. Add(' Result:=Self.LastVal-ClMobileId;');
  12101. Add('end;');
  12102. Add('class function TMobile.StFuncC: longint;');
  12103. Add('begin');
  12104. Add(' Result:=LastVal;');
  12105. Add(' // Forbidden: no Self in static methods');
  12106. Add('end;');
  12107. Add('');
  12108. Add('constructor TCar.Create;');
  12109. Add('begin');
  12110. Add(' inherited Create;');
  12111. Add(' Self.CarId:=8;');
  12112. Add(' TMobile(Self).LastVal:=5;');
  12113. Add(' if TMobile(Self).LastVal=25 then ;');
  12114. Add('end;');
  12115. Add('');
  12116. Add('var');
  12117. Add(' car: TCar;');
  12118. Add(' cartype: TCars;');
  12119. Add('begin');
  12120. Add(' car:=TCar.Create;');
  12121. Add(' car.MobileId:=10;');
  12122. Add(' car.ClProcA;');
  12123. Add(' exit;');
  12124. Add(' car.ClMobileId:=11;');
  12125. Add(' if car.ClFuncB=16 then ;');
  12126. Add(' if 17=car.ClFuncB then ;');
  12127. Add(' cartype:=TCar;');
  12128. Add(' cartype.LastVal:=18;');
  12129. Add(' if cartype.LastVal=19 then ;');
  12130. Add(' if 20=cartype.LastVal then ;');
  12131. ParseProgram;
  12132. end;
  12133. procedure TTestResolver.TestClassOf_AsFail;
  12134. begin
  12135. StartProgram(false);
  12136. Add('type');
  12137. Add(' TClass = class of TObject;');
  12138. Add(' TObject = class');
  12139. Add(' end;');
  12140. Add('var');
  12141. Add(' c: tclass;');
  12142. Add('begin');
  12143. Add(' c:=c as TClass;');
  12144. CheckResolverException('Operator is not overloaded: "TClass" as "class of TClass"',
  12145. nOperatorIsNotOverloadedAOpB);
  12146. end;
  12147. procedure TTestResolver.TestClassOf_MemberAsFail;
  12148. begin
  12149. StartProgram(false);
  12150. Add('type');
  12151. Add(' TClass = class of TObject;');
  12152. Add(' TObject = class');
  12153. Add(' c: tclass;');
  12154. Add(' end;');
  12155. Add('var o: TObject;');
  12156. Add('begin');
  12157. Add(' o.c:=o.c as TClass;');
  12158. CheckResolverException('Operator is not overloaded: "TClass" as "class of TClass"',nOperatorIsNotOverloadedAOpB);
  12159. end;
  12160. procedure TTestResolver.TestClassOf_IsFail;
  12161. begin
  12162. StartProgram(false);
  12163. Add('type');
  12164. Add(' TClass = class of TObject;');
  12165. Add(' TObject = class');
  12166. Add(' end;');
  12167. Add('var');
  12168. Add(' c: tclass;');
  12169. Add('begin');
  12170. Add(' if c is TObject then;');
  12171. CheckResolverException('left side of is-operator expects a class, but got "class of"',
  12172. nLeftSideOfIsOperatorExpectsAClassButGot);
  12173. end;
  12174. procedure TTestResolver.TestClass_TypeCast;
  12175. begin
  12176. StartProgram(false);
  12177. Add('type');
  12178. Add(' TObject = class');
  12179. Add(' class procedure {#TObject_DoIt}DoIt;');
  12180. Add(' end;');
  12181. Add(' TClass = class of TObject;');
  12182. Add(' TMobile = class');
  12183. Add(' class procedure {#TMobile_DoIt}DoIt;');
  12184. Add(' end;');
  12185. Add(' TMobileClass = class of TMobile;');
  12186. Add(' TCar = class(TMobile)');
  12187. Add(' class procedure {#TCar_DoIt}DoIt;');
  12188. Add(' end;');
  12189. Add(' TCarClass = class of TCar;');
  12190. Add('class procedure TObject.DoIt;');
  12191. Add('begin');
  12192. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  12193. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  12194. Add('end;');
  12195. Add('class procedure TMobile.DoIt;');
  12196. Add('begin');
  12197. Add(' TClass(Self).{@TObject_DoIt}DoIt;');
  12198. Add(' TMobileClass(Self).{@TMobile_DoIt}DoIt;');
  12199. Add(' TCarClass(Self).{@TCar_DoIt}DoIt;');
  12200. Add('end;');
  12201. Add('class procedure TCar.DoIt; begin end;');
  12202. Add('var');
  12203. Add(' ObjC: TClass;');
  12204. Add(' MobileC: TMobileClass;');
  12205. Add(' CarC: TCarClass;');
  12206. Add('begin');
  12207. Add(' ObjC.{@TObject_DoIt}DoIt;');
  12208. Add(' MobileC.{@TMobile_DoIt}DoIt;');
  12209. Add(' CarC.{@TCar_DoIt}DoIt;');
  12210. Add(' TClass(ObjC).{@TObject_DoIt}DoIt;');
  12211. Add(' TMobileClass(ObjC).{@TMobile_DoIt}DoIt;');
  12212. Add(' TCarClass(ObjC).{@TCar_DoIt}DoIt;');
  12213. Add(' TClass(MobileC).{@TObject_DoIt}DoIt;');
  12214. Add(' TMobileClass(MobileC).{@TMobile_DoIt}DoIt;');
  12215. Add(' TCarClass(MobileC).{@TCar_DoIt}DoIt;');
  12216. Add(' TClass(CarC).{@TObject_DoIt}DoIt;');
  12217. Add(' TMobileClass(CarC).{@TMobile_DoIt}DoIt;');
  12218. Add(' TCarClass(CarC).{@TCar_DoIt}DoIt;');
  12219. ParseProgram;
  12220. end;
  12221. procedure TTestResolver.TestClassOf_AlwaysForward;
  12222. begin
  12223. AddModuleWithIntfImplSrc('unit2.pp',
  12224. LinesToStr([
  12225. 'type',
  12226. ' TObject = class',
  12227. ' end;',
  12228. ' TCar = class',
  12229. ' end;',
  12230. ' TCarry = TCar;']),
  12231. LinesToStr([
  12232. '']));
  12233. StartProgram(true);
  12234. Add('uses unit2;');
  12235. Add('type');
  12236. Add(' {#C}{=A}TCars = class of TCarry;');
  12237. Add(' {#A}TCarry = class');
  12238. Add(' class var {#B}B: longint;');
  12239. Add(' end;');
  12240. Add('begin');
  12241. Add(' {@C}TCars.{@B}B:=3;');
  12242. ParseProgram;
  12243. end;
  12244. procedure TTestResolver.TestClassOf_ClassOfBeforeClass_FuncResult;
  12245. begin
  12246. StartProgram(false);
  12247. Add('type');
  12248. Add(' TClass = class of TObject;');
  12249. Add(' TObject = class');
  12250. Add(' end;');
  12251. Add('function GetClass: TClass;');
  12252. Add('begin');
  12253. Add(' Result:=TObject;');
  12254. Add('end;');
  12255. Add('begin');
  12256. ParseProgram;
  12257. end;
  12258. procedure TTestResolver.TestClassOf_Const;
  12259. begin
  12260. StartProgram(false);
  12261. Add([
  12262. 'type',
  12263. ' TObject = class',
  12264. ' end;',
  12265. ' TBird = TObject;',
  12266. ' TBirds = class of TBird;',
  12267. ' TEagles = TBirds;',
  12268. ' THawk = class(TBird);',
  12269. 'const',
  12270. ' Hawk: TEagles = THawk;',
  12271. ' DefaultBirdClasses : Array [1..2] of TEagles = (',
  12272. ' TBird,',
  12273. ' THawk',
  12274. ' );',
  12275. 'begin']);
  12276. ParseProgram;
  12277. end;
  12278. procedure TTestResolver.TestClassOf_Const2;
  12279. begin
  12280. StartProgram(false);
  12281. Add([
  12282. 'type',
  12283. ' TObject = class',
  12284. ' end;',
  12285. ' TFieldType = (fta,ftb);',
  12286. ' TField = Class;',
  12287. ' TFieldClass = class of TField;',
  12288. ' TField = Class(TObject);',
  12289. ' TFieldA = Class(TField);',
  12290. ' TFieldB = Class(TField);',
  12291. 'Const',
  12292. ' DefaultFieldClasses : Array [TFieldType] of TFieldClass = (TFieldA,TFieldB);',
  12293. 'begin']);
  12294. ParseProgram;
  12295. end;
  12296. procedure TTestResolver.TestProperty1;
  12297. begin
  12298. StartProgram(false);
  12299. Add('type');
  12300. Add(' integer = longint;');
  12301. Add(' {#TOBJ}TObject = class');
  12302. Add(' end;');
  12303. Add(' {#A}TClassA = class');
  12304. Add(' {#FB}FB: integer;');
  12305. Add(' property {#B}B: longint read {@FB}FB write {@FB}FB;');
  12306. Add(' end;');
  12307. Add('var');
  12308. Add(' {#v}{=A}v: TClassA;');
  12309. Add('begin');
  12310. Add(' {@v}v.{@b}b:=3;');
  12311. ParseProgram;
  12312. end;
  12313. procedure TTestResolver.TestPropertyAccessorNotInFront;
  12314. begin
  12315. StartProgram(false);
  12316. Add('type');
  12317. Add(' TObject = class');
  12318. Add(' property B: longint read FB;');
  12319. Add(' FB: longint;');
  12320. Add(' end;');
  12321. Add('begin');
  12322. CheckResolverException('identifier not found "FB"',nIdentifierNotFound);
  12323. end;
  12324. procedure TTestResolver.TestPropertyReadAndWriteMissingFail;
  12325. begin
  12326. StartProgram(false);
  12327. Add([
  12328. 'type',
  12329. ' TObject = class',
  12330. ' property B: longint;',
  12331. ' end;',
  12332. 'begin']);
  12333. CheckResolverException(sPropertyMustHaveReadOrWrite,nPropertyMustHaveReadOrWrite);
  12334. end;
  12335. procedure TTestResolver.TestPropertyReadAccessorVarWrongType;
  12336. begin
  12337. StartProgram(false);
  12338. Add('type');
  12339. Add(' TObject = class');
  12340. Add(' FB: string;');
  12341. Add(' property B: longint read FB;');
  12342. Add(' end;');
  12343. Add('begin');
  12344. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  12345. nIncompatibleTypesGotExpected);
  12346. end;
  12347. procedure TTestResolver.TestPropertyReadAccessorProcNotFunc;
  12348. begin
  12349. StartProgram(false);
  12350. Add('type');
  12351. Add(' TObject = class');
  12352. Add(' procedure GetB;');
  12353. Add(' property B: longint read GetB;');
  12354. Add(' end;');
  12355. Add('begin');
  12356. CheckResolverException('function expected, but procedure found',nXExpectedButYFound);
  12357. end;
  12358. procedure TTestResolver.TestPropertyReadAccessorFuncWrongResult;
  12359. begin
  12360. StartProgram(false);
  12361. Add('type');
  12362. Add(' TObject = class');
  12363. Add(' function GetB: string;');
  12364. Add(' property B: longint read GetB;');
  12365. Add(' end;');
  12366. Add('begin');
  12367. CheckResolverException('function result Longint expected, but String found',
  12368. nXExpectedButYFound);
  12369. end;
  12370. procedure TTestResolver.TestPropertyReadAccessorFuncWrongArgCount;
  12371. begin
  12372. StartProgram(false);
  12373. Add('type');
  12374. Add(' TObject = class');
  12375. Add(' function GetB(i: longint): longint;');
  12376. Add(' property B: longint read GetB;');
  12377. Add(' end;');
  12378. Add('begin');
  12379. CheckResolverException('Wrong number of parameters specified for call to "GetB"',
  12380. nWrongNumberOfParametersForCallTo);
  12381. end;
  12382. procedure TTestResolver.TestPropertyReadAccessorFunc;
  12383. begin
  12384. StartProgram(false);
  12385. Add('type');
  12386. Add(' {#TOBJ}TObject = class');
  12387. Add(' function {#GetB}GetB: longint;');
  12388. Add(' property {#B}B: longint read {@GetB}GetB;');
  12389. Add(' end;');
  12390. Add('function TObject.GetB: longint;');
  12391. Add('begin');
  12392. Add('end;');
  12393. Add('var');
  12394. Add(' {#o}{=TOBJ}o: TObject;');
  12395. Add('begin');
  12396. Add(' if {@o}o.{@B}B=3 then ;');
  12397. ParseProgram;
  12398. end;
  12399. procedure TTestResolver.TestPropertyReadAccessorStrictPrivate;
  12400. begin
  12401. StartProgram(false);
  12402. Add([
  12403. 'type',
  12404. ' TObject = class',
  12405. ' strict private',
  12406. ' FSize: word;',
  12407. ' property Size: word read FSize;',
  12408. ' strict protected',
  12409. ' FName: string;',
  12410. ' property Name: string read FName;',
  12411. ' end;',
  12412. ' TBird = class',
  12413. ' strict protected',
  12414. ' property Caption: string read FName;',
  12415. ' end;',
  12416. 'begin',
  12417. '']);
  12418. ParseProgram;
  12419. end;
  12420. procedure TTestResolver.TestPropertyReadAccessorNonClassFail;
  12421. begin
  12422. StartProgram(false);
  12423. Add([
  12424. 'type',
  12425. ' TObject = class',
  12426. ' FSize: word;',
  12427. ' class property Size: word read FSize;',
  12428. ' end;',
  12429. 'begin',
  12430. '']);
  12431. CheckResolverException('class var expected, but var found',nXExpectedButYFound);
  12432. end;
  12433. procedure TTestResolver.TestPropertyWriteAccessorVarWrongType;
  12434. begin
  12435. StartProgram(false);
  12436. Add('type');
  12437. Add(' TObject = class');
  12438. Add(' FB: string;');
  12439. Add(' property B: longint write FB;');
  12440. Add(' end;');
  12441. Add('begin');
  12442. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  12443. nIncompatibleTypesGotExpected);
  12444. end;
  12445. procedure TTestResolver.TestPropertyWriteAccessorFuncNotProc;
  12446. begin
  12447. StartProgram(false);
  12448. Add('type');
  12449. Add(' TObject = class');
  12450. Add(' function SetB: longint;');
  12451. Add(' property B: longint write SetB;');
  12452. Add(' end;');
  12453. Add('begin');
  12454. CheckResolverException('procedure expected, but function found',nXExpectedButYFound);
  12455. end;
  12456. procedure TTestResolver.TestPropertyWriteAccessorProcWrongArgCount;
  12457. begin
  12458. StartProgram(false);
  12459. Add('type');
  12460. Add(' TObject = class');
  12461. Add(' procedure SetB;');
  12462. Add(' property B: longint write SetB;');
  12463. Add(' end;');
  12464. Add('begin');
  12465. CheckResolverException('Wrong number of parameters specified for call to "SetB"',
  12466. nWrongNumberOfParametersForCallTo);
  12467. end;
  12468. procedure TTestResolver.TestPropertyWriteAccessorProcWrongArg;
  12469. begin
  12470. StartProgram(false);
  12471. Add('type');
  12472. Add(' TObject = class');
  12473. Add(' procedure SetB(var Value: longint);');
  12474. Add(' property B: longint write SetB;');
  12475. Add(' end;');
  12476. Add('begin');
  12477. CheckResolverException('Incompatible type for arg no. 1: Got "var", expected "const"',
  12478. nIncompatibleTypeArgNo);
  12479. end;
  12480. procedure TTestResolver.TestPropertyWriteAccessorProcWrongArgType;
  12481. begin
  12482. StartProgram(false);
  12483. Add('type');
  12484. Add(' TObject = class');
  12485. Add(' procedure SetB(Value: string);');
  12486. Add(' property B: longint write SetB;');
  12487. Add(' end;');
  12488. Add('begin');
  12489. CheckResolverException('Incompatible type for arg no. 1: Got "String", expected "Longint"',
  12490. nIncompatibleTypeArgNo);
  12491. end;
  12492. procedure TTestResolver.TestPropertyWriteAccessorProc;
  12493. begin
  12494. StartProgram(false);
  12495. Add('type');
  12496. Add(' {#TOBJ}TObject = class');
  12497. Add(' procedure {#SetB}SetB(Value: longint);');
  12498. Add(' property {#B}B: longint write {@SetB}SetB;');
  12499. Add(' end;');
  12500. Add('procedure TObject.SetB(Value: longint);');
  12501. Add('begin');
  12502. Add('end;');
  12503. Add('var');
  12504. Add(' {#o}{=TOBJ}o: TObject;');
  12505. Add('begin');
  12506. Add(' {@o}o.{@B}B:=3;');
  12507. ParseProgram;
  12508. end;
  12509. procedure TTestResolver.TestPropertyTypeless;
  12510. begin
  12511. StartProgram(false);
  12512. Add([
  12513. 'type',
  12514. ' {#TOBJ}TObject = class',
  12515. ' {#FB}FB: longint;',
  12516. ' property {#TOBJ_B}B: longint write {@FB}FB;',
  12517. ' property {#TOBJ_D}D: longint write {@FB}FB;',
  12518. ' end;',
  12519. ' {#TA}TClassA = class',
  12520. ' {#FC}FC: longint;',
  12521. ' property {#TA_B}{@TOBJ_B}B write {@FC}FC;',
  12522. ' end;',
  12523. ' {#TB}TClassB = class(TClassA)',
  12524. ' published',
  12525. ' property {#TB_D}{@TOBJ_D}D;',
  12526. ' end;',
  12527. 'var',
  12528. ' {#v}{=TA}v: TClassA;',
  12529. 'begin',
  12530. ' {@v}v.{@TA_B}B:=3;',
  12531. ' {@v}v.{@TObj_D}D:=4;',
  12532. '']);
  12533. ParseProgram;
  12534. end;
  12535. procedure TTestResolver.TestPropertyTypelessNoAncestorFail;
  12536. begin
  12537. StartProgram(false);
  12538. Add('type');
  12539. Add(' TObject = class');
  12540. Add(' end;');
  12541. Add(' TClassA = class');
  12542. Add(' property B;');
  12543. Add(' end;');
  12544. Add('begin');
  12545. CheckResolverException(sNoPropertyFoundToOverride,
  12546. nNoPropertyFoundToOverride);
  12547. end;
  12548. procedure TTestResolver.TestPropertyStoredAccessor;
  12549. begin
  12550. StartProgram(false);
  12551. Add('const StoreB = true;');
  12552. Add('type');
  12553. Add(' TObject = class');
  12554. Add(' FBird: longint;');
  12555. Add(' VStored: boolean;');
  12556. Add(' function IsBirdStored: boolean; virtual; abstract;');
  12557. Add(' property Bird: longint read FBird stored VStored;');
  12558. Add(' property B: longint read FBird stored IsBirdStored;');
  12559. Add(' property Eagle: longint read FBird stored StoreB;');
  12560. Add(' property Hawk: longint read FBird stored false;');
  12561. Add(' end;');
  12562. Add('begin');
  12563. ParseProgram;
  12564. end;
  12565. procedure TTestResolver.TestPropertyStoredAccessorVarWrongType;
  12566. begin
  12567. StartProgram(false);
  12568. Add('type');
  12569. Add(' TObject = class');
  12570. Add(' FB: longint;');
  12571. Add(' BStored: longint;');
  12572. Add(' property B: longint read FB stored BStored;');
  12573. Add(' end;');
  12574. Add('begin');
  12575. CheckResolverException('Incompatible types: got "Longint" expected "Boolean"',
  12576. nIncompatibleTypesGotExpected);
  12577. end;
  12578. procedure TTestResolver.TestPropertyStoredAccessorProcNotFunc;
  12579. begin
  12580. StartProgram(false);
  12581. Add('type');
  12582. Add(' TObject = class');
  12583. Add(' FB: longint;');
  12584. Add(' procedure GetB;');
  12585. Add(' property B: longint read FB stored GetB;');
  12586. Add(' end;');
  12587. Add('begin');
  12588. CheckResolverException('function expected, but procedure found',nXExpectedButYFound);
  12589. end;
  12590. procedure TTestResolver.TestPropertyStoredAccessorFuncWrongResult;
  12591. begin
  12592. StartProgram(false);
  12593. Add('type');
  12594. Add(' TObject = class');
  12595. Add(' FB: longint;');
  12596. Add(' function GetB: string;');
  12597. Add(' property B: longint read FB stored GetB;');
  12598. Add(' end;');
  12599. Add('begin');
  12600. CheckResolverException('function: boolean expected, but function:String found',
  12601. nXExpectedButYFound);
  12602. end;
  12603. procedure TTestResolver.TestPropertyStoredAccessorFuncWrongArgCount;
  12604. begin
  12605. StartProgram(false);
  12606. Add('type');
  12607. Add(' TObject = class');
  12608. Add(' FB: longint;');
  12609. Add(' function GetB(i: longint): boolean;');
  12610. Add(' property B: longint read FB stored GetB;');
  12611. Add(' end;');
  12612. Add('begin');
  12613. CheckResolverException('Wrong number of parameters specified for call to "GetB"',
  12614. nWrongNumberOfParametersForCallTo);
  12615. end;
  12616. procedure TTestResolver.TestPropertyIndexSpec;
  12617. begin
  12618. StartProgram(false);
  12619. Add([
  12620. 'const',
  12621. ' CB = true or false;',
  12622. ' CI = 1+2;',
  12623. 'type',
  12624. ' TEnum = (red, blue);',
  12625. ' TObject = class',
  12626. ' FB: boolean;',
  12627. ' function GetIntBool(Index: longint): boolean; virtual; abstract;',
  12628. ' procedure SetIntBool(Index: longint; b: boolean); virtual; abstract;',
  12629. ' function GetBoolBool(Index: boolean): boolean; virtual; abstract;',
  12630. ' procedure SetBoolBool(Index: boolean; b: boolean); virtual; abstract;',
  12631. ' function GetEnumBool(Index: TEnum): boolean; virtual; abstract;',
  12632. ' procedure SetEnumBool(Index: TEnum; b: boolean); virtual; abstract;',
  12633. ' function GetStrIntBool(A: String; I: longint): boolean; virtual; abstract;',
  12634. ' procedure SetStrIntBool(A: String; I: longint; b: boolean); virtual; abstract;',
  12635. ' property B1: boolean index 1 read GetIntBool write SetIntBool stored GetIntBool;',
  12636. ' property B2: boolean index CI read GetIntBool write SetIntBool stored GetIntBool;',
  12637. ' property B3: boolean index false read GetBoolBool write SetBoolBool stored GetBoolBool;',
  12638. ' property B4: boolean index CB read GetBoolBool write SetBoolBool stored GetBoolBool;',
  12639. ' property B5: boolean index red read GetEnumBool write SetEnumBool stored GetEnumBool;',
  12640. ' property B6: boolean index TEnum.blue read GetEnumBool write SetEnumBool stored GetEnumBool;',
  12641. ' property B7: boolean index 1 read GetIntBool write FB stored FB;',
  12642. ' property I1[A: String]: boolean index 2 read GetStrIntBool write SetStrIntBool;',
  12643. ' end;',
  12644. ' TBird = class',
  12645. ' function GetIntBoolOvr(Index: longint): boolean; virtual; abstract;',
  12646. ' property B1 index 3;',
  12647. ' property B2 read GetIntBoolOvr;',
  12648. ' end;',
  12649. 'begin']);
  12650. ParseProgram;
  12651. end;
  12652. procedure TTestResolver.TestPropertyIndexSpec_ReadAccessorWrongArgCount;
  12653. begin
  12654. StartProgram(false);
  12655. Add([
  12656. 'type',
  12657. ' TObject = class',
  12658. ' function GetB: boolean; virtual; abstract;',
  12659. ' property B: boolean index 1 read GetB;',
  12660. ' end;',
  12661. 'begin']);
  12662. CheckResolverException('Wrong number of parameters specified for call to "GetB"',
  12663. nWrongNumberOfParametersForCallTo);
  12664. end;
  12665. procedure TTestResolver.TestPropertyIndexSpec_ReadAccessorWrongIndexArgType;
  12666. begin
  12667. StartProgram(false);
  12668. Add([
  12669. 'type',
  12670. ' TObject = class',
  12671. ' function GetB(S: string): boolean; virtual; abstract;',
  12672. ' property B: boolean index 1 read GetB;',
  12673. ' end;',
  12674. 'begin']);
  12675. CheckResolverException('Incompatible type for arg no. 1: Got "Longint", expected "String"',
  12676. nIncompatibleTypeArgNo);
  12677. end;
  12678. procedure TTestResolver.TestPropertyDefaultValue;
  12679. begin
  12680. StartProgram(false);
  12681. Add([
  12682. 'type',
  12683. ' TEnum = (red, blue, green, white, grey, black);',
  12684. ' TEnumRg = blue..grey;',
  12685. ' TSet = set of TEnum;',
  12686. 'const',
  12687. ' CB = true or false;',
  12688. ' CI = 1+2;',
  12689. ' CS = [red,blue];',
  12690. 'type',
  12691. ' TObject = class',
  12692. ' FB: boolean;',
  12693. ' property B1: boolean read FB default true;',
  12694. ' property B2: boolean read FB default CB;',
  12695. ' property B3: boolean read FB default afile.cb;',
  12696. ' FI: longint;',
  12697. ' property I1: longint read FI default 2;',
  12698. ' property I2: longint read FI default CI;',
  12699. ' FE: TEnum;',
  12700. ' property E1: TEnum read FE default red;',
  12701. ' property E2: TEnum read FE default TEnum.blue;',
  12702. ' FEnumRg: TEnumRg;',
  12703. ' property EnumRg1: TEnumRg read FEnumRg default white;',
  12704. ' FSet: TSet;',
  12705. ' property Set1: TSet read FSet default [];',
  12706. ' property Set2: TSet read FSet default [red];',
  12707. ' property Set3: TSet read FSet default [red,blue];',
  12708. ' property Set4: TSet read FSet default CS;',
  12709. ' end;',
  12710. 'begin']);
  12711. ParseProgram;
  12712. end;
  12713. procedure TTestResolver.TestPropertyArgs1;
  12714. begin
  12715. StartProgram(false);
  12716. Add('type');
  12717. Add(' TObject = class');
  12718. Add(' function GetB(Index: longint): boolean;');
  12719. Add(' procedure SetB(Index: longint; Value: boolean);');
  12720. Add(' property B[Index: longint]: boolean read GetB write SetB;');
  12721. Add(' end;');
  12722. Add('function TObject.GetB(Index: longint): boolean;');
  12723. Add('begin');
  12724. Add('end;');
  12725. Add('procedure TObject.SetB(Index: longint; Value: boolean);');
  12726. Add('begin');
  12727. Add('end;');
  12728. Add('var o: TObject;');
  12729. Add('begin');
  12730. Add(' o.B[3]:=true;');
  12731. Add(' if o.B[4] then;');
  12732. Add(' if o.B[5]=true then;');
  12733. Add(' if false=o.B[6] then;');
  12734. ParseProgram;
  12735. end;
  12736. procedure TTestResolver.TestPropertyArgs2;
  12737. begin
  12738. StartProgram(false);
  12739. Add('type');
  12740. Add(' TObject = class');
  12741. Add(' function GetB(Index: longint; const ID: string): longint;');
  12742. Add(' procedure SetB(Index: longint; const ID: string; Value: longint);');
  12743. Add(' property B[Index: longint; const ID: string]: longint read GetB write SetB;');
  12744. Add(' end;');
  12745. Add('function TObject.GetB(Index: longint; const ID: string): longint;');
  12746. Add('begin');
  12747. Add('end;');
  12748. Add('procedure TObject.SetB(Index: longint; const ID: string; Value: longint);');
  12749. Add('begin');
  12750. Add('end;');
  12751. Add('var o: TObject;');
  12752. Add('begin');
  12753. Add(' o.B[3,''abc'']:=7;');
  12754. Add(' if o.B[4,'''']=8 then;');
  12755. Add(' if 9=o.B[6,''d''] then;');
  12756. ParseProgram;
  12757. end;
  12758. procedure TTestResolver.TestPropertyArgsWithDefaultsFail;
  12759. begin
  12760. StartProgram(false);
  12761. Add('type');
  12762. Add(' TObject = class');
  12763. Add(' function GetB(Index: longint): boolean;');
  12764. Add(' procedure SetB(Index: longint; Value: boolean);');
  12765. Add(' property B[Index: longint = 0]: boolean read GetB write SetB;');
  12766. Add(' end;');
  12767. Add('function TObject.GetB(Index: longint): boolean;');
  12768. Add('begin');
  12769. Add('end;');
  12770. Add('procedure TObject.SetB(Index: longint; Value: boolean);');
  12771. Add('begin');
  12772. Add('end;');
  12773. Add('begin');
  12774. CheckParserException('Property arguments can not have default values',
  12775. PParser.nParserPropertyArgumentsCanNotHaveDefaultValues);
  12776. end;
  12777. procedure TTestResolver.TestPropertyArgs_StringConstDefault;
  12778. begin
  12779. StartProgram(false);
  12780. Add([
  12781. 'type',
  12782. ' TObject = class',
  12783. ' function GetItems(const s: string): byte; virtual; abstract;',
  12784. ' procedure SetItems(const s: string; b: byte); virtual; abstract;',
  12785. ' property Items[s: string]: byte read GetItems write SetItems;',
  12786. ' end;',
  12787. 'begin']);
  12788. ParseProgram;
  12789. end;
  12790. procedure TTestResolver.TestPropertyInherited;
  12791. var
  12792. aMarker: PSrcMarker;
  12793. Elements: TFPList;
  12794. i: Integer;
  12795. El: TPasElement;
  12796. Ref: TResolvedReference;
  12797. begin
  12798. StartProgram(false);
  12799. Add(['type',
  12800. ' TObject = class',
  12801. ' FA: word;',
  12802. ' property A: word read FA write FA;',
  12803. ' end;',
  12804. ' TBird = class(TObject)',
  12805. ' FB: word;',
  12806. ' procedure Run(Value: word);',
  12807. ' property A read FB write FB;',
  12808. ' end;',
  12809. 'procedure TBird.Run(Value: word);',
  12810. 'begin',
  12811. ' inherited {#A}A:=Value;',
  12812. //' Value:=inherited {@A1}A;',
  12813. 'end;',
  12814. 'begin',
  12815. '']);
  12816. ParseProgram;
  12817. aMarker:=FirstSrcMarker;
  12818. while aMarker<>nil do
  12819. begin
  12820. {$IFNDEF NOCONSOLE}
  12821. writeln('TTestResolver.TestPropertyInherited ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  12822. {$ENDIF}
  12823. Elements:=FindElementsAt(aMarker);
  12824. try
  12825. for i:=0 to Elements.Count-1 do
  12826. begin
  12827. El:=TPasElement(Elements[i]);
  12828. {$IFNDEF NOCONSOLE}
  12829. writeln('TTestResolver.TestPropertyInherited ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' CustomData=',GetObjName(El.CustomData));
  12830. {$ENDIF}
  12831. if not (El.CustomData is TResolvedReference) then continue;
  12832. Ref:=TResolvedReference(El.CustomData);
  12833. if not (Ref.Declaration is TPasProperty) then continue;
  12834. {$IFNDEF NOCONSOLE}
  12835. writeln('TTestResolver.TestPropertyInherited ',GetObjName(Ref.Declaration),' Ref.Access=',Ref.Access);
  12836. {$ENDIF}
  12837. case aMarker^.Identifier of
  12838. 'A': if Ref.Access<>rraAssign then
  12839. RaiseErrorAtSrcMarker('expected property write at "#'+aMarker^.Identifier+', but got "'+dbgs(Ref.Access),aMarker);
  12840. 'B': if Ref.Access<>rraRead then
  12841. RaiseErrorAtSrcMarker('expected property read at "#'+aMarker^.Identifier+', but got "'+dbgs(Ref.Access),aMarker);
  12842. end;
  12843. break;
  12844. end;
  12845. finally
  12846. Elements.Free;
  12847. end;
  12848. aMarker:=aMarker^.Next;
  12849. end;
  12850. end;
  12851. procedure TTestResolver.TestClassProperty;
  12852. begin
  12853. StartProgram(false);
  12854. Add([
  12855. 'type',
  12856. ' TObject = class',
  12857. ' class function GetStatic: word; static;',
  12858. ' class procedure SetStatic(Value: word); static;',
  12859. ' class property StaticP: word read GetStatic write SetStatic;',
  12860. ' end;',
  12861. 'class function TObject.GetStatic: word;',
  12862. 'begin',
  12863. ' StaticP:=StaticP;',
  12864. 'end;',
  12865. 'class procedure TObject.SetStatic(Value: word);',
  12866. 'begin',
  12867. 'end;',
  12868. 'begin',
  12869. '']);
  12870. ParseProgram;
  12871. end;
  12872. procedure TTestResolver.TestClassPropertyNonStaticFail;
  12873. begin
  12874. StartProgram(false);
  12875. Add([
  12876. 'type',
  12877. ' TObject = class',
  12878. ' class function GetNonStatic: word;',
  12879. ' class property NonStatic: word read GetNonStatic;',
  12880. ' end;',
  12881. 'class function TObject.GetNonStatic: word;',
  12882. 'begin',
  12883. 'end;',
  12884. 'begin',
  12885. '']);
  12886. CheckResolverException(sClassPropertyAccessorMustBeStatic,nClassPropertyAccessorMustBeStatic);
  12887. end;
  12888. procedure TTestResolver.TestClassPropertyNonStaticAllow;
  12889. begin
  12890. ResolverEngine.Options:=ResolverEngine.Options+[proClassPropertyNonStatic];
  12891. StartProgram(false);
  12892. Add([
  12893. 'type',
  12894. ' TObject = class',
  12895. ' class function GetStatic: word; static;',
  12896. ' class procedure SetStatic(Value: word); static;',
  12897. ' class property StaticP: word read GetStatic write SetStatic;',
  12898. ' class function GetNonStatic: word;',
  12899. ' class procedure SetNonStatic(Value: word);',
  12900. ' class property NonStatic: word read GetNonStatic write SetNonStatic;',
  12901. ' end;',
  12902. ' TClass = class of TObject;',
  12903. 'class function TObject.GetStatic: word;',
  12904. 'begin',
  12905. ' StaticP:=StaticP;',
  12906. ' NonStatic:=NonStatic;',
  12907. 'end;',
  12908. 'class procedure TObject.SetStatic(Value: word);',
  12909. 'begin',
  12910. 'end;',
  12911. 'class function TObject.GetNonStatic: word;',
  12912. 'begin',
  12913. ' StaticP:=StaticP;',
  12914. ' NonStatic:=NonStatic;',
  12915. 'end;',
  12916. 'class procedure TObject.SetNonStatic(Value: word);',
  12917. 'begin',
  12918. 'end;',
  12919. 'var',
  12920. ' c: TClass;',
  12921. ' o: TObject;',
  12922. 'begin',
  12923. ' c.STaticP:=c.StaticP;',
  12924. ' o.STaticP:=o.StaticP;',
  12925. ' c.NonStatic:=c.NonStatic;',
  12926. ' o.NonStatic:=o.NonStatic;',
  12927. '']);
  12928. ParseProgram;
  12929. end;
  12930. procedure TTestResolver.TestArrayProperty;
  12931. begin
  12932. StartProgram(false);
  12933. Add('type');
  12934. Add(' TObject = class');
  12935. Add(' {#FItems}FItems: array of string;');
  12936. Add(' function {#GetItems}GetItems(Index: longint): string;');
  12937. Add(' procedure {#SetItems}SetItems(Index: longint; Value: string);');
  12938. Add(' procedure DoIt;');
  12939. Add(' property {#Items}Items[Index: longint]: string read {@GetItems}getitems write {@SetItems}setitems;');
  12940. Add(' end;');
  12941. Add('function tobject.getitems(index: longint): string;');
  12942. Add('begin');
  12943. Add(' Result:={@FItems}fitems[index];');
  12944. Add('end;');
  12945. Add('procedure tobject.setitems(index: longint; value: string);');
  12946. Add('begin');
  12947. Add(' {@FItems}fitems[index]:=value;');
  12948. Add('end;');
  12949. Add('procedure tobject.doit;');
  12950. Add('begin');
  12951. Add(' {@Items}items[1]:={@Items}items[2];');
  12952. Add(' self.{@Items}items[3]:=self.{@Items}items[4];');
  12953. Add('end;');
  12954. Add('var Obj: tobject;');
  12955. Add('begin');
  12956. Add(' obj.{@Items}Items[11]:=obj.{@Items}Items[12];');
  12957. ParseProgram;
  12958. end;
  12959. procedure TTestResolver.TestArrayProperty_PassImplicitCallClassFunc;
  12960. var
  12961. aMarker: PSrcMarker;
  12962. Elements: TFPList;
  12963. ActualImplicitCallWithoutParams, ExpectedImplicitCallWithoutParams: Boolean;
  12964. i: Integer;
  12965. El: TPasElement;
  12966. Ref: TResolvedReference;
  12967. begin
  12968. StartProgram(false);
  12969. Add([
  12970. 'type',
  12971. ' TObject = class',
  12972. ' function GetItems(s: string): string;',
  12973. ' property Items[s: string]: string read GetItems; default;',
  12974. ' class function Desc: string; virtual; abstract;',
  12975. ' end;',
  12976. 'function TObject.GetItems(s: string): string;',
  12977. 'begin',
  12978. ' Result:=Items[{#a_implicit}Desc];',
  12979. ' Result:=Items[{#b_direct}Desc()];',
  12980. ' Result:=Items[Self.{#c_implicit}Desc];',
  12981. ' Result:=Items[Self.{#d_direct}Desc()];',
  12982. 'end;',
  12983. 'var b: TObject;',
  12984. ' s: string;',
  12985. 'begin',
  12986. ' s:=b.Items[b.{#m_implicit}Desc];',
  12987. ' s:=b.Items[b.{#n_direct}Desc()];',
  12988. ' s:=b.Items[TObject.{#o_implicit}Desc];',
  12989. ' s:=b.Items[TObject.{#p_direct}Desc()];',
  12990. ' s:=b[b.{#q_implicit}Desc];',
  12991. ' s:=b[b.{#r_direct}Desc()];',
  12992. ' s:=b[TObject.{#s_implicit}Desc];',
  12993. ' s:=b[TObject.{#t_direct}Desc()];',
  12994. '']);
  12995. ParseProgram;
  12996. aMarker:=FirstSrcMarker;
  12997. while aMarker<>nil do
  12998. begin
  12999. //writeln('TTestResolver.TestArrayProperty_PassImplicitCallClassFunc ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  13000. Elements:=FindElementsAt(aMarker);
  13001. try
  13002. ActualImplicitCallWithoutParams:=false;
  13003. Ref:=nil;
  13004. for i:=0 to Elements.Count-1 do
  13005. begin
  13006. El:=TPasElement(Elements[i]);
  13007. //writeln('TTestResolver.TestArrayProperty_PassImplicitCallClassFunc ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  13008. if not (El.CustomData is TResolvedReference) then continue;
  13009. Ref:=TResolvedReference(El.CustomData);
  13010. if Ref.Declaration is TPasProcedure then
  13011. break
  13012. else
  13013. Ref:=nil;
  13014. end;
  13015. if Ref=nil then
  13016. RaiseErrorAtSrcMarker('missing proc ref at "#'+aMarker^.Identifier+'"',aMarker);
  13017. ActualImplicitCallWithoutParams:=rrfImplicitCallWithoutParams in Ref.Flags;
  13018. ExpectedImplicitCallWithoutParams:=RightStr(aMarker^.Identifier,length('_implicit'))='_implicit';
  13019. if ActualImplicitCallWithoutParams<>ExpectedImplicitCallWithoutParams then
  13020. RaiseErrorAtSrcMarker('wrong implicit call at "#'+aMarker^.Identifier
  13021. +', ExpectedImplicitCall='+BoolToStr(ExpectedImplicitCallWithoutParams,true)+'"',aMarker);
  13022. finally
  13023. Elements.Free;
  13024. end;
  13025. aMarker:=aMarker^.Next;
  13026. end;
  13027. end;
  13028. procedure TTestResolver.TestProperty_WrongTypeAsIndexFail;
  13029. begin
  13030. StartProgram(false);
  13031. Add('type');
  13032. Add(' TObject = class');
  13033. Add(' function GetItems(Index: string): string;');
  13034. Add(' property Items[Index: string]: string read getitems;');
  13035. Add(' end;');
  13036. Add('function tobject.getitems(index: string): string;');
  13037. Add('begin');
  13038. Add('end;');
  13039. Add('var Obj: tobject;');
  13040. Add('begin');
  13041. Add(' obj.Items[3]:=''4'';');
  13042. CheckResolverException('Incompatible type for arg no. 1: Got "Longint", expected "String"',
  13043. nIncompatibleTypeArgNo);
  13044. end;
  13045. procedure TTestResolver.TestProperty_Option_ClassPropertyNonStatic;
  13046. begin
  13047. ResolverEngine.Options:=ResolverEngine.Options+[proClassPropertyNonStatic];
  13048. StartProgram(false);
  13049. Add('type');
  13050. Add(' TObject = class');
  13051. Add(' class function GetB: longint;');
  13052. Add(' class procedure SetB(Value: longint);');
  13053. Add(' class property B: longint read GetB write SetB;');
  13054. Add(' end;');
  13055. Add('class function TObject.GetB: longint;');
  13056. Add('begin');
  13057. Add('end;');
  13058. Add('class procedure TObject.SetB(Value: longint);');
  13059. Add('begin');
  13060. Add('end;');
  13061. Add('begin');
  13062. Add(' TObject.B:=4;');
  13063. Add(' if TObject.B=6 then;');
  13064. Add(' if 7=TObject.B then;');
  13065. ParseProgram;
  13066. end;
  13067. procedure TTestResolver.TestDefaultProperty;
  13068. begin
  13069. StartProgram(false);
  13070. Add([
  13071. 'type',
  13072. ' TObject = class',
  13073. ' end;',
  13074. ' TBird = class',
  13075. ' function GetB(Index: longint): longint;',
  13076. ' procedure SetB(Index: longint; Value: longint);',
  13077. ' property B[Index: longint]: longint read GetB write SetB; default;',
  13078. ' end;',
  13079. 'function TBird.GetB(Index: longint): longint;',
  13080. 'begin',
  13081. 'end;',
  13082. 'procedure TBird.SetB(Index: longint; Value: longint);',
  13083. 'begin',
  13084. ' if Value=Self[Index] then ;',
  13085. ' Self[Index]:=Value;',
  13086. 'end;',
  13087. 'var',
  13088. ' b: TBird;',
  13089. ' o: TObject;',
  13090. 'begin',
  13091. ' b[3]:=4;',
  13092. ' if b[5]=6 then;',
  13093. ' if 7=b[8] then;',
  13094. ' (o as TBird)[9]:=10;',
  13095. '']);
  13096. ParseProgram;
  13097. end;
  13098. procedure TTestResolver.TestDefaultPropertyIncVisibility;
  13099. begin
  13100. AddModuleWithIntfImplSrc('unit1.pp',
  13101. LinesToStr([
  13102. 'type',
  13103. ' TNumber = longint;',
  13104. ' TInteger = longint;',
  13105. ' TObject = class',
  13106. ' private',
  13107. ' function GetItems(Index: TNumber): TInteger; virtual; abstract;',
  13108. ' procedure SetItems(Index: TInteger; Value: TNumber); virtual; abstract;',
  13109. ' protected',
  13110. ' property Items[Index: TNumber]: longint read GetItems write SetItems;',
  13111. ' end;']),
  13112. LinesToStr([
  13113. '']));
  13114. StartProgram(true);
  13115. Add([
  13116. 'uses unit1;',
  13117. 'type',
  13118. ' TBird = class',
  13119. ' public',
  13120. ' property Items;',
  13121. ' end;',
  13122. 'procedure DoIt(i: TInteger);',
  13123. 'begin',
  13124. 'end;',
  13125. 'var b: TBird;',
  13126. 'begin',
  13127. ' b.Items[1]:=2;',
  13128. ' b.Items[3]:=b.Items[4];',
  13129. ' DoIt(b.Items[5]);',
  13130. '']);
  13131. ParseProgram;
  13132. end;
  13133. procedure TTestResolver.TestProperty_MissingDefault;
  13134. begin
  13135. StartProgram(false);
  13136. Add('type');
  13137. Add(' TObject = class');
  13138. Add(' end;');
  13139. Add('var o: TObject;');
  13140. Add('begin');
  13141. Add(' if o[5]=6 then;');
  13142. CheckResolverException('illegal qualifier "[" after "TObject"',
  13143. nIllegalQualifierAfter);
  13144. end;
  13145. procedure TTestResolver.TestProperty_DefaultDotFail;
  13146. begin
  13147. StartProgram(false);
  13148. Add([
  13149. 'type',
  13150. ' TObject = class',
  13151. ' function GetItems(Index: byte): byte;',
  13152. ' property Items[Index: byte]: byte read GetItems; default;',
  13153. ' end;',
  13154. 'function TObject.GetItems(Index: byte): byte; begin end;',
  13155. 'var o: TObject;',
  13156. 'begin',
  13157. ' if o.Items.i=6 then;',
  13158. '']);
  13159. CheckResolverException('illegal qualifier "." after "Items:array property"',
  13160. nIllegalQualifierAfter);
  13161. end;
  13162. procedure TTestResolver.TestClassInterface;
  13163. begin
  13164. StartProgram(false);
  13165. Add([
  13166. 'type',
  13167. ' {$interfaces corba}',
  13168. ' ICorbaIntf = interface',
  13169. ' end;',
  13170. ' {$interfaces com}',
  13171. ' IUnknown = interface',
  13172. ' end;',
  13173. ' IInterface = IUnknown;',
  13174. ' IComIntf = interface',
  13175. ' end;',
  13176. 'begin']);
  13177. ParseProgram;
  13178. end;
  13179. procedure TTestResolver.TestClassInterfaceForward;
  13180. begin
  13181. StartProgram(false);
  13182. Add([
  13183. 'type',
  13184. ' IBird = interface;',
  13185. ' TObject = class',
  13186. ' Bird: IBird;',
  13187. ' end;',
  13188. ' IUnknown = interface',
  13189. ' end;',
  13190. ' IBird = interface(IUnknown)',
  13191. ' end;',
  13192. 'begin']);
  13193. ParseProgram;
  13194. end;
  13195. procedure TTestResolver.TestClassInterfaceVarFail;
  13196. begin
  13197. StartProgram(false);
  13198. Add([
  13199. 'type',
  13200. ' IUnknown = interface',
  13201. ' i: longint;',
  13202. ' end;',
  13203. 'begin']);
  13204. CheckParserException('Fields are not allowed in interface',nParserNoFieldsAllowed);
  13205. end;
  13206. procedure TTestResolver.TestClassInterfaceConstFail;
  13207. begin
  13208. StartProgram(false);
  13209. Add([
  13210. 'type',
  13211. ' IUnknown = interface',
  13212. ' const i = 3;',
  13213. ' end;',
  13214. 'begin']);
  13215. CheckParserException('CONST is not allowed in interface',nParserXNotAllowedInY);
  13216. end;
  13217. procedure TTestResolver.TestClassInterfaceClassMethodFail;
  13218. begin
  13219. StartProgram(false);
  13220. Add([
  13221. 'type',
  13222. ' IUnknown = interface',
  13223. ' class procedure DoIt;',
  13224. ' end;',
  13225. 'begin']);
  13226. CheckParserException('CLASS is not allowed in interface',nParserXNotAllowedInY);
  13227. end;
  13228. procedure TTestResolver.TestClassInterfaceNestedTypeFail;
  13229. begin
  13230. StartProgram(false);
  13231. Add([
  13232. 'type',
  13233. ' IUnknown = interface',
  13234. ' type l = longint;',
  13235. ' end;',
  13236. 'begin']);
  13237. CheckParserException('TYPE is not allowed in interface',nParserXNotAllowedInY);
  13238. end;
  13239. procedure TTestResolver.TestClassInterfacePropertyStoredFail;
  13240. begin
  13241. StartProgram(false);
  13242. Add([
  13243. 'type',
  13244. ' IUnknown = interface',
  13245. ' function GetSize: longint;',
  13246. ' property Size: longint read GetSize stored false;',
  13247. ' end;',
  13248. 'begin']);
  13249. CheckParserException('STORED is not allowed in interface',nParserXNotAllowedInY);
  13250. end;
  13251. procedure TTestResolver.TestClassInterface_ConstructorFail;
  13252. begin
  13253. StartProgram(false);
  13254. Add([
  13255. 'type',
  13256. ' IUnknown = interface',
  13257. ' constructor Create;',
  13258. ' end;',
  13259. 'begin']);
  13260. CheckParserException('constructor is not allowed in interface',nParserXNotAllowedInY);
  13261. end;
  13262. procedure TTestResolver.TestClassInterface_DelphiClassAncestorIntfFail;
  13263. begin
  13264. StartProgram(false);
  13265. Add([
  13266. '{$mode delphi}',
  13267. 'type',
  13268. ' IInterface = interface',
  13269. ' end;',
  13270. ' TObject = class(IInterface)',
  13271. ' end;',
  13272. 'begin']);
  13273. CheckResolverException('class type expected, but interface type found',nXExpectedButYFound);
  13274. end;
  13275. procedure TTestResolver.TestClassInterface_ObjFPCClassAncestorIntf;
  13276. begin
  13277. StartProgram(false);
  13278. Add([
  13279. '{$mode objfpc}',
  13280. 'type',
  13281. ' IUnknown = interface',
  13282. ' end;',
  13283. ' TObject = class(IUnknown)',
  13284. ' end;',
  13285. 'begin']);
  13286. ParseProgram;
  13287. end;
  13288. procedure TTestResolver.TestClassInterface_MethodVirtualFail;
  13289. begin
  13290. StartProgram(false);
  13291. Add([
  13292. 'type',
  13293. ' IUnknown = interface',
  13294. ' procedure DoIt; virtual;',
  13295. ' end;',
  13296. 'begin']);
  13297. CheckParserException('Fields are not allowed in interface',nParserNoFieldsAllowed);
  13298. end;
  13299. procedure TTestResolver.TestClassInterface_Overloads;
  13300. begin
  13301. StartProgram(false);
  13302. Add([
  13303. 'type',
  13304. ' IUnknown = interface',
  13305. ' procedure DoIt(i: longint);',
  13306. ' procedure DoIt(s: string);',
  13307. ' end;',
  13308. ' IBird = interface',
  13309. ' procedure DoIt(b: boolean); overload;',
  13310. ' end;',
  13311. ' TObject = class end;',
  13312. ' TBird = class(TObject,IBird)',
  13313. ' procedure DoIt(i: longint); virtual; abstract;',
  13314. ' procedure DoIt(s: string); virtual; abstract;',
  13315. ' procedure DoIt(b: boolean); virtual; abstract;',
  13316. ' end;',
  13317. 'var i: IBird;',
  13318. 'begin',
  13319. ' i.DoIt(3);',
  13320. ' i.DoIt(''abc'');',
  13321. ' i.DoIt(true);',
  13322. '']);
  13323. ParseProgram;
  13324. CheckResolverUnexpectedHints();
  13325. end;
  13326. procedure TTestResolver.TestClassInterface_OverloadHint;
  13327. begin
  13328. StartProgram(false);
  13329. Add([
  13330. 'type',
  13331. ' IUnknown = interface',
  13332. ' procedure DoIt;',
  13333. ' end;',
  13334. ' IBird = interface',
  13335. ' procedure DoIt;',
  13336. ' end;',
  13337. 'begin']);
  13338. ParseProgram;
  13339. CheckResolverHint(mtHint,nMethodHidesNonVirtualMethodExactly,
  13340. 'method hides identifier at "afile.pp(4,19)". Use reintroduce');
  13341. end;
  13342. procedure TTestResolver.TestClassInterface_OverloadNoHint;
  13343. begin
  13344. StartProgram(false);
  13345. Add([
  13346. 'type',
  13347. ' IUnknown = interface',
  13348. ' procedure DoIt;',
  13349. ' procedure DoIt(i: longint);',
  13350. ' end;',
  13351. 'begin']);
  13352. ParseProgram;
  13353. CheckResolverUnexpectedHints;
  13354. end;
  13355. procedure TTestResolver.TestClassInterface_IntfListClassFail;
  13356. begin
  13357. StartProgram(false);
  13358. Add([
  13359. 'type',
  13360. ' TObject = class',
  13361. ' end;',
  13362. ' TAnimal = class',
  13363. ' end;',
  13364. ' TBird = class(TObject,TAnimal)',
  13365. ' end;',
  13366. 'begin']);
  13367. CheckResolverException('interface type expected, but class type found',nXExpectedButYFound);
  13368. end;
  13369. procedure TTestResolver.TestClassInterface_IntfListDuplicateFail;
  13370. begin
  13371. StartProgram(false);
  13372. Add([
  13373. 'type',
  13374. ' IUnknown = interface',
  13375. ' end;',
  13376. ' IA = interface',
  13377. ' end;',
  13378. ' IB = IA;',
  13379. ' TObject = class(IA,IB)',
  13380. ' end;',
  13381. 'begin']);
  13382. CheckResolverException('Duplicate identifier "IB" at 1',nDuplicateIdentifier);
  13383. end;
  13384. procedure TTestResolver.TestClassInterface_MissingMethodFail;
  13385. begin
  13386. StartProgram(false);
  13387. Add([
  13388. 'type',
  13389. ' IUnknown = interface',
  13390. ' procedure DoIt;',
  13391. ' end;',
  13392. ' TObject = class(IUnknown)',
  13393. ' end;',
  13394. 'begin']);
  13395. CheckResolverException('No matching implementation for interface method "procedure IUnknown.DoIt of Object" found',
  13396. nNoMatchingImplForIntfMethodXFound);
  13397. end;
  13398. procedure TTestResolver.TestClassInterface_MissingAncestorMethodFail;
  13399. begin
  13400. StartProgram(false);
  13401. Add([
  13402. 'type',
  13403. ' IUnknown = interface',
  13404. ' procedure DoIt;',
  13405. ' end;',
  13406. ' IBird = interface',
  13407. ' end;',
  13408. ' TObject = class(IBird)',
  13409. ' end;',
  13410. 'begin']);
  13411. CheckResolverException('No matching implementation for interface method "procedure IUnknown.DoIt of Object" found',
  13412. nNoMatchingImplForIntfMethodXFound);
  13413. end;
  13414. procedure TTestResolver.TestClassInterface_DefaultProperty;
  13415. begin
  13416. StartProgram(false);
  13417. Add([
  13418. 'type',
  13419. ' IUnknown = interface',
  13420. ' end;',
  13421. ' IA = interface',
  13422. ' function GetItems(Index: longint): boolean;',
  13423. ' procedure SetItems(Index: longint; Value: boolean);',
  13424. ' property Items[IndeX: longint]: boolean read GetItems write SetItems; default;',
  13425. ' end;',
  13426. ' IB = IA;',
  13427. ' TObject = class(IB)',
  13428. ' strict private',
  13429. ' function GetItems(Index: longint): boolean; virtual; abstract;',
  13430. ' procedure SetItems(Index: longint; Value: boolean); virtual; abstract;',
  13431. ' end;',
  13432. 'var',
  13433. ' a: IA;',
  13434. ' b: IB;',
  13435. 'begin',
  13436. ' a[1]:=a[2];',
  13437. ' b[3]:=b[4];']);
  13438. ParseProgram;
  13439. end;
  13440. procedure TTestResolver.TestClassInterface_MethodResolution;
  13441. begin
  13442. StartProgram(false);
  13443. Add([
  13444. 'type',
  13445. ' IUnknown = interface',
  13446. ' procedure DoIt(i: longint);',
  13447. ' procedure DoIt(s: string);',
  13448. ' function DoIt(b: boolean): boolean;',
  13449. ' function GetIt: longint;',
  13450. ' end;',
  13451. ' TObject = class(IUnknown)',
  13452. ' procedure IUnknown.DoIt = DoSome;',
  13453. ' function IUnknown.GetIt = GetIt;',
  13454. ' procedure DoSome(i: longint); virtual; abstract;',
  13455. ' procedure DoSome(s: string); virtual; abstract;',
  13456. ' function GetIt: longint; virtual; abstract;',
  13457. ' function DoIt(b: boolean): boolean; virtual; abstract;',
  13458. ' end;',
  13459. 'begin']);
  13460. ParseProgram;
  13461. end;
  13462. procedure TTestResolver.TestClassInterface_MethodResolutionDuplicateFail;
  13463. begin
  13464. StartProgram(false);
  13465. Add([
  13466. 'type',
  13467. ' IUnknown = interface',
  13468. ' procedure DoIt;',
  13469. ' end;',
  13470. ' TObject = class(IUnknown)',
  13471. ' procedure IUnknown.DoIt = DoSome;',
  13472. ' procedure IUnknown.DoIt = DoMore;',
  13473. ' procedure DoSome; virtual; abstract;',
  13474. ' procedure DoMore; virtual; abstract;',
  13475. ' end;',
  13476. 'begin']);
  13477. CheckResolverException('Duplicate identifier "procedure IUnknown.DoIt" at afile.pp(7,14) at afile.pp (8,24)',nDuplicateIdentifier);
  13478. end;
  13479. procedure TTestResolver.TestClassInterface_DelegationIntf;
  13480. begin
  13481. StartProgram(false);
  13482. Add([
  13483. 'type',
  13484. ' IUnknown = interface',
  13485. ' procedure DoIt;',
  13486. ' end;',
  13487. ' IBird = interface',
  13488. ' end;',
  13489. ' TObject = class(IUnknown, IBird)',
  13490. ' function GetI: IBird; virtual; abstract;',
  13491. ' property MyI: IBird read GetI implements IUnknown, IBird;',
  13492. ' end;',
  13493. 'begin']);
  13494. ParseProgram;
  13495. end;
  13496. procedure TTestResolver.TestClassInterface_Delegation_DuplPropFail;
  13497. begin
  13498. StartProgram(false);
  13499. Add([
  13500. 'type',
  13501. ' IUnknown = interface',
  13502. ' procedure DoIt;',
  13503. ' end;',
  13504. ' IBird = interface',
  13505. ' end;',
  13506. ' TObject = class(IUnknown, IBird)',
  13507. ' function GetI: IBird; virtual; abstract;',
  13508. ' property MyI: IBird read GetI implements IBird;',
  13509. ' property MyJ: IBird read GetI implements IBird;',
  13510. ' end;',
  13511. 'begin']);
  13512. CheckResolverException('Duplicate implements for interface "IBird" at afile.pp(10,17)',
  13513. nDuplicateImplementsForIntf);
  13514. end;
  13515. procedure TTestResolver.TestClassInterface_Delegation_MethodResFail;
  13516. begin
  13517. StartProgram(false);
  13518. Add([
  13519. 'type',
  13520. ' IUnknown = interface',
  13521. ' procedure DoIt;',
  13522. ' end;',
  13523. ' IBird = interface',
  13524. ' end;',
  13525. ' TObject = class(IUnknown, IBird)',
  13526. ' function GetI: IBird; virtual; abstract;',
  13527. ' procedure IBird.DoIt = DoSome;',
  13528. ' procedure DoSome; virtual; abstract;',
  13529. ' property MyI: IBird read GetI implements IBird;',
  13530. ' end;',
  13531. 'begin']);
  13532. CheckResolverException('Cannot mix method resolution and delegation at afile.pp(12,17)',
  13533. nCannotMixMethodResolutionAndDelegationAtX);
  13534. end;
  13535. procedure TTestResolver.TestClassInterface_DelegationClass;
  13536. begin
  13537. StartProgram(false);
  13538. Add([
  13539. 'type',
  13540. ' IUnknown = interface',
  13541. ' procedure DoIt;',
  13542. ' end;',
  13543. ' IBird = interface',
  13544. ' end;',
  13545. ' TObject = class',
  13546. ' end;',
  13547. ' TBird = class(IBird)',
  13548. ' procedure DoIt; virtual; abstract;',
  13549. ' end;',
  13550. ' TEagle = class(IBird)',
  13551. ' FBird: TBird;',
  13552. ' property Bird: TBird read FBird implements IBird;',
  13553. ' end;',
  13554. 'begin']);
  13555. ParseProgram;
  13556. end;
  13557. procedure TTestResolver.TestClassInterface_DelegationFQN;
  13558. begin
  13559. StartProgram(false);
  13560. Add([
  13561. 'type',
  13562. ' IUnknown = interface',
  13563. ' procedure DoIt;',
  13564. ' end;',
  13565. ' TObject = class',
  13566. ' end;',
  13567. ' TBird = class(IUnknown)',
  13568. ' procedure DoIt; virtual; abstract;',
  13569. ' end;',
  13570. ' TEagle = class(IUnknown)',
  13571. ' FBird: TBird;',
  13572. ' property Bird: TBird read FBird implements afile.IUnknown;',
  13573. ' end;',
  13574. 'begin']);
  13575. ParseProgram;
  13576. end;
  13577. procedure TTestResolver.TestClassInterface_Assign;
  13578. begin
  13579. StartProgram(false);
  13580. Add([
  13581. 'type',
  13582. ' IUnknown = interface',
  13583. ' end;',
  13584. ' IBird = interface',
  13585. ' procedure Fly;',
  13586. ' end;',
  13587. ' IEagle = interface(IBird)',
  13588. ' end;',
  13589. ' TObject = class',
  13590. ' end;',
  13591. ' TBird = class(IBird)',
  13592. ' procedure Fly; virtual; abstract;',
  13593. ' end;',
  13594. ' TAlbatros = class(TBird)',
  13595. ' end;',
  13596. 'var',
  13597. ' i: IUnknown = nil;',
  13598. ' e: IEagle;',
  13599. ' b: IBird;',
  13600. ' oBird,oBird2: TBird;',
  13601. ' o: TObject;',
  13602. ' a: TAlbatros;',
  13603. ' p: pointer;',
  13604. 'begin',
  13605. ' if Assigned(i) then ;',
  13606. ' if TypeInfo(i)=nil then ;',
  13607. ' i:=nil;',
  13608. ' i:=i;',
  13609. ' i:=e;',
  13610. ' if i=nil then ;',
  13611. ' if i=e then ;',
  13612. ' if e=i then ;',
  13613. ' e:=IEagle(i);',
  13614. ' if i is IEagle then ;',
  13615. ' e:=i as IEagle;',
  13616. ' b:=oBird;',
  13617. ' b:=a;',
  13618. ' i:=IBird(oBird);', // FPC needs GUID
  13619. ' oBird2:=TBird(i);', // not supported by FPC
  13620. ' oBird2:=TBird(e);', // not supported by FPC
  13621. ' i:=o as IBird;', // FPC needs GUID
  13622. ' oBird2:=i as TBird;',
  13623. ' oBird2:=e as TBird;',
  13624. ' if o is IBird then ;', // FPC needs GUID
  13625. ' if i is TBird then ;',
  13626. ' if e is TBird then ;',
  13627. ' p:=i;',
  13628. ' if p=i then ;',
  13629. ' if i=p then ;',
  13630. '']);
  13631. ParseProgram;
  13632. end;
  13633. procedure TTestResolver.TestClassInterface_AssignObjVarIntfVarFail;
  13634. begin
  13635. StartProgram(false);
  13636. Add([
  13637. 'type',
  13638. ' IUnknown = interface',
  13639. ' end;',
  13640. ' TObject = class(IUnknown)',
  13641. ' end;',
  13642. 'var',
  13643. ' i: IUnknown;',
  13644. ' o: TObject;',
  13645. 'begin',
  13646. ' o:=i;',
  13647. '']);
  13648. CheckResolverException('Incompatible types: got "IUnknown" expected "TObject"',nIncompatibleTypesGotExpected);
  13649. end;
  13650. procedure TTestResolver.TestClassInterface_AssignDescendentFail;
  13651. begin
  13652. StartProgram(false);
  13653. Add([
  13654. 'type',
  13655. ' IUnknown = interface',
  13656. ' end;',
  13657. ' IBird = interface',
  13658. ' end;',
  13659. ' TObject = class(IBird)',
  13660. ' end;',
  13661. 'var',
  13662. ' i: IUnknown;',
  13663. ' o: TObject;',
  13664. 'begin',
  13665. ' i:=o;',
  13666. '']);
  13667. CheckResolverException('Incompatible types: got "TObject" expected "IUnknown"',nIncompatibleTypesGotExpected);
  13668. end;
  13669. procedure TTestResolver.TestClassInterface_Args;
  13670. begin
  13671. StartProgram(false);
  13672. Add([
  13673. 'type',
  13674. ' IUnknown = interface',
  13675. ' end;',
  13676. ' IBird = interface',
  13677. ' end;',
  13678. ' TObject = class',
  13679. ' end;',
  13680. ' TBird = class(IBird)',
  13681. ' end;',
  13682. 'function GetIt(var u; i: IBird; const j: IBird): IBird;',
  13683. 'begin',
  13684. ' Result:=IBird(u);',
  13685. ' Result:=i;',
  13686. ' Result:=j;',
  13687. 'end;',
  13688. 'procedure Change(var i: IBird; out j: IBird);',
  13689. 'begin',
  13690. ' i:=GetIt(i,i,i);',
  13691. 'end;',
  13692. 'var',
  13693. ' i: IBird;',
  13694. ' o: TBird;',
  13695. 'begin',
  13696. ' i:=GetIt(i,i,i);',
  13697. ' Change(i,i);',
  13698. ' GetIt(i,o,o);',
  13699. '']);
  13700. ParseProgram;
  13701. end;
  13702. procedure TTestResolver.TestClassInterface_Enumerator;
  13703. begin
  13704. StartProgram(false);
  13705. Add([
  13706. 'type',
  13707. ' TObject = class end;',
  13708. ' TItem = TObject;',
  13709. ' TEnumerator = class',
  13710. ' FCurrent: TItem;',
  13711. ' property Current: TItem read FCurrent;',
  13712. ' function MoveNext: boolean;',
  13713. ' end;',
  13714. ' IUnknown = interface end;',
  13715. ' IEnumerator = interface',
  13716. ' function GetCurrent: TItem;',
  13717. ' property Current: TItem read GetCurrent;',
  13718. ' function MoveNext: boolean;',
  13719. ' end;',
  13720. ' IEnumerable = interface',
  13721. ' function GetEnumerator: IEnumerator;',
  13722. ' end;',
  13723. ' IBird = interface',
  13724. ' function GetEnumerator: TEnumerator;',
  13725. ' end;',
  13726. 'function TEnumerator.MoveNext: boolean;',
  13727. 'begin',
  13728. 'end;',
  13729. 'var',
  13730. ' e: IEnumerable;',
  13731. ' b: IBird;',
  13732. ' i: TItem;',
  13733. ' {#i2}i2: TItem;',
  13734. 'begin',
  13735. ' for i in e do {@i2}i2:=i;',
  13736. ' for i in b do {@i2}i2:=i;']);
  13737. ParseProgram;
  13738. end;
  13739. procedure TTestResolver.TestClassInterface_PassTypecastClassToIntfAsVarParamFail;
  13740. begin
  13741. StartProgram(false);
  13742. Add([
  13743. '{$interfaces corba}',
  13744. 'type',
  13745. ' IUnknown = interface end;',
  13746. ' TObject = class end;',
  13747. ' TBall = class(IUnknown) end;',
  13748. 'procedure DoIt(var i: IUnknown); begin end;',
  13749. 'var b: TBall;',
  13750. 'begin',
  13751. ' DoIt(IUnknown(b));']);
  13752. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  13753. end;
  13754. procedure TTestResolver.
  13755. TestClassInterface_PassTypecastIntfToClassAsVarParamFail;
  13756. begin
  13757. StartProgram(false);
  13758. Add([
  13759. '{$interfaces corba}',
  13760. 'type',
  13761. ' IUnknown = interface end;',
  13762. ' TObject = class end;',
  13763. ' TBall = class(IUnknown) end;',
  13764. 'procedure DoIt(var i: IUnknown); begin end;',
  13765. 'var i: IUnknown;',
  13766. 'begin',
  13767. ' DoIt(TBall(i));']);
  13768. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  13769. end;
  13770. procedure TTestResolver.TestClassInterface_GUID;
  13771. begin
  13772. StartProgram(false);
  13773. Add([
  13774. '{$interfaces corba}',
  13775. 'type',
  13776. ' IUnknown = interface',
  13777. ' [''{F31DB68F-3010-D355-4EBA-CDD4EF4A737C}'']',
  13778. ' end;',
  13779. ' TObject = class end;',
  13780. ' TGUID = record D1,D2,D3,D4: word; end;',
  13781. ' TAliasGUID = TGUID;',
  13782. ' TGUIDString = type string;',
  13783. ' TAliasGUIDString = TGUIDString;',
  13784. 'procedure {#A}DoIt(const g: TAliasGUID); overload;',
  13785. 'begin end;',
  13786. 'procedure {#B}DoIt(const s: TAliasGUIDString); overload;',
  13787. 'begin end;',
  13788. 'var',
  13789. ' i: IUnknown;',
  13790. ' g: TAliasGUID = ''{D91C9AF4-3C93-420F-A303-BF5BA82BFD23}'';',
  13791. ' s: TAliasGUIDString;',
  13792. 'begin',
  13793. ' {@A}DoIt(IUnknown);',
  13794. ' {@A}DoIt(i);',
  13795. ' g:=i;',
  13796. ' g:=IUnknown;',
  13797. ' g:=''{D91C9AF4-3C93-420F-A303-BF5BA82BFD23}'';',
  13798. ' s:=g;',
  13799. ' s:=IUnknown;',
  13800. ' s:=i;',
  13801. ' {@B}DoIt(s);',
  13802. ' if s=IUnknown then ;',
  13803. ' if IUnknown=s then ;',
  13804. ' if s=i then ;',
  13805. ' if i=s then ;',
  13806. ' if g=IUnknown then ;',
  13807. ' if IUnknown=g then ;',
  13808. ' if g=i then ;',
  13809. ' if i=g then ;',
  13810. ' if s=g then ;',
  13811. ' if g=s then ;',
  13812. '']);
  13813. ParseProgram;
  13814. end;
  13815. procedure TTestResolver.TestPropertyAssign;
  13816. begin
  13817. StartProgram(false);
  13818. Add('type');
  13819. Add(' TObject = class');
  13820. Add(' FB: longint;');
  13821. Add(' property B: longint read FB write FB;');
  13822. Add(' end;');
  13823. Add('var');
  13824. Add(' o: TObject;');
  13825. Add(' i: longint;');
  13826. Add('begin');
  13827. Add(' {#a1_read}o.{#a2_assign}B:=i;');
  13828. Add(' i:={#b1_read}o.{#b2_read}B;');
  13829. Add(' if i={#c1_read}o.{#c2_read}B then ;');
  13830. Add(' if {#d1_read}o.{#d2_read}B=3 then ;');
  13831. ParseProgram;
  13832. CheckAccessMarkers;
  13833. end;
  13834. procedure TTestResolver.TestPropertyAssignReadOnlyFail;
  13835. begin
  13836. StartProgram(false);
  13837. Add('type');
  13838. Add(' TObject = class');
  13839. Add(' FB: longint;');
  13840. Add(' property B: longint read FB;');
  13841. Add(' end;');
  13842. Add('var');
  13843. Add(' o: TObject;');
  13844. Add('begin');
  13845. Add(' o.B:=3;');
  13846. CheckResolverException('No member is provided to access property',nPropertyNotWritable);
  13847. end;
  13848. procedure TTestResolver.TestProperty_PassAsParam;
  13849. begin
  13850. ResolverEngine.Options:=ResolverEngine.Options+[proPropertyAsVarParam];
  13851. StartProgram(false);
  13852. Add('type');
  13853. Add(' TObject = class');
  13854. Add(' FA: longint;');
  13855. Add(' property A: longint read FA write FA;');
  13856. Add(' end;');
  13857. Add('procedure DoIt(i: longint; const j: longint; var k: longint; out l: longint);');
  13858. Add('begin');
  13859. Add('end;');
  13860. Add('var');
  13861. Add(' o: TObject;');
  13862. Add('begin');
  13863. Add(' DoIt({#o1_read}o.{#o_a1_read}a,');
  13864. Add(' {#o2_read}o.{#o_a2_read}a,');
  13865. Add(' {#o3_read}o.{#o_a3_var}a,');
  13866. Add(' {#o4_read}o.{#o_a4_out}a);');
  13867. Add(' with o do');
  13868. Add(' DoIt({#w_a1_read}a,');
  13869. Add(' {#w_a2_read}a,');
  13870. Add(' {#w_a3_var}a,');
  13871. Add(' {#w_a4_out}a);');
  13872. ParseProgram;
  13873. CheckAccessMarkers;
  13874. end;
  13875. procedure TTestResolver.TestPropertyReadNonReadableFail;
  13876. begin
  13877. StartProgram(false);
  13878. Add('type');
  13879. Add(' TObject = class');
  13880. Add(' FB: longint;');
  13881. Add(' property B: longint write FB;');
  13882. Add(' end;');
  13883. Add('var');
  13884. Add(' o: TObject;');
  13885. Add('begin');
  13886. Add(' if o.B=3 then;');
  13887. CheckResolverException('not readable',nNotReadable);
  13888. end;
  13889. procedure TTestResolver.TestWithDo1;
  13890. begin
  13891. StartProgram(false);
  13892. Add('type');
  13893. Add(' {#TOBJ}TObject = class');
  13894. Add(' {#TOBJ_A}A: longint;');
  13895. Add(' end;');
  13896. Add('var');
  13897. Add(' {#o}{=TOBJ}o: TObject;');
  13898. Add(' {#a}a: longint;');
  13899. Add('begin');
  13900. Add(' {@a}a:=1;');
  13901. Add(' with {@o}o do');
  13902. Add(' {@TOBJ_A}a:=2;');
  13903. ParseProgram;
  13904. end;
  13905. procedure TTestResolver.TestWithDo2;
  13906. begin
  13907. StartProgram(false);
  13908. Add('type');
  13909. Add(' {#TOBJ}TObject = class');
  13910. Add(' {#TOBJ_i}i: longint;');
  13911. Add(' end;');
  13912. Add(' {#TA}TClassA = class');
  13913. Add(' {#TA_j}j: longint;');
  13914. Add(' {#TA_b}{=TA}b: TClassA;');
  13915. Add(' end;');
  13916. Add('var');
  13917. Add(' {#o}{=TOBJ}o: TObject;');
  13918. Add(' {#a}{=TA}a: TClassA;');
  13919. Add(' {#i}i: longint;');
  13920. Add('begin');
  13921. Add(' {@i}i:=1;');
  13922. Add(' with {@o}o do');
  13923. Add(' {@TOBJ_i}i:=2;');
  13924. Add(' {@i}i:=1;');
  13925. Add(' with {@o}o,{@a}a do begin');
  13926. Add(' {@TOBJ_i}i:=3;');
  13927. Add(' {@TA_j}j:=4;');
  13928. Add(' {@TA_b}b:={@a}a;');
  13929. Add(' end;');
  13930. ParseProgram;
  13931. end;
  13932. procedure TTestResolver.TestWithDoFuncResult;
  13933. begin
  13934. StartProgram(false);
  13935. Add('type');
  13936. Add(' {#TOBJ}TObject = class');
  13937. Add(' {#TOBJ_i}i: longint;');
  13938. Add(' end;');
  13939. Add(' {#TA}TClassA = class');
  13940. Add(' {#TA_j}j: longint;');
  13941. Add(' {#TA_b}{=TA}b: TClassA;');
  13942. Add(' end;');
  13943. Add('function {#GiveA}Give: TClassA;');
  13944. Add('begin');
  13945. Add('end;');
  13946. Add('function {#GiveB}Give(i: longint): TClassA;');
  13947. Add('begin');
  13948. Add('end;');
  13949. Add('var');
  13950. Add(' {#o}{=TOBJ}o: TObject;');
  13951. Add(' {#a}{=TA}a: TClassA;');
  13952. Add(' {#i}i: longint;');
  13953. Add('begin');
  13954. Add(' with {@GiveA}Give do {@TOBJ_i}i:=3;');
  13955. Add(' with {@GiveA}Give() do {@TOBJ_i}i:=3;');
  13956. Add(' with {@GiveB}Give(2) do {@TOBJ_i}i:=3;');
  13957. ParseProgram;
  13958. end;
  13959. procedure TTestResolver.TestWithDoConstructor;
  13960. begin
  13961. StartProgram(false);
  13962. Add('type');
  13963. Add(' {#TOBJ}TObject = class');
  13964. Add(' {#TOBJ_i}i: longint;');
  13965. Add(' end;');
  13966. Add(' {#TA}TClassA = class');
  13967. Add(' {#TA_j}j: longint;');
  13968. Add(' {#TA_b}{=TA}b: TClassA;');
  13969. Add(' constructor {#A_CreateA}Create;');
  13970. Add(' constructor {#A_CreateB}Create(i: longint);');
  13971. Add(' end;');
  13972. Add('constructor TClassA.Create;');
  13973. Add('begin');
  13974. Add('end;');
  13975. Add('constructor TClassA.Create(i: longint);');
  13976. Add('begin');
  13977. Add('end;');
  13978. Add('var');
  13979. Add(' {#o}{=TOBJ}o: TObject;');
  13980. Add(' {#a}{=TA}a: TClassA;');
  13981. Add(' {#i}i: longint;');
  13982. Add('begin');
  13983. Add(' with TClassA.{@A_CreateA}Create do {@TOBJ_i}i:=3;');
  13984. Add(' with TClassA.{@A_CreateA}Create() do {@TOBJ_i}i:=3;');
  13985. Add(' with TClassA.{@A_CreateB}Create(2) do {@TOBJ_i}i:=3;');
  13986. ParseProgram;
  13987. end;
  13988. procedure TTestResolver.TestDynArrayOfLongint;
  13989. begin
  13990. StartProgram(false);
  13991. Add('type TIntArray = array of longint;');
  13992. Add('var a: TIntArray;');
  13993. Add('begin');
  13994. Add(' a:=nil;');
  13995. Add(' if a=nil then ;');
  13996. Add(' if nil=a then ;');
  13997. Add(' SetLength(a,3);');
  13998. Add(' a[0]:=1;');
  13999. Add(' a[1]:=length(a);');
  14000. Add(' a[2]:=a[0];');
  14001. Add(' if a[3]=a[4] then ;');
  14002. Add(' a[a[5]]:=a[a[6]];');
  14003. ParseProgram;
  14004. end;
  14005. procedure TTestResolver.TestDynArrayOfSelfFail;
  14006. begin
  14007. StartProgram(false);
  14008. Add('type TIntArray = array of TIntArray;');
  14009. Add('begin');
  14010. CheckResolverException(sIllegalExpression,nIllegalExpression);
  14011. end;
  14012. procedure TTestResolver.TestStaticArray;
  14013. begin
  14014. StartProgram(false);
  14015. Add('type');
  14016. Add(' TArrA = array[1..2] of longint;');
  14017. Add(' TArrB = array[char] of boolean;');
  14018. Add(' TArrC = array[byte,''a''..''z''] of longint;');
  14019. Add('const');
  14020. Add(' ArrA: TArrA = (3,4);');
  14021. Add('var');
  14022. Add(' a: TArrA;');
  14023. Add(' b: TArrB;');
  14024. Add(' c: TArrC;');
  14025. Add('begin');
  14026. Add(' a[1]:=1;');
  14027. Add(' if a[2]=low(a) then ;');
  14028. Add(' b[''x'']:=true;');
  14029. Add(' if b[''y''] then ;');
  14030. Add(' c[3,''f'']:=1;');
  14031. Add(' if c[4,''g'']=a[1] then ;');
  14032. ParseProgram;
  14033. end;
  14034. procedure TTestResolver.TestStaticArrayOfChar;
  14035. begin
  14036. StartProgram(false);
  14037. Add([
  14038. 'type',
  14039. ' TArrA = array[1..3] of char;',
  14040. 'const',
  14041. {
  14042. ' A: TArrA = (''p'',''a'',''p'');', // duplicate allowed, this bracket is not a set
  14043. ' B: TArrA = ''pas'';',
  14044. ' Three = length(TArrA);',
  14045. ' C: array[1..Three] of char = ''pas'';',
  14046. ' D = ''pp'';',
  14047. ' E: array[length(D)..Three] of char = D;',
  14048. ' F: array[1..2] of widechar = ''äö'';',
  14049. }
  14050. ' G: array[1..2] of char = ''ä'';',
  14051. {
  14052. ' H: array[1..4] of char = ''äö'';',
  14053. ' I: array[1..4] of char = ''ä''+''ö'';',
  14054. }
  14055. 'begin']);
  14056. ParseProgram;
  14057. end;
  14058. procedure TTestResolver.TestStaticArrayOfCharDelphi;
  14059. begin
  14060. StartProgram(false);
  14061. Add([
  14062. '{$mode delphi}',
  14063. 'type',
  14064. ' TArrA = array[1..3] of char;',
  14065. 'const',
  14066. ' A: TArrA = (''p'',''a'',''p'');', // duplicate allowed, this bracket is not a set
  14067. ' B: TArrA = ''pas'';',
  14068. ' Three = length(TArrA);',
  14069. ' C: array[1..Three] of char = ''pas'';',
  14070. ' D = ''pp'';',
  14071. ' E: array[length(D)..Three] of char = D;',
  14072. ' F: array[1..2] of widechar = ''äö'';',
  14073. ' G: array[1..2] of char = ''ä'';',
  14074. ' H: array[1..4] of char = ''äö'';',
  14075. ' I: array[1..4] of char = ''ä''+''ö'';',
  14076. 'begin']);
  14077. ParseProgram;
  14078. end;
  14079. procedure TTestResolver.TestStaticArrayOfRangeElCheckFail;
  14080. begin
  14081. StartProgram(false);
  14082. Add('var');
  14083. Add(' A: array[1..2] of shortint = (1,300);');
  14084. Add('begin');
  14085. ParseProgram;
  14086. CheckResolverHint(mtWarning,nRangeCheckEvaluatingConstantsVMinMax,
  14087. 'range check error while evaluating constants (300 is not between -128 and 127)');
  14088. end;
  14089. procedure TTestResolver.TestArrayOfChar_String;
  14090. begin
  14091. StartProgram(false);
  14092. Add([
  14093. 'procedure {#a}Run(const s: string); overload;',
  14094. 'begin end;',
  14095. 'procedure {#b}Run(const a: array of char); overload;',
  14096. 'begin end;',
  14097. 'var',
  14098. ' s: string;',
  14099. ' c: char;',
  14100. 'begin',
  14101. ' {@a}Run(''foo'');',
  14102. ' {@a}Run(s);',
  14103. ' {@a}Run(c);',
  14104. '']);
  14105. ParseProgram;
  14106. end;
  14107. procedure TTestResolver.TestArrayOfArray;
  14108. begin
  14109. StartProgram(false);
  14110. Add('type');
  14111. Add(' TArrA = array[byte] of longint;');
  14112. Add(' TArrB = array[smallint] of TArrA;');
  14113. Add(' TArrC = array of array of longint;');
  14114. Add('var');
  14115. Add(' b: TArrB;');
  14116. Add(' c: TArrC;');
  14117. Add('begin');
  14118. Add(' b[1][2]:=5;');
  14119. Add(' b[1,2]:=5;');
  14120. Add(' if b[2,1]=b[0,1] then ;');
  14121. Add(' c[3][4]:=c[5,6];');
  14122. Add(' Setlength(c[3],7);');
  14123. Add(' Setlength(c,8,9);');
  14124. ParseProgram;
  14125. end;
  14126. procedure TTestResolver.TestArrayOfArray_NameAnonymous;
  14127. begin
  14128. ResolverEngine.AnonymousElTypePostfix:='$array';
  14129. StartProgram(false);
  14130. Add('type');
  14131. Add(' TArrA = array of array of longint;');
  14132. Add('var');
  14133. Add(' a: TArrA;');
  14134. Add('begin');
  14135. Add(' a[1][2]:=5;');
  14136. Add(' a[1,2]:=5;');
  14137. Add(' if a[2,1]=a[0,1] then ;');
  14138. Add(' a[3][4]:=a[5,6];');
  14139. ParseProgram;
  14140. end;
  14141. procedure TTestResolver.TestFunctionReturningArray;
  14142. begin
  14143. StartProgram(false);
  14144. Add([
  14145. 'type',
  14146. ' TArrA = array[1..20] of longint;',
  14147. ' TArrB = array of TArrA;',
  14148. 'function FuncC: TArrB;',
  14149. 'begin',
  14150. ' SetLength(Result,3);',
  14151. 'end;',
  14152. 'begin',
  14153. ' FuncC[2,4]:=6;',
  14154. ' FuncC()[1,3]:=5;']);
  14155. ParseProgram;
  14156. end;
  14157. procedure TTestResolver.TestArray_LowHigh;
  14158. begin
  14159. StartProgram(false);
  14160. Add('type');
  14161. Add(' TArrA = array[char] of longint;');
  14162. Add(' TArrB = array of TArrA;');
  14163. Add('var');
  14164. Add(' c: char;');
  14165. Add(' i: longint;');
  14166. Add('begin');
  14167. Add(' for c:=low(TArrA) to High(TArrA) do ;');
  14168. Add(' for i:=low(TArrB) to High(TArrB) do ;');
  14169. ParseProgram;
  14170. end;
  14171. procedure TTestResolver.TestArray_LowVarFail;
  14172. begin
  14173. StartProgram(false);
  14174. Add([
  14175. 'var a: array of longint;',
  14176. 'const l = length(a);',
  14177. 'begin']);
  14178. CheckResolverException(sConstantExpressionExpected,nConstantExpressionExpected);
  14179. end;
  14180. procedure TTestResolver.TestArray_AssignDiffElTypeFail;
  14181. begin
  14182. StartProgram(false);
  14183. Add('type');
  14184. Add(' TArrA = array of longint;');
  14185. Add(' TArrB = array of byte;');
  14186. Add('var');
  14187. Add(' a: TArrA;');
  14188. Add(' b: TArrB;');
  14189. Add('begin');
  14190. Add(' a:=b;');
  14191. CheckResolverException('Incompatible types: got "array of Longint" expected "array of Byte"',
  14192. nIncompatibleTypesGotExpected);
  14193. end;
  14194. procedure TTestResolver.TestArray_AssignSameSignatureDelphiFail;
  14195. begin
  14196. StartProgram(false);
  14197. Add('{$mode delphi}');
  14198. Add('type');
  14199. Add(' TArrA = array of longint;');
  14200. Add(' TArrB = array of longint;');
  14201. Add('var');
  14202. Add(' a: TArrA;');
  14203. Add(' b: TArrB;');
  14204. Add('begin');
  14205. Add(' a:=b;');
  14206. CheckResolverException('Incompatible types: got "TArrB" expected "TArrA"',
  14207. nIncompatibleTypesGotExpected);
  14208. end;
  14209. procedure TTestResolver.TestArray_Assigned;
  14210. begin
  14211. StartProgram(false);
  14212. Add('var a: array of longint;');
  14213. Add('begin');
  14214. Add(' if Assigned(a) then ;');
  14215. ParseProgram;
  14216. end;
  14217. procedure TTestResolver.TestPropertyOfTypeArray;
  14218. begin
  14219. StartProgram(false);
  14220. Add('type');
  14221. Add(' TArray = array of longint;');
  14222. Add(' TObject = class');
  14223. Add(' FItems: TArray;');
  14224. Add(' function GetItems: TArray;');
  14225. Add(' procedure SetItems(Value: TArray);');
  14226. Add(' property Items: TArray read FItems write FItems;');
  14227. Add(' property Numbers: TArray read GetItems write SetItems;');
  14228. Add(' end;');
  14229. Add('function TObject.GetItems: TArray;');
  14230. Add('begin');
  14231. Add(' Result:=FItems;');
  14232. Add('end;');
  14233. Add('procedure TObject.SetItems(Value: TArray);');
  14234. Add('begin');
  14235. Add(' FItems:=Value;');
  14236. Add('end;');
  14237. Add('var Obj: TObject;');
  14238. Add('begin');
  14239. Add(' Obj.Items[3]:=4;');
  14240. Add(' if Obj.Items[5]=6 then;');
  14241. Add(' Obj.Numbers[7]:=8;');
  14242. Add(' if Obj.Numbers[9]=10 then;');
  14243. ParseProgram;
  14244. end;
  14245. procedure TTestResolver.TestArrayElementFromFuncResult_AsParams;
  14246. var
  14247. aMarker: PSrcMarker;
  14248. Elements: TFPList;
  14249. ActualImplicitCall: Boolean;
  14250. i: Integer;
  14251. El: TPasElement;
  14252. Ref: TResolvedReference;
  14253. begin
  14254. StartProgram(false);
  14255. Add('type Integer = longint;');
  14256. Add('type TArrayInt = array of integer;');
  14257. Add('function GetArr(vB: integer = 0): tarrayint;');
  14258. Add('begin');
  14259. Add('end;');
  14260. Add('procedure DoIt(vG: integer);');
  14261. Add('begin');
  14262. Add('end;');
  14263. Add('begin');
  14264. Add(' doit({#a}getarr[1+1]);');
  14265. Add(' doit({#b}getarr()[2+1]);');
  14266. Add(' doit({#c}getarr(7)[3+1]);');
  14267. ParseProgram;
  14268. aMarker:=FirstSrcMarker;
  14269. while aMarker<>nil do
  14270. begin
  14271. //writeln('TTestResolver.TestArrayElementFromFuncResult_AsParams ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  14272. Elements:=FindElementsAt(aMarker);
  14273. try
  14274. ActualImplicitCall:=false;
  14275. for i:=0 to Elements.Count-1 do
  14276. begin
  14277. El:=TPasElement(Elements[i]);
  14278. //writeln('TTestResolver.TestArrayElementFromFuncResult_AsParams ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  14279. if not (El.CustomData is TResolvedReference) then continue;
  14280. Ref:=TResolvedReference(El.CustomData);
  14281. if rrfImplicitCallWithoutParams in Ref.Flags then
  14282. ActualImplicitCall:=true;
  14283. break;
  14284. end;
  14285. case aMarker^.Identifier of
  14286. 'a':
  14287. if not ActualImplicitCall then
  14288. RaiseErrorAtSrcMarker('expected rrfImplicitCallWithoutParams at "#'+aMarker^.Identifier+'"',aMarker);
  14289. else
  14290. if ActualImplicitCall then
  14291. RaiseErrorAtSrcMarker('expected no rrfImplicitCallWithoutParams at "#'+aMarker^.Identifier+'"',aMarker);
  14292. end;
  14293. finally
  14294. Elements.Free;
  14295. end;
  14296. aMarker:=aMarker^.Next;
  14297. end;
  14298. end;
  14299. procedure TTestResolver.TestArrayEnumTypeRange;
  14300. begin
  14301. StartProgram(false);
  14302. Add('type');
  14303. Add(' TEnum = (red,blue);');
  14304. Add(' TEnumArray = array[TEnum] of longint;');
  14305. Add('var');
  14306. Add(' e: TEnum;');
  14307. Add(' i: longint;');
  14308. Add(' a: TEnumArray;');
  14309. Add(' names: array[TEnum] of string = (''red'',''blue'');');
  14310. Add('begin');
  14311. Add(' e:=low(a);');
  14312. Add(' e:=high(a);');
  14313. Add(' i:=a[red];');
  14314. Add(' a[e]:=a[e];');
  14315. ParseProgram;
  14316. end;
  14317. procedure TTestResolver.TestArrayEnumTypeConstNotEnoughValuesFail1;
  14318. begin
  14319. StartProgram(false);
  14320. Add('type');
  14321. Add(' TEnum = (red,blue);');
  14322. Add('var');
  14323. Add(' a: array[TEnum] of string = (''red'');');
  14324. Add('begin');
  14325. CheckResolverException('Expect 2 array elements, but found 1',nExpectXArrayElementsButFoundY);
  14326. end;
  14327. procedure TTestResolver.TestArrayEnumTypeConstNotEnoughValuesFail2;
  14328. begin
  14329. StartProgram(false);
  14330. Add('type');
  14331. Add(' TEnum = (red,blue,green);');
  14332. Add('var');
  14333. Add(' a: array[TEnum] of string = (''red'',''blue'');');
  14334. Add('begin');
  14335. CheckResolverException('Expect 3 array elements, but found 2',nExpectXArrayElementsButFoundY);
  14336. end;
  14337. procedure TTestResolver.TestArrayEnumTypeConstWrongTypeFail;
  14338. begin
  14339. StartProgram(false);
  14340. Add('type');
  14341. Add(' TEnum = (red,blue);');
  14342. Add('var');
  14343. Add(' a: array[TEnum] of string = (1,2);');
  14344. Add('begin');
  14345. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  14346. nIncompatibleTypesGotExpected);
  14347. end;
  14348. procedure TTestResolver.TestArrayEnumTypeConstNonConstFail;
  14349. begin
  14350. StartProgram(false);
  14351. Add('type');
  14352. Add(' TEnum = (red,blue);');
  14353. Add('var');
  14354. Add(' s: string;');
  14355. Add(' a: array[TEnum] of string = (''red'',s);');
  14356. Add('begin');
  14357. CheckResolverException('Constant expression expected',
  14358. nConstantExpressionExpected);
  14359. end;
  14360. procedure TTestResolver.TestArrayEnumTypeSetLengthFail;
  14361. begin
  14362. StartProgram(false);
  14363. Add('type');
  14364. Add(' TEnum = (red,blue);');
  14365. Add('var');
  14366. Add(' a: array[TEnum] of longint;');
  14367. Add('begin');
  14368. Add(' SetLength(a,1);');
  14369. CheckResolverException('Incompatible type for arg no. 1: Got "static array[] of Longint", expected "string or dynamic array variable"',
  14370. nIncompatibleTypeArgNo);
  14371. end;
  14372. procedure TTestResolver.TestArrayEnumCustomRange;
  14373. begin
  14374. StartProgram(false);
  14375. Add([
  14376. 'type',
  14377. ' TEnum = (red,blue,green);',
  14378. ' TEnumRg = blue..green;',
  14379. ' TEnumArray = array[TEnumRg] of longint;',
  14380. ' TEnumArray2 = array[blue..green] of longint;',
  14381. 'var',
  14382. ' e: TEnum;',
  14383. ' r: TEnumRg;',
  14384. ' i: longint;',
  14385. ' a: TEnumArray;',
  14386. ' b: array[TEnum] of longint;',
  14387. ' c: TEnumArray2;',
  14388. ' names: array[TEnumRg] of string = (''blue'',''green'');',
  14389. 'begin',
  14390. ' r:=low(a);',
  14391. ' r:=high(a);',
  14392. ' i:=a[red];',
  14393. ' a[e]:=a[e];',
  14394. ' a[r]:=a[r];',
  14395. ' b[r]:=b[r];',
  14396. ' r:=low(c);',
  14397. ' r:=high(c);',
  14398. ' i:=c[red];',
  14399. ' c[e]:=c[e];',
  14400. ' c[r]:=c[r];',
  14401. '']);
  14402. ParseProgram;
  14403. end;
  14404. procedure TTestResolver.TestArray_DynArrayConstObjFPC;
  14405. begin
  14406. Parser.Options:=Parser.Options+[po_cassignments];
  14407. StartProgram(false);
  14408. Add([
  14409. '{$modeswitch arrayoperators}',
  14410. 'type',
  14411. ' integer = longint;',
  14412. ' TArrInt = array of integer;',
  14413. ' TArrStr = array of string;',
  14414. 'const',
  14415. ' Ints: TArrInt = (1,2,3);',
  14416. ' Aliases: TarrStr = (''foo'',''b'');',
  14417. ' OneInt: TArrInt = (7);',
  14418. ' OneInt2: array of integer = (7);',
  14419. ' Chars: array of char = ''aoc'';',
  14420. ' Names: array of string = (''a'',''foo'');',
  14421. ' NameCount = low(Names)+high(Names)+length(Names);',
  14422. 'procedure DoIt(Ints: TArrInt);',
  14423. 'begin',
  14424. 'end;',
  14425. 'var i: integer;',
  14426. 'begin',
  14427. ' Ints:= {#a_array}[1,i];',
  14428. ' Ints:= {#b1_array}[1,1]+ {#b2_array}[2]+ {#b3_array}[i];',
  14429. ' Ints:= {#c_array}[i]+ {#d_array}[2,2];',
  14430. ' Ints:=Ints+ {#e_array}[1];',
  14431. ' Ints:= {#f_array}[1]+Ints;',
  14432. ' Ints:=Ints+OneInt+OneInt2;',
  14433. ' Ints+= {#g_array}[i];',
  14434. ' Ints+= {#h_array}[1,1];',
  14435. ' DoIt( {#i_array}[1,1]);',
  14436. ' DoIt( {#j_array}[i]);',
  14437. '']);
  14438. ParseProgram;
  14439. CheckParamsExpr_pkSet_Markers;
  14440. CheckResolverUnexpectedHints;
  14441. end;
  14442. procedure TTestResolver.TestArray_DynArrayConstDelphi;
  14443. begin
  14444. StartProgram(false);
  14445. Add([
  14446. '{$mode delphi}',
  14447. 'const c= {#c_set}[1,2];',
  14448. 'type',
  14449. ' integer = longint;',
  14450. ' TArrInt = array of integer;',
  14451. ' TArrStr = array of string;',
  14452. ' TArrInt2 = array of TArrInt;',
  14453. ' TSetOfEnum = set of (red,blue);',
  14454. ' TArrOfSet = array of TSetOfEnum;',
  14455. 'const',
  14456. ' Ints: TArrInt = {#ints_array}[1,2,1];',
  14457. ' Aliases: TarrStr = {#aliases_array}[''foo'',''b'',''b''];',
  14458. ' OneInt: TArrInt = {#oneint_array}[7];',
  14459. ' TwoInt: array of integer = {#twoint1_array}[7]+{#twoint2_array}[8];',
  14460. ' Chars: array of char = ''aoc'';',
  14461. ' Names: array of string = {#names_array}[''a'',''a''];',
  14462. ' NameCount = low(Names)+high(Names)+length(Names);',
  14463. 'procedure {#DoArrOfSet}DoIt(const s: TArrOfSet); overload; begin end;',
  14464. 'procedure {#DoArrOfArrInt}DoIt(const a: TArrInt2); overload; begin end;',
  14465. 'begin',
  14466. ' {@DoArrOfSet}DoIt( {#a1_array}[ {#a2_set}[blue], {#a3_set}[red] ]);',
  14467. ' {@DoArrOfArrInt}DoIt( {#b1_array}[ {#b2_array}[1], {#b3_array}[2] ]);',
  14468. '']);
  14469. ParseProgram;
  14470. CheckParamsExpr_pkSet_Markers;
  14471. CheckResolverUnexpectedHints;
  14472. end;
  14473. procedure TTestResolver.TestArray_DynArrAssignStaticDelphiFail;
  14474. begin
  14475. StartProgram(false);
  14476. Add([
  14477. '{$mode delphi}',
  14478. 'type',
  14479. ' TIntArr = array[1..3] of longint;',
  14480. 'var',
  14481. ' dyn: array of longint;',
  14482. ' sta: TIntArr;',
  14483. 'begin',
  14484. ' dyn:=sta;']);
  14485. CheckResolverException('Incompatible types: got "static array" expected "dynamic array"',
  14486. nIncompatibleTypesGotExpected);
  14487. end;
  14488. procedure TTestResolver.TestArray_Static_Const;
  14489. begin
  14490. StartProgram(false);
  14491. Add([
  14492. 'type',
  14493. ' TIntArr = array[1..3] of longint;',
  14494. 'const',
  14495. ' a = low(TIntArr)+high(TIntArr);',
  14496. ' b: array[1..3] of longint = (10,11,12);',
  14497. ' c: array[boolean] of TIntArr = ((21,22,23),(31,32,33));',
  14498. 'begin']);
  14499. ParseProgram;
  14500. CheckResolverUnexpectedHints;
  14501. end;
  14502. procedure TTestResolver.TestArray_Record_Const;
  14503. begin
  14504. StartProgram(false);
  14505. Add([
  14506. 'type',
  14507. ' TPoint = record x, y: longint; end;',
  14508. ' TDynArray = array of TPoint;',
  14509. ' TStaticArray = array[1..2] of TPoint;',
  14510. ' TRecArr = record',
  14511. ' DA: TDynArray;',
  14512. ' SA: TStaticArray;',
  14513. ' end;',
  14514. 'const',
  14515. ' sa: TStaticArray = ( (x:2; y:3), (x:12;y:14) );',
  14516. ' da: TDynArray = ( (x:22; y:23), (x:32;y:34) );',
  14517. ' ra: TRecArr = (',
  14518. ' DA: ( (x:42; y:43), (x:44;y:45) );',
  14519. ' SA: ( (x:51; y:52), (x:53;y:54) );',
  14520. ' );',
  14521. 'begin',
  14522. '']);
  14523. ParseProgram;
  14524. end;
  14525. procedure TTestResolver.TestArray_MultiDim_Const;
  14526. begin
  14527. StartProgram(false);
  14528. Add([
  14529. '{$modeswitch arrayoperators}',
  14530. 'type',
  14531. ' TDynArray = array of longint;',
  14532. ' TDynArray2 = array of TDynArray;',
  14533. ' TArrOfArr = array[1..2] of TDynArray;',
  14534. ' TMultiDimArr = array[1..2,3..4] of longint;',
  14535. 'const',
  14536. ' AoA: TArrOfArr = ( (1,2), (2,3) );',
  14537. ' MultiDimArr: TMultiDimArr = ( (11,12), (13,14) );',
  14538. ' A2: TDynArray2 = ( (1,2), (2,3) );',
  14539. 'var',
  14540. ' A: TDynArray;',
  14541. 'procedure DoIt(const a: TDynArray2); begin end;',
  14542. 'var i: longint;',
  14543. 'begin',
  14544. ' AoA:= {#a1_array}[ {#a2_array}[1], {#a3_array}[i] ];',
  14545. ' AoA:= {#b1_array}[ {#b2_array}[i], A ];',
  14546. ' AoA:= {#c1_array}[ {#c2_array}[i,2], {#c3_array}[2,i] ];',
  14547. ' MultiDimArr:= {#d1_array}[ {#d2_array}[11,12], [13,14] ];',
  14548. ' A2:= {#e1_array}[ {#e2_array}[1,2], {#e3_array}[2,3], {#e4_array}[i] ];',
  14549. ' DoIt( {#f1_array}[ {#f2_array}[i,32], {#f3_array}[32,i] ]);',
  14550. ' A2:= A2+ {#g1_array}[A];',
  14551. ' A2:= {#h1_array}[A]+A2;',
  14552. '']);
  14553. ParseProgram;
  14554. CheckParamsExpr_pkSet_Markers;
  14555. end;
  14556. procedure TTestResolver.TestArray_AssignNilToStaticArrayFail1;
  14557. begin
  14558. StartProgram(false);
  14559. Add('type');
  14560. Add(' TEnum = (red,blue);');
  14561. Add('var');
  14562. Add(' a: array[TEnum] of longint;');
  14563. Add('begin');
  14564. Add(' a:=nil;');
  14565. CheckResolverException('Incompatible types: got "nil" expected "static array[] of Longint"',
  14566. nIncompatibleTypesGotExpected);
  14567. end;
  14568. procedure TTestResolver.TestArray_SetLengthProperty;
  14569. begin
  14570. ResolverEngine.Options:=ResolverEngine.Options+[proPropertyAsVarParam];
  14571. StartProgram(false);
  14572. Add('type');
  14573. Add(' TArrInt = array of longint;');
  14574. Add(' TObject = class');
  14575. Add(' function GetColors: TArrInt; external name ''GetColors'';');
  14576. Add(' procedure SetColors(const Value: TArrInt); external name ''SetColors'';');
  14577. Add(' property Colors: TArrInt read GetColors write SetColors;');
  14578. Add(' end;');
  14579. Add('procedure DoIt(var i: longint; out j: longint; const k: longint); begin end;');
  14580. Add('var Obj: TObject;');
  14581. Add('begin');
  14582. Add(' SetLength(Obj.Colors,2);');
  14583. Add(' DoIt(Obj.Colors[1],Obj.Colors[2],Obj.Colors[3]);');
  14584. ParseProgram;
  14585. end;
  14586. procedure TTestResolver.TestStaticArray_SetlengthFail;
  14587. begin
  14588. StartProgram(false);
  14589. Add('type');
  14590. Add(' TArrInt = array[1..3] of longint;');
  14591. Add('var a: TArrInt;');
  14592. Add('begin');
  14593. Add(' SetLength(a,2);');
  14594. CheckResolverException(sIncompatibleTypeArgNo,nIncompatibleTypeArgNo);
  14595. end;
  14596. procedure TTestResolver.TestArray_PassArrayElementToVarParam;
  14597. begin
  14598. StartProgram(false);
  14599. Add('type');
  14600. Add(' TArrInt = array of longint;');
  14601. Add('procedure DoIt(var i: longint; out j: longint; const k: longint); begin end;');
  14602. Add('var a: TArrInt;');
  14603. Add('begin');
  14604. Add(' DoIt(a[1],a[2],a[3]);');
  14605. ParseProgram;
  14606. end;
  14607. procedure TTestResolver.TestArray_OpenArrayOfString;
  14608. begin
  14609. StartProgram(false);
  14610. Add([
  14611. 'type TArrStr = array of string;',
  14612. 'procedure DoIt(const a: array of String);',
  14613. 'var',
  14614. ' i: longint;',
  14615. ' s: string;',
  14616. 'begin',
  14617. ' for i:=low(a) to high(a) do s:=a[length(a)-i-1];',
  14618. 'end;',
  14619. 'const arr: array[0..1] of string = (''A'', ''B'');',
  14620. 'var s: string;',
  14621. 'begin',
  14622. ' DoIt([]);',
  14623. ' DoIt([s,''foo'','''',s+s]);',
  14624. ' DoIt(arr);',
  14625. '']);
  14626. ParseProgram;
  14627. end;
  14628. procedure TTestResolver.TestArray_OpenArrayOfString_IntFail;
  14629. begin
  14630. StartProgram(false);
  14631. Add('procedure DoIt(const a: array of String);');
  14632. Add('begin');
  14633. Add('end;');
  14634. Add('begin');
  14635. Add(' DoIt([1]);');
  14636. CheckResolverException('Incompatible types: got "Longint" expected "String"',nIncompatibleTypesGotExpected);
  14637. end;
  14638. procedure TTestResolver.TestArray_OpenArrayOverride;
  14639. begin
  14640. StartProgram(false);
  14641. Add('type');
  14642. Add(' TObject = class');
  14643. Add(' end;');
  14644. Add(' Exception = class');
  14645. Add(' constructor CreateFmt(const Msg: string; const Args: array of string); virtual;');
  14646. Add(' end;');
  14647. Add(' ESome = class(Exception)');
  14648. Add(' constructor CreateFmt(const Msg: string; const Args: array of string); override;');
  14649. Add(' end;');
  14650. Add('constructor Exception.CreateFmt(const Msg: string; const Args: array of string);');
  14651. Add('begin end;');
  14652. Add('constructor ESome.CreateFmt(const Msg: string; const Args: array of string);');
  14653. Add('begin');
  14654. Add(' inherited CreateFmt(Msg,Args);');
  14655. Add('end;');
  14656. Add('begin');
  14657. ParseProgram;
  14658. end;
  14659. procedure TTestResolver.TestArray_OpenArrayAsDynArraySetLengthFail;
  14660. begin
  14661. StartProgram(false);
  14662. Add([
  14663. 'procedure DoIt(a: array of byte);',
  14664. 'begin',
  14665. ' SetLength(a,3);',
  14666. 'end;',
  14667. 'begin']);
  14668. CheckResolverException('Incompatible type for arg no. 1: Got "open array of Byte", expected "string or dynamic array variable"',
  14669. nIncompatibleTypeArgNo);
  14670. end;
  14671. procedure TTestResolver.TestArray_OpenArrayAsDynArray;
  14672. begin
  14673. ResolverEngine.Options:=ResolverEngine.Options+[proOpenAsDynArrays];
  14674. StartProgram(false);
  14675. Add([
  14676. '{$modeswitch arrayoperators}',
  14677. 'type TArrStr = array of string;',
  14678. 'procedure DoStr(const a: TArrStr); forward;',
  14679. 'procedure DoIt(a: array of String);',
  14680. 'var',
  14681. ' i: longint;',
  14682. ' s: string;',
  14683. 'begin',
  14684. ' SetLength(a,3);',
  14685. ' DoStr(a);',
  14686. ' DoStr(a+[s]);',
  14687. ' DoStr([s]+a);',
  14688. 'end;',
  14689. 'procedure DoStr(const a: TArrStr);',
  14690. 'var s: string;',
  14691. 'begin',
  14692. ' DoIt(a);',
  14693. ' DoIt(a+[s]);',
  14694. ' DoIt([s]+a);',
  14695. 'end;',
  14696. 'begin']);
  14697. ParseProgram;
  14698. end;
  14699. procedure TTestResolver.TestArray_OpenArrayDelphi;
  14700. begin
  14701. StartProgram(false);
  14702. Add([
  14703. '{$mode delphi}',
  14704. 'type',
  14705. ' TDynArrInt = array of byte;',
  14706. ' TStaArrInt = array[1..2] of byte;',
  14707. 'procedure Fly(var a: array of byte);',
  14708. 'begin',
  14709. ' Fly(a);',
  14710. 'end;',
  14711. 'procedure DoIt(a: array of byte);',
  14712. 'var',
  14713. ' d: TDynArrInt;',
  14714. ' s: TStaArrInt;',
  14715. 'begin',
  14716. ' DoIt(a);',
  14717. ' // d:=s; forbidden in delphi', // see TestArray_DynArrAssignStaticDelphiFail
  14718. ' // d:=a; forbidden in delphi',
  14719. ' DoIt(d);',
  14720. ' DoIt(s);',
  14721. ' Fly(a);',
  14722. ' Fly(d);', // dyn array can be passed to a var open array
  14723. 'end;',
  14724. 'begin',
  14725. '']);
  14726. ParseProgram;
  14727. end;
  14728. procedure TTestResolver.TestArray_OpenArrayChar;
  14729. begin
  14730. StartProgram(false);
  14731. Add([
  14732. '{$mode delphi}',
  14733. 'Function CharInSet(Ch: char;Const CSet : array of char) : Boolean;',
  14734. 'begin',
  14735. 'end;',
  14736. 'var Key: char;',
  14737. 'begin',
  14738. ' if CharInSet(Key, [^V, ^X, ^C]) then ;',
  14739. ' CharInSet(Key,''abc'');',
  14740. ' CharInSet(Key,Key);',
  14741. '']);
  14742. ParseProgram;
  14743. end;
  14744. procedure TTestResolver.TestArray_DynArrayChar;
  14745. begin
  14746. StartProgram(false);
  14747. Add([
  14748. '{$mode delphi}',
  14749. 'type TArrChr = array of char;',
  14750. 'var',
  14751. ' Key: char;',
  14752. ' s: string;',
  14753. ' a: TArrChr;',
  14754. 'begin',
  14755. ' a:=''Foo'';',
  14756. ' a:=Key;',
  14757. ' a:=s;',
  14758. '']);
  14759. ParseProgram;
  14760. end;
  14761. procedure TTestResolver.TestArray_CopyConcat;
  14762. begin
  14763. StartProgram(false);
  14764. Add([
  14765. '{$modeswitch arrayoperators}',
  14766. 'type',
  14767. ' integer = longint;',
  14768. ' TArrayInt = array of integer;',
  14769. ' TFlag = (red, blue);',
  14770. ' TArrayFlag = array of TFlag;',
  14771. 'function Get(A: TArrayInt): TArrayInt; begin end;',
  14772. 'var',
  14773. ' i: integer;',
  14774. ' A: TArrayInt;',
  14775. ' FA: TArrayFlag;',
  14776. 'begin',
  14777. ' A:=Copy(A);',
  14778. ' A:=Copy(A,1);',
  14779. ' A:=Copy(A,2,3);',
  14780. ' A:=Copy(Get(A),2,3);',
  14781. ' Get(Copy(A));',
  14782. ' A:=Concat(A);',
  14783. ' A:=Concat(A,Get(A));',
  14784. ' A:=Copy( {#a_array}[1]);',
  14785. ' A:=Copy( {#b1_array}[1]+ {#b2_array}[2,3]);',
  14786. ' A:=Concat( {#c_array}[1]);',
  14787. ' A:=Concat( {#d1_array}[1], {#d2_array}[2,3]);',
  14788. ' FA:=concat([red]);',
  14789. ' FA:=concat([red],FA);',
  14790. '']);
  14791. ParseProgram;
  14792. CheckParamsExpr_pkSet_Markers;
  14793. end;
  14794. procedure TTestResolver.TestStaticArray_CopyConcat;
  14795. begin
  14796. exit;
  14797. //ResolverEngine.Options:=ResolverEngine.Options+[proStaticArrayCopy,proStaticArrayConcat];
  14798. StartProgram(false);
  14799. Add([
  14800. 'type',
  14801. ' integer = longint;',
  14802. ' TArrayInt = array of integer;',
  14803. ' TThreeInts = array[1..3] of integer;',
  14804. 'function Get(A: TThreeInts): TThreeInts; begin end;',
  14805. 'var',
  14806. ' i: integer;',
  14807. ' A: TArrayInt;',
  14808. ' S: TThreeInts;',
  14809. 'begin',
  14810. ' A:=Copy(S);',
  14811. ' A:=Copy(S,1);',
  14812. ' A:=Copy(S,2,3);',
  14813. ' A:=Copy(Get(S),2,3);',
  14814. ' A:=Concat(S,Get(S));']);
  14815. ParseProgram;
  14816. end;
  14817. procedure TTestResolver.TestRecordArray_CopyConcat;
  14818. begin
  14819. StartProgram(false);
  14820. Add([
  14821. '{$modeswitch arrayoperators}',
  14822. 'type',
  14823. ' TRec = record w: word; end;',
  14824. ' TDynRec = array of TRec;',
  14825. 'var',
  14826. ' r: TRec;',
  14827. ' A: TDynRec;',
  14828. ' B: TDynRec;',
  14829. ' C: array of TRec;',
  14830. 'begin',
  14831. ' A:=A+[r];',
  14832. ' A:=Concat(A,[r]);',
  14833. ' A:=Concat(B,[r]);',
  14834. ' A:=Concat(C,[r]);',
  14835. ' C:=Concat(A,[r]);',
  14836. ' A:=Copy(B,1);',
  14837. ' A:=Copy(B,2,3);',
  14838. ' A:=Copy(C,4);',
  14839. ' A:=Copy(C,5,6);',
  14840. '']);
  14841. ParseProgram;
  14842. end;
  14843. procedure TTestResolver.TestArray_CopyMismatchFail;
  14844. begin
  14845. StartProgram(false);
  14846. Add('type');
  14847. Add(' integer = longint;');
  14848. Add(' TArrayInt = array of integer;');
  14849. Add(' TArrayStr = array of string;');
  14850. Add('var');
  14851. Add(' i: integer;');
  14852. Add(' A: TArrayInt;');
  14853. Add(' B: TArrayStr;');
  14854. Add('begin');
  14855. Add(' A:=Copy(B);');
  14856. CheckResolverException('Incompatible types: got "array of integer" expected "array of String"',
  14857. nIncompatibleTypesGotExpected);
  14858. end;
  14859. procedure TTestResolver.TestArray_InsertDeleteAccess;
  14860. begin
  14861. StartProgram(false);
  14862. Add([
  14863. '{$modeswitch arrayoperators}',
  14864. 'type',
  14865. ' integer = longint;',
  14866. ' TArrayInt = array of integer;',
  14867. ' TArrArrInt = array of TArrayInt;',
  14868. 'var',
  14869. ' i: integer;',
  14870. ' A: TArrayInt;',
  14871. ' A2: TArrArrInt;',
  14872. 'begin',
  14873. ' Insert({#a1_read}i+1,{#a2_var}A,{#a3_read}i+2);',
  14874. ' Insert([i],A2,i+2);',
  14875. ' Insert(A+[1],A2,i+2);',
  14876. ' Delete({#b1_var}A,{#b2_read}i+3,{#b3_read}i+4);']);
  14877. ParseProgram;
  14878. CheckAccessMarkers;
  14879. end;
  14880. procedure TTestResolver.TestArray_InsertArray;
  14881. begin
  14882. StartProgram(false);
  14883. Add([
  14884. '{$modeswitch arrayoperators}',
  14885. 'type',
  14886. ' integer = longint;',
  14887. ' TArrayInt = array of integer;',
  14888. ' TArrArrInt = array of TArrayInt;',
  14889. ' TCol = (red,blue);',
  14890. ' TSetCol = set of TCol;',
  14891. ' TArrayCol = array of TCol;',
  14892. ' TArrArrCol = array of TArrayCol;',
  14893. ' TArrSetCol = array of TSetCol;',
  14894. 'var',
  14895. ' i: integer;',
  14896. ' ArrInt: TArrayInt;',
  14897. ' ArrArrInt: TArrArrInt;',
  14898. ' ArrArrCol: TArrArrCol;',
  14899. ' ArrSetCol: TArrSetCol;',
  14900. 'begin',
  14901. ' Insert( {#a_array}[1], ArrArrInt, i+2);',
  14902. ' Insert( {#b_array}[i], ArrArrInt, 3);',
  14903. ' Insert( ArrInt+ {#c_array}[1], ArrArrInt, 4);',
  14904. ' Insert( {#d_set}[red], ArrSetCol, 5);',
  14905. ' Insert( {#e_array}[red], ArrArrCol, 6);',
  14906. '']);
  14907. ParseProgram;
  14908. CheckParamsExpr_pkSet_Markers;
  14909. end;
  14910. procedure TTestResolver.TestStaticArray_InsertFail;
  14911. begin
  14912. StartProgram(false);
  14913. Add('type');
  14914. Add(' integer = longint;');
  14915. Add(' TArrayInt = array[1..3] of integer;');
  14916. Add('var');
  14917. Add(' i: integer;');
  14918. Add(' A: TArrayInt;');
  14919. Add('begin');
  14920. Add(' Insert(1,A,i);');
  14921. CheckResolverException(sIncompatibleTypeArgNo,nIncompatibleTypeArgNo);
  14922. end;
  14923. procedure TTestResolver.TestStaticArray_DeleteFail;
  14924. begin
  14925. StartProgram(false);
  14926. Add('type');
  14927. Add(' integer = longint;');
  14928. Add(' TArrayInt = array[1..3] of integer;');
  14929. Add('var');
  14930. Add(' i: integer;');
  14931. Add(' A: TArrayInt;');
  14932. Add('begin');
  14933. Add(' Delete(A,i,1);');
  14934. CheckResolverException(sIncompatibleTypeArgNo,nIncompatibleTypeArgNo);
  14935. end;
  14936. procedure TTestResolver.TestArray_InsertItemMismatchFail;
  14937. begin
  14938. StartProgram(false);
  14939. Add('type');
  14940. Add(' TCaption = string;');
  14941. Add(' TArrayCap = array of TCaption;');
  14942. Add('var');
  14943. Add(' i: longint;');
  14944. Add(' A: TArrayCap;');
  14945. Add('begin');
  14946. Add(' Insert(i,{#a2_var}A,2);');
  14947. CheckResolverException('Incompatible types: got "Longint" expected "String"',
  14948. nIncompatibleTypesGotExpected);
  14949. end;
  14950. procedure TTestResolver.TestArray_TypeCast;
  14951. begin
  14952. StartProgram(false);
  14953. Add('type');
  14954. Add(' integer = longint;');
  14955. Add(' TArrIntA = array of integer;');
  14956. Add(' TArrIntB = array of longint;');
  14957. Add(' TArrIntC = array of integer;');
  14958. Add('var');
  14959. Add(' a: TArrIntA;');
  14960. Add(' b: TArrIntB;');
  14961. Add(' c: TArrIntC;');
  14962. Add('begin');
  14963. Add(' a:=TArrIntA(a);');
  14964. Add(' a:=TArrIntA(b);');
  14965. Add(' a:=TArrIntA(c);');
  14966. ParseProgram;
  14967. end;
  14968. procedure TTestResolver.TestArray_TypeCastWrongElTypeFail;
  14969. begin
  14970. StartProgram(false);
  14971. Add('type');
  14972. Add(' integer = longint;');
  14973. Add(' TArrInt = array of integer;');
  14974. Add(' TArrStr = array of string;');
  14975. Add('var');
  14976. Add(' a: TArrInt;');
  14977. Add(' s: TArrStr;');
  14978. Add('begin');
  14979. Add(' a:=TArrInt(s);');
  14980. CheckResolverException('Illegal type conversion: "TArrStr" to "TArrInt"',
  14981. nIllegalTypeConversionTo);
  14982. end;
  14983. procedure TTestResolver.TestArray_ConstDynArrayWrite;
  14984. begin
  14985. StartProgram(false);
  14986. Add('type');
  14987. Add(' TArrInt = array of longint;');
  14988. Add('Procedure DoIt(const a: tarrint);');
  14989. Add('begin');
  14990. Add(' a[2]:=3;'); // FPC allows this for dynamic arrays
  14991. Add('end;');
  14992. Add('begin');
  14993. ParseProgram;
  14994. CheckResolverUnexpectedHints;
  14995. end;
  14996. procedure TTestResolver.TestArray_ConstOpenArrayWriteFail;
  14997. begin
  14998. StartProgram(false);
  14999. Add('Procedure DoIt(const a: array of longint);');
  15000. Add('begin');
  15001. Add(' a[2]:=3;');
  15002. Add('end;');
  15003. Add('begin');
  15004. CheckResolverException('Variable identifier expected',nVariableIdentifierExpected);
  15005. end;
  15006. procedure TTestResolver.TestArray_ForIn;
  15007. begin
  15008. StartProgram(false);
  15009. Add([
  15010. '{$modeswitch arrayoperators}',
  15011. 'var',
  15012. ' a: array of longint;',
  15013. ' s: array[1,2] of longint;',
  15014. ' i: longint;',
  15015. 'begin',
  15016. ' for i in a do ;',
  15017. ' for i in s do ;',
  15018. ' for i in a+ {#a_array}[1] do ;',
  15019. ' for i in {#b1_set}[1]+ {#b2_set}[2] do ;',
  15020. ' for i in {#c_set}[1,2] do ;',
  15021. '']);
  15022. ParseProgram;
  15023. CheckParamsExpr_pkSet_Markers;
  15024. end;
  15025. procedure TTestResolver.TestArray_Arg_AnonymousStaticFail;
  15026. begin
  15027. StartProgram(false);
  15028. Add([
  15029. 'procedure DoIt(args: array[1..2] of word);',
  15030. 'begin',
  15031. 'end;',
  15032. 'begin']);
  15033. CheckParserException('Expected "of"',nParserExpectTokenError);
  15034. end;
  15035. procedure TTestResolver.TestArray_Arg_AnonymousMultiDimFail;
  15036. begin
  15037. StartProgram(false);
  15038. Add([
  15039. 'procedure DoIt(args: array of array of word);',
  15040. 'begin',
  15041. 'end;',
  15042. 'begin']);
  15043. CheckParserException(SParserExpectedIdentifier,nParserExpectedIdentifier);
  15044. end;
  15045. procedure TTestResolver.TestArrayOfConst;
  15046. begin
  15047. StartProgram(true,[supTVarRec]);
  15048. Add([
  15049. 'type',
  15050. ' TArrOfVarRec = array of TVarRec;',
  15051. 'procedure DoIt(args: array of const);',
  15052. 'var',
  15053. ' i: longint;',
  15054. ' v: TVarRec;',
  15055. ' a: TArrOfVarRec;',
  15056. ' sa: array[1..2] of TVarRec;',
  15057. 'begin',
  15058. ' DoIt(args);',
  15059. ' DoIt(a);',
  15060. ' DoIt([]);',
  15061. ' DoIt([1]);',
  15062. ' DoIt([i]);',
  15063. ' DoIt([true,''foo'',''c'',1.3,nil,@DoIt]);',
  15064. ' for i:=low(args) to high(args) do begin',
  15065. ' v:=args[i];',
  15066. ' case args[i].VType of',
  15067. ' vtInteger: if length(args)=args[i].VInteger then ;',
  15068. ' end;',
  15069. ' end;',
  15070. ' for v in Args do ;',
  15071. ' args:=sa;',
  15072. 'end;',
  15073. 'begin']);
  15074. ParseProgram;
  15075. end;
  15076. procedure TTestResolver.TestArrayOfConst_PassDynArrayOfIntFail;
  15077. begin
  15078. StartProgram(true,[supTVarRec]);
  15079. Add([
  15080. 'type',
  15081. ' TArr = array of word;',
  15082. 'procedure DoIt(args: array of const);',
  15083. 'begin',
  15084. 'end;',
  15085. 'var a: TArr;',
  15086. 'begin',
  15087. ' DoIt(a)']);
  15088. CheckResolverException('Incompatible type for arg no. 1: Got "TArr", expected "array of const"',
  15089. nIncompatibleTypeArgNo);
  15090. end;
  15091. procedure TTestResolver.TestArrayOfConst_AssignNilFail;
  15092. begin
  15093. StartProgram(true,[supTVarRec]);
  15094. Add([
  15095. 'type',
  15096. ' TArr = array of word;',
  15097. 'procedure DoIt(args: array of const);',
  15098. 'begin',
  15099. ' args:=nil;',
  15100. 'end;',
  15101. 'begin']);
  15102. CheckResolverException('Incompatible types: got "nil" expected "array of const"',nIncompatibleTypesGotExpected);
  15103. end;
  15104. procedure TTestResolver.TestArrayOfConst_SetLengthFail;
  15105. begin
  15106. StartProgram(true,[supTVarRec]);
  15107. Add([
  15108. 'type',
  15109. ' TArr = array of word;',
  15110. 'procedure DoIt(args: array of const);',
  15111. 'begin',
  15112. ' SetLength(args,2);',
  15113. 'end;',
  15114. 'begin']);
  15115. CheckResolverException('Incompatible type for arg no. 1: Got "array of const", expected "string or dynamic array variable"',
  15116. nIncompatibleTypeArgNo);
  15117. end;
  15118. procedure TTestResolver.TestArrayIntRange_OutOfRange;
  15119. begin
  15120. StartProgram(false);
  15121. Add([
  15122. 'type TArr = array[1..2] of longint;',
  15123. 'var a: TArr;',
  15124. 'begin',
  15125. ' a[0]:=3;',
  15126. '']);
  15127. ParseProgram;
  15128. CheckResolverHint(mtWarning,nRangeCheckEvaluatingConstantsVMinMax,
  15129. 'range check error while evaluating constants (0 is not between 1 and 2)');
  15130. CheckResolverUnexpectedHints;
  15131. end;
  15132. procedure TTestResolver.TestArrayIntRange_OutOfRangeError;
  15133. begin
  15134. StartProgram(false);
  15135. Add([
  15136. '{$R+}',
  15137. 'type TArr = array[1..2] of longint;',
  15138. 'var a: TArr;',
  15139. 'begin',
  15140. ' a[0]:=3;',
  15141. '']);
  15142. CheckResolverException('range check error while evaluating constants (0 is not between 1 and 2)',
  15143. nRangeCheckEvaluatingConstantsVMinMax);
  15144. end;
  15145. procedure TTestResolver.TestArrayCharRange_OutOfRange;
  15146. begin
  15147. StartProgram(false);
  15148. Add([
  15149. 'type TArr = array[''a''..''b''] of longint;',
  15150. 'var a: TArr;',
  15151. 'begin',
  15152. ' a[''0'']:=3;',
  15153. '']);
  15154. ParseProgram;
  15155. CheckResolverHint(mtWarning,nRangeCheckEvaluatingConstantsVMinMax,
  15156. 'range check error while evaluating constants (''0'' is not between ''a'' and ''b'')');
  15157. CheckResolverUnexpectedHints;
  15158. end;
  15159. procedure TTestResolver.TestProcTypesAssignObjFPC;
  15160. begin
  15161. StartProgram(false);
  15162. Add([
  15163. 'type',
  15164. ' TProcedure = procedure;',
  15165. ' TFunctionInt = function:longint;',
  15166. ' TFunctionIntFunc = function:TFunctionInt;',
  15167. ' TFunctionIntFuncFunc = function:TFunctionIntFunc;',
  15168. 'function GetNumber: longint;',
  15169. 'begin',
  15170. ' Result:=3;',
  15171. 'end;',
  15172. 'function GetNumberFunc: TFunctionInt;',
  15173. 'begin',
  15174. ' Result:=@GetNumber;',
  15175. 'end;',
  15176. 'function GetNumberFuncFunc: TFunctionIntFunc;',
  15177. 'begin',
  15178. ' Result:=@GetNumberFunc;',
  15179. 'end;',
  15180. 'var',
  15181. ' i: longint;',
  15182. ' f: TFunctionInt;',
  15183. ' ff: TFunctionIntFunc;',
  15184. 'begin',
  15185. ' i:=GetNumber; // omit ()',
  15186. ' i:=GetNumber();',
  15187. ' i:=GetNumberFunc()();',
  15188. ' i:=GetNumberFuncFunc()()();',
  15189. ' if i=GetNumberFunc()() then ;',
  15190. ' if GetNumberFunc()()=i then ;',
  15191. ' if i=GetNumberFuncFunc()()() then ;',
  15192. ' if GetNumberFuncFunc()()()=i then ;',
  15193. ' f:=nil;',
  15194. ' if f=nil then ;',
  15195. ' if nil=f then ;',
  15196. ' if Assigned(f) then ;',
  15197. ' f:=f;',
  15198. ' f:=@GetNumber;',
  15199. ' f:=GetNumberFunc; // not in Delphi',
  15200. ' f:=GetNumberFunc(); // not in Delphi',
  15201. ' f:=GetNumberFuncFunc()();',
  15202. ' if f=f then ;',
  15203. ' if i=f then ;',
  15204. ' if i=f() then ;',
  15205. ' if f()=i then ;',
  15206. ' if f()=f() then ;',
  15207. ' if f=@GetNumber then ;',
  15208. ' if @GetNumber=f then ;',
  15209. ' if f=GetNumberFunc then ;',
  15210. ' if f=GetNumberFunc() then ;',
  15211. ' if f=GetNumberFuncFunc()() then ;',
  15212. ' ff:=nil;',
  15213. ' if ff=nil then ;',
  15214. ' if nil=ff then ;',
  15215. ' ff:=ff;',
  15216. ' if ff=ff then ;',
  15217. ' ff:=@GetNumberFunc;',
  15218. ' ff:=GetNumberFuncFunc; // not in Delphi',
  15219. ' ff:=GetNumberFuncFunc();']);
  15220. ParseProgram;
  15221. end;
  15222. procedure TTestResolver.TestMethodTypesAssignObjFPC;
  15223. begin
  15224. StartProgram(false);
  15225. Add('type');
  15226. Add(' TObject = class;');
  15227. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  15228. Add(' TObject = class');
  15229. Add(' FOnClick: TNotifyEvent;');
  15230. Add(' procedure SetOnClick(const Value: TNotifyEvent);');
  15231. Add(' procedure Notify(Sender: TObject);');
  15232. Add(' property OnClick: TNotifyEvent read FOnClick write SetOnClick;');
  15233. Add(' end;');
  15234. Add('procedure TObject.SetOnClick(const Value: TNotifyEvent);');
  15235. Add('begin');
  15236. Add(' if FOnClick=Value then exit;');
  15237. Add(' FOnClick:=Value;');
  15238. Add('end;');
  15239. Add('procedure TObject.Notify(Sender: TObject);');
  15240. Add('begin');
  15241. Add(' if Assigned(OnClick) and (OnClick<>@Notify) then begin');
  15242. Add(' OnClick(Sender);');
  15243. Add(' OnClick(Self);');
  15244. Add(' Self.OnClick(nil);');
  15245. Add(' end;');
  15246. Add(' if [email protected] then ;');
  15247. Add(' if [email protected] then ;');
  15248. Add('end;');
  15249. Add('var o: TObject;');
  15250. Add('begin');
  15251. Add(' o.OnClick:[email protected];');
  15252. Add(' o.OnClick(nil);');
  15253. Add(' o.OnClick(o);');
  15254. Add(' o.SetOnClick(@o.Notify);');
  15255. ParseProgram;
  15256. end;
  15257. procedure TTestResolver.TestProcTypeCall;
  15258. var
  15259. aMarker: PSrcMarker;
  15260. Elements: TFPList;
  15261. ActualImplicitCallWithoutParams: Boolean;
  15262. i: Integer;
  15263. El: TPasElement;
  15264. Ref: TResolvedReference;
  15265. begin
  15266. StartProgram(false);
  15267. Add('type');
  15268. Add(' TFuncInt = function(vI: longint = 1):longint;');
  15269. Add(' TFuncFuncInt = function(vI: longint = 1): TFuncInt;');
  15270. Add('procedure DoI(vI: longint); begin end;');
  15271. Add('procedure DoFConst(const vI: tfuncint); begin end;');
  15272. Add('procedure DoFVar(var vI: tfuncint); begin end;');
  15273. Add('procedure DoFDefault(vI: tfuncint); begin end;');
  15274. Add('var');
  15275. Add(' i: longint;');
  15276. Add(' f: tfuncint;');
  15277. Add('begin');
  15278. Add(' {#a}f;');
  15279. Add(' {#b}f();');
  15280. Add(' {#c}f(2);');
  15281. Add(' i:={#d}f;');
  15282. Add(' i:={#e}f();');
  15283. Add(' i:={#f}f(2);');
  15284. Add(' doi({#g}f);');
  15285. Add(' doi({#h}f());');
  15286. Add(' doi({#i}f(2));');
  15287. Add(' dofconst({#j}f);');
  15288. Add(' if Assigned({#k}f) then;');
  15289. Add(' if {#l}f=nil then;');
  15290. Add(' if nil={#m}f then;');
  15291. ParseProgram;
  15292. aMarker:=FirstSrcMarker;
  15293. while aMarker<>nil do
  15294. begin
  15295. //writeln('TTestResolver.TestProcTypeCall ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  15296. Elements:=FindElementsAt(aMarker);
  15297. try
  15298. ActualImplicitCallWithoutParams:=false;
  15299. for i:=0 to Elements.Count-1 do
  15300. begin
  15301. El:=TPasElement(Elements[i]);
  15302. //writeln('TTestResolver.TestProcTypeCall ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  15303. if not (El.CustomData is TResolvedReference) then continue;
  15304. Ref:=TResolvedReference(El.CustomData);
  15305. //writeln('TTestResolver.TestProcTypeCall ',GetObjName(Ref.Declaration),' rrfImplicitCallWithoutParams=',rrfImplicitCallWithoutParams in Ref.Flags);
  15306. if rrfImplicitCallWithoutParams in Ref.Flags then
  15307. ActualImplicitCallWithoutParams:=true;
  15308. break;
  15309. end;
  15310. case aMarker^.Identifier of
  15311. 'a','d','g':
  15312. if not ActualImplicitCallWithoutParams then
  15313. RaiseErrorAtSrcMarker('expected implicit call at "#'+aMarker^.Identifier+'"',aMarker);
  15314. else
  15315. if ActualImplicitCallWithoutParams then
  15316. RaiseErrorAtSrcMarker('expected no implicit call at "#'+aMarker^.Identifier+'"',aMarker);
  15317. end;
  15318. finally
  15319. Elements.Free;
  15320. end;
  15321. aMarker:=aMarker^.Next;
  15322. end;
  15323. end;
  15324. procedure TTestResolver.TestProcType_FunctionFPC;
  15325. begin
  15326. StartProgram(false);
  15327. Add('type');
  15328. Add(' TFuncInt = function(vA: longint = 1): longint;');
  15329. Add('function DoIt(vI: longint): longint;');
  15330. Add('begin end;');
  15331. Add('var');
  15332. Add(' b: boolean;');
  15333. Add(' vP, vQ: tfuncint;');
  15334. Add('begin');
  15335. Add(' vp:=nil;');
  15336. Add(' vp:=vp;');
  15337. Add(' vp:=@doit;'); // ok in fpc and delphi
  15338. //Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  15339. Add(' vp;'); // ok in fpc and delphi
  15340. Add(' vp();');
  15341. Add(' vp(2);');
  15342. Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  15343. Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  15344. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  15345. Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  15346. Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  15347. //Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  15348. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  15349. Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  15350. Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  15351. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  15352. Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  15353. Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  15354. //Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  15355. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  15356. Add(' b:=Assigned(vp);');
  15357. //Add(' doit(vp);'); // illegal in fpc, ok in delphi
  15358. Add(' doit(vp());'); // ok in fpc and delphi
  15359. Add(' doit(vp(2));'); // ok in fpc and delphi
  15360. ParseProgram;
  15361. end;
  15362. procedure TTestResolver.TestProcType_FunctionDelphi;
  15363. begin
  15364. StartProgram(false);
  15365. Add('{$mode Delphi}');
  15366. Add('type');
  15367. Add(' TFuncInt = function(vA: longint = 1): longint;');
  15368. Add('function DoIt(vI: longint): longint;');
  15369. Add('begin end;');
  15370. Add('var');
  15371. Add(' b: boolean;');
  15372. Add(' vP, vQ: tfuncint;');
  15373. Add(' ');
  15374. Add('begin');
  15375. Add(' vp:=nil;');
  15376. Add(' vp:=vp;');
  15377. Add(' vp:=@doit;'); // ok in fpc and delphi
  15378. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  15379. Add(' vp;'); // ok in fpc and delphi
  15380. Add(' vp();');
  15381. Add(' vp(2);');
  15382. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  15383. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  15384. Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  15385. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  15386. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  15387. Add(' b:=vp=3;'); // illegal in fpc, ok in delphi
  15388. Add(' b:=4=vp;'); // illegal in fpc, ok in delphi
  15389. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  15390. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  15391. Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  15392. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  15393. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  15394. Add(' b:=vp<>5;'); // illegal in fpc, ok in delphi
  15395. Add(' b:=6<>vp;'); // illegal in fpc, ok in delphi
  15396. Add(' b:=Assigned(vp);');
  15397. Add(' doit(vp);'); // illegal in fpc, ok in delphi
  15398. Add(' doit(vp());'); // ok in fpc and delphi
  15399. Add(' doit(vp(2));'); // ok in fpc and delphi *)
  15400. ParseProgram;
  15401. end;
  15402. procedure TTestResolver.TestProcType_ProcedureDelphi;
  15403. begin
  15404. StartProgram(false);
  15405. Add('{$mode Delphi}');
  15406. Add('type');
  15407. Add(' TProc = procedure;');
  15408. Add('procedure Doit;');
  15409. Add('begin end;');
  15410. Add('var');
  15411. Add(' b: boolean;');
  15412. Add(' vP, vQ: tproc;');
  15413. Add('begin');
  15414. Add(' vp:=nil;');
  15415. Add(' vp:=vp;');
  15416. Add(' vp:=vq;');
  15417. Add(' vp:=@doit;'); // ok in fpc and delphi, Note that in Delphi type of @F is Pointer, while in FPC it is the proc type
  15418. Add(' vp:=doit;'); // illegal in fpc, ok in delphi
  15419. //Add(' vp:=@doit;'); // illegal in fpc, ok in delphi (because Delphi treats @F as Pointer), not supported by resolver
  15420. Add(' vp;'); // ok in fpc and delphi
  15421. Add(' vp();');
  15422. // equal
  15423. //Add(' b:=vp=nil;'); // ok in fpc, illegal in delphi
  15424. Add(' b:=@@vp=nil;'); // ok in fpc delphi mode, ok in delphi
  15425. //Add(' b:=nil=vp;'); // ok in fpc, illegal in delphi
  15426. Add(' b:=nil=@@vp;'); // ok in fpc delphi mode, ok in delphi
  15427. Add(' b:=@@vp=@@vq;'); // ok in fpc delphi mode, ok in Delphi
  15428. //Add(' b:=vp=vq;'); // in fpc compare proctypes, in delphi compare results
  15429. //Add(' b:=vp=@doit;'); // ok in fpc, illegal in delphi
  15430. Add(' b:=@@vp=@doit;'); // ok in fpc delphi mode, ok in delphi
  15431. //Add(' b:=@doit=vp;'); // ok in fpc, illegal in delphi
  15432. Add(' b:=@doit=@@vp;'); // ok in fpc delphi mode, ok in delphi
  15433. // unequal
  15434. //Add(' b:=vp<>nil;'); // ok in fpc, illegal in delphi
  15435. Add(' b:=@@vp<>nil;'); // ok in fpc mode delphi, ok in delphi
  15436. //Add(' b:=nil<>vp;'); // ok in fpc, illegal in delphi
  15437. Add(' b:=nil<>@@vp;'); // ok in fpc mode delphi, ok in delphi
  15438. //Add(' b:=vp<>vq;'); // in fpc compare proctypes, in delphi compare results
  15439. Add(' b:=@@vp<>@@vq;'); // ok in fpc mode delphi, ok in delphi
  15440. //Add(' b:=vp<>@doit;'); // ok in fpc, illegal in delphi
  15441. Add(' b:=@@vp<>@doit;'); // ok in fpc mode delphi, illegal in delphi
  15442. //Add(' b:=@doit<>vp;'); // ok in fpc, illegal in delphi
  15443. Add(' b:=@doit<>@@vp;'); // ok in fpc mode delphi, illegal in delphi
  15444. Add(' b:=Assigned(vp);');
  15445. ParseProgram;
  15446. end;
  15447. procedure TTestResolver.TestProcType_MethodFPC;
  15448. begin
  15449. StartProgram(false);
  15450. Add('type');
  15451. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  15452. Add(' TObject = class');
  15453. Add(' function DoIt(vA: longint = 1): longint;');
  15454. Add(' end;');
  15455. Add('function tobject.doit(vA: longint): longint;');
  15456. Add('begin');
  15457. Add('end;');
  15458. Add('var');
  15459. Add(' Obj: TObject;');
  15460. Add(' vP: tfuncint;');
  15461. Add(' b: boolean;');
  15462. Add('begin');
  15463. Add(' vp:[email protected];'); // ok in fpc and delphi
  15464. //Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  15465. Add(' vp;'); // ok in fpc and delphi
  15466. Add(' vp();');
  15467. Add(' vp(2);');
  15468. Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  15469. Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  15470. Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  15471. Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  15472. ParseProgram;
  15473. end;
  15474. procedure TTestResolver.TestProcType_MethodDelphi;
  15475. begin
  15476. StartProgram(false);
  15477. Add('{$mode delphi}');
  15478. Add('type');
  15479. Add(' TFuncInt = function(vA: longint = 1): longint of object;');
  15480. Add(' TObject = class');
  15481. Add(' function DoIt(vA: longint = 1): longint;');
  15482. Add(' end;');
  15483. Add('function tobject.doit(vA: longint): longint;');
  15484. Add('begin');
  15485. Add('end;');
  15486. Add('var');
  15487. Add(' Obj: TObject;');
  15488. Add(' vP: tfuncint;');
  15489. Add(' b: boolean;');
  15490. Add('begin');
  15491. Add(' vp:[email protected];'); // ok in fpc and delphi
  15492. Add(' vp:=obj.doit;'); // illegal in fpc, ok in delphi
  15493. Add(' vp;'); // ok in fpc and delphi
  15494. Add(' vp();');
  15495. Add(' vp(2);');
  15496. //Add(' b:[email protected];'); // ok in fpc, illegal in delphi
  15497. //Add(' b:[email protected]=vp;'); // ok in fpc, illegal in delphi
  15498. //Add(' b:=vp<>@obj.doit;'); // ok in fpc, illegal in delphi
  15499. //Add(' b:[email protected]<>vp;'); // ok in fpc, illegal in delphi
  15500. ParseProgram;
  15501. end;
  15502. procedure TTestResolver.TestAssignProcToMethodFail;
  15503. begin
  15504. StartProgram(false);
  15505. Add('type');
  15506. Add(' TObject = class end;');
  15507. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  15508. Add('procedure ProcA(Sender: TObject);');
  15509. Add('begin end;');
  15510. Add('var n: TNotifyEvent;');
  15511. Add('begin');
  15512. Add(' n:=@ProcA;');
  15513. CheckResolverException('procedural type modifier "of Object" mismatch',
  15514. nXModifierMismatchY);
  15515. end;
  15516. procedure TTestResolver.TestAssignMethodToProcFail;
  15517. begin
  15518. StartProgram(false);
  15519. Add('type');
  15520. Add(' TObject = class');
  15521. Add(' procedure ProcA(Sender: TObject);');
  15522. Add(' end;');
  15523. Add(' TNotifyProc = procedure(Sender: TObject);');
  15524. Add('procedure TObject.ProcA(Sender: TObject);');
  15525. Add('begin end;');
  15526. Add('var');
  15527. Add(' n: TNotifyProc;');
  15528. Add(' o: TObject;');
  15529. Add('begin');
  15530. Add(' n:[email protected];');
  15531. CheckResolverException('procedural type modifier "of Object" mismatch',
  15532. nXModifierMismatchY);
  15533. end;
  15534. procedure TTestResolver.TestAssignProcToFunctionFail;
  15535. begin
  15536. StartProgram(false);
  15537. Add('type');
  15538. Add(' TFuncInt = function(i: longint): longint;');
  15539. Add('procedure ProcA(i: longint);');
  15540. Add('begin end;');
  15541. Add('var p: TFuncInt;');
  15542. Add('begin');
  15543. Add(' p:=@ProcA;');
  15544. CheckResolverException(
  15545. 'Incompatible types: got "procedural type" expected "functional type"',
  15546. nIncompatibleTypesGotExpected);
  15547. end;
  15548. procedure TTestResolver.TestAssignProcWrongArgsFail;
  15549. begin
  15550. StartProgram(false);
  15551. Add('type');
  15552. Add(' TProcInt = procedure(i: longint);');
  15553. Add('procedure ProcA(i: string);');
  15554. Add('begin end;');
  15555. Add('var p: TProcInt;');
  15556. Add('begin');
  15557. Add(' p:=@ProcA;');
  15558. CheckResolverException('Incompatible type for arg no. 1: Got "Longint", expected "String"',
  15559. nIncompatibleTypeArgNo);
  15560. end;
  15561. procedure TTestResolver.TestAssignProcWrongArgAccessFail;
  15562. begin
  15563. StartProgram(false);
  15564. Add('type');
  15565. Add(' TProcInt = procedure(i: longint);');
  15566. Add('procedure ProcA(const i: longint);');
  15567. Add('begin end;');
  15568. Add('var p: TProcInt;');
  15569. Add('begin');
  15570. Add(' p:=@ProcA;');
  15571. CheckResolverException('Incompatible type for arg no. 1: Got "access modifier const", expected "default"',
  15572. nIncompatibleTypeArgNo);
  15573. end;
  15574. procedure TTestResolver.TestProcType_SameSignatureObjFPC;
  15575. begin
  15576. StartProgram(false);
  15577. Add([
  15578. '{$mode objfpc}',
  15579. 'type',
  15580. ' TRun = procedure(a: Word);',
  15581. ' TRunIt = procedure(a: TRun);',
  15582. ' TFly = procedure(a: Word);',
  15583. 'procedure FlyIt(a: TFly);',
  15584. 'begin',
  15585. 'end;',
  15586. 'var RunIt: TRunIt;',
  15587. 'begin',
  15588. ' RunIt:=@FlyIt;',
  15589. '']);
  15590. ParseProgram;
  15591. end;
  15592. procedure TTestResolver.TestProcType_AssignNestedProcFail;
  15593. begin
  15594. StartProgram(false);
  15595. Add('type');
  15596. Add(' TProcInt = procedure(i: longint);');
  15597. Add('procedure ProcA;');
  15598. Add('var p: TProcInt;');
  15599. Add(' procedure SubProc(i: longint);');
  15600. Add(' begin');
  15601. Add(' end;');
  15602. Add('begin');
  15603. Add(' p:=@SubProc;');
  15604. Add('end;');
  15605. Add('begin');
  15606. CheckResolverException('procedural type modifier "is nested" mismatch',
  15607. nXModifierMismatchY);
  15608. end;
  15609. procedure TTestResolver.TestArrayOfProc;
  15610. begin
  15611. StartProgram(false);
  15612. Add([
  15613. 'type',
  15614. ' TObject = class end;',
  15615. ' TNotifyProc = function(Sender: TObject = nil): longint;',
  15616. ' TProcArray = array of TNotifyProc;',
  15617. 'function ProcA(Sender: TObject): longint;',
  15618. 'begin end;',
  15619. 'procedure DoIt(const a: TProcArray);',
  15620. 'begin end;',
  15621. 'var',
  15622. ' a: TProcArray;',
  15623. ' p: TNotifyProc;',
  15624. 'begin',
  15625. ' a[0]:=@ProcA;',
  15626. ' if a[1]=@ProcA then ;',
  15627. ' if @ProcA=a[2] then ;',
  15628. // ' a[3];', ToDo
  15629. ' a[3](nil);',
  15630. ' if a[4](nil)=5 then ;',
  15631. ' if 6=a[7](nil) then ;',
  15632. ' a[8]:=a[9];',
  15633. ' p:=a[10];',
  15634. ' a[11]:=p;',
  15635. ' if a[12]=p then ;',
  15636. ' if p=a[13] then ;',
  15637. ' DoIt([@ProcA]);',
  15638. ' DoIt([nil]);',
  15639. ' DoIt([nil,@ProcA]);',
  15640. ' DoIt([p]);',
  15641. '']);
  15642. ParseProgram;
  15643. end;
  15644. procedure TTestResolver.TestProcType_Assigned;
  15645. begin
  15646. StartProgram(false);
  15647. Add('type');
  15648. Add(' TFuncInt = function(i: longint): longint;');
  15649. Add('function ProcA(i: longint): longint;');
  15650. Add('begin end;');
  15651. Add('var');
  15652. Add(' a: array of TFuncInt;');
  15653. Add(' p: TFuncInt;');
  15654. Add('begin');
  15655. Add(' if Assigned(p) then ;');
  15656. Add(' if Assigned(a[1]) then ;');
  15657. ParseProgram;
  15658. end;
  15659. procedure TTestResolver.TestProcType_TNotifyEvent;
  15660. begin
  15661. StartProgram(true,[supTObject]);
  15662. Add('type');
  15663. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  15664. Add(' TButton = class(TObject)');
  15665. Add(' private');
  15666. Add(' FOnClick: TNotifyEvent;');
  15667. Add(' published');
  15668. Add(' property OnClick: TNotifyEvent read FOnClick write FOnClick;');
  15669. Add(' end;');
  15670. Add(' TApplication = class(TObject)');
  15671. Add(' procedure BtnClickHandler(Sender: TObject); external name ''BtnClickHandler'';');
  15672. Add(' end;');
  15673. Add('var ');
  15674. Add(' App: TApplication;');
  15675. Add(' Button1: TButton;');
  15676. Add('begin');
  15677. Add(' Button1.OnClick := @App.BtnClickHandler;');
  15678. ParseProgram;
  15679. end;
  15680. procedure TTestResolver.TestProcType_TNotifyEvent_NoAtFPC_Fail1;
  15681. begin
  15682. StartProgram(true,[supTObject]);
  15683. Add('type');
  15684. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  15685. Add(' TButton = class(TObject)');
  15686. Add(' private');
  15687. Add(' FOnClick: TNotifyEvent;');
  15688. Add(' published');
  15689. Add(' property OnClick: TNotifyEvent read FOnClick write FOnClick;');
  15690. Add(' end;');
  15691. Add(' TApplication = class(TObject)');
  15692. Add(' procedure BtnClickHandler(Sender: TObject); external name ''BtnClickHandler'';');
  15693. Add(' end;');
  15694. Add('var ');
  15695. Add(' App: TApplication;');
  15696. Add(' Button1: TButton;');
  15697. Add('begin');
  15698. Add(' Button1.OnClick := App.BtnClickHandler;');
  15699. CheckResolverException(
  15700. 'Wrong number of parameters specified for call to "BtnClickHandler"',
  15701. nWrongNumberOfParametersForCallTo);
  15702. end;
  15703. procedure TTestResolver.TestProcType_TNotifyEvent_NoAtFPC_Fail2;
  15704. begin
  15705. StartProgram(true,[supTObject]);
  15706. Add('type');
  15707. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  15708. Add(' TButton = class(TObject)');
  15709. Add(' private');
  15710. Add(' FOnClick: TNotifyEvent;');
  15711. Add(' published');
  15712. Add(' property OnClick: TNotifyEvent read FOnClick write FOnClick;');
  15713. Add(' end;');
  15714. Add(' TApplication = class(TObject)');
  15715. Add(' procedure BtnClickHandler(Sender: TObject); external name ''BtnClickHandler'';');
  15716. Add(' end;');
  15717. Add('var ');
  15718. Add(' App: TApplication;');
  15719. Add(' Button1: TButton;');
  15720. Add('begin');
  15721. Add(' Button1.OnClick := App.BtnClickHandler();');
  15722. CheckResolverException(
  15723. 'Wrong number of parameters specified for call to "procedure BtnClickHandler(TObject) of Object"',
  15724. nWrongNumberOfParametersForCallTo);
  15725. end;
  15726. procedure TTestResolver.TestProcType_TNotifyEvent_NoAtFPC_Fail3;
  15727. begin
  15728. StartProgram(true,[supTObject]);
  15729. Add('type');
  15730. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  15731. Add(' TButton = class(TObject)');
  15732. Add(' private');
  15733. Add(' FOnClick: TNotifyEvent;');
  15734. Add(' published');
  15735. Add(' property OnClick: TNotifyEvent read FOnClick write FOnClick;');
  15736. Add(' end;');
  15737. Add(' TApplication = class(TObject)');
  15738. Add(' procedure BtnClickHandler(Sender: TObject); external name ''BtnClickHandler'';');
  15739. Add(' end;');
  15740. Add('var ');
  15741. Add(' App: TApplication;');
  15742. Add(' Button1: TButton;');
  15743. Add('begin');
  15744. Add(' Button1.OnClick := @App.BtnClickHandler();');
  15745. CheckResolverException(
  15746. 'Wrong number of parameters specified for call to "procedure BtnClickHandler(TObject) of Object"',
  15747. nWrongNumberOfParametersForCallTo);
  15748. end;
  15749. procedure TTestResolver.TestProcType_PassAsArg_NoAtFPC_Fail;
  15750. begin
  15751. StartProgram(false);
  15752. Add('{$mode objfpc}');
  15753. Add('type');
  15754. Add(' TProc = procedure;');
  15755. Add('procedure Run;');
  15756. Add('begin end;');
  15757. Add('procedure Fly(p: TProc);');
  15758. Add('begin end;');
  15759. Add('begin');
  15760. Add(' Fly(Run);');
  15761. CheckResolverException(
  15762. 'Incompatible type for arg no. 1: Got "procedural type", expected "TProc"',
  15763. nIncompatibleTypeArgNo);
  15764. end;
  15765. procedure TTestResolver.TestProcType_PassAsArg_NoAtDelphi;
  15766. begin
  15767. StartProgram(false);
  15768. Add('{$mode delphi}');
  15769. Add('type');
  15770. Add(' TFunc = function: word;');
  15771. Add('function Run: word;');
  15772. Add('begin end;');
  15773. Add('procedure Fly(p: TFunc);');
  15774. Add('begin end;');
  15775. Add('begin');
  15776. Add(' Fly(Run);');
  15777. ParseProgram;
  15778. end;
  15779. procedure TTestResolver.TestProcType_WhileListCompare;
  15780. begin
  15781. StartProgram(false);
  15782. Add('type');
  15783. Add(' integer = longint;');
  15784. Add(' TArrInt = array of Integer;');
  15785. Add(' TListCompare = function(Item1, Item2: Integer): integer;');
  15786. Add('procedure Sort(P: Integer; const List: TArrInt; const Compare: TListCompare);');
  15787. Add('begin');
  15788. Add(' while Compare(P,List[0])>0 do ;');
  15789. Add('end;');
  15790. Add('begin');
  15791. ParseProgram;
  15792. end;
  15793. procedure TTestResolver.TestProcType_IsNested;
  15794. begin
  15795. StartProgram(false);
  15796. Add('{$modeswitch nestedprocvars}');
  15797. Add('type');
  15798. Add(' integer = longint;');
  15799. Add(' TNestedProc = procedure(i: integer) is nested;');
  15800. Add('procedure DoIt(i: integer);');
  15801. Add('var p: TNestedProc;');
  15802. Add(' procedure Sub(i: integer);');
  15803. Add(' var SubP: TNestedProc;');
  15804. Add(' procedure SubSub(i: integer);');
  15805. Add(' begin');
  15806. Add(' p:=@Sub;');
  15807. Add(' p:=@SubSub;');
  15808. Add(' SubP:=@Sub;');
  15809. Add(' SubP:=@SubSub;');
  15810. Add(' end;');
  15811. Add(' begin');
  15812. Add(' p:=@Sub;');
  15813. Add(' p:=@SubSub;');
  15814. Add(' SubP:=@Sub;');
  15815. Add(' SubP:=@SubSub;');
  15816. Add(' end;');
  15817. Add('begin');
  15818. Add(' p:=@Sub;');
  15819. Add('end;');
  15820. Add('begin');
  15821. ParseProgram;
  15822. end;
  15823. procedure TTestResolver.TestProcType_IsNested_AssignProcFail;
  15824. begin
  15825. StartProgram(false);
  15826. Add('{$modeswitch nestedprocvars}');
  15827. Add('type');
  15828. Add(' integer = longint;');
  15829. Add(' TNestedProc = procedure(i: integer) is nested;');
  15830. Add('procedure DoIt(i: integer); begin end;');
  15831. Add('var p: TNestedProc;');
  15832. Add('begin');
  15833. Add(' p:=@DoIt;');
  15834. CheckResolverException('procedural type modifier "is nested" mismatch',nXModifierMismatchY);
  15835. end;
  15836. procedure TTestResolver.TestProcType_ReferenceTo;
  15837. begin
  15838. StartProgram(false);
  15839. Add([
  15840. 'type',
  15841. ' TProcRef = reference to procedure(i: longint = 0);',
  15842. ' TFuncRef = reference to function(i: longint = 0): longint;',
  15843. ' TObject = class',
  15844. ' function Grow(s: longint): longint;',
  15845. ' end;',
  15846. 'var',
  15847. ' p: TProcRef;',
  15848. ' f: TFuncRef;',
  15849. 'function tobject.Grow(s: longint): longint;',
  15850. ' function GrowSub(i: longint): longint;',
  15851. ' begin',
  15852. ' f:=@Grow;',
  15853. ' f:=@GrowSub;',
  15854. ' f;',
  15855. ' f();',
  15856. ' f(1);',
  15857. ' end;',
  15858. 'begin',
  15859. ' f:=@Grow;',
  15860. ' f:=@GrowSub;',
  15861. ' f;',
  15862. ' f();',
  15863. ' f(1);',
  15864. 'end;',
  15865. 'procedure DoIt(i: longint);',
  15866. 'begin',
  15867. 'end;',
  15868. 'function GetIt(i: longint): longint;',
  15869. ' function Sub(i: longint): longint;',
  15870. ' begin',
  15871. ' p:=@DoIt;',
  15872. ' f:=@GetIt;',
  15873. ' f:=@Sub;',
  15874. ' end;',
  15875. 'begin',
  15876. ' p:=@DoIt;',
  15877. ' f:=@GetIt;',
  15878. ' f;',
  15879. ' f();',
  15880. ' f(1);',
  15881. 'end;',
  15882. 'begin',
  15883. ' p:=@DoIt;',
  15884. ' f:=@GetIt;',
  15885. ' f;',
  15886. ' f();',
  15887. ' f(1);',
  15888. ' p:=TProcRef(f);',
  15889. '']);
  15890. ParseProgram;
  15891. end;
  15892. procedure TTestResolver.TestProcType_AllowNested;
  15893. begin
  15894. ResolverEngine.Options:=ResolverEngine.Options+[proProcTypeWithoutIsNested];
  15895. StartProgram(false);
  15896. Add('type');
  15897. Add(' integer = longint;');
  15898. Add(' TProc = procedure(i: integer);');
  15899. Add('procedure DoIt(i: integer);');
  15900. Add('var p: TProc;');
  15901. Add(' procedure Sub(i: integer);');
  15902. Add(' var SubP: TProc;');
  15903. Add(' procedure SubSub(i: integer);');
  15904. Add(' begin');
  15905. Add(' p:=@DoIt;');
  15906. Add(' p:=@Sub;');
  15907. Add(' p:=@SubSub;');
  15908. Add(' SubP:=@DoIt;');
  15909. Add(' SubP:=@Sub;');
  15910. Add(' SubP:=@SubSub;');
  15911. Add(' end;');
  15912. Add(' begin');
  15913. Add(' p:=@DoIt;');
  15914. Add(' p:=@Sub;');
  15915. Add(' p:=@SubSub;');
  15916. Add(' SubP:=@DoIt;');
  15917. Add(' SubP:=@Sub;');
  15918. Add(' SubP:=@SubSub;');
  15919. Add(' end;');
  15920. Add('begin');
  15921. Add(' p:=@DoIt;');
  15922. Add(' p:=@Sub;');
  15923. Add('end;');
  15924. Add('begin');
  15925. ParseProgram;
  15926. end;
  15927. procedure TTestResolver.TestProcType_AllowNestedOfObject;
  15928. begin
  15929. ResolverEngine.Options:=ResolverEngine.Options+[proProcTypeWithoutIsNested];
  15930. StartProgram(false);
  15931. Add('type');
  15932. Add(' integer = longint;');
  15933. Add(' TMethodProc = procedure(i: integer) of object;');
  15934. Add(' TObject = class');
  15935. Add(' procedure DoIt(i: integer);');
  15936. Add(' end;');
  15937. Add('procedure TObject.DoIt(i: integer);');
  15938. Add('var p: TMethodProc;');
  15939. Add(' procedure Sub(i: integer);');
  15940. Add(' var SubP: TMethodProc;');
  15941. Add(' procedure SubSub(i: integer);');
  15942. Add(' begin');
  15943. Add(' p:=@DoIt;');
  15944. Add(' p:=@Sub;');
  15945. Add(' p:=@SubSub;');
  15946. Add(' SubP:=@DoIt;');
  15947. Add(' SubP:=@Sub;');
  15948. Add(' SubP:=@SubSub;');
  15949. Add(' end;');
  15950. Add(' begin');
  15951. Add(' p:=@DoIt;');
  15952. Add(' p:=@Sub;');
  15953. Add(' p:=@SubSub;');
  15954. Add(' SubP:=@DoIt;');
  15955. Add(' SubP:=@Sub;');
  15956. Add(' SubP:=@SubSub;');
  15957. Add(' end;');
  15958. Add('begin');
  15959. Add(' p:=@DoIt;');
  15960. Add(' p:=@Sub;');
  15961. Add('end;');
  15962. Add('begin');
  15963. ParseProgram;
  15964. end;
  15965. procedure TTestResolver.TestProcType_AsArgOtherUnit;
  15966. begin
  15967. AddModuleWithIntfImplSrc('unit2.pas',
  15968. LinesToStr([
  15969. 'type',
  15970. ' JSInteger = longint;',
  15971. ' TObject = class;',
  15972. ' TJSArrayCallBack = function (element : JSInteger) : Boolean;',
  15973. ' TObject = class',
  15974. ' public',
  15975. ' procedure forEach(const aCallBack : TJSArrayCallBack); virtual; abstract;',
  15976. ' end;',
  15977. '']),
  15978. '');
  15979. StartProgram(true);
  15980. Add('uses unit2;');
  15981. Add('function showElement(el : JSInteger) : boolean ;');
  15982. Add('begin');
  15983. Add(' result:=true;');
  15984. Add('end;');
  15985. Add('var a: TObject;');
  15986. Add('begin');
  15987. Add(' a.forEach(@ShowElement);');
  15988. ParseProgram;
  15989. end;
  15990. procedure TTestResolver.TestProcType_Property;
  15991. begin
  15992. StartProgram(false);
  15993. Add([
  15994. 'type',
  15995. ' TObject = class end;',
  15996. ' TNotifyEvent = procedure(Sender: TObject) of object;',
  15997. ' TControl = class',
  15998. ' FOnClick: TNotifyEvent;',
  15999. ' property OnClick: TNotifyEvent read FOnClick write FOnClick;',
  16000. ' procedure Click(Sender: TObject);',
  16001. ' end;',
  16002. ' TButton = class(TControl)',
  16003. ' property OnClick;',
  16004. ' end;',
  16005. 'procedure TControl.Click(Sender: TObject);',
  16006. 'begin',
  16007. ' if Assigned(OnClick) then ;',
  16008. ' OnClick:=@Click;',
  16009. ' OnClick(Sender);',
  16010. ' Self.OnClick(Sender);',
  16011. ' with Self do OnClick(Sender);',
  16012. 'end;',
  16013. 'var',
  16014. ' Ctrl: TControl;',
  16015. ' Btn: TButton;',
  16016. 'begin',
  16017. ' if Assigned(Ctrl.OnClick) then ;',
  16018. ' Ctrl.OnClick(Ctrl);',
  16019. ' with Ctrl do OnClick(Ctrl);',
  16020. ' if Assigned(Btn.OnClick) then ;',
  16021. ' Btn.OnClick(Btn);',
  16022. ' with Btn do OnClick(Btn);',
  16023. '']);
  16024. ParseProgram;
  16025. end;
  16026. procedure TTestResolver.TestProcType_PropertyCallWrongArgFail;
  16027. begin
  16028. StartProgram(false);
  16029. Add('type');
  16030. Add(' TObject = class end;');
  16031. Add(' TNotifyEvent = procedure(Sender: TObject) of object;');
  16032. Add(' TControl = class');
  16033. Add(' FOnClick: TNotifyEvent;');
  16034. Add(' property OnClick: TNotifyEvent read FOnClick write FOnClick;');
  16035. Add(' end;');
  16036. Add('var Btn: TControl;');
  16037. Add('begin');
  16038. Add(' Btn.OnClick(3);');
  16039. CheckResolverException('Incompatible type for arg no. 1: Got "Longint", expected "TObject"',
  16040. nIncompatibleTypeArgNo);
  16041. end;
  16042. procedure TTestResolver.TestProcType_Typecast;
  16043. begin
  16044. StartProgram(false);
  16045. Add('type');
  16046. Add(' TNotifyEvent = procedure(Sender: Pointer) of object;');
  16047. Add(' TEvent = procedure of object;');
  16048. Add(' TProcA = procedure(i: longint);');
  16049. Add(' TFuncB = function(i, j: longint): longint;');
  16050. Add('var');
  16051. Add(' Notify: TNotifyEvent;');
  16052. Add(' Event: TEvent;');
  16053. Add(' ProcA: TProcA;');
  16054. Add(' FuncB: TFuncB;');
  16055. Add(' p: pointer;');
  16056. Add('begin');
  16057. Add(' Notify:=TNotifyEvent(Event);');
  16058. Add(' Event:=TEvent(Event);');
  16059. Add(' Event:=TEvent(Notify);');
  16060. Add(' ProcA:=TProcA(FuncB);');
  16061. Add(' FuncB:=TFuncB(FuncB);');
  16062. Add(' FuncB:=TFuncB(ProcA);');
  16063. Add(' ProcA:=TProcA(p);');
  16064. Add(' FuncB:=TFuncB(p);');
  16065. ParseProgram;
  16066. end;
  16067. procedure TTestResolver.TestProcType_InsideFunction;
  16068. begin
  16069. StartProgram(false);
  16070. Add([
  16071. 'function GetIt: longint;',
  16072. 'type TGetter = function: longint;',
  16073. 'var',
  16074. ' p: Pointer;',
  16075. 'begin',
  16076. ' Result:=TGetter(p)();',
  16077. 'end;',
  16078. 'begin',
  16079. '']);
  16080. ParseProgram;
  16081. end;
  16082. procedure TTestResolver.TestProcType_PassProcToUntyped;
  16083. var
  16084. aMarker: PSrcMarker;
  16085. Elements: TFPList;
  16086. ActualImplicitCallWithoutParams: Boolean;
  16087. i: Integer;
  16088. El: TPasElement;
  16089. Ref: TResolvedReference;
  16090. begin
  16091. StartProgram(false);
  16092. Add([
  16093. 'type',
  16094. ' TEvent = procedure of object;',
  16095. ' TFunc = function: longint of object;',
  16096. 'procedure DoIt; varargs; begin end;',
  16097. 'procedure DoSome(const a; var b; c: pointer); begin end;',
  16098. 'var',
  16099. ' E: TEvent;',
  16100. ' F: TFunc;',
  16101. 'begin',
  16102. ' DoIt({#a1}E,{#a2}F);',
  16103. ' DoSome({#b1}E,{#b2}E,{#b3}E);',
  16104. ' DoSome({#c1}F,{#c2}F,{#c3}F);',
  16105. '']);
  16106. ParseProgram;
  16107. aMarker:=FirstSrcMarker;
  16108. while aMarker<>nil do
  16109. begin
  16110. //writeln('TTestResolver.TestProcType_PassProcToUntyped ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  16111. Elements:=FindElementsAt(aMarker);
  16112. try
  16113. ActualImplicitCallWithoutParams:=false;
  16114. for i:=0 to Elements.Count-1 do
  16115. begin
  16116. El:=TPasElement(Elements[i]);
  16117. //writeln('TTestResolver.TestProcType_PassProcToUntyped ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  16118. if not (El.CustomData is TResolvedReference) then continue;
  16119. Ref:=TResolvedReference(El.CustomData);
  16120. //writeln('TTestResolver.TestProcType_PassProcToUntyped ',GetObjName(Ref.Declaration),' rrfImplicitCallWithoutParams=',rrfImplicitCallWithoutParams in Ref.Flags);
  16121. if rrfImplicitCallWithoutParams in Ref.Flags then
  16122. ActualImplicitCallWithoutParams:=true;
  16123. break;
  16124. end;
  16125. if ActualImplicitCallWithoutParams then
  16126. RaiseErrorAtSrcMarker('expected no implicit call at "#'+aMarker^.Identifier+'"',aMarker);
  16127. finally
  16128. Elements.Free;
  16129. end;
  16130. aMarker:=aMarker^.Next;
  16131. end;
  16132. end;
  16133. procedure TTestResolver.TestProcTypeAnonymous_Var;
  16134. begin
  16135. StartProgram(false);
  16136. Add([
  16137. 'var',
  16138. ' f: function: word;',
  16139. 'begin']);
  16140. ParseProgram;
  16141. end;
  16142. procedure TTestResolver.TestProcTypeAnonymous_FunctionFunctionFail;
  16143. begin
  16144. StartProgram(false);
  16145. Add([
  16146. 'var',
  16147. ' f: function:function:longint;',
  16148. 'begin']);
  16149. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  16150. end;
  16151. procedure TTestResolver.TestProcTypeAnonymous_ResultTypeFail;
  16152. begin
  16153. StartProgram(false);
  16154. Add([
  16155. 'function Fly: procedure;',
  16156. 'begin',
  16157. 'end;',
  16158. 'begin']);
  16159. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  16160. end;
  16161. procedure TTestResolver.TestProcTypeAnonymous_ArgumentFail;
  16162. begin
  16163. StartProgram(false);
  16164. Add([
  16165. 'procedure Fly(p: procedure);',
  16166. 'begin',
  16167. 'end;',
  16168. 'begin']);
  16169. CheckParserException('Parameters or result types cannot contain local type definitions. Use a separate type definition in a type block.',nParserParamsOrResultTypesNoLocalTypeDefs);
  16170. end;
  16171. procedure TTestResolver.TestProcTypeAnonymous_PropertyFail;
  16172. begin
  16173. StartProgram(false);
  16174. Add([
  16175. 'type',
  16176. ' TObject = class',
  16177. ' FProc: procedure;',
  16178. ' property Proc: procedure read FProc;',
  16179. ' end;',
  16180. 'begin']);
  16181. CheckParserException('Expected ";" at token "Identifier read" in file afile.pp at line 5 column 30',
  16182. nParserExpectTokenError);
  16183. end;
  16184. procedure TTestResolver.TestPointer;
  16185. begin
  16186. StartProgram(false);
  16187. Add([
  16188. 'type',
  16189. ' TObject = class end;',
  16190. ' TClass = class of TObject;',
  16191. ' TMyPtr = pointer;',
  16192. ' TArrInt = array of longint;',
  16193. ' TFunc = function: longint;',
  16194. 'procedure DoIt; begin end;',
  16195. 'var',
  16196. ' p: TMyPtr;',
  16197. ' Obj: TObject;',
  16198. ' Cl: TClass;',
  16199. ' a: tarrint;',
  16200. ' f: TFunc;',
  16201. ' s: string;',
  16202. ' u: unicodestring;',
  16203. 'begin',
  16204. ' p:=nil;',
  16205. ' if p=nil then;',
  16206. ' if nil=p then;',
  16207. ' if Assigned(p) then;',
  16208. ' p:=obj;',
  16209. ' p:=cl;',
  16210. ' p:=a;',
  16211. ' p:=Pointer(f);',
  16212. ' p:=@DoIt;',
  16213. ' p:=Pointer(@DoIt);',
  16214. ' obj:=TObject(p);',
  16215. ' cl:=TClass(p);',
  16216. ' a:=TArrInt(p);',
  16217. ' p:=Pointer(a);',
  16218. ' p:=Pointer(s);',
  16219. ' s:=String(p);',
  16220. ' p:=pointer(u);',
  16221. ' u:=UnicodeString(p);']);
  16222. ParseProgram;
  16223. end;
  16224. procedure TTestResolver.TestPointer_AnonymousSetFail;
  16225. begin
  16226. StartProgram(false);
  16227. Add([
  16228. 'type p = ^(red, green);',
  16229. 'begin']);
  16230. CheckParserException('Expected "Identifier or file"',
  16231. nParserExpectTokenError);
  16232. end;
  16233. procedure TTestResolver.TestPointer_AssignPointerToClassFail;
  16234. begin
  16235. StartProgram(false);
  16236. Add('type');
  16237. Add(' TObject = class end;');
  16238. Add('var');
  16239. Add(' Obj: TObject;');
  16240. Add(' p: pointer;');
  16241. Add('begin');
  16242. Add(' obj:=p;');
  16243. CheckResolverException('Incompatible types: got "Pointer" expected "TObject"',
  16244. nIncompatibleTypesGotExpected);
  16245. end;
  16246. procedure TTestResolver.TestPointer_TypecastToMethodTypeFail;
  16247. begin
  16248. StartProgram(false);
  16249. Add('type');
  16250. Add(' TEvent = procedure of object;');
  16251. Add('var');
  16252. Add(' p: pointer;');
  16253. Add(' e: TEvent;');
  16254. Add('begin');
  16255. Add(' e:=TEvent(p);');
  16256. CheckResolverException('Illegal type conversion: "Pointer" to "procedure type of Object"',
  16257. nIllegalTypeConversionTo);
  16258. end;
  16259. procedure TTestResolver.TestPointer_TypecastFromMethodTypeFail;
  16260. begin
  16261. StartProgram(false);
  16262. Add('type');
  16263. Add(' TEvent = procedure of object;');
  16264. Add('var');
  16265. Add(' p: pointer;');
  16266. Add(' e: TEvent;');
  16267. Add('begin');
  16268. Add(' p:=Pointer(e);');
  16269. CheckResolverException('Illegal type conversion: "procedural type of Object" to "Pointer"',
  16270. nIllegalTypeConversionTo);
  16271. end;
  16272. procedure TTestResolver.TestPointer_TypecastMethod_proMethodAddrAsPointer;
  16273. begin
  16274. ResolverEngine.Options:=ResolverEngine.Options+[proMethodAddrAsPointer];
  16275. StartProgram(false);
  16276. Add('type');
  16277. Add(' TEvent = procedure of object;');
  16278. Add('var');
  16279. Add(' p: pointer;');
  16280. Add(' e: TEvent;');
  16281. Add('begin');
  16282. Add(' e:=TEvent(p);');
  16283. Add(' p:=Pointer(e);');
  16284. ParseProgram;
  16285. end;
  16286. procedure TTestResolver.TestPointer_OverloadSignature;
  16287. begin
  16288. StartProgram(false);
  16289. Add('type');
  16290. Add(' TObject = class end;');
  16291. Add(' TClass = class of TObject;');
  16292. Add(' TBird = class(TObject) end;');
  16293. Add(' TBirds = class of TBird;');
  16294. Add('procedure {#pointer}DoIt(p: Pointer); begin end;');
  16295. Add('procedure {#tobject}DoIt(o: TObject); begin end;');
  16296. Add('procedure {#tclass}DoIt(c: TClass); begin end;');
  16297. Add('var');
  16298. Add(' p: pointer;');
  16299. Add(' o: TObject;');
  16300. Add(' c: TClass;');
  16301. Add(' b: TBird;');
  16302. Add(' bc: TBirds;');
  16303. Add('begin');
  16304. Add(' {@pointer}DoIt(p);');
  16305. Add(' {@tobject}DoIt(o);');
  16306. Add(' {@tclass}DoIt(c);');
  16307. Add(' {@tobject}DoIt(b);');
  16308. Add(' {@tclass}DoIt(bc);');
  16309. ParseProgram;
  16310. end;
  16311. procedure TTestResolver.TestPointer_Assign;
  16312. begin
  16313. StartProgram(false);
  16314. Add([
  16315. 'type',
  16316. ' TPtr = pointer;',
  16317. ' TClass = class of TObject;',
  16318. ' TObject = class end;',
  16319. 'var',
  16320. ' p: TPtr;',
  16321. ' o: TObject;',
  16322. ' c: TClass;',
  16323. 'begin',
  16324. ' p:=o;',
  16325. ' if p=o then ;',
  16326. ' if o=p then ;',
  16327. ' p:=c;',
  16328. ' if p=c then ;',
  16329. ' if c=p then ;',
  16330. '']);
  16331. ParseProgram;
  16332. end;
  16333. procedure TTestResolver.TestPointerTyped;
  16334. begin
  16335. StartProgram(false);
  16336. Add([
  16337. 'type',
  16338. ' PBoolean = ^boolean;',
  16339. ' PPInteger = ^PInteger;',
  16340. ' PInteger = ^integer;',
  16341. ' integer = longint;',
  16342. 'var',
  16343. ' i: integer;',
  16344. ' p1: PInteger;',
  16345. ' p2: ^Integer;',
  16346. ' p3: ^PInteger;',
  16347. ' a: array of integer;',
  16348. 'begin',
  16349. ' p1:=@i;',
  16350. ' p1:=p2;',
  16351. ' p2:=@i;',
  16352. ' p3:=@p1;',
  16353. ' p1:=@a[1];',
  16354. ' p1^:=i;',
  16355. ' i:=(@i)^;',
  16356. ' i:=p1^;',
  16357. ' i:=p2^;',
  16358. ' i:=p3^^;',
  16359. ' i:=PInteger(p3)^;',
  16360. ' if p1=@i then ;',
  16361. ' if @i=p1 then ;',
  16362. ' if p1=p2 then ;',
  16363. ' if p2=p1 then ;',
  16364. ' if p2=@i then ;',
  16365. ' if @i=p2 then ;',
  16366. ' if p1=@a[2] then ;',
  16367. ' if @a[3]=p1 then ;',
  16368. ' if i=p1^ then ;',
  16369. ' if p1^=i then ;',
  16370. ' i:=p1[1];',
  16371. ' i:=(@i)[1];',
  16372. ' i:=p2[2];',
  16373. ' i:=p3[3][4];',
  16374. '']);
  16375. ParseProgram;
  16376. end;
  16377. procedure TTestResolver.TestPointerTypedForwardMissingFail;
  16378. begin
  16379. StartProgram(false);
  16380. Add([
  16381. 'type',
  16382. ' PInteger = ^integer;',
  16383. 'var',
  16384. ' i: integer;',
  16385. 'begin',
  16386. '']);
  16387. CheckResolverException('identifier not found "integer"',nIdentifierNotFound);
  16388. end;
  16389. procedure TTestResolver.TestPointerTyped_CycleFail;
  16390. begin
  16391. StartProgram(false);
  16392. Add([
  16393. 'type',
  16394. ' PInteger = ^integer;',
  16395. ' integer = PInteger;',
  16396. 'var',
  16397. ' i: integer;',
  16398. ' p1: PInteger;',
  16399. 'begin',
  16400. '']);
  16401. CheckResolverException(sTypeCycleFound,nTypeCycleFound);
  16402. end;
  16403. procedure TTestResolver.TestPointerTyped_AssignMismatchFail;
  16404. begin
  16405. StartProgram(false);
  16406. Add([
  16407. 'type',
  16408. ' PInt = ^longint;',
  16409. ' PBool = ^boolean;',
  16410. 'var',
  16411. ' pi: Pint;',
  16412. ' pb: PBool;',
  16413. 'begin',
  16414. ' pi:=pb;',
  16415. '']);
  16416. CheckResolverException('Incompatible types: got "PBool" expected "PInt"',nIncompatibleTypesGotExpected);
  16417. end;
  16418. procedure TTestResolver.TestPointerTyped_AddrAddrFail;
  16419. begin
  16420. StartProgram(false);
  16421. Add([
  16422. 'type',
  16423. ' PInt = ^longint;',
  16424. ' PPInt = ^PInt;',
  16425. 'var',
  16426. ' i: longint;',
  16427. ' p: PPint;',
  16428. 'begin',
  16429. ' p:=@(@i);',
  16430. '']);
  16431. CheckResolverException('illegal qualifier "@" in front of "Pointer"',nIllegalQualifierInFrontOf);
  16432. end;
  16433. procedure TTestResolver.TestPointerTyped_RecordObjFPC;
  16434. begin
  16435. StartProgram(false);
  16436. Add([
  16437. 'type',
  16438. ' PRec = ^TRec;',
  16439. ' TRec = record x: longint; end;',
  16440. 'var',
  16441. ' r: TRec;',
  16442. ' p: PRec;',
  16443. ' i: longint;',
  16444. ' Ptr: pointer;',
  16445. 'begin',
  16446. ' p:=@r;',
  16447. ' i:=p^.x;',
  16448. ' p^.x:=i;',
  16449. ' if i=p^.x then;',
  16450. ' if p^.x=i then;',
  16451. ' ptr:=p;',
  16452. ' p:=PRec(ptr);',
  16453. '']);
  16454. ParseProgram;
  16455. end;
  16456. procedure TTestResolver.TestPointerTyped_RecordDelphi;
  16457. begin
  16458. StartProgram(false);
  16459. Add([
  16460. '{$mode delphi}',
  16461. 'type',
  16462. ' PRec = ^TRec;',
  16463. ' TRec = record x: longint; end;',
  16464. 'procedure DoIt(const p: PRec);',
  16465. 'begin',
  16466. ' p.x:=p.x;',
  16467. ' with p^ do',
  16468. ' x:=x;',
  16469. 'end;',
  16470. 'var',
  16471. ' r: TRec;',
  16472. ' p: PRec;',
  16473. ' i: longint;',
  16474. 'begin',
  16475. ' i:=p.x;',
  16476. ' p.x:=i;',
  16477. ' if i=p.x then;',
  16478. ' if p.x=i then;',
  16479. ' DoIt(@r);',
  16480. '']);
  16481. ParseProgram;
  16482. end;
  16483. procedure TTestResolver.TestPointerTyped_Arithmetic;
  16484. begin
  16485. StartProgram(false);
  16486. Add([
  16487. 'type',
  16488. ' PInt = ^longint;',
  16489. 'var',
  16490. ' i: longint;',
  16491. ' p: PInt;',
  16492. 'begin',
  16493. ' inc(p);',
  16494. ' inc(p,2);',
  16495. ' p:=p+3;',
  16496. ' p:=4+p;',
  16497. ' p:=@i+5;',
  16498. ' p:=6+@i;',
  16499. ' i:=(p+7)^;',
  16500. ' i:=(@i+8)^;',
  16501. '']);
  16502. ParseProgram;
  16503. end;
  16504. procedure TTestResolver.TestResourcestring;
  16505. begin
  16506. StartProgram(false);
  16507. Add([
  16508. 'const Foo = ''foo'';',
  16509. 'Resourcestring',
  16510. ' Bar = foo;',
  16511. ' Red = ''Red'';',
  16512. ' r = ''Rd''+foo;',
  16513. 'procedure DoIt(s: string; const h: string); begin end;',
  16514. 'begin',
  16515. ' if bar=red then ;',
  16516. ' if bar=''a'' then ;',
  16517. ' doit(r,r);',
  16518. '']);
  16519. ParseProgram;
  16520. end;
  16521. procedure TTestResolver.TestResourcestringAssignFail;
  16522. begin
  16523. StartProgram(false);
  16524. Add([
  16525. 'Resourcestring Foo = ''bar'';',
  16526. 'begin',
  16527. ' Foo:=''a'';',
  16528. '']);
  16529. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  16530. end;
  16531. procedure TTestResolver.TestResourcestringLocalFail;
  16532. begin
  16533. StartProgram(false);
  16534. Add([
  16535. 'procedure DoIt;',
  16536. 'Resourcestring Foo = ''bar'';',
  16537. 'begin end;',
  16538. 'begin;',
  16539. '']);
  16540. CheckParserException(SParserResourcestringsMustBeGlobal,nParserResourcestringsMustBeGlobal);
  16541. end;
  16542. procedure TTestResolver.TestResourcestringInConstFail;
  16543. begin
  16544. StartProgram(false);
  16545. Add([
  16546. 'Resourcestring Foo = ''foo'';',
  16547. 'const Bar = ''Prefix''+Foo;',
  16548. 'begin',
  16549. '']);
  16550. CheckResolverException(sConstantExpressionExpected,nConstantExpressionExpected);
  16551. end;
  16552. procedure TTestResolver.TestResourcestringPassVarArgFail;
  16553. begin
  16554. StartProgram(false);
  16555. Add([
  16556. 'Resourcestring Bar = ''foo'';',
  16557. 'procedure DoIt(var s: string); begin end;',
  16558. 'begin',
  16559. ' doit(bar);',
  16560. '']);
  16561. CheckResolverException(sVariableIdentifierExpected,nVariableIdentifierExpected);
  16562. end;
  16563. procedure TTestResolver.TestHint_ElementHintModifiers;
  16564. begin
  16565. StartProgram(false);
  16566. Add([
  16567. 'type',
  16568. ' TDeprecated = longint deprecated;',
  16569. ' TLibrary = longint library;',
  16570. ' TPlatform = longint platform;',
  16571. ' TExperimental = longint experimental;',
  16572. ' TUnimplemented = longint unimplemented;',
  16573. ' TExperimentalPlatform = boolean experimental platform;',
  16574. 'var',
  16575. ' vDeprecated: TDeprecated;',
  16576. ' vLibrary: TLibrary;',
  16577. ' vPlatform: TPlatform;',
  16578. ' vExperimental: TExperimental;',
  16579. ' vUnimplemented: TUnimplemented;',
  16580. ' vExperimentalPlatform: TExperimentalPlatform;',
  16581. 'begin',
  16582. '']);
  16583. ParseProgram;
  16584. CheckResolverHint(mtWarning,nSymbolXIsDeprecated,'Symbol "TDeprecated" is deprecated');
  16585. CheckResolverHint(mtWarning,nSymbolXBelongsToALibrary,'Symbol "TLibrary" belongs to a library');
  16586. CheckResolverHint(mtWarning,nSymbolXIsNotPortable,'Symbol "TPlatform" is not portable');
  16587. CheckResolverHint(mtWarning,nSymbolXIsExperimental,'Symbol "TExperimental" is experimental');
  16588. CheckResolverHint(mtWarning,nSymbolXIsNotImplemented,'Symbol "TUnimplemented" is not implemented');
  16589. CheckResolverHint(mtWarning,nSymbolXIsExperimental,'Symbol "TExperimentalPlatform" is experimental');
  16590. CheckResolverHint(mtWarning,nSymbolXIsNotPortable,'Symbol "TExperimentalPlatform" is not portable');
  16591. CheckResolverUnexpectedHints;
  16592. end;
  16593. procedure TTestResolver.TestHint_ElementHintsMsg;
  16594. begin
  16595. StartProgram(false);
  16596. Add([
  16597. 'type',
  16598. ' TDeprecated = longint deprecated ''foo'';',
  16599. 'var',
  16600. ' vDeprecated: TDeprecated;',
  16601. 'begin',
  16602. '']);
  16603. ParseProgram;
  16604. CheckResolverHint(mtWarning,nSymbolXIsDeprecatedY,'Symbol "TDeprecated" is deprecated: ''foo''');
  16605. CheckResolverUnexpectedHints;
  16606. end;
  16607. procedure TTestResolver.TestHint_ElementHintsAlias;
  16608. var
  16609. aMarker: PSrcMarker;
  16610. begin
  16611. StartProgram(false);
  16612. Add([
  16613. 'type',
  16614. ' TPlatform = longint platform;',
  16615. ' {#a}TAlias = TPlatform;',
  16616. 'var',
  16617. ' {#b}vB: TPlatform;',
  16618. ' {#c}vC: TAlias;',
  16619. 'function {#d}DoIt: TPlatform;',
  16620. 'begin',
  16621. ' Result:=0;',
  16622. 'end;',
  16623. 'function {#e}DoSome: TAlias;',
  16624. 'begin',
  16625. ' Result:=0;',
  16626. 'end;',
  16627. 'begin',
  16628. '']);
  16629. ParseProgram;
  16630. //WriteSources('afile.pp',3,4);
  16631. aMarker:=FirstSrcMarker;
  16632. while aMarker<>nil do
  16633. begin
  16634. //writeln('TTestResolver.TestHint_ElementHintsAlias Marker "',aMarker^.Identifier,'" ',aMarker^.StartCol,'..',aMarker^.EndCol);
  16635. CheckResolverHint(mtWarning,nSymbolXIsNotPortable,'Symbol "TPlatform" is not portable',aMarker);
  16636. aMarker:=aMarker^.Next;
  16637. end;
  16638. CheckResolverUnexpectedHints(true);
  16639. end;
  16640. procedure TTestResolver.TestHint_ElementHints_WarnOff_SymbolDeprecated;
  16641. begin
  16642. StartProgram(false);
  16643. Add([
  16644. '{$warn symbol_deprecated off}',
  16645. 'var',
  16646. ' i: byte deprecated;',
  16647. 'begin',
  16648. ' if i=3 then ;']);
  16649. ParseProgram;
  16650. CheckResolverUnexpectedHints(true);
  16651. end;
  16652. procedure TTestResolver.TestHint_ClassElementHints;
  16653. begin
  16654. StartProgram(false);
  16655. Add([
  16656. 'type',
  16657. ' TObject = class',
  16658. ' FWing: word experimental;',
  16659. ' property Wing: word read FWing; platform; experimental;',
  16660. ' procedure Fly; library;',
  16661. ' end;',
  16662. 'procedure TObject.Fly;',
  16663. 'begin',
  16664. ' if Wing=3 then ;',
  16665. 'end;',
  16666. 'var',
  16667. ' Bird: TObject;',
  16668. 'begin',
  16669. ' Bird.Fly;',
  16670. '']);
  16671. ParseProgram;
  16672. CheckResolverHint(mtWarning,nSymbolXIsExperimental,'Symbol "FWing" is experimental');
  16673. CheckResolverHint(mtWarning,nSymbolXIsNotPortable,'Symbol "Wing" is not portable');
  16674. CheckResolverHint(mtWarning,nSymbolXIsExperimental,'Symbol "Wing" is experimental');
  16675. CheckResolverHint(mtWarning,nSymbolXBelongsToALibrary,'Symbol "Fly" belongs to a library');
  16676. CheckResolverUnexpectedHints;
  16677. end;
  16678. procedure TTestResolver.TestHint_UsesHints;
  16679. var
  16680. Src: String;
  16681. begin
  16682. Src:='{$mode objfpc}';
  16683. Src+='unit unit2 experimental platform;'+LineEnding;
  16684. Src+='interface'+LineEnding;
  16685. Src+='implementation'+LineEnding;
  16686. Src+='end.'+LineEnding;
  16687. AddModuleWithSrc('unit2',Src);
  16688. StartProgram(true);
  16689. Add([
  16690. 'uses unit2;',
  16691. 'begin']);
  16692. ParseProgram;
  16693. CheckResolverHint(mtWarning,nSymbolXIsExperimental,'Symbol "unit2" is experimental');
  16694. CheckResolverHint(mtWarning,nSymbolXIsNotPortable,'Symbol "unit2" is not portable');
  16695. end;
  16696. procedure TTestResolver.TestHint_Garbage;
  16697. begin
  16698. StartProgram(false);
  16699. Add([
  16700. 'begin',
  16701. 'end.']);
  16702. ParseProgram;
  16703. CheckResolverHint(mtHint,nTextAfterFinalIgnored,sTextAfterFinalIgnored+' afile.pp(4,4)');
  16704. CheckResolverUnexpectedHints(true);
  16705. end;
  16706. procedure TTestResolver.TestClassHelper;
  16707. begin
  16708. StartProgram(false);
  16709. Add([
  16710. 'type',
  16711. ' TObject = class',
  16712. ' end;',
  16713. ' TObjectHelper = class helper for TObject',
  16714. ' type T = word;',
  16715. ' const',
  16716. ' c: T = 3;',
  16717. ' k: T = 4;',
  16718. ' class var',
  16719. ' v: T;',
  16720. ' w: T;',
  16721. ' end;',
  16722. ' TBird = class(TObject)',
  16723. ' end;',
  16724. ' TBirdHelper = class helper for TBird',
  16725. ' end;',
  16726. ' TExtObjHelper = class helper(TObjectHelper) for TBird',
  16727. ' end;',
  16728. 'begin',
  16729. '']);
  16730. ParseProgram;
  16731. end;
  16732. procedure TTestResolver.TestClassHelper_AncestorIsNotHelperForDescendantFail;
  16733. begin
  16734. StartProgram(false);
  16735. Add([
  16736. 'type',
  16737. ' TObject = class',
  16738. ' end;',
  16739. ' TBird = class(TObject)',
  16740. ' end;',
  16741. ' TBirdHelper = class helper for TBird',
  16742. ' end;',
  16743. ' TFish = class(TObject)',
  16744. ' end;',
  16745. ' THelper = class helper(TBirdHelper) for TFish',
  16746. ' end;',
  16747. 'begin',
  16748. '']);
  16749. CheckResolverException('Derived class helper must extend a subclass of "TBird" or the class itself',
  16750. nDerivedXMustExtendASubClassY);
  16751. end;
  16752. procedure TTestResolver.TestClassHelper_HelperForParentFail;
  16753. begin
  16754. StartProgram(false);
  16755. Add([
  16756. 'type',
  16757. ' TObject = class',
  16758. ' end;',
  16759. ' TBird = class(TObject)',
  16760. ' type',
  16761. ' TBirdHelper = class helper for TBird',
  16762. ' end;',
  16763. ' end;',
  16764. 'begin',
  16765. '']);
  16766. CheckResolverException(sTypeXIsNotYetCompletelyDefined,
  16767. nTypeXIsNotYetCompletelyDefined);
  16768. end;
  16769. procedure TTestResolver.TestClassHelper_ForInterfaceFail;
  16770. begin
  16771. StartProgram(false);
  16772. Add([
  16773. 'type',
  16774. ' IUnknown = interface',
  16775. ' procedure DoIt;',
  16776. ' end;',
  16777. ' TBirdHelper = class helper for IUnknown',
  16778. ' end;',
  16779. 'begin',
  16780. '']);
  16781. CheckResolverException('class type expected, but IUnknown found',
  16782. nXExpectedButYFound);
  16783. end;
  16784. procedure TTestResolver.TestClassHelper_FieldFail;
  16785. begin
  16786. StartProgram(false);
  16787. Add([
  16788. 'type',
  16789. ' TObject = class',
  16790. ' end;',
  16791. ' TObjHelper = class helper for TObject',
  16792. ' F: word;',
  16793. ' end;',
  16794. 'begin',
  16795. '']);
  16796. CheckParserException('Fields are not allowed in class helper',
  16797. nParserNoFieldsAllowed);
  16798. end;
  16799. procedure TTestResolver.TestClassHelper_AbstractFail;
  16800. begin
  16801. StartProgram(false);
  16802. Add([
  16803. '{$mode delphi}',
  16804. 'type',
  16805. ' TObject = class',
  16806. ' end;',
  16807. ' TObjHelper = class helper for TObject',
  16808. ' procedure DoIt; virtual; abstract;',
  16809. ' end;',
  16810. 'begin',
  16811. '']);
  16812. CheckResolverException('Invalid class helper procedure modifier abstract',
  16813. nInvalidXModifierY);
  16814. end;
  16815. procedure TTestResolver.TestClassHelper_VirtualObjFPCFail;
  16816. begin
  16817. StartProgram(false);
  16818. Add([
  16819. 'type',
  16820. ' TObject = class',
  16821. ' end;',
  16822. ' TObjHelper = class helper for TObject',
  16823. ' procedure DoIt; virtual;',
  16824. ' end;',
  16825. 'procedure TObjHelper.DoIt;',
  16826. 'begin end;',
  16827. 'begin',
  16828. '']);
  16829. CheckResolverException('Invalid class helper procedure modifier virtual',
  16830. nInvalidXModifierY);
  16831. end;
  16832. procedure TTestResolver.TestClassHelper_VirtualDelphiFail;
  16833. begin
  16834. StartProgram(false);
  16835. Add([
  16836. '{$mode delphi}',
  16837. 'type',
  16838. ' TObject = class',
  16839. ' end;',
  16840. ' TObjHelper = class helper for TObject',
  16841. ' procedure DoIt; virtual;',
  16842. ' end;',
  16843. 'procedure TObjHelper.DoIt;',
  16844. 'begin end;',
  16845. 'begin',
  16846. '']);
  16847. CheckResolverException('Invalid class helper procedure modifier virtual',
  16848. nInvalidXModifierY);
  16849. end;
  16850. procedure TTestResolver.TestClassHelper_DestructorFail;
  16851. begin
  16852. StartProgram(false);
  16853. Add([
  16854. 'type',
  16855. ' TObject = class',
  16856. ' end;',
  16857. ' TObjHelper = class helper for TObject',
  16858. ' destructor Destroyer;',
  16859. ' end;',
  16860. 'destructor TObjHelper.Destroyer;',
  16861. 'begin end;',
  16862. 'begin',
  16863. '']);
  16864. CheckParserException('destructor is not allowed in class helper',
  16865. nParserXNotAllowedInY);
  16866. end;
  16867. procedure TTestResolver.TestClassHelper_ClassRefersToTypeHelperOfAncestor;
  16868. begin
  16869. StartProgram(false);
  16870. Add([
  16871. 'type',
  16872. ' TObject = class',
  16873. ' end;',
  16874. ' TObjHelper = class helper for TObject',
  16875. ' type',
  16876. ' TInt = word;',
  16877. ' function GetSize: TInt;',
  16878. ' end;',
  16879. ' TAnt = class',
  16880. ' procedure SetSize(Value: TInt);',
  16881. ' property Size: TInt read GetSize write SetSize;',
  16882. ' end;',
  16883. 'function Tobjhelper.getSize: TInt;',
  16884. 'begin',
  16885. 'end;',
  16886. 'procedure TAnt.SetSize(Value: TInt);',
  16887. 'begin',
  16888. 'end;',
  16889. 'begin',
  16890. '']);
  16891. ParseProgram;
  16892. end;
  16893. procedure TTestResolver.TestClassHelper_InheritedObjFPC;
  16894. begin
  16895. StartProgram(false);
  16896. Add([
  16897. 'type',
  16898. ' TObject = class',
  16899. ' procedure {#TObject_Fly}Fly;',
  16900. ' end;',
  16901. ' TObjHelper = class helper for TObject',
  16902. ' procedure {#TObjHelper_Fly}Fly;',
  16903. ' end;',
  16904. ' TBird = class',
  16905. ' procedure {#TBird_Fly}Fly;',
  16906. ' end;',
  16907. ' TBirdHelper = class helper for TBird',
  16908. ' procedure {#TBirdHelper_Fly}Fly;',
  16909. ' procedure {#TBirdHelper_Walk}Walk;',
  16910. ' end;',
  16911. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  16912. ' procedure {#TEagleHelper_Fly}Fly;',
  16913. ' procedure {#TEagleHelper_Walk}Walk;',
  16914. ' end;',
  16915. 'procedure Tobject.fly;',
  16916. 'begin',
  16917. ' inherited;', // ignore
  16918. 'end;',
  16919. 'procedure Tobjhelper.fly;',
  16920. 'begin',
  16921. ' {@TObject_Fly}inherited;',
  16922. ' inherited {@TObject_Fly}Fly;',
  16923. 'end;',
  16924. 'procedure Tbird.fly;',
  16925. 'begin',
  16926. ' {@TObjHelper_Fly}inherited;',
  16927. ' inherited {@TObjHelper_Fly}Fly;',
  16928. 'end;',
  16929. 'procedure Tbirdhelper.fly;',
  16930. 'begin',
  16931. ' {@TBird_Fly}inherited;',
  16932. ' inherited {@TBird_Fly}Fly;',
  16933. 'end;',
  16934. 'procedure Tbirdhelper.walk;',
  16935. 'begin',
  16936. 'end;',
  16937. 'procedure teagleHelper.fly;',
  16938. 'begin',
  16939. ' {@TBird_Fly}inherited;',
  16940. ' inherited {@TBird_Fly}Fly;',
  16941. 'end;',
  16942. 'procedure teagleHelper.walk;',
  16943. 'begin',
  16944. ' {@TBirdHelper_Walk}inherited;',
  16945. ' inherited {@TBirdHelper_Walk}Walk;',
  16946. 'end;',
  16947. 'var',
  16948. ' o: TObject;',
  16949. ' b: TBird;',
  16950. 'begin',
  16951. ' o.{@TObjHelper_Fly}Fly;',
  16952. ' b.{@TEagleHelper_Fly}Fly;',
  16953. '']);
  16954. ParseProgram;
  16955. end;
  16956. procedure TTestResolver.TestClassHelper_InheritedObjFPC2;
  16957. begin
  16958. StartProgram(false);
  16959. Add([
  16960. 'type',
  16961. ' TObject = class',
  16962. ' procedure {#TObject_Fly}Fly;',
  16963. ' end;',
  16964. ' TObjHelper = class helper for TObject',
  16965. ' procedure {#TObjHelper_Walk}Walk;',
  16966. ' end;',
  16967. ' TBird = class',
  16968. ' procedure {#TBird_Fly}Fly;',
  16969. ' end;',
  16970. ' TBirdHelper = class helper for TBird',
  16971. ' procedure {#TBirdHelper_Walk}Walk;',
  16972. ' end;',
  16973. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  16974. ' procedure {#TEagleHelper_Walk}Walk;',
  16975. ' end;',
  16976. 'procedure Tobject.fly;',
  16977. 'begin',
  16978. ' inherited;', // ignore
  16979. 'end;',
  16980. 'procedure Tobjhelper.walk;',
  16981. 'begin',
  16982. ' inherited;', // ignore
  16983. 'end;',
  16984. 'procedure Tbird.fly;',
  16985. 'begin',
  16986. ' {@TObject_Fly}inherited;', // no helper, search further in ancestor
  16987. ' inherited {@TObject_Fly}Fly;', // no helper, search further in ancestor
  16988. 'end;',
  16989. 'procedure Tbirdhelper.walk;',
  16990. 'begin',
  16991. ' {@TObjHelper_Walk}inherited;',
  16992. ' inherited {@TObjHelper_Walk}Walk;',
  16993. 'end;',
  16994. 'procedure teagleHelper.walk;',
  16995. 'begin',
  16996. ' {@TObjHelper_Walk}inherited;',
  16997. ' inherited {@TObjHelper_Walk}Walk;',
  16998. 'end;',
  16999. 'begin',
  17000. '']);
  17001. ParseProgram;
  17002. end;
  17003. procedure TTestResolver.TestClassHelper_InheritedObjFPCStrictPrivateFail;
  17004. begin
  17005. StartProgram(false);
  17006. Add([
  17007. 'type',
  17008. ' TObject = class',
  17009. ' strict private i: word;',
  17010. ' end;',
  17011. ' THelper = class helper for TObject',
  17012. ' property a: word read i;',
  17013. ' end;',
  17014. 'begin',
  17015. '']);
  17016. CheckResolverException('Can''t access strict private member i',nCantAccessXMember);
  17017. end;
  17018. procedure TTestResolver.TestClassHelper_InheritedClassObjFPC;
  17019. begin
  17020. StartProgram(false);
  17021. Add([
  17022. 'type',
  17023. ' TObject = class',
  17024. ' class procedure {#TObject_Fly}Fly;',
  17025. ' end;',
  17026. ' TObjHelper = class helper for TObject',
  17027. ' class procedure {#TObjHelper_Fly}Fly;',
  17028. ' end;',
  17029. ' TBird = class',
  17030. ' class procedure {#TBird_Fly}Fly;',
  17031. ' end;',
  17032. ' TBirdHelper = class helper for TBird',
  17033. ' class procedure {#TBirdHelper_Fly}Fly;',
  17034. ' class procedure {#TBirdHelper_Walk}Walk;',
  17035. ' end;',
  17036. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  17037. ' class procedure {#TEagleHelper_Fly}Fly;',
  17038. ' class procedure {#TEagleHelper_Walk}Walk;',
  17039. ' end;',
  17040. 'class procedure Tobject.fly;',
  17041. 'begin',
  17042. ' inherited;', // ignore
  17043. 'end;',
  17044. 'class procedure Tobjhelper.fly;',
  17045. 'begin',
  17046. ' {@TObject_Fly}inherited;',
  17047. ' inherited {@TObject_Fly}Fly;',
  17048. 'end;',
  17049. 'class procedure Tbird.fly;',
  17050. 'begin',
  17051. ' {@TObjHelper_Fly}inherited;',
  17052. ' inherited {@TObjHelper_Fly}Fly;',
  17053. 'end;',
  17054. 'class procedure Tbirdhelper.fly;',
  17055. 'begin',
  17056. ' {@TBird_Fly}inherited;',
  17057. ' inherited {@TBird_Fly}Fly;',
  17058. 'end;',
  17059. 'class procedure Tbirdhelper.walk;',
  17060. 'begin',
  17061. 'end;',
  17062. 'class procedure teagleHelper.fly;',
  17063. 'begin',
  17064. ' {@TBird_Fly}inherited;',
  17065. ' inherited {@TBird_Fly}Fly;',
  17066. 'end;',
  17067. 'class procedure teagleHelper.walk;',
  17068. 'begin',
  17069. ' {@TBirdHelper_Walk}inherited;',
  17070. ' inherited {@TBirdHelper_Walk}Walk;',
  17071. 'end;',
  17072. 'var',
  17073. ' o: TObject;',
  17074. ' b: TBird;',
  17075. 'begin',
  17076. ' o.{@TObjHelper_Fly}Fly;',
  17077. ' TObject.{@TObjHelper_Fly}Fly;',
  17078. ' b.{@TEagleHelper_Fly}Fly;',
  17079. ' TBird.{@TEagleHelper_Fly}Fly;',
  17080. '']);
  17081. ParseProgram;
  17082. end;
  17083. procedure TTestResolver.TestClassHelper_InheritedDelphi;
  17084. begin
  17085. StartProgram(false);
  17086. Add([
  17087. '{$mode delphi}',
  17088. 'type',
  17089. ' TObject = class',
  17090. ' procedure {#TObject_Fly}Fly;',
  17091. ' end;',
  17092. ' TObjHelper = class helper for TObject',
  17093. ' procedure {#TObjHelper_Fly}Fly;',
  17094. ' end;',
  17095. ' TBird = class',
  17096. ' procedure {#TBird_Fly}Fly;',
  17097. ' end;',
  17098. ' TBirdHelper = class helper for TBird',
  17099. ' procedure {#TBirdHelper_Fly}Fly;',
  17100. ' procedure {#TBirdHelper_Walk}Walk;',
  17101. ' end;',
  17102. ' TEagleHelper = class helper(TBirdHelper) for TBird',
  17103. ' procedure {#TEagleHelper_Fly}Fly;',
  17104. ' procedure {#TEagleHelper_Walk}Walk;',
  17105. ' end;',
  17106. 'procedure Tobject.fly;',
  17107. 'begin',
  17108. ' inherited;', // ignore
  17109. 'end;',
  17110. 'procedure Tobjhelper.fly;',
  17111. 'begin',
  17112. ' inherited;', // ignore
  17113. ' inherited {@TObject_Fly}Fly;',
  17114. 'end;',
  17115. 'procedure Tbird.fly;',
  17116. 'begin',
  17117. ' {@TObjHelper_Fly}inherited;',
  17118. ' inherited {@TObjHelper_Fly}Fly;',
  17119. 'end;',
  17120. 'procedure Tbirdhelper.fly;',
  17121. 'begin',
  17122. ' {@TObjHelper_Fly}inherited;',// skip helperfortype too
  17123. ' inherited {@TBird_Fly}Fly;',
  17124. 'end;',
  17125. 'procedure Tbirdhelper.walk;',
  17126. 'begin',
  17127. 'end;',
  17128. 'procedure teagleHelper.fly;',
  17129. 'begin',
  17130. ' {@TObjHelper_Fly}inherited;',// skip helperfortype too
  17131. ' inherited {@TBird_Fly}Fly;',
  17132. 'end;',
  17133. 'procedure teagleHelper.walk;',
  17134. 'begin',
  17135. ' inherited;', // ignore
  17136. ' inherited {@TBirdHelper_Walk}Walk;',
  17137. 'end;',
  17138. 'var',
  17139. ' o: TObject;',
  17140. ' b: TBird;',
  17141. 'begin',
  17142. ' o.{@TObjHelper_Fly}Fly;',
  17143. ' b.{@TEagleHelper_Fly}Fly;',
  17144. '']);
  17145. ParseProgram;
  17146. end;
  17147. procedure TTestResolver.TestClassHelper_NestedInheritedParentFail;
  17148. begin
  17149. StartProgram(false);
  17150. Add([
  17151. 'type',
  17152. ' TObject = class',
  17153. ' end;',
  17154. ' TBird = class',
  17155. ' procedure Fly;',
  17156. ' type',
  17157. ' TBirdHelper = class helper for TObject',
  17158. ' procedure Fly;',
  17159. ' end;',
  17160. ' end;',
  17161. 'procedure TBird.fly;',
  17162. 'begin',
  17163. 'end;',
  17164. 'procedure TBird.Tbirdhelper.fly;',
  17165. 'begin',
  17166. ' inherited Fly;',
  17167. 'end;',
  17168. 'begin',
  17169. '']);
  17170. CheckResolverException('identifier not found "Fly"',nIdentifierNotFound);
  17171. end;
  17172. procedure TTestResolver.TestClassHelper_AccessFields;
  17173. begin
  17174. StartProgram(false);
  17175. Add([
  17176. 'type',
  17177. ' TObject = class end;',
  17178. ' TBird = class',
  17179. ' Size: word;',
  17180. ' FItems: array of word;',
  17181. ' end;',
  17182. ' TBirdHelper = class helper for TBird',
  17183. ' procedure Fly;',
  17184. ' end;',
  17185. 'procedure TBirdHelper.Fly;',
  17186. 'begin',
  17187. ' Size:=FItems[0];',
  17188. ' Self.Size:=Self.FItems[0];',
  17189. 'end;',
  17190. 'var',
  17191. ' b: TBird;',
  17192. 'begin',
  17193. ' b.Fly;',
  17194. ' b.Fly()',
  17195. '']);
  17196. ParseProgram;
  17197. end;
  17198. procedure TTestResolver.TestClassHelper_HelperDotClassMethodFail;
  17199. begin
  17200. StartProgram(false);
  17201. Add([
  17202. 'type',
  17203. ' TObject = class end;',
  17204. ' THelper = class helper for TObject',
  17205. ' class procedure Fly;',
  17206. ' end;',
  17207. 'class procedure THelper.Fly;',
  17208. 'begin',
  17209. 'end;',
  17210. 'begin',
  17211. ' THelper.Fly;',
  17212. '']);
  17213. CheckResolverException(sHelpersCannotBeUsedAsTypes,nHelpersCannotBeUsedAsTypes);
  17214. end;
  17215. procedure TTestResolver.TestClassHelper_WithDoHelperFail;
  17216. begin
  17217. StartProgram(false);
  17218. Add([
  17219. 'type',
  17220. ' TObject = class end;',
  17221. ' THelper = class helper for TObject',
  17222. ' end;',
  17223. 'begin',
  17224. ' with THelper do ;',
  17225. '']);
  17226. CheckResolverException(sHelpersCannotBeUsedAsTypes,nHelpersCannotBeUsedAsTypes);
  17227. end;
  17228. procedure TTestResolver.TestClassHelper_AsTypeFail;
  17229. begin
  17230. StartProgram(false);
  17231. Add([
  17232. 'type',
  17233. ' TObject = class end;',
  17234. ' THelper = class helper for TObject',
  17235. ' end;',
  17236. 'var h: THelper;',
  17237. 'begin',
  17238. '']);
  17239. CheckResolverException(sHelpersCannotBeUsedAsTypes,nHelpersCannotBeUsedAsTypes);
  17240. end;
  17241. procedure TTestResolver.TestClassHelper_WithDo;
  17242. var
  17243. aMarker: PSrcMarker;
  17244. Elements: TFPList;
  17245. ActualWith, ExpectedWith: Boolean;
  17246. i: Integer;
  17247. El: TPasElement;
  17248. Ref: TResolvedReference;
  17249. begin
  17250. StartProgram(false);
  17251. Add([
  17252. 'type',
  17253. ' TObject = class end;',
  17254. ' TBird = class',
  17255. ' procedure Run;',
  17256. ' end;',
  17257. ' THelper = class helper for TBird',
  17258. ' procedure Foo(w: word = 1);',
  17259. ' end;',
  17260. 'procedure TBird.Run;',
  17261. 'var b: TBird;',
  17262. 'begin',
  17263. ' b.{#a1_not}Foo;',
  17264. ' b.{#b1_not}Foo();',
  17265. ' b.{#c1_not}Foo(2);',
  17266. ' with b do begin',
  17267. ' {#d1_with}Foo;',
  17268. ' {#e1_with}Foo();',
  17269. ' {#f1_with}Foo(3);',
  17270. ' end;',
  17271. 'end;',
  17272. 'procedure THelper.Foo(w: word);',
  17273. 'var b: TBird;',
  17274. 'begin',
  17275. ' b.{#a2_not}Foo;',
  17276. ' b.{#b2_not}Foo();',
  17277. ' b.{#c2_not}Foo(2);',
  17278. ' with b do begin',
  17279. ' {#d2_with}Foo;',
  17280. ' {#e2_with}Foo();',
  17281. ' {#f2_with}Foo(3);',
  17282. ' end;',
  17283. 'end;',
  17284. 'var b: TBird;',
  17285. 'begin',
  17286. ' b.{#a3_not}Foo;',
  17287. ' b.{#b3_not}Foo();',
  17288. ' b.{#c3_not}Foo(4);',
  17289. ' with b do begin',
  17290. ' {#d3_with}Foo;',
  17291. ' {#e3_with}Foo();',
  17292. ' {#f3_with}Foo(5);',
  17293. ' end;',
  17294. '']);
  17295. ParseProgram;
  17296. aMarker:=FirstSrcMarker;
  17297. while aMarker<>nil do
  17298. begin
  17299. //writeln('TTestResolver.TestClassHelper_WithDo ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  17300. Elements:=FindElementsAt(aMarker);
  17301. try
  17302. ActualWith:=false;
  17303. for i:=0 to Elements.Count-1 do
  17304. begin
  17305. El:=TPasElement(Elements[i]);
  17306. {$IFNDEF NOCONSOLE}
  17307. writeln('TTestResolver.TestClassHelper_WithDo ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  17308. {$ENDIF}
  17309. if not (El.CustomData is TResolvedReference) then continue;
  17310. Ref:=TResolvedReference(El.CustomData);
  17311. if Ref.WithExprScope<>nil then
  17312. ActualWith:=true;
  17313. break;
  17314. end;
  17315. ExpectedWith:=RightStr(aMarker^.Identifier,5)='_with';
  17316. if ActualWith<>ExpectedWith then
  17317. if ExpectedWith then
  17318. RaiseErrorAtSrcMarker('expected Ref.WithExprScope<>nil at "#'+aMarker^.Identifier+'"',aMarker)
  17319. else
  17320. RaiseErrorAtSrcMarker('expected Ref.WithExprScope=nil at "#'+aMarker^.Identifier+'"',aMarker);
  17321. finally
  17322. Elements.Free;
  17323. end;
  17324. aMarker:=aMarker^.Next;
  17325. end;
  17326. end;
  17327. procedure TTestResolver.TestClassHelper_ClassMethod;
  17328. begin
  17329. StartProgram(false);
  17330. Add([
  17331. 'type',
  17332. ' TObject = class end;',
  17333. ' THelper = class helper for TObject',
  17334. ' class procedure Fly(w: word = 1);',
  17335. ' class procedure Run(w: word = 1); static;',
  17336. ' end;',
  17337. 'class procedure THelper.Fly(w: word = 1);',
  17338. 'begin',
  17339. ' Fly;',
  17340. ' Fly();',
  17341. ' Run;',
  17342. ' Run();',
  17343. ' Self.Fly;',
  17344. ' Self.Fly();',
  17345. ' Self.Run;',
  17346. ' Self.Run();',
  17347. ' with Self do begin',
  17348. ' Fly;',
  17349. ' Fly();',
  17350. ' Run;',
  17351. ' Run();',
  17352. ' end;',
  17353. 'end;',
  17354. 'class procedure THelper.Run(w: word = 1);',
  17355. 'begin',
  17356. ' Fly;',
  17357. ' Fly();',
  17358. ' Run;',
  17359. ' Run();',
  17360. 'end;',
  17361. 'var o: TObject;',
  17362. 'begin',
  17363. ' o.Fly;',
  17364. ' o.Fly();',
  17365. ' o.Run;',
  17366. ' o.Run();',
  17367. ' with o do begin',
  17368. ' Fly;',
  17369. ' Fly();',
  17370. ' Run;',
  17371. ' Run();',
  17372. ' end;',
  17373. ' TObject.Fly;',
  17374. ' TObject.Fly();',
  17375. ' TObject.Run;',
  17376. ' TObject.Run();',
  17377. ' with TObject do begin',
  17378. ' Fly;',
  17379. ' Fly();',
  17380. ' Run;',
  17381. ' Run();',
  17382. ' end;',
  17383. '']);
  17384. ParseProgram;
  17385. end;
  17386. procedure TTestResolver.TestClassHelper_Enumerator;
  17387. begin
  17388. StartProgram(false);
  17389. Add([
  17390. 'type',
  17391. ' TObject = class end;',
  17392. ' TItem = TObject;',
  17393. ' TEnumerator = class',
  17394. ' FCurrent: TItem;',
  17395. ' property Current: TItem read FCurrent;',
  17396. ' function MoveNext: boolean;',
  17397. ' end;',
  17398. ' TBird = class',
  17399. ' FItems: array of TItem;',
  17400. ' end;',
  17401. ' TBirdHelper = class helper for TBird',
  17402. ' function GetEnumerator: TEnumerator;',
  17403. ' end;',
  17404. 'function TEnumerator.MoveNext: boolean;',
  17405. 'begin',
  17406. 'end;',
  17407. 'function TBirdHelper.GetEnumerator: TEnumerator;',
  17408. 'begin',
  17409. ' Result.FCurrent:=FItems[0];',
  17410. ' Result.FCurrent:=Self.FItems[0];',
  17411. 'end;',
  17412. 'var',
  17413. ' b: TBird;',
  17414. ' i: TItem;',
  17415. ' {#i2}i2: TItem;',
  17416. 'begin',
  17417. ' for i in b do {@i2}i2:=i;']);
  17418. ParseProgram;
  17419. end;
  17420. procedure TTestResolver.TestClassHelper_FromUnitInterface;
  17421. begin
  17422. AddModuleWithIntfImplSrc('unit2.pas',
  17423. LinesToStr([
  17424. 'type',
  17425. ' TObject = class',
  17426. ' public',
  17427. ' Id: word;',
  17428. ' FSize: string;',
  17429. ' end;',
  17430. ' TOb21Helper = class helper for TObject',
  17431. ' property Size: string read FSize write FSize;',
  17432. ' end;',
  17433. '']),
  17434. '');
  17435. AddModuleWithIntfImplSrc('unit3.pas',
  17436. LinesToStr([
  17437. 'uses unit2;',
  17438. 'type',
  17439. ' TOb3Helper = class helper for TObject',
  17440. ' property Size: word read ID write ID;',
  17441. ' end;',
  17442. '']),
  17443. '');
  17444. StartProgram(true);
  17445. Add([
  17446. 'uses unit2, unit3;',
  17447. 'var o: TObject;',
  17448. 'begin',
  17449. ' o.Size:=3;', // last unit wins
  17450. ' o.Size:=o.Size;']);
  17451. ParseProgram;
  17452. end;
  17453. procedure TTestResolver.TestClassHelper_Constructor_NewInstance;
  17454. var
  17455. aMarker: PSrcMarker;
  17456. Elements: TFPList;
  17457. i: Integer;
  17458. El: TPasElement;
  17459. Ref: TResolvedReference;
  17460. ActualNewInstance, ActualImplicitCallWithoutParams: Boolean;
  17461. begin
  17462. StartProgram(false);
  17463. Add([
  17464. 'type',
  17465. ' TObject = class',
  17466. ' end;',
  17467. ' THelper = class helper for TObject',
  17468. ' constructor Create;',
  17469. ' class function DoSome: TObject;',
  17470. ' end;',
  17471. 'constructor THelper.Create;',
  17472. 'begin',
  17473. ' {#a}Create; // normal call',
  17474. ' TObject.{#b}Create; // new instance',
  17475. 'end;',
  17476. 'class function THelper.DoSome: TObject;',
  17477. 'begin',
  17478. ' Result:={#c}Create; // new instance',
  17479. 'end;',
  17480. 'var',
  17481. ' o: TObject;',
  17482. 'begin',
  17483. ' TObject.{#p}Create; // new object',
  17484. ' o:=TObject.{#q}Create; // new object',
  17485. ' with TObject do begin',
  17486. ' {#r}Create; // new object',
  17487. ' o:={#s}Create; // new object',
  17488. ' end;',
  17489. ' o.{#t}Create; // normal call',
  17490. ' o:=o.{#u}Create; // normal call',
  17491. ' with o do begin',
  17492. ' {#v}Create; // normal call',
  17493. ' o:={#w}Create; // normal call',
  17494. ' end;',
  17495. '']);
  17496. ParseProgram;
  17497. aMarker:=FirstSrcMarker;
  17498. while aMarker<>nil do
  17499. begin
  17500. //writeln('TTestResolver.TestClassHelper_Constructor_NewInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  17501. Elements:=FindElementsAt(aMarker);
  17502. try
  17503. ActualNewInstance:=false;
  17504. ActualImplicitCallWithoutParams:=false;
  17505. for i:=0 to Elements.Count-1 do
  17506. begin
  17507. El:=TPasElement(Elements[i]);
  17508. //writeln('TTestResolver.TestClassHelper_Constructor_NewInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  17509. if not (El.CustomData is TResolvedReference) then continue;
  17510. Ref:=TResolvedReference(El.CustomData);
  17511. if not (Ref.Declaration is TPasProcedure) then continue;
  17512. //writeln('TTestResolver.TestClassHelper_Constructor_NewInstance ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  17513. if (Ref.Declaration is TPasConstructor) then
  17514. ActualNewInstance:=rrfNewInstance in Ref.Flags;
  17515. ActualImplicitCallWithoutParams:=rrfImplicitCallWithoutParams in Ref.Flags;
  17516. break;
  17517. end;
  17518. if not ActualImplicitCallWithoutParams then
  17519. RaiseErrorAtSrcMarker('expected implicit call at "#'+aMarker^.Identifier+', but got function ref"',aMarker);
  17520. case aMarker^.Identifier of
  17521. 'a','t','u','v','w':// should be normal call
  17522. if ActualNewInstance then
  17523. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got newinstance"',aMarker);
  17524. else // should be newinstance
  17525. if not ActualNewInstance then
  17526. RaiseErrorAtSrcMarker('expected newinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  17527. end;
  17528. finally
  17529. Elements.Free;
  17530. end;
  17531. aMarker:=aMarker^.Next;
  17532. end;
  17533. end;
  17534. procedure TTestResolver.TestClassHelper_ReintroduceHides_CallFail;
  17535. begin
  17536. StartProgram(false);
  17537. Add([
  17538. 'type',
  17539. ' TObject = class',
  17540. ' constructor Create(o: tobject);',
  17541. ' end;',
  17542. ' TBird = class helper for TObject',
  17543. ' constructor Create(i: longint); reintroduce;',
  17544. ' end;',
  17545. 'constructor tobject.Create(o: tobject); begin end;',
  17546. 'constructor tbird.Create(i: longint); begin end;',
  17547. 'var o: TObject;',
  17548. 'begin',
  17549. ' o:=TObject.Create(nil);',
  17550. '']);
  17551. CheckResolverException('Incompatible type for arg no. 1: Got "Nil", expected "Longint"',
  17552. nIncompatibleTypeArgNo);
  17553. end;
  17554. procedure TTestResolver.TestClassHelper_DefaultProperty;
  17555. begin
  17556. StartProgram(false);
  17557. Add([
  17558. 'type',
  17559. ' TObject = class',
  17560. ' function GetB(Index: longint): longint;',
  17561. ' procedure SetB(Index: longint; Value: longint);',
  17562. ' end;',
  17563. ' THelper = class helper for TObject',
  17564. ' property B[Index: longint]: longint read GetB write SetB; default;',
  17565. ' end;',
  17566. 'function TObject.GetB(Index: longint): longint;',
  17567. 'begin',
  17568. 'end;',
  17569. 'procedure TObject.SetB(Index: longint; Value: longint);',
  17570. 'begin',
  17571. ' if Value=Self[Index] then ;',
  17572. ' Self[Index]:=Value;',
  17573. 'end;',
  17574. 'var o: TObject;',
  17575. 'begin',
  17576. ' o[3]:=4;',
  17577. ' if o[5]=6 then;',
  17578. ' if 7=o[8] then;',
  17579. '']);
  17580. ParseProgram;
  17581. end;
  17582. procedure TTestResolver.TestClassHelper_DefaultClassProperty;
  17583. begin
  17584. StartProgram(false);
  17585. Add([
  17586. 'type',
  17587. ' TClass = class of TObject;',
  17588. ' TObject = class',
  17589. ' class function GetB(Index: longint): longint; static;',
  17590. ' class procedure SetB(Index: longint; Value: longint); static;',
  17591. ' end;',
  17592. ' THelper = class helper for TObject',
  17593. ' class property B[Index: longint]: longint read GetB write SetB; default;',
  17594. ' end;',
  17595. 'class function TObject.GetB(Index: longint): longint;',
  17596. 'begin',
  17597. 'end;',
  17598. 'class procedure TObject.SetB(Index: longint; Value: longint);',
  17599. 'begin',
  17600. ' if Value=TObject[Index] then ;',
  17601. ' TObject[Index]:=Value;',
  17602. 'end;',
  17603. 'var c: TClass;',
  17604. 'begin',
  17605. ' c[3]:=4;',
  17606. ' if c[5]=6 then;',
  17607. ' if 7=c[8] then;',
  17608. '']);
  17609. ParseProgram;
  17610. end;
  17611. procedure TTestResolver.TestClassHelper_MultiHelpers;
  17612. begin
  17613. StartProgram(false);
  17614. Add([
  17615. '{$modeswitch multihelpers}',
  17616. 'type',
  17617. ' TObject = class',
  17618. ' end;',
  17619. ' TFlyHelper = class helper for TObject',
  17620. ' procedure {#Fly}Fly;',
  17621. ' procedure {#FlyMove}Move;',
  17622. ' end;',
  17623. ' TRunHelper = class helper for TObject',
  17624. ' procedure {#Run}Run;',
  17625. ' procedure {#RunMove}Move;',
  17626. ' procedure {#RunBack}Back;',
  17627. ' end;',
  17628. ' TSwimHelper = class helper for TObject',
  17629. ' procedure {#Swim}Swim;',
  17630. ' procedure {#SwimBack}Back;',
  17631. ' end;',
  17632. 'procedure TFlyHelper.Fly; begin end;',
  17633. 'procedure TFlyHelper.Move; begin end;',
  17634. 'procedure TRunHelper.Run; begin end;',
  17635. 'procedure TRunHelper.Move; begin end;',
  17636. 'procedure TRunHelper.Back; begin end;',
  17637. 'procedure TSwimHelper.Swim; begin end;',
  17638. 'procedure TSwimHelper.Back; begin end;',
  17639. 'var o: TObject;',
  17640. 'begin',
  17641. ' o.{@Fly}Fly;',
  17642. ' o.{@Run}Run;',
  17643. ' o.{@Swim}Swim;',
  17644. ' o.{@RunMove}Move;',
  17645. ' o.{@SwimBack}Back;',
  17646. '']);
  17647. ParseProgram;
  17648. end;
  17649. procedure TTestResolver.TestRecordHelper;
  17650. begin
  17651. StartProgram(false);
  17652. Add([
  17653. '{$mode delphi}',
  17654. 'type',
  17655. ' TProc = procedure of object;',
  17656. ' TRec = record',
  17657. ' x: word;',
  17658. ' end;',
  17659. ' TRecHelper = record helper for TRec',
  17660. ' type T = word;',
  17661. ' const',
  17662. ' c: T = 3;',
  17663. ' k: T = 4;',
  17664. ' class var',
  17665. ' v: T;',
  17666. ' w: T;',
  17667. ' procedure Fly;',
  17668. ' end;',
  17669. ' TAnt = word;',
  17670. ' TAntHelper = record helper for TAnt',
  17671. ' end;',
  17672. 'procedure TRecHelper.Fly;',
  17673. 'var',
  17674. ' r: TRec;',
  17675. ' p: TProc;',
  17676. 'begin',
  17677. ' Self:=r;',
  17678. ' r:=Self;',
  17679. ' c:=v+x;',
  17680. ' x:=k+w;',
  17681. ' p:=Fly;',
  17682. 'end;',
  17683. 'var',
  17684. ' r: TRec;',
  17685. ' p: TProc;',
  17686. 'begin',
  17687. ' p:=r.Fly;',
  17688. '']);
  17689. ParseProgram;
  17690. end;
  17691. procedure TTestResolver.TestRecordHelper_ForByteFail;
  17692. begin
  17693. StartProgram(false);
  17694. Add([
  17695. '{$mode objfpc}',
  17696. 'type',
  17697. ' TRecHelper = record helper for byte',
  17698. ' class var Glob: word;',
  17699. ' end;',
  17700. 'begin',
  17701. '']);
  17702. CheckResolverException('Type "Byte" cannot be extended by a record helper',nTypeXCannotBeExtendedByARecordHelper);
  17703. end;
  17704. procedure TTestResolver.TestRecordHelper_ClassNonStaticFail;
  17705. begin
  17706. StartProgram(false);
  17707. Add([
  17708. '{$mode delphi}',
  17709. 'type',
  17710. ' TRec = record',
  17711. ' x: word;',
  17712. ' end;',
  17713. ' TRecHelper = record helper for TRec',
  17714. ' class procedure Fly;',
  17715. ' end;',
  17716. 'class procedure TRecHelper.Fly;',
  17717. 'begin',
  17718. 'end;',
  17719. 'begin',
  17720. '']);
  17721. CheckResolverException('Class methods must be static in record helper',nClassMethodsMustBeStaticInX);
  17722. end;
  17723. procedure TTestResolver.TestRecordHelper_InheritedObjFPC;
  17724. begin
  17725. StartProgram(false);
  17726. Add([
  17727. '{$mode objfpc}',
  17728. '{$modeswitch advancedrecords}',
  17729. 'type',
  17730. ' TRec = record',
  17731. ' procedure {#TRec_Fly}Fly;',
  17732. ' end;',
  17733. ' TRecHelper = record helper for TRec',
  17734. ' procedure {#TRecHelper_Fly}Fly;',
  17735. ' procedure {#TRecHelper_Walk}Walk;',
  17736. ' procedure {#TRecHelper_Run}Run;',
  17737. ' end;',
  17738. ' TEagleHelper = record helper(TRecHelper) for TRec',
  17739. ' procedure {#TEagleHelper_Fly}Fly;',
  17740. ' procedure {#TEagleHelper_Run}Run;',
  17741. ' end;',
  17742. 'procedure TRec.fly;',
  17743. 'begin',
  17744. 'end;',
  17745. 'procedure TRechelper.fly;',
  17746. 'begin',
  17747. ' {@TRec_Fly}inherited;',
  17748. ' inherited {@TRec_Fly}Fly;',
  17749. 'end;',
  17750. 'procedure TRechelper.walk;',
  17751. 'begin',
  17752. ' inherited;', // ignore
  17753. 'end;',
  17754. 'procedure TRechelper.run;',
  17755. 'begin',
  17756. ' inherited;', // ignore
  17757. 'end;',
  17758. 'procedure teagleHelper.fly;',
  17759. 'begin',
  17760. ' {@TRec_Fly}inherited;',
  17761. ' inherited {@TRec_Fly}Fly;',
  17762. 'end;',
  17763. 'procedure teagleHelper.run;',
  17764. 'begin',
  17765. ' {@TRecHelper_Run}inherited;',
  17766. ' inherited {@TRecHelper_Run}Run;',
  17767. 'end;',
  17768. 'var',
  17769. ' r: TRec;',
  17770. 'begin',
  17771. ' r.{@TEagleHelper_Fly}Fly;',
  17772. ' r.{@TRecHelper_Walk}Walk;',
  17773. ' r.{@TEagleHelper_Run}Run;',
  17774. '']);
  17775. ParseProgram;
  17776. end;
  17777. procedure TTestResolver.TestRecordHelper_Constructor_NewInstance;
  17778. var
  17779. aMarker: PSrcMarker;
  17780. Elements: TFPList;
  17781. ActualNewInstance: Boolean;
  17782. i: Integer;
  17783. El: TPasElement;
  17784. Ref: TResolvedReference;
  17785. begin
  17786. StartProgram(false);
  17787. Add([
  17788. '{$modeswitch advancedrecords}',
  17789. '{$modeswitch typehelpers}',
  17790. 'type',
  17791. ' TRec = record',
  17792. ' constructor Create(w: word);',
  17793. ' class function DoSome: TRec; static;',
  17794. ' end;',
  17795. 'constructor TRec.Create(w: word);',
  17796. 'begin',
  17797. ' {#a}Create(1); // normal call',
  17798. ' TRec.{#b}Create(2); // new instance',
  17799. 'end;',
  17800. 'class function TRec.DoSome: TRec;',
  17801. 'begin',
  17802. ' Result:={#c}Create(3); // new instance',
  17803. 'end;',
  17804. 'var',
  17805. ' r: TRec;',
  17806. 'begin',
  17807. ' TRec.{#p}Create(4); // new object',
  17808. ' r:=TRec.{#q}Create(5); // new object',
  17809. ' with TRec do begin',
  17810. ' {#r}Create(6); // new object',
  17811. ' r:={#s}Create(7); // new object',
  17812. ' end;',
  17813. ' r.{#t}Create(8); // normal call',
  17814. ' r:=r.{#u}Create(9); // normal call',
  17815. ' with r do begin',
  17816. ' {#v}Create(10); // normal call',
  17817. ' r:={#w}Create(11); // normal call',
  17818. ' end;',
  17819. '']);
  17820. ParseProgram;
  17821. aMarker:=FirstSrcMarker;
  17822. while aMarker<>nil do
  17823. begin
  17824. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  17825. Elements:=FindElementsAt(aMarker);
  17826. try
  17827. ActualNewInstance:=false;
  17828. for i:=0 to Elements.Count-1 do
  17829. begin
  17830. El:=TPasElement(Elements[i]);
  17831. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  17832. if not (El.CustomData is TResolvedReference) then continue;
  17833. Ref:=TResolvedReference(El.CustomData);
  17834. if not (Ref.Declaration is TPasProcedure) then continue;
  17835. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  17836. if (Ref.Declaration is TPasConstructor) then
  17837. ActualNewInstance:=rrfNewInstance in Ref.Flags;
  17838. if rrfImplicitCallWithoutParams in Ref.Flags then
  17839. RaiseErrorAtSrcMarker('unexpected implicit call at "#'+aMarker^.Identifier+' ref"',aMarker);
  17840. break;
  17841. end;
  17842. case aMarker^.Identifier of
  17843. 'a','t','u','v','w':// should be normal call
  17844. if ActualNewInstance then
  17845. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got newinstance"',aMarker);
  17846. else // should be newinstance
  17847. if not ActualNewInstance then
  17848. RaiseErrorAtSrcMarker('expected newinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  17849. end;
  17850. finally
  17851. Elements.Free;
  17852. end;
  17853. aMarker:=aMarker^.Next;
  17854. end;
  17855. end;
  17856. procedure TTestResolver.TestTypeHelper;
  17857. begin
  17858. StartProgram(false);
  17859. Add([
  17860. '{$modeswitch typehelpers}',
  17861. 'type',
  17862. ' TStringHelper = type helper for string',
  17863. ' end;',
  17864. ' TCaption = string;',
  17865. ' TCapHelper = type helper(TStringHelper) for TCaption',
  17866. ' procedure Fly;',
  17867. ' end;',
  17868. ' TProc = procedure of object;',
  17869. 'procedure TCapHelper.Fly; begin end;',
  17870. 'var',
  17871. ' c: TCaption;',
  17872. ' p: TProc;',
  17873. 'begin',
  17874. ' c.Fly;',
  17875. ' p:[email protected];',
  17876. '']);
  17877. ParseProgram;
  17878. end;
  17879. procedure TTestResolver.TestTypeHelper_HelperForProcTypeFail;
  17880. begin
  17881. StartProgram(false);
  17882. Add([
  17883. '{$modeswitch typehelpers}',
  17884. 'type',
  17885. ' TProc = procedure;',
  17886. ' THelper = type helper for TProc',
  17887. ' end;',
  17888. 'begin',
  17889. '']);
  17890. CheckResolverException('Type "TProc" cannot be extended by a type helper',
  17891. nTypeXCannotBeExtendedByATypeHelper);
  17892. end;
  17893. procedure TTestResolver.TestTypeHelper_DefaultPropertyFail;
  17894. begin
  17895. StartProgram(false);
  17896. Add([
  17897. '{$modeswitch typehelpers}',
  17898. 'type',
  17899. ' TStringHelper = type helper for string',
  17900. ' end;',
  17901. ' TCaption = string;',
  17902. ' TCapHelper = type helper(TStringHelper) for TCaption',
  17903. ' function GetItems(Index: boolean): boolean;',
  17904. ' property Items[Index: boolean]: boolean read GetItems; default;',
  17905. ' end;',
  17906. 'function TCapHelper.GetItems(Index: boolean): boolean; begin end;',
  17907. 'begin',
  17908. '']);
  17909. CheckResolverException('Default property not allowed in helper for TCaption',
  17910. nDefaultPropertyNotAllowedInHelperForX);
  17911. end;
  17912. procedure TTestResolver.TestTypeHelper_Enum;
  17913. begin
  17914. StartProgram(false);
  17915. Add([
  17916. '{$modeswitch typehelpers}',
  17917. 'type',
  17918. ' TFlag = (Red, Green, Blue);',
  17919. ' THelper = type helper for TFlag',
  17920. ' function toString: string;',
  17921. ' class procedure Fly; static;',
  17922. ' end;',
  17923. 'function THelper.toString: string;',
  17924. 'begin',
  17925. ' Self:=Red;',
  17926. ' if Self=TFlag.Blue then ;',
  17927. ' Result:=str(Self);',
  17928. 'end;',
  17929. 'class procedure THelper.Fly;',
  17930. 'begin',
  17931. 'end;',
  17932. 'var',
  17933. ' f: TFlag;',
  17934. 'begin',
  17935. ' f.toString;',
  17936. ' green.toString;',
  17937. ' TFlag.green.toString;',
  17938. ' TFlag.Fly;',
  17939. '']);
  17940. ParseProgram;
  17941. end;
  17942. procedure TTestResolver.TestTypeHelper_EnumDotValueFail;
  17943. begin
  17944. StartProgram(false);
  17945. Add([
  17946. '{$modeswitch typehelpers}',
  17947. 'type',
  17948. ' TFlag = (Red, Green, Blue);',
  17949. ' THelper = type helper for TFlag',
  17950. ' end;',
  17951. 'var',
  17952. ' f: TFlag;',
  17953. 'begin',
  17954. ' f:=f.red;',
  17955. '']);
  17956. CheckResolverException('identifier not found "red"',nIdentifierNotFound);
  17957. end;
  17958. procedure TTestResolver.TestTypeHelper_EnumHelperDotProcFail;
  17959. begin
  17960. StartProgram(false);
  17961. Add([
  17962. '{$modeswitch typehelpers}',
  17963. 'type',
  17964. ' TFlag = (Red, Green, Blue);',
  17965. ' THelper = type helper for TFlag',
  17966. ' procedure Fly;',
  17967. ' end;',
  17968. 'procedure THelper.Fly;',
  17969. 'begin',
  17970. 'end;',
  17971. 'begin',
  17972. ' TFlag.Fly;',
  17973. '']);
  17974. CheckResolverException('Instance member "Fly" inaccessible here',
  17975. nInstanceMemberXInaccessible);
  17976. end;
  17977. procedure TTestResolver.TestTypeHelper_Set;
  17978. begin
  17979. StartProgram(false);
  17980. Add([
  17981. '{$modeswitch typehelpers}',
  17982. 'type',
  17983. ' TEnum = (Red, Green, Blue);',
  17984. ' TSetOfEnum = set of TEnum;',
  17985. ' THelper = type helper for TSetOfEnum',
  17986. ' procedure Fly;',
  17987. ' class procedure Run; static;',
  17988. ' end;',
  17989. 'procedure THelper.Fly;',
  17990. 'begin',
  17991. ' Self:=[];',
  17992. ' Self:=[green];',
  17993. ' Include(Self,blue);',
  17994. 'end;',
  17995. 'class procedure THelper.Run;',
  17996. 'begin',
  17997. 'end;',
  17998. 'var s: TSetOfEnum;',
  17999. 'begin',
  18000. ' s.Fly;',
  18001. //' with s do Fly;',
  18002. ' TSetOfEnum.Run;',
  18003. //' with TSetOfEnum do Run;',
  18004. //' [green].Fly', not supported
  18005. '']);
  18006. ParseProgram;
  18007. end;
  18008. procedure TTestResolver.TestTypeHelper_Enumerator;
  18009. begin
  18010. StartProgram(false);
  18011. Add([
  18012. '{$modeswitch typehelpers}',
  18013. 'type',
  18014. ' TObject = class end;',
  18015. ' TItem = byte;',
  18016. ' TEnumerator = class',
  18017. ' FCurrent: TItem;',
  18018. ' property Current: TItem read FCurrent;',
  18019. ' function MoveNext: boolean;',
  18020. ' end;',
  18021. ' TWordHelper = type helper for Word',
  18022. ' function GetEnumerator: TEnumerator;',
  18023. ' end;',
  18024. 'function TEnumerator.MoveNext: boolean;',
  18025. 'begin',
  18026. 'end;',
  18027. 'function TWordHelper.GetEnumerator: TEnumerator;',
  18028. 'begin',
  18029. ' if Self=2 then ;',
  18030. ' Self:=Self+3;',
  18031. 'end;',
  18032. 'var',
  18033. ' w: word;',
  18034. ' i: TItem;',
  18035. ' {#i2}i2: TItem;',
  18036. 'begin',
  18037. ' w.GetEnumerator;',
  18038. ' for i in w do {@i2}i2:=i;']);
  18039. ParseProgram;
  18040. end;
  18041. procedure TTestResolver.TestTypeHelper_String;
  18042. begin
  18043. StartProgram(false);
  18044. Add([
  18045. '{$modeswitch typehelpers}',
  18046. 'type',
  18047. ' TStringHelper = type helper for String',
  18048. ' procedure DoIt;',
  18049. ' end;',
  18050. ' TCharHelper = type helper for char',
  18051. ' procedure Fly;',
  18052. ' end;',
  18053. 'procedure TStringHelper.DoIt;',
  18054. 'begin',
  18055. ' Self[1]:=Self[2];',
  18056. 'end;',
  18057. 'procedure TCharHelper.Fly;',
  18058. 'begin',
  18059. ' Self:=''c'';',
  18060. ' Self:=Self;',
  18061. 'end;',
  18062. 'begin',
  18063. ' ''abc''.DoIt;',
  18064. ' ''xyz''.DoIt();',
  18065. ' ''c''.Fly;',
  18066. '']);
  18067. ParseProgram;
  18068. end;
  18069. procedure TTestResolver.TestTypeHelper_StringOtherUnit;
  18070. begin
  18071. AddModuleWithIntfImplSrc('unit2.pas',
  18072. LinesToStr([
  18073. '{$modeswitch typehelpers}',
  18074. 'type',
  18075. ' TStringHelper = type helper for String',
  18076. ' procedure DoIt;',
  18077. ' end;',
  18078. ' TCharHelper = type helper for char',
  18079. ' procedure Fly;',
  18080. ' end;',
  18081. '']),
  18082. LinesToStr([
  18083. 'procedure TStringHelper.DoIt;',
  18084. 'begin',
  18085. ' Self[1]:=Self[2];',
  18086. 'end;',
  18087. 'procedure TCharHelper.Fly;',
  18088. 'begin',
  18089. ' Self:=''c'';',
  18090. ' Self:=Self;',
  18091. 'end;',
  18092. '']));
  18093. StartProgram(true);
  18094. Add([
  18095. 'uses unit2;',
  18096. 'var s: string;',
  18097. 'begin',
  18098. ' ''abc''.DoIt;',
  18099. ' ''xyz''.DoIt();',
  18100. ' ''c''.Fly;',
  18101. ' s.DoIt;',
  18102. '']);
  18103. ParseProgram;
  18104. end;
  18105. procedure TTestResolver.TestTypeHelper_Boolean;
  18106. begin
  18107. StartProgram(false);
  18108. Add([
  18109. '{$modeswitch typehelpers}',
  18110. 'type',
  18111. ' THelper = type helper for boolean',
  18112. ' procedure DoIt;',
  18113. ' end;',
  18114. 'procedure THelper.DoIt;',
  18115. 'begin',
  18116. ' Self:=not Self;',
  18117. 'end;',
  18118. 'begin',
  18119. ' false.DoIt;',
  18120. ' true.DoIt();']);
  18121. ParseProgram;
  18122. end;
  18123. procedure TTestResolver.TestTypeHelper_Double;
  18124. begin
  18125. StartProgram(false);
  18126. Add([
  18127. '{$modeswitch typehelpers}',
  18128. 'type',
  18129. ' Float = double;',
  18130. ' THelper = type helper for float',
  18131. ' const NPI = 3.141592;',
  18132. ' function ToStr: String;',
  18133. ' end;',
  18134. 'function THelper.ToStr: String;',
  18135. 'begin',
  18136. 'end;',
  18137. 'var',
  18138. ' a,b: Float;',
  18139. ' s: string;',
  18140. 'begin',
  18141. ' s:=(a * b.NPI).ToStr;',
  18142. ' s:=(a * float.NPI).ToStr;',
  18143. ' s:=float.NPI.ToStr;',
  18144. ' s:=3.2.ToStr;',
  18145. '']);
  18146. ParseProgram;
  18147. end;
  18148. procedure TTestResolver.TestTypeHelper_DoubleAlias;
  18149. begin
  18150. StartProgram(false);
  18151. Add([
  18152. '{$modeswitch typehelpers}',
  18153. 'type',
  18154. ' Float = type double;',
  18155. ' THelper = type helper for float',
  18156. ' const NPI = 3.141592;',
  18157. ' function ToStr: String;',
  18158. ' end;',
  18159. 'function THelper.ToStr: String;',
  18160. 'begin',
  18161. 'end;',
  18162. 'var',
  18163. ' a,b: Float;',
  18164. ' s: string;',
  18165. 'begin',
  18166. ' s:=(a * b.NPI).ToStr;',
  18167. ' s:=(a * float.NPI).ToStr;',
  18168. '']);
  18169. ParseProgram;
  18170. end;
  18171. procedure TTestResolver.TestTypeHelper_Constructor_NewInstance;
  18172. var
  18173. aMarker: PSrcMarker;
  18174. Elements: TFPList;
  18175. ActualNewInstance: Boolean;
  18176. i: Integer;
  18177. El: TPasElement;
  18178. Ref: TResolvedReference;
  18179. begin
  18180. StartProgram(false);
  18181. Add([
  18182. '{$modeswitch typehelpers}',
  18183. 'type',
  18184. ' TInt = type word;',
  18185. ' THelper = type helper for TInt',
  18186. ' constructor Create(w: TInt);',
  18187. ' class function DoSome: TInt; static;',
  18188. ' end;',
  18189. 'constructor THelper.Create(w: TInt);',
  18190. 'begin',
  18191. ' {#a}Create(1); // normal call',
  18192. ' TInt.{#b}Create(2); // new instance',
  18193. 'end;',
  18194. 'class function THelper.DoSome: TInt;',
  18195. 'begin',
  18196. ' Result:={#c}Create(3); // new instance',
  18197. 'end;',
  18198. 'var',
  18199. ' r: TInt;',
  18200. 'begin',
  18201. ' TInt.{#p}Create(4); // new object',
  18202. ' r:=TInt.{#q}Create(5); // new object',
  18203. ' with TInt do begin',
  18204. ' {#r}Create(6); // new object',
  18205. ' r:={#s}Create(7); // new object',
  18206. ' end;',
  18207. ' r.{#t}Create(8); // normal call',
  18208. ' r:=r.{#u}Create(9); // normal call',
  18209. ' with r do begin',
  18210. ' {#v}Create(10); // normal call',
  18211. ' r:={#w}Create(11); // normal call',
  18212. ' end;',
  18213. '']);
  18214. ParseProgram;
  18215. aMarker:=FirstSrcMarker;
  18216. while aMarker<>nil do
  18217. begin
  18218. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',aMarker^.Identifier,' ',aMarker^.StartCol,' ',aMarker^.EndCol);
  18219. Elements:=FindElementsAt(aMarker);
  18220. try
  18221. ActualNewInstance:=false;
  18222. for i:=0 to Elements.Count-1 do
  18223. begin
  18224. El:=TPasElement(Elements[i]);
  18225. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',aMarker^.Identifier,' ',i,'/',Elements.Count,' El=',GetObjName(El),' ',GetObjName(El.CustomData));
  18226. if not (El.CustomData is TResolvedReference) then continue;
  18227. Ref:=TResolvedReference(El.CustomData);
  18228. if not (Ref.Declaration is TPasProcedure) then continue;
  18229. //writeln('TTestResolver.TestAdvRecord_Constructor_NewInstance ',GetObjName(Ref.Declaration),' rrfNewInstance=',rrfNewInstance in Ref.Flags);
  18230. if (Ref.Declaration is TPasConstructor) then
  18231. ActualNewInstance:=rrfNewInstance in Ref.Flags;
  18232. if rrfImplicitCallWithoutParams in Ref.Flags then
  18233. RaiseErrorAtSrcMarker('unexpected implicit call at "#'+aMarker^.Identifier+' ref"',aMarker);
  18234. break;
  18235. end;
  18236. case aMarker^.Identifier of
  18237. 'a','t','u','v','w':// should be normal call
  18238. if ActualNewInstance then
  18239. RaiseErrorAtSrcMarker('expected normal call at "#'+aMarker^.Identifier+', but got newinstance"',aMarker);
  18240. else // should be newinstance
  18241. if not ActualNewInstance then
  18242. RaiseErrorAtSrcMarker('expected newinstance at "#'+aMarker^.Identifier+', but got normal call"',aMarker);
  18243. end;
  18244. finally
  18245. Elements.Free;
  18246. end;
  18247. aMarker:=aMarker^.Next;
  18248. end;
  18249. end;
  18250. procedure TTestResolver.TestTypeHelper_Interface;
  18251. begin
  18252. StartProgram(false);
  18253. Add([
  18254. '{$modeswitch typehelpers}',
  18255. 'type',
  18256. ' IUnknown = interface',
  18257. ' function GetSizes(Index: word): word;',
  18258. ' procedure SetSizes(Index: word; value: word);',
  18259. ' end;',
  18260. ' TObject = class(IUnknown)',
  18261. ' function GetSizes(Index: word): word; virtual; abstract;',
  18262. ' procedure SetSizes(Index: word; value: word); virtual; abstract;',
  18263. ' end;',
  18264. ' THelper = type helper for IUnknown',
  18265. ' procedure Fly;',
  18266. ' class procedure Run; static;',
  18267. ' property Sizes[Index: word]: word read GetSizes write SetSizes; default;',
  18268. ' end;',
  18269. 'var',
  18270. ' i: IUnknown;',
  18271. ' o: TObject;',
  18272. 'procedure THelper.Fly;',
  18273. 'begin',
  18274. ' i:=Self;',
  18275. ' o:=Self as TObject;',
  18276. ' Self:=nil;',
  18277. ' Self:=i;',
  18278. ' Self:=o;',
  18279. 'end;',
  18280. 'class procedure THelper.Run;',
  18281. 'begin',
  18282. 'end;',
  18283. 'begin',
  18284. ' i.Fly;',
  18285. ' i.Fly();',
  18286. ' i.Run;',
  18287. ' i.Run();',
  18288. ' i.Sizes[3]:=i.Sizes[4];',
  18289. ' i[5]:=i[6];',
  18290. ' IUnknown.Run;',
  18291. ' IUnknown.Run();',
  18292. '']);
  18293. ParseProgram;
  18294. end;
  18295. procedure TTestResolver.TestTypeHelper_Interface_ConstructorFail;
  18296. begin
  18297. StartProgram(false);
  18298. Add([
  18299. '{$modeswitch typehelpers}',
  18300. 'type',
  18301. ' IUnknown = interface',
  18302. ' end;',
  18303. ' THelper = type helper for IUnknown',
  18304. ' constructor Fly;',
  18305. ' end;',
  18306. 'constructor THelper.Fly;',
  18307. 'begin',
  18308. 'end;',
  18309. 'begin',
  18310. '']);
  18311. CheckResolverException('constructor is not supported',nXIsNotSupported);
  18312. end;
  18313. procedure TTestResolver.TestTypeHelper_TypeAliasType;
  18314. begin
  18315. StartProgram(false);
  18316. Add([
  18317. '{$modeswitch typehelpers}',
  18318. 'type',
  18319. ' TEnum = type longint;',
  18320. ' TIntHelper = type helper for longint',
  18321. ' procedure Run;',
  18322. ' end;',
  18323. ' TEnumHelper = type helper for TEnum',
  18324. ' procedure Fly;',
  18325. ' end;',
  18326. 'procedure TIntHelper.Run;',
  18327. 'begin',
  18328. 'end;',
  18329. 'procedure TEnumHelper.Fly;',
  18330. 'begin',
  18331. 'end;',
  18332. 'var',
  18333. ' e: TEnum;',
  18334. ' i: longint;',
  18335. 'begin',
  18336. ' i.Run;',
  18337. ' e.Fly;',
  18338. ' with i do Run;',
  18339. ' with e do Fly;',
  18340. '']);
  18341. ParseProgram;
  18342. end;
  18343. procedure TTestResolver.TestAttributes_Globals;
  18344. begin
  18345. StartProgram(false);
  18346. Add([
  18347. '{$modeswitch prefixedattributes}',
  18348. 'type',
  18349. ' TObject = class',
  18350. ' constructor {#TObject_Create}Create;',
  18351. ' end;',
  18352. ' {#Custom}TCustomAttribute = class',
  18353. ' end;',
  18354. ' {#Red}RedAttribute = class(TCustomAttribute)',
  18355. ' constructor {#Red_A}Create(Id: word = 3; Deep: boolean = false); overload;',
  18356. ' constructor {#Red_B}Create(Size: double); overload;',
  18357. ' end;',
  18358. ' Red = word;',
  18359. 'constructor TObject.Create; begin end;',
  18360. 'constructor RedAttribute.Create(Id: word; Deep: boolean); begin end;',
  18361. 'constructor RedAttribute.Create(Size: double); begin end;',
  18362. 'var',
  18363. ' [{#Attr__Custom__TObject_Create}TCustom]',
  18364. ' [{#Attr__Red__Red_A__1}Red,afile.{#Attr__Red__Red_A__2}Red]',
  18365. ' o: TObject;',
  18366. 'const',
  18367. ' [{#Attr__Red__Red_B}RedAttribute(1.3)]',
  18368. ' c = 3;',
  18369. 'begin',
  18370. '']);
  18371. ParseProgram;
  18372. CheckAttributeMarkers;
  18373. CheckResolverUnexpectedHints;
  18374. end;
  18375. procedure TTestResolver.TestAttributes_NonConstParam_Fail;
  18376. begin
  18377. StartProgram(false);
  18378. Add([
  18379. '{$modeswitch prefixedattributes}',
  18380. 'type',
  18381. ' TObject = class',
  18382. ' constructor Create(w: word);',
  18383. ' end;',
  18384. ' TCustomAttribute = class',
  18385. ' end;',
  18386. 'constructor TObject.Create(w: word);',
  18387. 'begin',
  18388. 'end;',
  18389. 'var',
  18390. ' w: word;',
  18391. ' [TCustom(w)]',
  18392. ' o: TObject;',
  18393. 'begin',
  18394. '']);
  18395. CheckResolverException(sConstantExpressionExpected,nConstantExpressionExpected);
  18396. end;
  18397. procedure TTestResolver.TestAttributes_UnknownAttrWarning;
  18398. begin
  18399. StartProgram(false);
  18400. Add([
  18401. '{$modeswitch prefixedattributes}',
  18402. 'type',
  18403. ' TObject = class',
  18404. ' end;',
  18405. ' TCustomAttribute = class',
  18406. ' end;',
  18407. 'var',
  18408. ' [Red]',
  18409. ' o: TObject;',
  18410. 'begin',
  18411. '']);
  18412. ParseProgram;
  18413. CheckResolverHint(mtWarning,nUnknownCustomAttributeX,'Unknown custom attribute "Red"');
  18414. end;
  18415. procedure TTestResolver.TestAttributes_Members;
  18416. begin
  18417. StartProgram(false);
  18418. Add([
  18419. '{$modeswitch prefixedattributes}',
  18420. 'type',
  18421. ' TObject = class',
  18422. ' constructor {#create}Create;',
  18423. ' end;',
  18424. ' {#custom}TCustomAttribute = class',
  18425. ' end;',
  18426. ' TMyClass = class',
  18427. ' [{#attr__custom__create__cl}TCustom]',
  18428. ' Field: word;',
  18429. ' end;',
  18430. ' TMyRecord = record',
  18431. ' [{#attr__custom__create__rec}TCustom]',
  18432. ' Field: word;',
  18433. ' end;',
  18434. 'constructor TObject.Create;',
  18435. 'begin',
  18436. 'end;',
  18437. 'begin',
  18438. '']);
  18439. ParseProgram;
  18440. CheckAttributeMarkers;
  18441. end;
  18442. procedure TTestResolver.TestAttributes_MethodParams;
  18443. begin
  18444. StartProgram(false);
  18445. Add([
  18446. '{$modeswitch prefixedattributes}',
  18447. 'type',
  18448. ' TObject = class',
  18449. ' constructor {#create}Create;',
  18450. ' end;',
  18451. ' {#custom}TCustomAttribute = class',
  18452. ' end;',
  18453. ' TMyClass = class',
  18454. ' procedure Fly([{#attr__custom__create__size}TCustom]Size: word);',
  18455. ' procedure Eat(const [ref] Portion: word);',
  18456. ' end;',
  18457. 'constructor TObject.Create;',
  18458. 'begin',
  18459. 'end;',
  18460. 'procedure TMyClass.Fly(Size: word);',
  18461. 'begin',
  18462. 'end;',
  18463. 'procedure TMyClass.Eat(const [ref] Portion: word);',
  18464. 'begin',
  18465. 'end;',
  18466. 'begin',
  18467. '']);
  18468. ParseProgram;
  18469. CheckAttributeMarkers;
  18470. CheckResolverUnexpectedHints;
  18471. end;
  18472. procedure TTestResolver.TestAttributes_MethodParamsGroup;
  18473. begin
  18474. StartProgram(false);
  18475. Add([
  18476. '{$modeswitch prefixedattributes}',
  18477. 'type',
  18478. ' TObject = class',
  18479. ' constructor {#create}Create;',
  18480. ' end;',
  18481. ' {#custom}TCustomAttribute = class',
  18482. ' end;',
  18483. ' TMyClass = class',
  18484. ' procedure Fly([{#attr__custom__create__size}TCustom]Speed, Dist: word);',
  18485. ' end;',
  18486. 'constructor TObject.Create;',
  18487. 'begin',
  18488. 'end;',
  18489. 'procedure TMyClass.Fly(Speed, Dist: word);',
  18490. 'begin',
  18491. 'end;',
  18492. 'begin',
  18493. '']);
  18494. ParseProgram;
  18495. CheckAttributeMarkers;
  18496. CheckResolverUnexpectedHints;
  18497. end;
  18498. procedure TTestResolver.TestLibrary_Empty;
  18499. begin
  18500. StartLibrary(false);
  18501. Add(['begin']);
  18502. ParseLibrary;
  18503. end;
  18504. procedure TTestResolver.TestLibrary_ExportFunc;
  18505. begin
  18506. StartLibrary(false);
  18507. Add([
  18508. 'procedure Run;',
  18509. 'begin',
  18510. 'end;',
  18511. 'procedure Fly;',
  18512. 'begin',
  18513. 'end;',
  18514. 'exports',
  18515. ' Run,',
  18516. ' Fly name ''FlyHi'',',
  18517. ' afile.run name ''Runner'';',
  18518. 'exports',
  18519. ' Run index 3+4;',
  18520. 'begin',
  18521. '']);
  18522. ParseLibrary;
  18523. end;
  18524. procedure TTestResolver.TestLibrary_ExportFunc_NameIntFail;
  18525. begin
  18526. StartLibrary(false);
  18527. Add([
  18528. 'procedure Run;',
  18529. 'begin',
  18530. 'end;',
  18531. 'exports',
  18532. ' Run name 4;',
  18533. 'begin',
  18534. '']);
  18535. CheckResolverException('string expected, but Longint found',nXExpectedButYFound);
  18536. end;
  18537. procedure TTestResolver.TestLibrary_ExportFunc_IndexStringFail;
  18538. begin
  18539. StartLibrary(false);
  18540. Add([
  18541. 'procedure Run;',
  18542. 'begin',
  18543. 'end;',
  18544. 'exports',
  18545. ' Run index ''abc'';',
  18546. 'begin',
  18547. '']);
  18548. CheckResolverException('integer expected, but String found',nXExpectedButYFound);
  18549. end;
  18550. procedure TTestResolver.TestLibrary_ExportVar;
  18551. begin
  18552. StartLibrary(false);
  18553. Add([
  18554. 'var',
  18555. ' Size: word; export name ''size'';',
  18556. ' Fly: string;',
  18557. ' Run: word;',
  18558. 'exports',
  18559. ' Size,',
  18560. ' Fly name ''FlyHi'',',
  18561. ' Run index 3+4;',
  18562. 'begin',
  18563. '']);
  18564. ParseLibrary;
  18565. end;
  18566. procedure TTestResolver.TestLibrary_ExportLocalFuncFail;
  18567. begin
  18568. StartLibrary(false);
  18569. Add([
  18570. 'procedure Run;',
  18571. 'exports',
  18572. ' Run;',
  18573. 'begin',
  18574. 'end;',
  18575. 'begin',
  18576. '']);
  18577. CheckParserException('Expected "begin"',nParserExpectTokenError);
  18578. end;
  18579. procedure TTestResolver.TestLibrary_Initialization_Finalization;
  18580. begin
  18581. StartLibrary(false);
  18582. Add([
  18583. 'procedure Run(w: word);',
  18584. 'begin',
  18585. 'end;',
  18586. 'exports',
  18587. ' Run;',
  18588. 'initialization',
  18589. ' Run(3);',
  18590. 'finalization',
  18591. ' Run(4);',
  18592. '']);
  18593. ParseLibrary;
  18594. end;
  18595. procedure TTestResolver.TestLibrary_ExportFuncOverloadFail;
  18596. begin
  18597. StartLibrary(false);
  18598. Add([
  18599. 'procedure Run(w: word); overload;',
  18600. 'begin',
  18601. 'end;',
  18602. 'procedure Run(d: double); overload;',
  18603. 'begin',
  18604. 'end;',
  18605. 'exports',
  18606. ' Run,',
  18607. ' afile.run;',
  18608. 'begin']);
  18609. CheckResolverException(sCantDetermineWhichOverloadedFunctionToCall,
  18610. nCantDetermineWhichOverloadedFunctionToCall);
  18611. end;
  18612. procedure TTestResolver.TestLibrary_UnitExports;
  18613. begin
  18614. StartUnit(false);
  18615. Add([
  18616. 'interface' ,
  18617. 'procedure Run;',
  18618. 'implementation',
  18619. 'procedure Run;',
  18620. 'begin',
  18621. 'end;',
  18622. 'exports',
  18623. ' Run;',
  18624. '']);
  18625. ParseUnit;
  18626. end;
  18627. initialization
  18628. RegisterTests([TTestResolver]);
  18629. end.