102030405060708090100110120130140150160170180190200210220230240250260270281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751760770780790800810820830840850860870880890900910920930940950960970980990100010101020103010401050106010701080109011001110112011301140115011601170118011901200121012201230124012501260127012801290130013101320133013401350136013701380139014001410142014301440145014601470148014901500151015201530154015501560157015801590160016101620163016401650166016701680169017001710172017301740175017601770178017901800181018201830184018501860187018801890190019101920193019401950196019701980199020002010202020302040205020602070208020902100211021202130214021502160217021802190220022102220223022402250226022702280229023002310232023302340235023602370238023902400241024202430244024502460247024802490250025102520253025402550256025702580259026002610262026302640265026602670268026902700271027202730274027502760277027802790280028102820283028402850286028702880289029002910292029302940295029602970298029903000301030203030304030503060307030803090310031103120313031403150316031703180319032003210322032303240325032603270328032903300331033203330334033503360337033803390340034103420343034403450346034703480349035003510352035303540355035603570358035903600361036203630364036503660367036803690370037103720373037403750376037703780379038003810382038303840385038603870388038903900391039203930394039503960397039803990400040104020403040404050406040704080409041004110412041304140415041604170418041904200421042204230424042504260427042804290430043104320433043404350436043704380439044004410442044304440445044604470448044904500451045204530454045504560457045804590460046104620463046404650466046704680469047004710472047304740475047604770478047904800481048204830484048504860487048804890490049104920493049404950496049704980499050005010502050305040505050605070508050905100511051205130514051505160517051805190520052105220523052405250526052705280529053005310532053305340535053605370538053905400541054205430544054505460547054805490550055105520553055405550556055705580559056005610562056305640565056605670568056905700571057205730574057505760577057805790580058105820583058405850586058705880589059005910592059305940595059605970598059906000601060206030604060506060607060806090610061106120613061406150616061706180619062006210622062306240625062606270628062906300631063206330634063506360637063806390640064106420643064406450646064706480649065006510652065306540655065606570658065906600661066206630664066506660667066806690670067106720673067406750676067706780679068006810682068306840685068606870688068906900691069206930694069506960697069806990700070107020703070407050706070707080709071007110712071307140715071607170718071907200721072207230724072507260727072807290730073107320733073407350736073707380739074007410742074307440745074607470748074907500751075207530754075507560757075807590760076107620763076407650766076707680769077007710772077307740775077607770778077907800781078207830784078507860787078807890790079107920793079407950796079707980799080008010802080308040805080608070808080908100811081208130814081508160817081808190820082108220823082408250826082708280829083008310832083308340835083608370838083908400841084208430844084508460847084808490850085108520853085408550856085708580859086008610862086308640865086608670868086908700871087208730874087508760877087808790880088108820883088408850886088708880889089008910892089308940895089608970898089909000901090209030904090509060907090809090910091109120913091409150916091709180919092009210922092309240925092609270928092909300931093209330934093509360937093809390940094109420943094409450946094709480949095009510952095309540955095609570958095909600961096209630964096509660967096809690970097109720973097409750976097709780979098009810982098309840985098609870988098909900991099209930994099509960997099809990100001001010020100301004010050100601007010080100901010010110101201013010140101501016010170101801019010200102101022010230102401025010260102701028010290103001031010320103301034010350103601037010380103901040010410104201043010440104501046010470104801049010500105101052010530105401055010560105701058010590106001061010620106301064010650106601067010680106901070010710107201073010740107501076010770107801079010800108101082010830108401085010860108701088010890109001091010920109301094010950109601097010980109901100011010110201103011040110501106011070110801109011100111101112011130111401115011160111701118011190112001121011220112301124011250112601127011280112901130011310113201133011340113501136011370113801139011400114101142011430114401145011460114701148011490115001151011520115301154011550115601157011580115901160011610116201163011640116501166011670116801169011700117101172011730117401175011760117701178011790118001181011820118301184011850118601187011880118901190011910119201193011940119501196011970119801199012000120101202012030120401205012060120701208012090121001211012120121301214012150121601217012180121901220012210122201223012240122501226012270122801229012300123101232012330123401235012360123701238012390124001241012420124301244012450124601247012480124901250012510125201253012540125501256012570125801259012600126101262012630126401265012660126701268012690127001271012720127301274012750127601277012780127901280012810128201283012840128501286012870128801289012900129101292012930129401295012960129701298012990130001301013020130301304013050130601307013080130901310013110131201313013140131501316013170131801319013200132101322013230132401325013260132701328013290133001331013320133301334013350133601337013380133901340013410134201343013440134501346013470134801349013500135101352013530135401355013560135701358013590136001361013620136301364013650136601367013680136901370013710137201373013740137501376013770137801379013800138101382013830138401385013860138701388013890139001391013920139301394013950139601397013980139901400014010140201403014040140501406014070140801409014100141101412014130141401415014160141701418014190142001421014220142301424014250142601427014280142901430014310143201433014340143501436014370143801439014400144101442014430144401445014460144701448014490145001451014520145301454014550145601457014580145901460014610146201463014640146501466014670146801469014700147101472014730147401475014760147701478014790148001481014820148301484014850148601487014880148901490014910149201493014940149501496014970149801499015000150101502015030150401505015060150701508015090151001511015120151301514015150151601517015180151901520015210152201523015240152501526015270152801529015300153101532015330153401535015360153701538015390154001541015420154301544015450154601547015480154901550015510155201553015540155501556015570155801559015600156101562015630156401565015660156701568015690157001571015720157301574015750157601577015780157901580015810158201583015840158501586015870158801589015900159101592015930159401595015960159701598015990160001601016020160301604016050160601607016080160901610016110161201613016140161501616016170161801619016200162101622016230162401625016260162701628016290163001631016320163301634016350163601637016380163901640016410164201643016440164501646016470164801649016500165101652016530165401655016560165701658016590166001661016620166301664016650166601667016680166901670016710167201673016740167501676016770167801679016800168101682016830168401685016860168701688016890169001691016920169301694016950169601697016980169901700017010170201703017040170501706017070170801709017100171101712017130171401715017160171701718017190172001721017220172301724017250172601727017280172901730017310173201733017340173501736017370173801739017400174101742017430174401745017460174701748017490175001751017520175301754017550175601757017580175901760017610176201763017640176501766017670176801769017700177101772017730177401775017760177701778017790178001781017820178301784017850178601787017880178901790017910179201793017940179501796017970179801799018000180101802018030180401805018060180701808018090181001811018120181301814018150181601817018180181901820018210182201823018240182501826018270182801829018300183101832018330183401835018360183701838018390184001841018420184301844018450184601847018480184901850018510185201853018540185501856018570185801859018600186101862018630186401865018660186701868018690187001871018720187301874018750187601877018780187901880018810188201883018840188501886018870188801889018900189101892018930189401895018960189701898018990190001901019020190301904019050190601907019080190901910019110191201913019140191501916019170191801919019200192101922019230192401925019260192701928019290193001931019320193301934019350193601937019380193901940019410194201943019440194501946019470194801949019500195101952019530195401955019560195701958019590196001961019620196301964019650196601967019680196901970019710197201973019740197501976019770197801979019800198101982019830198401985019860198701988019890199001991019920199301994019950199601997019980199902000020010200202003020040200502006020070200802009020100201102012020130201402015020160201702018020190202002021020220202302024020250202602027020280202902030020310203202033020340203502036020370203802039020400204102042020430204402045020460204702048020490205002051020520205302054020550205602057020580205902060020610206202063020640206502066020670206802069020700207102072020730207402075020760207702078020790208002081020820208302084020850208602087020880208902090020910209202093020940209502096020970209802099021000210102102021030210402105021060210702108021090211002111021120211302114021150211602117021180211902120021210212202123021240212502126021270212802129021300213102132021330213402135021360213702138021390214002141021420214302144021450214602147021480214902150021510215202153021540215502156021570215802159021600216102162021630216402165021660216702168021690217002171021720217302174021750217602177021780217902180021810218202183021840218502186021870218802189021900219102192021930219402195021960219702198021990220002201022020220302204022050220602207022080220902210022110221202213022140221502216022170221802219022200222102222022230222402225022260222702228022290223002231022320223302234022350223602237022380223902240022410224202243022440224502246022470224802249022500225102252022530225402255022560225702258022590226002261022620226302264022650226602267022680226902270022710227202273022740227502276022770227802279022800228102282022830228402285022860228702288022890229002291022920229302294022950229602297022980229902300023010230202303023040230502306023070230802309023100231102312023130231402315023160231702318023190232002321023220232302324023250232602327023280232902330023310233202333023340233502336023370233802339023400234102342023430234402345023460234702348023490235002351023520235302354023550235602357023580235902360023610236202363023640236502366023670236802369023700237102372023730237402375023760237702378023790238002381023820238302384023850238602387023880238902390023910239202393023940239502396023970239802399024000240102402024030240402405024060240702408024090241002411024120241302414024150241602417024180241902420024210242202423024240242502426024270242802429024300243102432024330243402435024360243702438024390244002441024420244302444024450244602447024480244902450024510245202453024540245502456024570245802459024600246102462024630246402465024660246702468024690247002471024720247302474024750247602477024780247902480024810248202483024840248502486024870248802489024900249102492024930249402495024960249702498024990250002501025020250302504025050250602507025080250902510025110251202513025140251502516025170251802519025200252102522025230252402525025260252702528025290253002531025320253302534025350253602537025380253902540025410254202543025440254502546025470254802549025500255102552025530255402555025560255702558025590256002561025620256302564025650256602567025680256902570025710257202573025740257502576025770257802579025800258102582025830258402585025860258702588025890259002591025920259302594025950259602597025980259902600026010260202603026040260502606026070260802609026100261102612026130261402615026160261702618026190262002621026220262302624026250262602627026280262902630026310263202633026340263502636026370263802639026400264102642026430264402645026460264702648026490265002651026520265302654026550265602657026580265902660026610266202663026640266502666026670266802669026700267102672026730267402675026760267702678026790268002681026820268302684026850268602687026880268902690026910269202693026940269502696026970269802699027000270102702027030270402705027060270702708027090271002711027120271302714027150271602717027180271902720027210272202723027240272502726027270272802729027300273102732027330273402735027360273702738027390274002741027420274302744027450274602747027480274902750027510275202753027540275502756027570275802759027600276102762027630276402765027660276702768027690277002771027720277302774027750277602777027780277902780027810278202783027840278502786027870278802789027900279102792027930279402795027960279702798027990280002801028020280302804028050280602807028080280902810028110281202813028140281502816028170281802819028200282102822028230282402825028260282702828028290283002831028320283302834028350283602837028380283902840028410284202843028440284502846028470284802849028500285102852028530285402855028560285702858028590286002861028620286302864028650286602867028680286902870028710287202873028740287502876028770287802879028800288102882028830288402885028860288702888028890289002891028920289302894028950289602897028980289902900029010290202903029040290502906029070290802909029100291102912029130291402915029160291702918029190292002921029220292302924029250292602927029280292902930029310293202933029340293502936029370293802939029400294102942029430294402945029460294702948029490295002951029520295302954029550295602957029580295902960029610296202963029640296502966029670296802969029700297102972029730297402975029760297702978029790298002981029820298302984029850298602987029880298902990029910299202993029940299502996029970299802999030000300103002030030300403005030060300703008030090301003011030120301303014030150301603017030180301903020030210302203023030240302503026030270302803029030300303103032030330303403035030360303703038030390304003041030420304303044030450304603047030480304903050030510305203053030540305503056030570305803059030600306103062030630306403065030660306703068030690307003071030720307303074030750307603077030780307903080030810308203083030840308503086030870308803089030900309103092030930309403095030960309703098030990310003101031020310303104031050310603107031080310903110031110311203113031140311503116031170311803119031200312103122031230312403125031260312703128031290313003131031320313303134031350313603137031380313903140031410314203143031440314503146031470314803149031500315103152031530315403155031560315703158031590316003161031620316303164031650316603167031680316903170031710317203173031740317503176031770317803179031800318103182031830318403185031860318703188031890319003191031920319303194031950319603197031980319903200032010320203203032040320503206032070320803209032100321103212032130321403215032160321703218032190322003221032220322303224032250322603227032280322903230032310323203233032340323503236032370323803239032400324103242032430324403245032460324703248032490325003251032520325303254032550325603257032580325903260032610326203263032640326503266032670326803269032700327103272032730327403275032760327703278032790328003281032820328303284032850328603287032880328903290032910329203293032940329503296032970329803299033000330103302033030330403305033060330703308033090331003311033120331303314033150331603317033180331903320033210332203323033240332503326033270332803329033300333103332033330333403335033360333703338033390334003341033420334303344033450334603347033480334903350033510335203353033540335503356033570335803359033600336103362033630336403365033660336703368033690337003371033720337303374033750337603377033780337903380033810338203383033840338503386033870338803389033900339103392033930339403395033960339703398033990340003401034020340303404034050340603407034080340903410034110341203413034140341503416034170341803419034200342103422034230342403425034260342703428034290343003431034320343303434034350343603437034380343903440034410344203443034440344503446034470344803449034500345103452034530345403455034560345703458034590346003461034620346303464034650346603467034680346903470034710347203473034740347503476034770347803479034800348103482034830348403485034860348703488034890349003491034920349303494034950349603497034980349903500035010350203503035040350503506035070350803509035100351103512035130351403515035160351703518035190352003521035220352303524035250352603527035280352903530035310353203533035340353503536035370353803539035400354103542035430354403545035460354703548035490355003551035520355303554035550355603557035580355903560035610356203563035640356503566035670356803569035700357103572035730357403575035760357703578035790358003581035820358303584035850358603587035880358903590035910359203593035940359503596035970359803599036000360103602036030360403605036060360703608036090361003611036120361303614036150361603617036180361903620036210362203623036240362503626036270362803629036300363103632036330363403635036360363703638036390364003641036420364303644036450364603647036480364903650036510365203653036540365503656036570365803659036600366103662036630366403665036660366703668036690367003671036720367303674036750367603677036780367903680036810368203683036840368503686036870368803689036900369103692036930369403695036960369703698036990370003701037020370303704037050370603707037080370903710037110371203713037140371503716037170371803719037200372103722037230372403725037260372703728037290373003731037320373303734037350373603737037380373903740037410374203743037440374503746037470374803749037500375103752037530375403755037560375703758037590376003761037620376303764037650376603767037680376903770037710377203773037740377503776037770377803779037800378103782037830378403785037860378703788037890379003791037920379303794037950379603797037980379903800038010380203803038040380503806038070380803809038100381103812038130381403815038160381703818038190382003821038220382303824038250382603827038280382903830038310383203833038340383503836038370383803839038400384103842038430384403845038460384703848038490385003851038520385303854038550385603857038580385903860038610386203863038640386503866038670386803869038700387103872038730387403875038760387703878038790388003881038820388303884038850388603887038880388903890038910389203893038940389503896038970389803899039000390103902039030390403905039060390703908039090391003911039120391303914039150391603917039180391903920039210392203923039240392503926039270392803929039300393103932039330393403935039360393703938039390394003941039420394303944039450394603947039480394903950039510395203953039540395503956039570395803959039600396103962039630396403965039660396703968039690397003971039720397303974039750 // Written in the D programming language. /** * This module defines an Abstract Syntax Tree for the D language * * Examples: * --- * // TODO * --- * * Copyright: Brian Schott 2013 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt Boost, License 1.0) * Authors: Brian Schott */ module dparse.ast; import dparse.lexer; import std.traits; import std.algorithm; import std.array; import std.string; private immutable uint[TypeInfo] typeMap; shared static this() { typeMap[typeid(AddExpression)] = 1; typeMap[typeid(AndAndExpression)] = 2; typeMap[typeid(AndExpression)] = 3; typeMap[typeid(AsmAddExp)] = 4; typeMap[typeid(AsmAndExp)] = 5; typeMap[typeid(AsmBrExp)] = 6; typeMap[typeid(AsmExp)] = 7; typeMap[typeid(AsmEqualExp)] = 8; typeMap[typeid(AsmLogAndExp)] = 9; typeMap[typeid(AsmLogOrExp)] = 10; typeMap[typeid(AsmMulExp)] = 11; typeMap[typeid(AsmOrExp)] = 12; typeMap[typeid(AsmRelExp)] = 13; typeMap[typeid(AsmUnaExp)] = 14; typeMap[typeid(AsmShiftExp)] = 15; typeMap[typeid(AsmXorExp)] = 16; typeMap[typeid(AssertExpression)] = 17; typeMap[typeid(AssignExpression)] = 18; typeMap[typeid(CmpExpression)] = 19; typeMap[typeid(DeleteExpression)] = 20; typeMap[typeid(EqualExpression)] = 21; typeMap[typeid(Expression)] = 22; typeMap[typeid(FunctionCallExpression)] = 23; typeMap[typeid(FunctionLiteralExpression)] = 24; typeMap[typeid(IdentityExpression)] = 25; typeMap[typeid(ImportExpression)] = 26; typeMap[typeid(IndexExpression)] = 27; typeMap[typeid(InExpression)] = 28; typeMap[typeid(IsExpression)] = 29; typeMap[typeid(MixinExpression)] = 30; typeMap[typeid(MulExpression)] = 31; typeMap[typeid(NewAnonClassExpression)] = 32; typeMap[typeid(NewExpression)] = 33; typeMap[typeid(OrExpression)] = 34; typeMap[typeid(OrOrExpression)] = 35; typeMap[typeid(PowExpression)] = 36; typeMap[typeid(PragmaExpression)] = 37; typeMap[typeid(PrimaryExpression)] = 38; typeMap[typeid(RelExpression)] = 39; typeMap[typeid(ShiftExpression)] = 40; typeMap[typeid(Index)] = 41; typeMap[typeid(TemplateMixinExpression)] = 42; typeMap[typeid(TernaryExpression)] = 43; typeMap[typeid(TraitsExpression)] = 44; typeMap[typeid(TypeidExpression)] = 45; typeMap[typeid(TypeofExpression)] = 46; typeMap[typeid(UnaryExpression)] = 47; typeMap[typeid(XorExpression)] = 48; } /// Describes which syntax was used in a list of declarations in the containing AST node enum DeclarationListStyle : ubyte { /// A declaration directly after the containing AST node making it the only child single, /// A colon (`:`) was used in the containing AST node meaning all following declarations are part here. colon, /// The declarations have been specified in a block denoted by starting `{` and ending `}` tokens. block } /** * Implements the $(LINK2 http://en.wikipedia.org/wiki/Visitor_pattern, Visitor Pattern) * for the various AST classes */ abstract class ASTVisitor { /** */ void visit(const ExpressionNode n) { switch (typeMap[typeid(n)]) { case 1: visit(cast(AddExpression) n); break; case 2: visit(cast(AndAndExpression) n); break; case 3: visit(cast(AndExpression) n); break; case 4: visit(cast(AsmAddExp) n); break; case 5: visit(cast(AsmAndExp) n); break; case 6: visit(cast(AsmBrExp) n); break; case 7: visit(cast(AsmExp) n); break; case 8: visit(cast(AsmEqualExp) n); break; case 9: visit(cast(AsmLogAndExp) n); break; case 10: visit(cast(AsmLogOrExp) n); break; case 11: visit(cast(AsmMulExp) n); break; case 12: visit(cast(AsmOrExp) n); break; case 13: visit(cast(AsmRelExp) n); break; case 14: visit(cast(AsmUnaExp) n); break; case 15: visit(cast(AsmShiftExp) n); break; case 16: visit(cast(AsmXorExp) n); break; case 17: visit(cast(AssertExpression) n); break; case 18: visit(cast(AssignExpression) n); break; case 19: visit(cast(CmpExpression) n); break; case 20: visit(cast(DeleteExpression) n); break; case 21: visit(cast(EqualExpression) n); break; case 22: visit(cast(Expression) n); break; case 23: visit(cast(FunctionCallExpression) n); break; case 24: visit(cast(FunctionLiteralExpression) n); break; case 25: visit(cast(IdentityExpression) n); break; case 26: visit(cast(ImportExpression) n); break; case 27: visit(cast(IndexExpression) n); break; case 28: visit(cast(InExpression) n); break; case 29: visit(cast(IsExpression) n); break; case 30: visit(cast(MixinExpression) n); break; case 31: visit(cast(MulExpression) n); break; case 32: visit(cast(NewAnonClassExpression) n); break; case 33: visit(cast(NewExpression) n); break; case 34: visit(cast(OrExpression) n); break; case 35: visit(cast(OrOrExpression) n); break; case 36: visit(cast(PowExpression) n); break; case 37: visit(cast(PragmaExpression) n); break; case 38: visit(cast(PrimaryExpression) n); break; case 39: visit(cast(RelExpression) n); break; case 40: visit(cast(ShiftExpression) n); break; case 41: visit(cast(Index) n); break; case 42: visit(cast(TemplateMixinExpression) n); break; case 43: visit(cast(TernaryExpression) n); break; case 44: visit(cast(TraitsExpression) n); break; case 45: visit(cast(TypeidExpression) n); break; case 46: visit(cast(TypeofExpression) n); break; case 47: visit(cast(UnaryExpression) n); break; case 48: visit(cast(XorExpression) n); break; default: assert(false, __MODULE__ ~ " has a bug"); } } /** */ void visit(const AddExpression addExpression) { addExpression.accept(this); } /** */ void visit(const AliasDeclaration aliasDeclaration) { aliasDeclaration.accept(this); } /** */ void visit(const AliasAssign aliasAssign) { aliasAssign.accept(this); } /** */ void visit(const AliasInitializer aliasInitializer) { aliasInitializer.accept(this); } /** */ void visit(const AliasThisDeclaration aliasThisDeclaration) { aliasThisDeclaration.accept(this); } /** */ void visit(const AlignAttribute alignAttribute) { alignAttribute.accept(this); } /** */ void visit(const AndAndExpression andAndExpression) { andAndExpression.accept(this); } /** */ void visit(const AndExpression andExpression) { andExpression.accept(this); } /** */ void visit(const AnonymousEnumDeclaration anonymousEnumDeclaration) { anonymousEnumDeclaration.accept(this); } /** */ void visit(const AnonymousEnumMember anonymousEnumMember) { anonymousEnumMember.accept(this); } /** */ void visit(const ArgumentList argumentList) { argumentList.accept(this); } /** */ void visit(const Arguments arguments) { arguments.accept(this); } /** */ void visit(const ArrayInitializer arrayInitializer) { arrayInitializer.accept(this); } /** */ void visit(const ArrayLiteral arrayLiteral) { arrayLiteral.accept(this); } /** */ void visit(const ArrayMemberInitialization arrayMemberInitialization) { arrayMemberInitialization.accept(this); } /** */ void visit(const AsmAddExp asmAddExp) { asmAddExp.accept(this); } /** */ void visit(const AsmAndExp asmAndExp) { asmAndExp.accept(this); } /** */ void visit(const AsmBrExp asmBrExp) { asmBrExp.accept(this); } /** */ void visit(const AsmEqualExp asmEqualExp) { asmEqualExp.accept(this); } /** */ void visit(const AsmExp asmExp) { asmExp.accept(this); } /** */ void visit(const AsmInstruction asmInstruction) { asmInstruction.accept(this); } /** */ void visit(const AsmLogAndExp asmLogAndExp) { asmLogAndExp.accept(this); } /** */ void visit(const AsmLogOrExp asmLogOrExp) { asmLogOrExp.accept(this); } /** */ void visit(const AsmMulExp asmMulExp) { asmMulExp.accept(this); } /** */ void visit(const AsmOrExp asmOrExp) { asmOrExp.accept(this); } /** */ void visit(const AsmPrimaryExp asmPrimaryExp) { asmPrimaryExp.accept(this); } /** */ void visit(const AsmRelExp asmRelExp) { asmRelExp.accept(this); } /** */ void visit(const AsmShiftExp asmShiftExp) { asmShiftExp.accept(this); } /** */ void visit(const AsmStatement asmStatement) { asmStatement.accept(this); } /** */ void visit(const AsmTypePrefix asmTypePrefix) { asmTypePrefix.accept(this); } /** */ void visit(const AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); } /** */ void visit(const AsmXorExp asmXorExp) { asmXorExp.accept(this); } /** */ void visit(const AssertArguments assertArguments) { assertArguments.accept(this); } /** */ void visit(const AssertExpression assertExpression) { assertExpression.accept(this); } /** */ void visit(const AssignExpression assignExpression) { assignExpression.accept(this); } /** */ void visit(const AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); } /** */ void visit(const AtAttribute atAttribute) { atAttribute.accept(this); } /** */ void visit(const Attribute attribute) { attribute.accept(this); } /** */ void visit(const AttributeDeclaration attributeDeclaration) { attributeDeclaration.accept(this); } /** */ void visit(const AutoDeclaration autoDeclaration) { autoDeclaration.accept(this); } /** */ void visit(const AutoDeclarationPart autoDeclarationPart) { autoDeclarationPart.accept(this); } /** */ void visit(const BlockStatement blockStatement) { blockStatement.accept(this); } /** */ void visit(const BreakStatement breakStatement) { breakStatement.accept(this); } /** */ void visit(const BaseClass baseClass) { baseClass.accept(this); } /** */ void visit(const BaseClassList baseClassList) { baseClassList.accept(this); } /** */ void visit(const CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); } /** */ void visit(const CaseStatement caseStatement) { caseStatement.accept(this); } /** */ void visit(const CastExpression castExpression) { castExpression.accept(this); } /** */ void visit(const CastQualifier castQualifier) { castQualifier.accept(this); } /** */ void visit(const Catch catch_) { catch_.accept(this); } /** */ void visit(const Catches catches) { catches.accept(this); } /** */ void visit(const ClassDeclaration classDeclaration) { classDeclaration.accept(this); } /** */ void visit(const CmpExpression cmpExpression) { cmpExpression.accept(this); } /** */ void visit(const CompileCondition compileCondition) { compileCondition.accept(this); } /** */ void visit(const ConditionalDeclaration conditionalDeclaration) { conditionalDeclaration.accept(this); } /** */ void visit(const ConditionalStatement conditionalStatement) { conditionalStatement.accept(this); } /** */ void visit(const Constraint constraint) { constraint.accept(this); } /** */ void visit(const Constructor constructor) { constructor.accept(this); } /** */ void visit(const ContinueStatement continueStatement) { continueStatement.accept(this); } /** */ void visit(const DebugCondition debugCondition) { debugCondition.accept(this); } /** */ void visit(const DebugSpecification debugSpecification) { debugSpecification.accept(this); } /** */ void visit(const Declaration declaration) { declaration.accept(this); } /** */ void visit(const DeclarationOrStatement declarationsOrStatement) { declarationsOrStatement.accept(this); } /** */ void visit(const DeclarationsAndStatements declarationsAndStatements) { declarationsAndStatements.accept(this); } /** */ void visit(const Declarator declarator) { declarator.accept(this); } /** */ void visit(const DefaultStatement defaultStatement) { defaultStatement.accept(this); } /** */ void visit(const DeleteExpression deleteExpression) { deleteExpression.accept(this); } /** */ void visit(const DeleteStatement deleteStatement) { deleteStatement.accept(this); } /** */ void visit(const Deprecated deprecated_) { deprecated_.accept(this); } /** */ void visit(const Destructor destructor) { destructor.accept(this); } /** */ void visit(const DoStatement doStatement) { doStatement.accept(this); } /** */ void visit(const EnumBody enumBody) { enumBody.accept(this); } /** */ void visit(const EnumDeclaration enumDeclaration) { enumDeclaration.accept(this); } /** */ void visit(const EnumMember enumMember) { enumMember.accept(this); } /** */ void visit(const EnumMemberAttribute enumMemberAttribute) { enumMemberAttribute.accept(this); } /** */ void visit(const EponymousTemplateDeclaration eponymousTemplateDeclaration) { eponymousTemplateDeclaration.accept(this); } /** */ void visit(const EqualExpression equalExpression) { equalExpression.accept(this); } /** */ void visit(const Expression expression) { expression.accept(this); } /** */ void visit(const ExpressionStatement expressionStatement) { expressionStatement.accept(this); } /** */ void visit(const FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); } /** */ void visit(const Finally finally_) { finally_.accept(this); } /** */ void visit(const ForStatement forStatement) { forStatement.accept(this); } /** */ void visit(const ForeachStatement foreachStatement) { foreachStatement.accept(this); } /** */ void visit(const StaticForeachDeclaration staticForeachDeclaration) { staticForeachDeclaration.accept(this); } /** */ void visit(const StaticForeachStatement staticForeachStatement) { staticForeachStatement.accept(this); } /** */ void visit(const ForeachType foreachType) { foreachType.accept(this); } /** */ void visit(const ForeachTypeList foreachTypeList) { foreachTypeList.accept(this); } /** */ void visit(const FunctionAttribute functionAttribute) { functionAttribute.accept(this); } /** */ void visit(const FunctionBody functionBody) { functionBody.accept(this); } /** */ void visit(const FunctionCallExpression functionCallExpression) { functionCallExpression.accept(this); } /** */ void visit(const FunctionContract functionContract) { functionContract.accept(this); } /** */ void visit(const FunctionDeclaration functionDeclaration) { functionDeclaration.accept(this); } /** */ void visit(const FunctionLiteralExpression functionLiteralExpression) { functionLiteralExpression.accept(this); } /** */ void visit(const GccAsmInstruction gccAsmInstruction) { gccAsmInstruction.accept(this); } /** */ void visit(const GccAsmOperandList gccAsmOperands) { gccAsmOperands.accept(this); } /** */ void visit(const GccAsmOperand gccAsmOperand) { gccAsmOperand.accept(this); } /** */ void visit(const GotoStatement gotoStatement) { gotoStatement.accept(this); } /** */ void visit(const IdentifierChain identifierChain) { identifierChain.accept(this); } /** */ void visit(const DeclaratorIdentifierList identifierList) { identifierList.accept(this); } /** */ void visit(const IdentifierOrTemplateChain identifierOrTemplateChain) { identifierOrTemplateChain.accept(this); } /** */ void visit(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { identifierOrTemplateInstance.accept(this); } /** */ void visit(const IdentityExpression identityExpression) { identityExpression.accept(this); } /** */ void visit(const IfStatement ifStatement) { ifStatement.accept(this); } /** */ void visit(const ImportBind importBind) { importBind.accept(this); } /** */ void visit(const ImportBindings importBindings) { importBindings.accept(this); } /** */ void visit(const ImportDeclaration importDeclaration) { importDeclaration.accept(this); } /** */ void visit(const ImportExpression importExpression) { importExpression.accept(this); } /** */ void visit(const IndexExpression indexExpression) { indexExpression.accept(this); } /** */ void visit(const InContractExpression inContractExpression) { inContractExpression.accept(this); } /** */ void visit(const InExpression inExpression) { inExpression.accept(this); } /** */ void visit(const InOutContractExpression inOutContractExpression) { inOutContractExpression.accept(this); } /** */ void visit(const InOutStatement inOutStatement) { inOutStatement.accept(this); } /** */ void visit(const InStatement inStatement) { inStatement.accept(this); } /** */ void visit(const Initialize initialize) { initialize.accept(this); } /** */ void visit(const Initializer initializer) { initializer.accept(this); } /** */ void visit(const InterfaceDeclaration interfaceDeclaration) { interfaceDeclaration.accept(this); } /** */ void visit(const Invariant invariant_) { invariant_.accept(this); } /** */ void visit(const IsExpression isExpression) { isExpression.accept(this); } /** */ void visit(const KeyValuePair keyValuePair) { keyValuePair.accept(this); } /** */ void visit(const KeyValuePairs keyValuePairs) { keyValuePairs.accept(this); } /** */ void visit(const LabeledStatement labeledStatement) { labeledStatement.accept(this); } /** */ void visit(const LastCatch lastCatch) { lastCatch.accept(this); } /** */ void visit(const LinkageAttribute linkageAttribute) { linkageAttribute.accept(this); } /** */ void visit(const MemberFunctionAttribute memberFunctionAttribute) { memberFunctionAttribute.accept(this); } /** */ void visit(const MissingFunctionBody missingFunctionBody) { missingFunctionBody.accept(this); } /** */ void visit(const MixinDeclaration mixinDeclaration) { mixinDeclaration.accept(this); } /** */ void visit(const MixinExpression mixinExpression) { mixinExpression.accept(this); } /** */ void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixinTemplateDeclaration.accept(this); } /** */ void visit(const MixinTemplateName mixinTemplateName) { mixinTemplateName.accept(this); } /** */ void visit(const Module module_) { module_.accept(this); } /** */ void visit(const ModuleDeclaration moduleDeclaration) { moduleDeclaration.accept(this); } /** */ void visit(const MulExpression mulExpression) { mulExpression.accept(this); } /** */ void visit(const NamespaceList namespaceList) { namespaceList.accept(this); } /** */ void visit(const NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); } /** */ void visit(const NewExpression newExpression) { newExpression.accept(this); } /** */ void visit(const NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); } /** */ void visit(const Operands operands) { operands.accept(this); } /** */ void visit(const OrExpression orExpression) { orExpression.accept(this); } /** */ void visit(const OrOrExpression orOrExpression) { orOrExpression.accept(this); } /** */ void visit(const OutContractExpression outContractExpression) { outContractExpression.accept(this); } /** */ void visit(const OutStatement outStatement) { outStatement.accept(this); } /** */ void visit(const ParameterAttribute parameterAttribute) { parameterAttribute.accept(this); } /** */ void visit(const Parameter parameter) { parameter.accept(this); } /** */ void visit(const Parameters parameters) { parameters.accept(this); } /** */ void visit(const Postblit postblit) { postblit.accept(this); } /** */ void visit(const PowExpression powExpression) { powExpression.accept(this); } /** */ void visit(const PragmaDeclaration pragmaDeclaration) { pragmaDeclaration.accept(this); } /** */ void visit(const PragmaStatement pragmaStatement) { pragmaStatement.accept(this); } /** */ void visit(const PragmaExpression pragmaExpression) { pragmaExpression.accept(this); } /** */ void visit(const PrimaryExpression primaryExpression) { primaryExpression.accept(this); } /** */ void visit(const Register register) { register.accept(this); } /** */ void visit(const RelExpression relExpression) { relExpression.accept(this); } /** */ void visit(const ReturnStatement returnStatement) { returnStatement.accept(this); } /** */ void visit(const ScopeGuardStatement scopeGuardStatement) { scopeGuardStatement.accept(this); } /** */ void visit(const SharedStaticConstructor sharedStaticConstructor) { sharedStaticConstructor.accept(this); } /** */ void visit(const SharedStaticDestructor sharedStaticDestructor) { sharedStaticDestructor.accept(this); } /** */ void visit(const ShiftExpression shiftExpression) { shiftExpression.accept(this); } /** */ void visit(const ShortenedFunctionBody shortenedFunctionBody) { shortenedFunctionBody.accept(this); } /** */ void visit(const SingleImport singleImport) { singleImport.accept(this); } /** */ void visit(const Index index) { index.accept(this); } /** */ void visit(const SpecifiedFunctionBody specifiedFunctionBody) { specifiedFunctionBody.accept(this); } /** */ void visit(const Statement statement) { statement.accept(this); } /** */ void visit(const StatementNoCaseNoDefault statementNoCaseNoDefault) { statementNoCaseNoDefault.accept(this); } /** */ void visit(const StaticAssertDeclaration staticAssertDeclaration) { staticAssertDeclaration.accept(this); } /** */ void visit(const StaticAssertStatement staticAssertStatement) { staticAssertStatement.accept(this); } /** */ void visit(const StaticConstructor staticConstructor) { staticConstructor.accept(this); } /** */ void visit(const StaticDestructor staticDestructor) { staticDestructor.accept(this); } /** */ void visit(const StaticIfCondition staticIfCondition) { staticIfCondition.accept(this); } /** */ void visit(const StorageClass storageClass) { storageClass.accept(this); } /** */ void visit(const StringLiteralList stringLiteralList) { stringLiteralList.accept(this); } /** */ void visit(const StructBody structBody) { structBody.accept(this); } /** */ void visit(const StructDeclaration structDeclaration) { structDeclaration.accept(this); } /** */ void visit(const StructInitializer structInitializer) { structInitializer.accept(this); } /** */ void visit(const StructMemberInitializer structMemberInitializer) { structMemberInitializer.accept(this); } /** */ void visit(const StructMemberInitializers structMemberInitializers) { structMemberInitializers.accept(this); } /** */ void visit(const SwitchStatement switchStatement) { switchStatement.accept(this); } /** */ void visit(const Symbol symbol) { symbol.accept(this); } /** */ void visit(const SynchronizedStatement synchronizedStatement) { synchronizedStatement.accept(this); } /** */ void visit(const TemplateAliasParameter templateAliasParameter) { templateAliasParameter.accept(this); } /** */ void visit(const TemplateArgument templateArgument) { templateArgument.accept(this); } /** */ void visit(const TemplateArgumentList templateArgumentList) { templateArgumentList.accept(this); } /** */ void visit(const TemplateArguments templateArguments) { templateArguments.accept(this); } /** */ void visit(const TemplateDeclaration templateDeclaration) { templateDeclaration.accept(this); } /** */ void visit(const TemplateInstance templateInstance) { templateInstance.accept(this); } /** */ void visit(const TemplateMixinExpression templateMixinExpression) { templateMixinExpression.accept(this); } /** */ void visit(const TemplateParameter templateParameter) { templateParameter.accept(this); } /** */ void visit(const TemplateParameterList templateParameterList) { templateParameterList.accept(this); } /** */ void visit(const TemplateParameters templateParameters) { templateParameters.accept(this); } /** */ void visit(const TemplateSingleArgument templateSingleArgument) { templateSingleArgument.accept(this); } /** */ void visit(const TemplateThisParameter templateThisParameter) { templateThisParameter.accept(this); } /** */ void visit(const TemplateTupleParameter templateTupleParameter) { templateTupleParameter.accept(this); } /** */ void visit(const TemplateTypeParameter templateTypeParameter) { templateTypeParameter.accept(this); } /** */ void visit(const TemplateValueParameter templateValueParameter) { templateValueParameter.accept(this); } /** */ void visit(const TemplateValueParameterDefault templateValueParameterDefault) { templateValueParameterDefault.accept(this); } /** */ void visit(const TernaryExpression ternaryExpression) { ternaryExpression.accept(this); } /** */ void visit(const ThrowExpression throwExpression) { throwExpression.accept(this); } /** */ void visit(const Token) { } /** */ void visit(const TraitsExpression traitsExpression) { traitsExpression.accept(this); } /** */ void visit(const TryStatement tryStatement) { tryStatement.accept(this); } /** */ void visit(const Type type) { type.accept(this); } /** */ void visit(const TypeIdentifierPart typeIdentChain) { typeIdentChain.accept(this); } /** */ void visit(const Type2 type2) { type2.accept(this); } /** */ void visit(const TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); } /** */ void visit(const TypeSuffix typeSuffix) { typeSuffix.accept(this); } /** */ void visit(const TypeidExpression typeidExpression) { typeidExpression.accept(this); } /** */ void visit(const TypeofExpression typeofExpression) { typeofExpression.accept(this); } /** */ void visit(const UnaryExpression unaryExpression) { unaryExpression.accept(this); } /** */ void visit(const UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); } /** */ void visit(const Unittest unittest_) { unittest_.accept(this); } /** */ void visit(const VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); } /** */ void visit(const Vector vector) { vector.accept(this); } /** */ void visit(const VersionCondition versionCondition) { versionCondition.accept(this); } /** */ void visit(const VersionSpecification versionSpecification) { versionSpecification.accept(this); } /** */ void visit(const WhileStatement whileStatement) { whileStatement.accept(this); } /** */ void visit(const WithStatement withStatement) { withStatement.accept(this); } /** */ void visit(const XorExpression xorExpression) { xorExpression.accept(this); } } interface ASTNode { /** */ void accept(ASTVisitor visitor) const; } template visitIfNotNull(fields ...) { static if (fields.length > 1) immutable visitIfNotNull = visitIfNotNull!(fields[0]) ~ visitIfNotNull!(fields[1..$]); else { static if (typeof(fields[0]).stringof[$ - 2 .. $] == "[]") { static if (__traits(hasMember, typeof(fields[0][0]), "classinfo")) immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") if (i !is null) visitor.visit(i);\n"; else immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") visitor.visit(i);\n"; } else static if (__traits(hasMember, typeof(fields[0]), "classinfo")) immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ " !is null) visitor.visit(" ~ fields[0].stringof ~ ");\n"; else static if (is(Unqual!(typeof(fields[0])) == Token)) immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ ` != tok!""` ~ ") visitor.visit(" ~ fields[0].stringof ~ ");\n"; else immutable visitIfNotNull = "visitor.visit(" ~ fields[0].stringof ~ ");\n"; } } mixin template OpEquals(bool print = false) { override bool opEquals(Object other) const { static if (print) pragma(msg, generateOpEquals!(typeof(this))); mixin (generateOpEquals!(typeof(this))); } } template generateOpEquals(T) { template opEqualsPart(p ...) { import std.traits : isSomeFunction, isDynamicArray; import std.algorithm : among; static if (p.length > 1) { enum opEqualsPart = opEqualsPart!(p[0 .. $/2]) ~ opEqualsPart!(p[$/2 .. $]); } else static if (p.length && !isSomeFunction!(typeof(__traits(getMember, T, p[0]))) && !p[0].among("comment", "line", "column", "endLocation", "startLocation", "index", "dotLocation")) { static if (isDynamicArray!(typeof(__traits(getMember, T, p[0])))) { enum opEqualsPart = "\tif (obj." ~ p[0] ~ ".length != " ~ p[0] ~ ".length) return false;\n" ~ "\tforeach (i; 0 .. " ~ p[0] ~ ".length)\n" ~ "\t\tif (" ~ p[0] ~ "[i] != obj." ~ p[0] ~ "[i]) return false;\n"; } else enum opEqualsPart = "\tif (obj." ~ p[0] ~ " != " ~ p[0] ~ ") return false;\n"; } else enum opEqualsPart = ""; } enum generateOpEquals = "if (auto obj = cast(" ~ T.stringof ~ ") other){\n" ~ opEqualsPart!(__traits(derivedMembers, T)) ~ "\treturn true;\n}\nreturn false;"; } abstract class BaseNode : ASTNode { /** List of tokens consumed by this AST node */ const(Token)[] tokens; abstract void accept(ASTVisitor visitor) const; } abstract class ExpressionNode : BaseNode { override void accept(ASTVisitor visitor) const { assert (false); } } mixin template BinaryExpressionBody() { ExpressionNode left; ExpressionNode right; size_t line; size_t column; } /// final class AddExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; /** */ IdType operator; mixin BinaryExpressionBody; } /// final class AliasDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(storageClasses, type, declaratorIdentifierList, initializers, parameters, memberFunctionAttributes)); } mixin OpEquals; /** */ StorageClass[] storageClasses; /** */ Type type; /** */ DeclaratorIdentifierList declaratorIdentifierList; /** */ AliasInitializer[] initializers; /** */ string comment; /** */ Parameters parameters; /** */ MemberFunctionAttribute[] memberFunctionAttributes; } /// final class AliasAssign : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, type)); } mixin OpEquals; /** */ Token identifier; /** */ Type type; /** */ string comment; } /// final class AliasInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, storageClasses, type, functionLiteralExpression)); } mixin OpEquals; /** */ Token name; /** */ StorageClass[] storageClasses; /** */ TemplateParameters templateParameters; /** */ Type type; /** */ FunctionLiteralExpression functionLiteralExpression; /** */ Parameters parameters; /** */ MemberFunctionAttribute[] memberFunctionAttributes; } /// final class AliasThisDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier)); } mixin OpEquals; /** */ Token identifier; /** */ string comment; } /// final class AlignAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } mixin OpEquals; /** */ ExpressionNode assignExpression; } /// final class AndAndExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; mixin BinaryExpressionBody; } /// final class AndExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; mixin BinaryExpressionBody; } /// final class AnonymousEnumDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(baseType, members)); } mixin OpEquals; /** */ Type baseType; /** */ AnonymousEnumMember[] members; } /// final class AnonymousEnumMember : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, name, assignExpression)); } /** */ Type type; /** */ Token name; /** */ ExpressionNode assignExpression; /** */ string comment; } /// final class ArgumentList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } mixin OpEquals; /** */ ExpressionNode[] items; /** */ size_t startLocation; /** */ size_t endLocation; } /// final class Arguments : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList)); } mixin OpEquals; /** */ ArgumentList argumentList; } /// final class ArrayInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(arrayMemberInitializations)); } mixin OpEquals; /** */ size_t startLocation; /** */ size_t endLocation; /** */ ArrayMemberInitialization[] arrayMemberInitializations; } /// final class ArrayLiteral : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList)); } mixin OpEquals; /** */ ArgumentList argumentList; } /// final class ArrayMemberInitialization : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression, nonVoidInitializer)); } mixin OpEquals; /** */ ExpressionNode assignExpression; /** */ NonVoidInitializer nonVoidInitializer; } /// final class AsmAddExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; /** */ IdType operator; mixin BinaryExpressionBody; } /// final class AsmAndExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; mixin BinaryExpressionBody; } /// final class AsmBrExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(asmBrExp, asmExp, asmUnaExp)); } mixin OpEquals; size_t line; size_t column; /** */ AsmBrExp asmBrExp; /** */ ExpressionNode asmExp; /** */ AsmUnaExp asmUnaExp; } /// final class AsmEqualExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; /** */ IdType operator; } /// final class AsmExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, middle, right)); } mixin OpEquals; /** */ ExpressionNode left; /** */ ExpressionNode middle; /** */ ExpressionNode right; } /// final class AsmInstruction : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrIntegerOrOpcode, asmInstruction, operands)); } mixin OpEquals; /** */ Token identifierOrIntegerOrOpcode; /** */ bool hasAlign; /** */ bool isLabel; /** */ AsmInstruction asmInstruction; /** */ Operands operands; } /// final class AsmLogAndExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmLogOrExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmMulExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmOrExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmPrimaryExp : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, register, asmExp, identifierChain, segmentOverrideSuffix)); } /** */ ExpressionNode asmExp; /** */ IdentifierChain identifierChain; /** */ Register register; /** */ ExpressionNode segmentOverrideSuffix; /** */ Token token; mixin OpEquals; } /// final class AsmRelExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; /** */ IdType operator; mixin OpEquals; } /// final class AsmShiftExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; /** */ IdType operator; mixin OpEquals; } /// final class AsmStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionAttributes, asmInstructions, gccAsmInstructions)); } /** */ AsmInstruction[] asmInstructions; /** */ GccAsmInstruction[] gccAsmInstructions; /** */ FunctionAttribute[] functionAttributes; mixin OpEquals; } /// final class AsmTypePrefix : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ Token left; /** */ Token right; mixin OpEquals; } /// final class AsmUnaExp : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(prefix, asmTypePrefix, asmExp, asmPrimaryExp, asmUnaExp)); } /** */ AsmTypePrefix asmTypePrefix; /** */ ExpressionNode asmExp; /** */ Token prefix; /** */ AsmPrimaryExp asmPrimaryExp; /** */ AsmUnaExp asmUnaExp; mixin OpEquals; } /// final class AsmXorExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AssertArguments : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertion, message)); } /** */ ExpressionNode assertion; /** */ ExpressionNode message; mixin OpEquals; } /// final class AssertExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertArguments)); } /** */ size_t line; /** */ size_t column; /** */ AssertArguments assertArguments; mixin OpEquals; } /// final class AssignExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(ternaryExpression, expression)); } /** */ ExpressionNode ternaryExpression; /** */ ExpressionNode expression; /** */ IdType operator; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class AssocArrayLiteral : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(keyValuePairs)); } /** */ KeyValuePairs keyValuePairs; mixin OpEquals; } /// final class AtAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateInstance, argumentList)); } /** */ ArgumentList argumentList; /** */ TemplateInstance templateInstance; /** */ Token identifier; /** */ bool useParen; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class Attribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(pragmaExpression, deprecated_, atAttribute, alignAttribute, identifierChain, linkageAttribute)); } /** */ PragmaExpression pragmaExpression; /** */ Deprecated deprecated_; /** */ AtAttribute atAttribute; /** */ AlignAttribute alignAttribute; /** */ LinkageAttribute linkageAttribute; /** */ Token attribute; /** */ IdentifierChain identifierChain; mixin OpEquals; } /// final class AttributeDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(attribute)); } /** */ Attribute attribute; /** */ size_t line; mixin OpEquals; } /// final class AutoDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { foreach (sc; storageClasses) visitor.visit(sc); foreach (part; parts) visitor.visit(part); } /** */ AutoDeclarationPart[] parts; /** */ StorageClass[] storageClasses; /** */ string comment; mixin OpEquals; } final class AutoDeclarationPart : BaseNode { override void accept(ASTVisitor visitor) const { if (templateParameters !is null) visitor.visit(templateParameters); visitor.visit(initializer); } /** */ Token identifier; /** */ Initializer initializer; /** */ TemplateParameters templateParameters; } /// final class BlockStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationsAndStatements)); } /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; /** */ DeclarationsAndStatements declarationsAndStatements; mixin OpEquals; } /// final class BreakStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(label)); } /** */ Token label; mixin OpEquals; } /// final class BaseClass : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type2)); } /** */ Type2 type2; mixin OpEquals; } /// final class BaseClassList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ BaseClass[] items; mixin OpEquals; } /// final class CaseRangeStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(low, high, declarationsAndStatements)); } /** */ ExpressionNode low; /** */ ExpressionNode high; /** */ DeclarationsAndStatements declarationsAndStatements; /** */ size_t colonLocation; mixin OpEquals; } /// final class CaseStatement: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList, declarationsAndStatements)); } /** */ ArgumentList argumentList; /** */ DeclarationsAndStatements declarationsAndStatements; /** */ size_t colonLocation; mixin OpEquals; } /// final class CastExpression: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, castQualifier, unaryExpression)); } /** */ Type type; /** */ CastQualifier castQualifier; /** */ UnaryExpression unaryExpression; mixin OpEquals; } /// final class CastQualifier: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(first, second)); } /** */ Token first; /** */ Token second; mixin OpEquals; } /// final class Catches: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(catches, lastCatch)); } /** */ Catch[] catches; /** */ LastCatch lastCatch; mixin OpEquals; } /// final class Catch: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, declarationOrStatement)); } /** */ Type type; /** */ Token identifier; /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class ClassDeclaration: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, constraint, baseClassList, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ BaseClassList baseClassList; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class CmpExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(shiftExpression, equalExpression, identityExpression, relExpression, inExpression)); } /** */ ExpressionNode shiftExpression; /** */ ExpressionNode equalExpression; /** */ ExpressionNode identityExpression; /** */ ExpressionNode relExpression; /** */ ExpressionNode inExpression; mixin OpEquals; } /// final class CompileCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(versionCondition, debugCondition, staticIfCondition)); } /** */ VersionCondition versionCondition; /** */ DebugCondition debugCondition; /** */ StaticIfCondition staticIfCondition; mixin OpEquals; } /// final class ConditionalDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(compileCondition, trueDeclarations, falseDeclarations)); } /** */ CompileCondition compileCondition; /** */ Declaration[] trueDeclarations; /** */ Declaration[] falseDeclarations; /** */ bool hasElse; /** */ DeclarationListStyle trueStyle; /** */ DeclarationListStyle falseStyle; mixin OpEquals; } /// final class ConditionalStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(compileCondition, trueStatement, falseStatement)); } /** */ CompileCondition compileCondition; /** */ DeclarationOrStatement trueStatement; /** */ DeclarationOrStatement falseStatement; mixin OpEquals; } /// final class Constraint : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ Expression expression; /** */ size_t location; mixin OpEquals; } /// final class Constructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameters, templateParameters, constraint, memberFunctionAttributes, functionBody)); } /** */ Parameters parameters; /** */ FunctionBody functionBody; /** */ Constraint constraint; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ TemplateParameters templateParameters; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class ContinueStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(label)); } /** */ Token label; mixin OpEquals; } /// final class DebugCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrInteger)); } /** */ size_t debugIndex; /** */ Token identifierOrInteger; mixin OpEquals; } /// final class DebugSpecification : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrInteger)); } /** */ Token identifierOrInteger; mixin OpEquals; } /// final class Declaration : BaseNode { override void accept(ASTVisitor visitor) const { foreach (attr; attributes) visitor.visit(attr); foreach (dec; declarations) visitor.visit(dec); foreach (Type; DeclarationTypes) { const(Type)* value = storage.peek!Type; if (value !is null) { static if (isArray!Type) foreach (item; *(cast(Type*) value)) visitor.visit(item); else if (*value !is null) visitor.visit(*(cast(Type*) value)); } } } private import std.variant:Algebraic; private import std.typetuple:TypeTuple; alias DeclarationTypes = TypeTuple!(AliasDeclaration, AliasAssign, AliasThisDeclaration, AnonymousEnumDeclaration, AttributeDeclaration, ClassDeclaration, ConditionalDeclaration, Constructor, DebugSpecification, Destructor, EnumDeclaration, EponymousTemplateDeclaration, FunctionDeclaration, ImportDeclaration, InterfaceDeclaration, Invariant, MixinDeclaration, MixinTemplateDeclaration, Postblit, PragmaDeclaration, SharedStaticConstructor, SharedStaticDestructor, StaticAssertDeclaration, StaticConstructor, StaticDestructor, StructDeclaration, TemplateDeclaration, UnionDeclaration, Unittest, VariableDeclaration, VersionSpecification, StaticForeachDeclaration); private Algebraic!(DeclarationTypes) storage; private static string generateProperty(string type, string name) { return "const(" ~ type ~ ") " ~ name ~ "() const @property { auto p = storage.peek!" ~ type ~ "; return p is null? null : *p;}\n" ~ "const(" ~ type ~ ") " ~ name ~ "(" ~ type ~ " node) @property { storage = node; return node; }"; } /** */ Attribute[] attributes; /** */ Declaration[] declarations; mixin(generateProperty("AliasDeclaration", "aliasDeclaration")); mixin(generateProperty("AliasAssign", "aliasAssign")); mixin(generateProperty("AliasThisDeclaration", "aliasThisDeclaration")); mixin(generateProperty("AnonymousEnumDeclaration", "anonymousEnumDeclaration")); mixin(generateProperty("AttributeDeclaration", "attributeDeclaration")); mixin(generateProperty("ClassDeclaration", "classDeclaration")); mixin(generateProperty("ConditionalDeclaration", "conditionalDeclaration")); mixin(generateProperty("Constructor", "constructor")); mixin(generateProperty("DebugSpecification", "debugSpecification")); mixin(generateProperty("Destructor", "destructor")); mixin(generateProperty("EnumDeclaration", "enumDeclaration")); mixin(generateProperty("EponymousTemplateDeclaration", "eponymousTemplateDeclaration")); mixin(generateProperty("FunctionDeclaration", "functionDeclaration")); mixin(generateProperty("ImportDeclaration", "importDeclaration")); mixin(generateProperty("InterfaceDeclaration", "interfaceDeclaration")); mixin(generateProperty("Invariant", "invariant_")); mixin(generateProperty("MixinDeclaration", "mixinDeclaration")); mixin(generateProperty("MixinTemplateDeclaration", "mixinTemplateDeclaration")); mixin(generateProperty("Postblit", "postblit")); mixin(generateProperty("PragmaDeclaration", "pragmaDeclaration")); mixin(generateProperty("SharedStaticConstructor", "sharedStaticConstructor")); mixin(generateProperty("SharedStaticDestructor", "sharedStaticDestructor")); mixin(generateProperty("StaticAssertDeclaration", "staticAssertDeclaration")); mixin(generateProperty("StaticConstructor", "staticConstructor")); mixin(generateProperty("StaticDestructor", "staticDestructor")); mixin(generateProperty("StructDeclaration", "structDeclaration")); mixin(generateProperty("TemplateDeclaration", "templateDeclaration")); mixin(generateProperty("UnionDeclaration", "unionDeclaration")); mixin(generateProperty("Unittest", "unittest_")); mixin(generateProperty("VariableDeclaration", "variableDeclaration")); mixin(generateProperty("VersionSpecification", "versionSpecification")); mixin(generateProperty("StaticForeachDeclaration", "staticForeachDeclaration")); override bool opEquals(Object other) const { auto otherDeclaration = cast(Declaration) other; if (otherDeclaration is null) return false; return attributes == otherDeclaration.attributes && declarations == otherDeclaration.declarations && storage == otherDeclaration.storage; } } /// final class DeclarationsAndStatements : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationsAndStatements)); } /** */ DeclarationOrStatement[] declarationsAndStatements; mixin OpEquals; } /// final class DeclarationOrStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declaration, statement)); } /** */ Declaration declaration; /** */ Statement statement; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class Declarator : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, initializer)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Initializer initializer; /** */ TypeSuffix[] cstyle; /** */ string comment; mixin OpEquals; } /// final class DeclaratorIdentifierList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifiers)); } /** */ Token[] identifiers; mixin OpEquals; } /// final class DefaultStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationsAndStatements)); } /** */ DeclarationsAndStatements declarationsAndStatements; /** */ size_t colonLocation; mixin OpEquals; } /// final class DeleteExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(unaryExpression)); } /** */ UnaryExpression unaryExpression; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class DeleteStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(deleteExpression)); } /** */ DeleteExpression deleteExpression; mixin OpEquals; } /// final class Deprecated : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class Destructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t line; /** */ size_t column; /** */ size_t index; /** */ string comment; mixin OpEquals; } /// final class DoStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; /** */ Expression expression; mixin OpEquals; } /// final class EnumBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(enumMembers)); } /** */ EnumMember[] enumMembers; /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; mixin OpEquals; } /// final class EnumDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, enumBody)); } /** */ Token name; /** */ Type type; /** */ EnumBody enumBody; /** */ string comment; mixin OpEquals; } final class EnumMemberAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(deprecated_, atAttribute)); } /** */ Deprecated deprecated_; /** */ AtAttribute atAttribute; mixin OpEquals; } /// final class EnumMember : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(enumMemberAttributes, name, type, assignExpression)); } /** */ EnumMemberAttribute[] enumMemberAttributes; /** */ Token name; /** */ Type type; /** */ ExpressionNode assignExpression; /** */ string comment; mixin OpEquals; } /// final class EponymousTemplateDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, assignExpression)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ ExpressionNode assignExpression; /** */ Type type; /** */ string comment; mixin OpEquals; } /// final class EqualExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class Expression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ ExpressionNode[] items; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class ExpressionStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ Expression expression; mixin OpEquals; } /// final class FinalSwitchStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(switchStatement)); } /** */ SwitchStatement switchStatement; mixin OpEquals; } /// final class Finally : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationOrStatement)); } /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class ForStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(initialization, test, increment, declarationOrStatement)); } /** */ DeclarationOrStatement initialization; /** */ Expression test; /** */ Expression increment; /** */ DeclarationOrStatement declarationOrStatement; /** */ size_t startIndex; mixin OpEquals; } /// final class Foreach(bool declOnly) : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(foreachType, foreachTypeList, low, high)); static if (declOnly) mixin (visitIfNotNull!(declarations)); else mixin (visitIfNotNull!(declarationOrStatement)); } /** */ IdType type; /** */ ForeachTypeList foreachTypeList; /** */ ForeachType foreachType; /** */ Expression low; /** */ Expression high; /** */ size_t startIndex; static if (declOnly) { /** */ Declaration[] declarations; /** */ DeclarationListStyle style; } else { /** */ DeclarationOrStatement declarationOrStatement; } mixin OpEquals; } /// alias StaticForeachDeclaration = Foreach!true; /// alias ForeachStatement = Foreach!false; /// final class StaticForeachStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(foreachStatement)); } /** */ ForeachStatement foreachStatement; mixin OpEquals; } /// final class ForeachType : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier)); } /** */ bool isAlias; /** */ bool isEnum; /** */ bool isRef; /** */ IdType[] typeConstructors; /** */ Type type; /** */ Token identifier; mixin OpEquals; } /// final class ForeachTypeList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ ForeachType[] items; mixin OpEquals; } /// final class FunctionAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, atAttribute)); } /** */ Token token; /** */ AtAttribute atAttribute; mixin OpEquals; } /// final class FunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(specifiedFunctionBody, missingFunctionBody, shortenedFunctionBody)); } /** */ size_t endLocation; /** */ SpecifiedFunctionBody specifiedFunctionBody; /** */ MissingFunctionBody missingFunctionBody; /** */ ShortenedFunctionBody shortenedFunctionBody; mixin OpEquals; } /// final class FunctionCallExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, unaryExpression, templateArguments, arguments)); } /** */ Type type; /** */ UnaryExpression unaryExpression; /** */ TemplateArguments templateArguments; /** */ Arguments arguments; mixin OpEquals; } /// final class FunctionContract : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(inOutContractExpression, inOutStatement)); } /** */ InOutContractExpression inOutContractExpression; /** */ InOutStatement inOutStatement; mixin OpEquals; } /// final class FunctionDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(attributes, storageClasses, returnType, parameters, templateParameters, constraint, memberFunctionAttributes, functionBody)); } /** */ bool hasAuto; /** */ bool hasRef; /** */ Type returnType; /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Parameters parameters; /** */ Constraint constraint; /** */ FunctionBody functionBody; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ string comment; /** */ Attribute[] attributes; /** */ StorageClass[] storageClasses; mixin OpEquals; } /// final class FunctionLiteralExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(returnType, parameters, functionAttributes, memberFunctionAttributes, specifiedFunctionBody, assignExpression)); } /** */ ExpressionNode assignExpression; /** */ FunctionAttribute[] functionAttributes; /** */ SpecifiedFunctionBody specifiedFunctionBody; /** */ IdType functionOrDelegate; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ Parameters parameters; /** */ Token identifier; /** */ Type returnType; /** */ bool isReturnRef; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class GccAsmInstruction : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assemblerTemplate, inputOperands, outputOperands, registers, gotos)); } /** */ Expression assemblerTemplate; /** */ GccAsmOperandList inputOperands; /** */ GccAsmOperandList outputOperands; /** */ StringLiteralList registers; /** */ DeclaratorIdentifierList gotos; mixin OpEquals; } /// final class GccAsmOperand : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, constraint, symbolicName)); } /** */ Token symbolicName; /** */ Token constraint; /** */ ExpressionNode expression; mixin OpEquals; } /// final class GccAsmOperandList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ GccAsmOperand[] items; mixin OpEquals; } /// final class GotoStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(label, expression)); } /** */ Expression expression; /** */ Token label; mixin OpEquals; } /// final class IdentifierChain : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifiers)); } /** */ Token[] identifiers; mixin OpEquals; } /// final class TypeIdentifierPart : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrTemplateInstance, typeIdentifierPart, indexer)); } /** */ bool dot; /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance; /** */ TypeIdentifierPart typeIdentifierPart ; /** */ ExpressionNode indexer; mixin OpEquals; } /// final class IdentifierOrTemplateChain : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifiersOrTemplateInstances)); } /** */ IdentifierOrTemplateInstance[] identifiersOrTemplateInstances; mixin OpEquals; } /// final class IdentifierOrTemplateInstance : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateInstance)); } /** */ Token identifier; /** */ TemplateInstance templateInstance; mixin OpEquals; } /// final class IdentityExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ bool negated; mixin BinaryExpressionBody; mixin OpEquals; } /// final class IfStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, type, expression, thenStatement, elseStatement)); } /** */ IdType[] typeCtors; /** */ Type type; /** */ Token identifier; /** */ Expression expression; /** */ DeclarationOrStatement thenStatement; /** */ DeclarationOrStatement elseStatement; /** */ size_t startIndex; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class ImportBind : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ Token left; /** */ Token right; mixin OpEquals; } /// final class ImportBindings : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(singleImport, importBinds)); } /** */ SingleImport singleImport; /** */ ImportBind[] importBinds; mixin OpEquals; } /// final class ImportDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(singleImports, importBindings)); } /** */ SingleImport[] singleImports; /** */ ImportBindings importBindings; /** */ size_t startIndex; /** */ size_t endIndex; mixin OpEquals; } /// final class ImportExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class Index : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(low, high)); } /** */ ExpressionNode low; /** */ ExpressionNode high; mixin OpEquals; } /// final class IndexExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(unaryExpression, indexes)); } /** */ UnaryExpression unaryExpression; /** */ Index[] indexes; mixin OpEquals; } /// final class InContractExpression : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertArguments)); } /** */ size_t inTokenLocation; /** */ AssertArguments assertArguments; mixin OpEquals; } /// final class InExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; bool negated; mixin OpEquals; } /// final class InOutContractExpression : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(inContractExpression, outContractExpression)); } /** */ InContractExpression inContractExpression; /** */ OutContractExpression outContractExpression; mixin OpEquals; } /// final class InOutStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(inStatement, outStatement)); } /** */ InStatement inStatement; /** */ OutStatement outStatement; mixin OpEquals; } /// final class InStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(blockStatement)); } /** */ size_t inTokenLocation; /** */ BlockStatement blockStatement; mixin OpEquals; } /// final class Initialize : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; mixin OpEquals; } /// final class Initializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(nonVoidInitializer)); } /** */ NonVoidInitializer nonVoidInitializer; mixin OpEquals; } /// final class InterfaceDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, constraint, baseClassList, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ BaseClassList baseClassList; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class Invariant : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(blockStatement, assertArguments)); } /** */ BlockStatement blockStatement; /** */ AssertArguments assertArguments; /** */ bool useParen; /** */ string comment; size_t line; size_t index; mixin OpEquals; } /// final class IsExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, typeSpecialization, templateParameterList)); } /** */ Type type; /** */ Token identifier; /** */ TypeSpecialization typeSpecialization; /** */ TemplateParameterList templateParameterList; /** */ IdType equalsOrColon; mixin OpEquals; } /// final class KeyValuePair : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(key, value)); } /** */ ExpressionNode key; /** */ ExpressionNode value; mixin OpEquals; } /// final class KeyValuePairs : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(keyValuePairs)); } /** */ KeyValuePair[] keyValuePairs; mixin OpEquals; } /// final class LabeledStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, declarationOrStatement)); } /** */ Token identifier; /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class LastCatch : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; size_t line; size_t column; mixin OpEquals; } /// final class LinkageAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, typeIdentifierPart, cppNamespaces)); } /** */ Token identifier; /** */ bool hasPlusPlus; /** */ TypeIdentifierPart typeIdentifierPart; /** */ IdType classOrStruct; /** */ NamespaceList cppNamespaces; mixin OpEquals; } /// final class MemberFunctionAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(atAttribute)); } /** */ IdType tokenType; /** */ AtAttribute atAttribute; mixin OpEquals; } /// final class MissingFunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionContracts)); } /** */ FunctionContract[] functionContracts; mixin OpEquals; } /// final class MixinDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(mixinExpression, templateMixinExpression)); } /** */ MixinExpression mixinExpression; /** */ TemplateMixinExpression templateMixinExpression; mixin OpEquals; } /// final class MixinExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList)); } /** */ ArgumentList argumentList; mixin OpEquals; } /// final class MixinTemplateDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateDeclaration)); } /** */ TemplateDeclaration templateDeclaration; mixin OpEquals; } /// final class MixinTemplateName : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(symbol, typeofExpression, identifierOrTemplateChain)); } /** */ Symbol symbol; /** */ IdentifierOrTemplateChain identifierOrTemplateChain; /** */ TypeofExpression typeofExpression; mixin OpEquals; } /// final class Module : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(scriptLine, moduleDeclaration, declarations)); } /** */ Token scriptLine; /** */ ModuleDeclaration moduleDeclaration; /** */ Declaration[] declarations; mixin OpEquals; } /// final class ModuleDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(atAttributes, deprecated_, moduleName)); } /** */ AtAttribute[] atAttributes; /** */ Deprecated deprecated_; /** */ IdentifierChain moduleName; /** */ size_t startLocation; /** */ size_t endLocation; /** */ string comment; mixin OpEquals; } /// final class MulExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class NamespaceList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } mixin OpEquals; /** */ TernaryExpression[] items; } /// final class NewAnonClassExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(allocatorArguments, constructorArguments, baseClassList, structBody)); } /** */ Arguments allocatorArguments; /** */ Arguments constructorArguments; /** */ BaseClassList baseClassList; /** */ StructBody structBody; mixin OpEquals; } /// final class NewExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(newAnonClassExpression, type, arguments, assignExpression)); } /** */ Type type; /** */ NewAnonClassExpression newAnonClassExpression; /** */ Arguments arguments; /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class StatementNoCaseNoDefault : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(labeledStatement, blockStatement, ifStatement, whileStatement, doStatement, forStatement, foreachStatement, switchStatement, finalSwitchStatement, continueStatement, breakStatement, returnStatement, gotoStatement, withStatement, synchronizedStatement, tryStatement, scopeGuardStatement, asmStatement, pragmaStatement, conditionalStatement, staticAssertStatement, versionSpecification, debugSpecification, expressionStatement, staticForeachStatement)); } /** */ LabeledStatement labeledStatement; /** */ BlockStatement blockStatement; /** */ IfStatement ifStatement; /** */ WhileStatement whileStatement; /** */ DoStatement doStatement; /** */ ForStatement forStatement; /** */ ForeachStatement foreachStatement; /** */ StaticForeachStatement staticForeachStatement; /** */ SwitchStatement switchStatement; /** */ FinalSwitchStatement finalSwitchStatement; /** */ ContinueStatement continueStatement; /** */ BreakStatement breakStatement; /** */ ReturnStatement returnStatement; /** */ GotoStatement gotoStatement; /** */ WithStatement withStatement; /** */ SynchronizedStatement synchronizedStatement; /** */ TryStatement tryStatement; /** */ ScopeGuardStatement scopeGuardStatement; /** */ AsmStatement asmStatement; /** */ PragmaStatement pragmaStatement; /** */ ConditionalStatement conditionalStatement; /** */ StaticAssertStatement staticAssertStatement; /** */ VersionSpecification versionSpecification; /** */ DebugSpecification debugSpecification; /** */ ExpressionStatement expressionStatement; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class NonVoidInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression, arrayInitializer, structInitializer)); } /** */ ExpressionNode assignExpression; /** */ ArrayInitializer arrayInitializer; /** */ StructInitializer structInitializer; mixin OpEquals; } /// final class Operands : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(operands)); } /** */ ExpressionNode[] operands; mixin OpEquals; } /// final class OrExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class OrOrExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class OutContractExpression : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameter, assertArguments)); } /** */ size_t outTokenLocation; /** */ Token parameter; /** */ AssertArguments assertArguments; mixin OpEquals; } /// final class OutStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameter, blockStatement)); } /** */ size_t outTokenLocation; /** */ Token parameter; /** */ BlockStatement blockStatement; mixin OpEquals; } final class ParameterAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(atAttribute)); } /** */ IdType idType; /** */ AtAttribute atAttribute; } /// final class Parameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, name, default_)); } /** */ ParameterAttribute[] parameterAttributes; /** */ Type type; /** */ Token name; /** */ bool vararg; /** */ ExpressionNode default_; /** */ TypeSuffix[] cstyle; mixin OpEquals; } /// final class Parameters : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameters)); } /** */ Parameter[] parameters; /** */ bool hasVarargs; /** */ ParameterAttribute[] varargsAttributes; mixin OpEquals; } /// final class Postblit : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionBody)); } /** */ FunctionBody functionBody; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ size_t location; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class PowExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class PragmaDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(pragmaExpression)); } /** */ PragmaExpression pragmaExpression; mixin OpEquals; } /// final class PragmaExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, argumentList)); } /** */ Token identifier; /** */ ArgumentList argumentList; mixin OpEquals; } /// final class PragmaStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(pragmaExpression, statement, blockStatement)); } /** */ PragmaExpression pragmaExpression; /** */ Statement statement; /** */ BlockStatement blockStatement; mixin OpEquals; } /// final class PrimaryExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin(visitIfNotNull!(basicType, typeConstructor, type, primary, typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral, expression, dot, identifierOrTemplateInstance, isExpression, functionLiteralExpression,traitsExpression, mixinExpression, importExpression, vector, arguments)); } /** */ Token dot; /** */ Token primary; /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance; /** */ Token basicType; /** */ TypeofExpression typeofExpression; /** */ TypeidExpression typeidExpression; /** */ ArrayLiteral arrayLiteral; /** */ AssocArrayLiteral assocArrayLiteral; /** */ Expression expression; /** */ IsExpression isExpression; /** */ FunctionLiteralExpression functionLiteralExpression; /** */ TraitsExpression traitsExpression; /** */ MixinExpression mixinExpression; /** */ ImportExpression importExpression; /** */ Vector vector; /** */ Type type; /** */ Token typeConstructor; /** */ Arguments arguments; mixin OpEquals; } /// final class Register : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, intLiteral)); } /** */ Token identifier; /** */ Token intLiteral; /** */ bool hasIntegerLiteral; mixin OpEquals; } /// final class RelExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class ReturnStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ Expression expression; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class ScopeGuardStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, statementNoCaseNoDefault)); } /** */ Token identifier; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; mixin OpEquals; } /// final class SharedStaticConstructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class SharedStaticDestructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class ShiftExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class SingleImport : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(rename, identifierChain)); } /** */ Token rename; /** */ IdentifierChain identifierChain; mixin OpEquals; } /// final class SpecifiedFunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionContracts, blockStatement)); } /** */ FunctionContract[] functionContracts; /** */ BlockStatement blockStatement; /** */ bool hasDo; mixin OpEquals; } /// final class ShortenedFunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin(visitIfNotNull!(functionContracts, expression)); } /** */ FunctionContract[] functionContracts; /** */ Expression expression; mixin OpEquals; } /// final class Statement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(statementNoCaseNoDefault, caseStatement, caseRangeStatement, defaultStatement)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; /** */ CaseStatement caseStatement; /** */ CaseRangeStatement caseRangeStatement; /** */ DefaultStatement defaultStatement; mixin OpEquals; } /// final class StaticAssertDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(staticAssertStatement)); } /** */ StaticAssertStatement staticAssertStatement; mixin OpEquals; } /// final class StaticAssertStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertExpression)); } /** */ AssertExpression assertExpression; mixin OpEquals; } /// final class StaticConstructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class StaticDestructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class StaticIfCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class StorageClass : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, alignAttribute, linkageAttribute, atAttribute, deprecated_)); } /** */ AlignAttribute alignAttribute; /** */ LinkageAttribute linkageAttribute; /** */ AtAttribute atAttribute; /** */ Deprecated deprecated_; /** */ Token token; mixin OpEquals; } /// final class StringLiteralList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ Token[] items; mixin OpEquals; } /// final class StructBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarations)); } /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; /** */ Declaration[] declarations; mixin OpEquals; } /// final class StructDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, constraint, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class StructInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(structMemberInitializers)); } /** */ StructMemberInitializers structMemberInitializers; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class StructMemberInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, nonVoidInitializer)); } /** */ Token identifier; /** */ NonVoidInitializer nonVoidInitializer; mixin OpEquals; } /// final class StructMemberInitializers : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(structMemberInitializers)); } /** */ StructMemberInitializer[] structMemberInitializers; mixin OpEquals; } /// final class SwitchStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, statement)); } /** */ Expression expression; /** */ Statement statement; mixin OpEquals; } /// final class Symbol : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrTemplateChain)); } /** */ IdentifierOrTemplateChain identifierOrTemplateChain; /** */ bool dot; mixin OpEquals; } /// final class SynchronizedStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, statementNoCaseNoDefault)); } /** */ Expression expression; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; mixin OpEquals; } /// final class TemplateAliasParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, colonType, colonExpression, assignType, assignExpression)); } /** */ Type type; /** */ Token identifier; /** */ Type colonType; /** */ ExpressionNode colonExpression; /** */ Type assignType; /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class TemplateArgument : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, assignExpression)); } /** */ Type type; /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class TemplateArgumentList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ TemplateArgument[] items; mixin OpEquals; } /// final class TemplateArguments : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateArgumentList, templateSingleArgument)); } /** */ TemplateArgumentList templateArgumentList; /** */ TemplateSingleArgument templateSingleArgument; mixin OpEquals; } /// final class TemplateDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, constraint, declarations)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ Declaration[] declarations; /** */ string comment; /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; mixin OpEquals; } /// final class TemplateInstance : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateArguments)); } /** */ Token identifier; /** */ TemplateArguments templateArguments; mixin OpEquals; } /// final class TemplateMixinExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateArguments, mixinTemplateName)); } /** */ Token identifier; /** */ TemplateArguments templateArguments; /** */ MixinTemplateName mixinTemplateName; mixin OpEquals; } /// final class TemplateParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateTypeParameter, templateValueParameter, templateAliasParameter, templateTupleParameter, templateThisParameter)); } /** */ TemplateTypeParameter templateTypeParameter; /** */ TemplateValueParameter templateValueParameter; /** */ TemplateAliasParameter templateAliasParameter; /** */ TemplateTupleParameter templateTupleParameter; /** */ TemplateThisParameter templateThisParameter; mixin OpEquals; } /// final class TemplateParameterList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ TemplateParameter[] items; mixin OpEquals; } /// final class TemplateParameters : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameterList)); } /** */ TemplateParameterList templateParameterList; mixin OpEquals; } /// final class TemplateSingleArgument : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token)); } /** */ Token token; mixin OpEquals; } /// final class TemplateThisParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateTypeParameter)); } /** */ TemplateTypeParameter templateTypeParameter; mixin OpEquals; } /// final class TemplateTupleParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier)); } /** */ Token identifier; mixin OpEquals; } /// final class TemplateTypeParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, colonType, assignType)); } /** */ Token identifier; /** */ Type colonType; /** */ Type assignType; mixin OpEquals; } /// final class TemplateValueParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, assignExpression, templateValueParameterDefault)); } /** */ Type type; /** */ Token identifier; /** */ ExpressionNode assignExpression; /** */ TemplateValueParameterDefault templateValueParameterDefault; mixin OpEquals; } /// final class TemplateValueParameterDefault : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, assignExpression)); } /** */ ExpressionNode assignExpression; /** */ Token token; mixin OpEquals; } /// final class TernaryExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(orOrExpression, expression, ternaryExpression)); } /** */ ExpressionNode orOrExpression; /** */ ExpressionNode expression; /** */ ExpressionNode ternaryExpression; /// Store this so that we know where the ':' is Token colon; mixin OpEquals; } deprecated("Replaced by ExpressionStatement + ThrowExpression") alias ThrowStatement = ThrowExpression; /// final class ThrowExpression: ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ ExpressionNode expression; mixin OpEquals; } /// final class TraitsExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateArgumentList)); } /** */ Token identifier; /** */ TemplateArgumentList templateArgumentList; mixin OpEquals; } /// final class TryStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationOrStatement, catches, finally_)); } /** */ DeclarationOrStatement declarationOrStatement; /** */ Catches catches; /** */ Finally finally_; mixin OpEquals; } /// final class Type : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type2, typeSuffixes)); } /** */ IdType[] typeConstructors; /** */ TypeSuffix[] typeSuffixes; /** */ Type2 type2; mixin OpEquals; } /// final class Type2 : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(typeofExpression, typeIdentifierPart, type, traitsExpression, vector, mixinExpression)); } /** */ IdType builtinType; /** */ alias superOrThis = builtinType; /** */ TypeofExpression typeofExpression; /** */ TypeIdentifierPart typeIdentifierPart; /** */ IdType typeConstructor; /** */ Type type; /** */ TraitsExpression traitsExpression; /** */ Vector vector; /** */ MixinExpression mixinExpression; mixin OpEquals; } /// final class TypeSpecialization : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, type)); } /** */ Token token; /** */ Type type; mixin OpEquals; } /// final class TypeSuffix : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, low, high, delegateOrFunction, parameters, memberFunctionAttributes)); } /** */ Token delegateOrFunction; /** */ Token star; /** */ bool array; /** */ Type type; /** */ ExpressionNode low; /** */ ExpressionNode high; /** */ Parameters parameters; /** */ MemberFunctionAttribute[] memberFunctionAttributes; mixin OpEquals; } /// final class TypeidExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, expression)); } /** */ Type type; /** */ Expression expression; mixin OpEquals; } /// final class TypeofExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, return_)); } /** */ Expression expression; /** */ Token return_; mixin OpEquals; } /// final class UnaryExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { // TODO prefix, postfix, unary mixin (visitIfNotNull!(primaryExpression, newExpression, deleteExpression, castExpression, functionCallExpression, argumentList, unaryExpression, type, identifierOrTemplateInstance, assertExpression, throwExpression, indexExpression)); } /** */ Type type; /** */ PrimaryExpression primaryExpression; /** */ Token prefix; /** */ Token suffix; /** */ UnaryExpression unaryExpression; /** */ NewExpression newExpression; /** */ DeleteExpression deleteExpression; /** */ CastExpression castExpression; /** */ FunctionCallExpression functionCallExpression; /** */ ArgumentList argumentList; /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance; /** */ AssertExpression assertExpression; /** */ ThrowExpression throwExpression; /** */ IndexExpression indexExpression; /** */ size_t dotLocation; mixin OpEquals; } /// final class UnionDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, constraint, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class Unittest : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(blockStatement)); } /** */ BlockStatement blockStatement; /** */ string comment; /** */ size_t location; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class VariableDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(storageClasses, type, declarators, autoDeclaration)); } /** */ Type type; /** */ Declarator[] declarators; /** */ StorageClass[] storageClasses; /** */ AutoDeclaration autoDeclaration; /** */ string comment; mixin OpEquals; } /// final class Vector : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type)); } /** */ Type type; mixin OpEquals; } /// final class VersionCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token)); } /** */ size_t versionIndex; /** */ Token token; mixin OpEquals; } /// final class VersionSpecification : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token)); } /** */ Token token; mixin OpEquals; } /// final class WhileStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, declarationOrStatement)); } /** */ Expression expression; /** */ DeclarationOrStatement declarationOrStatement; /** */ size_t startIndex; mixin OpEquals; } /// final class WithStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, declarationOrStatement)); } /** */ Expression expression; /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class XorExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } unittest // issue #133 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; string src = q{module test133; void main(){}}; final class TkTest : ASTVisitor { alias visit = ASTVisitor.visit; override void visit(const Token t){assert(t.text.length);} } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); TkTest t = new TkTest; t.visit(m); } unittest // issue #165 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; string src = q{module test165; enum foo(T) = bar!T;}; final class EpoTest : ASTVisitor { bool visited; alias visit = ASTVisitor.visit; override void visit(const EponymousTemplateDeclaration){visited = true;} } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); EpoTest et = new EpoTest; et.visit(m); assert(et.visited); } unittest // issue #156 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; final class Test : ASTVisitor { bool arrIndex, arrValue, arrValueOnly, aaLiteral; alias visit = ASTVisitor.visit; override void visit(const ArrayInitializer ai) { if (ai.arrayMemberInitializations.length == 1) { arrIndex = ai.arrayMemberInitializations[0].assignExpression !is null; arrValue = ai.arrayMemberInitializations[0].nonVoidInitializer !is null; arrValueOnly = arrValue && !arrIndex; } } override void visit(const AssocArrayLiteral aal) { aaLiteral = true; } } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); { // no colon so array. string src1 = q{void main(){const arr = [[0]];}}; Module m = parseModule(ParserConfig(getTokensForParser(src1, cf, &ca), "", &ra)); Test t = new Test; t.visit(m); assert(t.arrValueOnly); } { // simple primary before colon, assume array. string src2 = q{void main(){const arr = [0:0];}}; Module m = ParserConfig(getTokensForParser(src2, cf, &ca), "", &ra).parseModule(); Test t = new Test; t.visit(m); assert(t.arrIndex); assert(t.arrValue); assert(!t.aaLiteral); } { // more complex exp before colon, assume AA. string src3 = q{void main(){const arr = [[0]:0];}}; Module m = ParserConfig(getTokensForParser(src3, cf, &ca), "", &ra).parseModule(); Test t = new Test; t.visit(m); assert(!t.arrIndex); assert(!t.arrValue); assert(t.aaLiteral); } } unittest // issue #170, issue #316 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; abstract class TestCase : ASTVisitor { string src; bool visited; this() { RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); visit(m); assert(visited); } } class FunctionLiteralExpressionTestCase : TestCase { alias visit = ASTVisitor.visit; override void visit(const FunctionLiteralExpression){visited = true;} } class StructInitializerTestCase : TestCase { alias visit = ASTVisitor.visit; override void visit(const StructInitializer){visited = true;} } new class FunctionLiteralExpressionTestCase {this(){ TestCase.src = q{ void function() a = {call();};}; super(); }}; new class FunctionLiteralExpressionTestCase {this(){ TestCase.src = q{ const a = {int i;};}; super(); }}; new class FunctionLiteralExpressionTestCase {this(){ TestCase.src = q{ const a = {};}; super(); }}; new class StructInitializerTestCase {this(){ TestCase.src = q{A a = {member : call()};}; super(); }}; new class StructInitializerTestCase {this(){ TestCase.src = q{A a = {0};}; super(); }}; } unittest // issue #193 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; final class Test193 : ASTVisitor { static string src = q{const(Type1[immutable(Type2)]) qualAarray;}; size_t tc; alias visit = ASTVisitor.visit; override void visit(const TypeIdentifierPart tip) { tip.accept(this); assert(tip.indexer is null); } override void visit(const Type type) { tc++; if (tc == 1) //const( { assert(type.type2.typeConstructor == tok!"const"); assert(type.type2.typeIdentifierPart is null); } else if (tc == 2) //const(Type1 { assert(type.typeConstructors.length == 0); assert(type.type2.typeIdentifierPart.identifierOrTemplateInstance .identifier.text == "Type1"); assert(type.typeSuffixes.length == 1); } else if (tc == 3) // immutable( { assert(type.type2.typeConstructor == tok!"immutable"); assert(type.type2.typeIdentifierPart is null); } else if (tc == 4) // immutable(Type2 { assert(type.typeConstructors.length == 0); assert(type.type2.typeIdentifierPart.identifierOrTemplateInstance .identifier.text == "Type2"); assert(type.typeSuffixes.length == 0); } type.accept(this); } } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(Test193.src, cf, &ca), "", &ra).parseModule(); Test193 t193 = new Test193; t193.visit(m); } unittest // there used to be a small regression when adding the ParserConfig { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = q{module m;}; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m1 = parseModule(getTokensForParser(src, cf, &ca), "", &ra , null); Module m2 = parseModule(getTokensForParser(src, cf, &ca), "", &ra); } unittest //#318 : used to segfault { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = q{ auto a = new TestClass( }; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); static void shut(string, size_t, size_t, string ,bool){} Module m1 = parseModule(getTokensForParser(src, cf, &ca), "", &ra , &shut); } unittest //#365 : used to segfault { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = " o[{scope(x "; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); static void shut(string, size_t, size_t, string ,bool){} Module m1 = parseModule(getTokensForParser(src, cf, &ca), "", &ra , &shut); } unittest // issue #398: Support extern(C++, <string expressions...>) { import dparse.lexer : LexerConfig; import dparse.parser : ParserConfig, parseModule; import dparse.rollback_allocator : RollbackAllocator; RollbackAllocator ra; StringCache ca = StringCache(16); const(PrimaryExpression)[] getNamespaces(const string sourceCode) { final class Test398 : ASTVisitor { alias visit = ASTVisitor.visit; const(PrimaryExpression)[] namespaces; override void visit(const LinkageAttribute link) { assert(link.identifier.text == "C"); assert(link.hasPlusPlus); assert(!link.typeIdentifierPart); assert(!link.classOrStruct); assert(link.cppNamespaces); super.visit(link); } override void visit(const NamespaceList list) { assert(list.items.length); assert(!namespaces); foreach (const entry; list.items) { const prim = cast(PrimaryExpression) entry.expression; assert(prim); namespaces ~= prim; } } } LexerConfig cf = LexerConfig("", StringBehavior.source); Module m = ParserConfig(getTokensForParser(sourceCode, cf, &ca), "", &ra).parseModule(); scope visitor = new Test398(); visitor.visit(m); return visitor.namespaces; } void checkText(const PrimaryExpression pe, const string exp) { assert(pe); const act = pe.primary.text; assert(act == exp, '<' ~ act ~ '>'); } auto ns = getNamespaces(`extern(C++, "foo") int i;`); assert(ns.length == 1); checkText(ns[0], `"foo"`); ns = getNamespaces(`extern(C++, "foo", "bar", "baz",) int i;`); assert(ns.length == 3); checkText(ns[0], `"foo"`); checkText(ns[1], `"bar"`); checkText(ns[2], `"baz"`); } unittest // Differentiate between no and empty DDOC comments, e.g. for DDOC unittests { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = q{ /// unittest {} /// @safe pure unittest {} /****/ unittest {} /++++/ unittest {} /// This is a comment! unittest {} unittest {} }; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = parseModule(getTokensForParser(src, cf, &ca), "", &ra); final class UnittestVisitor : ASTVisitor { alias visit = ASTVisitor.visit; bool[size_t] found; override void visit(const Unittest test) { assert(test.line !in found); found[test.line] = true; switch (test.line) { case 3, 6, 8, 10: assert(test.comment !is null); assert(test.comment == ""); break; case 13: assert(test.comment == "This is a comment!"); break; case 15: assert(test.comment is null); break; default: assert(false, format("Unknown line: %d", test.line)); } } } scope visitor = new UnittestVisitor(); visitor.visit(m); assert(visitor.found.length == 6); } unittest // Support GCC-sytle asm statements { static void verify(T)(const string code, void function(scope const T) handler) { import dparse.lexer, dparse.parser, dparse.rollback_allocator; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = parseModule(getTokensForParser("void main() { " ~ code ~ '}', cf, &ca), "", &ra); final class AsmVisitor : ASTVisitor { alias visit = ASTVisitor.visit; bool found; override void visit(const T node) { assert(!found); found = true; handler(node); } } scope visitor = new AsmVisitor(); visitor.visit(m); assert(visitor.found); } static void first(scope const AsmStatement stmt) { assert(stmt.asmInstructions.length == 0); assert(stmt.gccAsmInstructions.length == 1); with (stmt.gccAsmInstructions[0]) { assert(assemblerTemplate); assert(assemblerTemplate.tokens.length == 1); assert(assemblerTemplate.tokens[0].type == tok!"stringLiteral"); assert(assemblerTemplate.tokens[0].text == `"mov %0, EAX"`); assert(outputOperands); assert(outputOperands.items.length == 1); with (outputOperands.items[0]) { assert(constraint.type == tok!"stringLiteral"); assert(constraint.text == `"=r"`); auto una = cast(UnaryExpression) expression; assert(una); assert(una.primaryExpression.identifierOrTemplateInstance.identifier.text == "var1"); } } } verify(q{ asm { "mov %0, EAX" : "=r" (var1) ; } }, &first); static void second(scope const AsmStatement stmt) { first(stmt); with (stmt.gccAsmInstructions[0]) { assert(inputOperands); assert(inputOperands.items.length == 2); with (inputOperands.items[0]) { assert(symbolicName.type == tok!"identifier"); assert(symbolicName.text == "xy"); assert(constraint.type == tok!"stringLiteral"); assert(constraint.text == `"=w"`); auto una = cast(UnaryExpression) expression; assert(una); assert(una.primaryExpression.identifierOrTemplateInstance.identifier.text == "var2"); } with (inputOperands.items[1]) { assert(constraint.type == tok!"stringLiteral"); assert(constraint.text == `"g"`); auto una = cast(UnaryExpression) expression; assert(una); assert(una.primaryExpression.identifierOrTemplateInstance.identifier.text == "var3"); } } } verify(q{ asm { "mov %0, EAX" : "=r" (var1) : [xy] "=w" (var2), "g" (var3); } }, &second); verify(q{ asm { "mov %0, EAX" : "=r" (var1) : [xy] "=w" (var2), "g" (var3) : "r0" ; } }, (scope const AsmStatement stmt) { second(stmt); with (stmt.gccAsmInstructions[0]) { assert(registers); assert(registers.items.length == 1); assert(registers.items[0].type == tok!"stringLiteral"); assert(registers.items[0].text == `"r0"`); } }); verify(q{ asm { "mov EBX, EAX" : : : "r0", "r1" ; } }, (scope const GccAsmInstruction instr) { with (instr) { assert(registers); assert(registers.items.length == 2); assert(registers.items[0].type == tok!"stringLiteral"); assert(registers.items[0].text == `"r0"`); assert(registers.items[1].type == tok!"stringLiteral"); assert(registers.items[1].text == `"r1"`); } }); verify(q{ asm { "jmp LEnd" : : : : LEnd ; } }, (scope const GccAsmInstruction instr) { with (instr) { assert(gotos); assert(gotos.identifiers.length == 1); assert(gotos.identifiers[0].type == tok!"identifier"); assert(gotos.identifiers[0].text == `LEnd`); } }); }
// Written in the D programming language. /** * This module defines an Abstract Syntax Tree for the D language * * Examples: * --- * // TODO * --- * * Copyright: Brian Schott 2013 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt Boost, License 1.0) * Authors: Brian Schott */ module dparse.ast; import dparse.lexer; import std.traits; import std.algorithm; import std.array; import std.string; private immutable uint[TypeInfo] typeMap; shared static this() { typeMap[typeid(AddExpression)] = 1; typeMap[typeid(AndAndExpression)] = 2; typeMap[typeid(AndExpression)] = 3; typeMap[typeid(AsmAddExp)] = 4; typeMap[typeid(AsmAndExp)] = 5; typeMap[typeid(AsmBrExp)] = 6; typeMap[typeid(AsmExp)] = 7; typeMap[typeid(AsmEqualExp)] = 8; typeMap[typeid(AsmLogAndExp)] = 9; typeMap[typeid(AsmLogOrExp)] = 10; typeMap[typeid(AsmMulExp)] = 11; typeMap[typeid(AsmOrExp)] = 12; typeMap[typeid(AsmRelExp)] = 13; typeMap[typeid(AsmUnaExp)] = 14; typeMap[typeid(AsmShiftExp)] = 15; typeMap[typeid(AsmXorExp)] = 16; typeMap[typeid(AssertExpression)] = 17; typeMap[typeid(AssignExpression)] = 18; typeMap[typeid(CmpExpression)] = 19; typeMap[typeid(DeleteExpression)] = 20; typeMap[typeid(EqualExpression)] = 21; typeMap[typeid(Expression)] = 22; typeMap[typeid(FunctionCallExpression)] = 23; typeMap[typeid(FunctionLiteralExpression)] = 24; typeMap[typeid(IdentityExpression)] = 25; typeMap[typeid(ImportExpression)] = 26; typeMap[typeid(IndexExpression)] = 27; typeMap[typeid(InExpression)] = 28; typeMap[typeid(IsExpression)] = 29; typeMap[typeid(MixinExpression)] = 30; typeMap[typeid(MulExpression)] = 31; typeMap[typeid(NewAnonClassExpression)] = 32; typeMap[typeid(NewExpression)] = 33; typeMap[typeid(OrExpression)] = 34; typeMap[typeid(OrOrExpression)] = 35; typeMap[typeid(PowExpression)] = 36; typeMap[typeid(PragmaExpression)] = 37; typeMap[typeid(PrimaryExpression)] = 38; typeMap[typeid(RelExpression)] = 39; typeMap[typeid(ShiftExpression)] = 40; typeMap[typeid(Index)] = 41; typeMap[typeid(TemplateMixinExpression)] = 42; typeMap[typeid(TernaryExpression)] = 43; typeMap[typeid(TraitsExpression)] = 44; typeMap[typeid(TypeidExpression)] = 45; typeMap[typeid(TypeofExpression)] = 46; typeMap[typeid(UnaryExpression)] = 47; typeMap[typeid(XorExpression)] = 48; } /// Describes which syntax was used in a list of declarations in the containing AST node enum DeclarationListStyle : ubyte { /// A declaration directly after the containing AST node making it the only child single, /// A colon (`:`) was used in the containing AST node meaning all following declarations are part here. colon, /// The declarations have been specified in a block denoted by starting `{` and ending `}` tokens. block } /** * Implements the $(LINK2 http://en.wikipedia.org/wiki/Visitor_pattern, Visitor Pattern) * for the various AST classes */ abstract class ASTVisitor { /** */ void visit(const ExpressionNode n) { switch (typeMap[typeid(n)]) { case 1: visit(cast(AddExpression) n); break; case 2: visit(cast(AndAndExpression) n); break; case 3: visit(cast(AndExpression) n); break; case 4: visit(cast(AsmAddExp) n); break; case 5: visit(cast(AsmAndExp) n); break; case 6: visit(cast(AsmBrExp) n); break; case 7: visit(cast(AsmExp) n); break; case 8: visit(cast(AsmEqualExp) n); break; case 9: visit(cast(AsmLogAndExp) n); break; case 10: visit(cast(AsmLogOrExp) n); break; case 11: visit(cast(AsmMulExp) n); break; case 12: visit(cast(AsmOrExp) n); break; case 13: visit(cast(AsmRelExp) n); break; case 14: visit(cast(AsmUnaExp) n); break; case 15: visit(cast(AsmShiftExp) n); break; case 16: visit(cast(AsmXorExp) n); break; case 17: visit(cast(AssertExpression) n); break; case 18: visit(cast(AssignExpression) n); break; case 19: visit(cast(CmpExpression) n); break; case 20: visit(cast(DeleteExpression) n); break; case 21: visit(cast(EqualExpression) n); break; case 22: visit(cast(Expression) n); break; case 23: visit(cast(FunctionCallExpression) n); break; case 24: visit(cast(FunctionLiteralExpression) n); break; case 25: visit(cast(IdentityExpression) n); break; case 26: visit(cast(ImportExpression) n); break; case 27: visit(cast(IndexExpression) n); break; case 28: visit(cast(InExpression) n); break; case 29: visit(cast(IsExpression) n); break; case 30: visit(cast(MixinExpression) n); break; case 31: visit(cast(MulExpression) n); break; case 32: visit(cast(NewAnonClassExpression) n); break; case 33: visit(cast(NewExpression) n); break; case 34: visit(cast(OrExpression) n); break; case 35: visit(cast(OrOrExpression) n); break; case 36: visit(cast(PowExpression) n); break; case 37: visit(cast(PragmaExpression) n); break; case 38: visit(cast(PrimaryExpression) n); break; case 39: visit(cast(RelExpression) n); break; case 40: visit(cast(ShiftExpression) n); break; case 41: visit(cast(Index) n); break; case 42: visit(cast(TemplateMixinExpression) n); break; case 43: visit(cast(TernaryExpression) n); break; case 44: visit(cast(TraitsExpression) n); break; case 45: visit(cast(TypeidExpression) n); break; case 46: visit(cast(TypeofExpression) n); break; case 47: visit(cast(UnaryExpression) n); break; case 48: visit(cast(XorExpression) n); break; default: assert(false, __MODULE__ ~ " has a bug"); } } /** */ void visit(const AddExpression addExpression) { addExpression.accept(this); } /** */ void visit(const AliasDeclaration aliasDeclaration) { aliasDeclaration.accept(this); } /** */ void visit(const AliasAssign aliasAssign) { aliasAssign.accept(this); } /** */ void visit(const AliasInitializer aliasInitializer) { aliasInitializer.accept(this); } /** */ void visit(const AliasThisDeclaration aliasThisDeclaration) { aliasThisDeclaration.accept(this); } /** */ void visit(const AlignAttribute alignAttribute) { alignAttribute.accept(this); } /** */ void visit(const AndAndExpression andAndExpression) { andAndExpression.accept(this); } /** */ void visit(const AndExpression andExpression) { andExpression.accept(this); } /** */ void visit(const AnonymousEnumDeclaration anonymousEnumDeclaration) { anonymousEnumDeclaration.accept(this); } /** */ void visit(const AnonymousEnumMember anonymousEnumMember) { anonymousEnumMember.accept(this); } /** */ void visit(const ArgumentList argumentList) { argumentList.accept(this); } /** */ void visit(const Arguments arguments) { arguments.accept(this); } /** */ void visit(const ArrayInitializer arrayInitializer) { arrayInitializer.accept(this); } /** */ void visit(const ArrayLiteral arrayLiteral) { arrayLiteral.accept(this); } /** */ void visit(const ArrayMemberInitialization arrayMemberInitialization) { arrayMemberInitialization.accept(this); } /** */ void visit(const AsmAddExp asmAddExp) { asmAddExp.accept(this); } /** */ void visit(const AsmAndExp asmAndExp) { asmAndExp.accept(this); } /** */ void visit(const AsmBrExp asmBrExp) { asmBrExp.accept(this); } /** */ void visit(const AsmEqualExp asmEqualExp) { asmEqualExp.accept(this); } /** */ void visit(const AsmExp asmExp) { asmExp.accept(this); } /** */ void visit(const AsmInstruction asmInstruction) { asmInstruction.accept(this); } /** */ void visit(const AsmLogAndExp asmLogAndExp) { asmLogAndExp.accept(this); } /** */ void visit(const AsmLogOrExp asmLogOrExp) { asmLogOrExp.accept(this); } /** */ void visit(const AsmMulExp asmMulExp) { asmMulExp.accept(this); } /** */ void visit(const AsmOrExp asmOrExp) { asmOrExp.accept(this); } /** */ void visit(const AsmPrimaryExp asmPrimaryExp) { asmPrimaryExp.accept(this); } /** */ void visit(const AsmRelExp asmRelExp) { asmRelExp.accept(this); } /** */ void visit(const AsmShiftExp asmShiftExp) { asmShiftExp.accept(this); } /** */ void visit(const AsmStatement asmStatement) { asmStatement.accept(this); } /** */ void visit(const AsmTypePrefix asmTypePrefix) { asmTypePrefix.accept(this); } /** */ void visit(const AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); } /** */ void visit(const AsmXorExp asmXorExp) { asmXorExp.accept(this); } /** */ void visit(const AssertArguments assertArguments) { assertArguments.accept(this); } /** */ void visit(const AssertExpression assertExpression) { assertExpression.accept(this); } /** */ void visit(const AssignExpression assignExpression) { assignExpression.accept(this); } /** */ void visit(const AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); } /** */ void visit(const AtAttribute atAttribute) { atAttribute.accept(this); } /** */ void visit(const Attribute attribute) { attribute.accept(this); } /** */ void visit(const AttributeDeclaration attributeDeclaration) { attributeDeclaration.accept(this); } /** */ void visit(const AutoDeclaration autoDeclaration) { autoDeclaration.accept(this); } /** */ void visit(const AutoDeclarationPart autoDeclarationPart) { autoDeclarationPart.accept(this); } /** */ void visit(const BlockStatement blockStatement) { blockStatement.accept(this); } /** */ void visit(const BreakStatement breakStatement) { breakStatement.accept(this); } /** */ void visit(const BaseClass baseClass) { baseClass.accept(this); } /** */ void visit(const BaseClassList baseClassList) { baseClassList.accept(this); } /** */ void visit(const CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); } /** */ void visit(const CaseStatement caseStatement) { caseStatement.accept(this); } /** */ void visit(const CastExpression castExpression) { castExpression.accept(this); } /** */ void visit(const CastQualifier castQualifier) { castQualifier.accept(this); } /** */ void visit(const Catch catch_) { catch_.accept(this); } /** */ void visit(const Catches catches) { catches.accept(this); } /** */ void visit(const ClassDeclaration classDeclaration) { classDeclaration.accept(this); } /** */ void visit(const CmpExpression cmpExpression) { cmpExpression.accept(this); } /** */ void visit(const CompileCondition compileCondition) { compileCondition.accept(this); } /** */ void visit(const ConditionalDeclaration conditionalDeclaration) { conditionalDeclaration.accept(this); } /** */ void visit(const ConditionalStatement conditionalStatement) { conditionalStatement.accept(this); } /** */ void visit(const Constraint constraint) { constraint.accept(this); } /** */ void visit(const Constructor constructor) { constructor.accept(this); } /** */ void visit(const ContinueStatement continueStatement) { continueStatement.accept(this); } /** */ void visit(const DebugCondition debugCondition) { debugCondition.accept(this); } /** */ void visit(const DebugSpecification debugSpecification) { debugSpecification.accept(this); } /** */ void visit(const Declaration declaration) { declaration.accept(this); } /** */ void visit(const DeclarationOrStatement declarationsOrStatement) { declarationsOrStatement.accept(this); } /** */ void visit(const DeclarationsAndStatements declarationsAndStatements) { declarationsAndStatements.accept(this); } /** */ void visit(const Declarator declarator) { declarator.accept(this); } /** */ void visit(const DefaultStatement defaultStatement) { defaultStatement.accept(this); } /** */ void visit(const DeleteExpression deleteExpression) { deleteExpression.accept(this); } /** */ void visit(const DeleteStatement deleteStatement) { deleteStatement.accept(this); } /** */ void visit(const Deprecated deprecated_) { deprecated_.accept(this); } /** */ void visit(const Destructor destructor) { destructor.accept(this); } /** */ void visit(const DoStatement doStatement) { doStatement.accept(this); } /** */ void visit(const EnumBody enumBody) { enumBody.accept(this); } /** */ void visit(const EnumDeclaration enumDeclaration) { enumDeclaration.accept(this); } /** */ void visit(const EnumMember enumMember) { enumMember.accept(this); } /** */ void visit(const EnumMemberAttribute enumMemberAttribute) { enumMemberAttribute.accept(this); } /** */ void visit(const EponymousTemplateDeclaration eponymousTemplateDeclaration) { eponymousTemplateDeclaration.accept(this); } /** */ void visit(const EqualExpression equalExpression) { equalExpression.accept(this); } /** */ void visit(const Expression expression) { expression.accept(this); } /** */ void visit(const ExpressionStatement expressionStatement) { expressionStatement.accept(this); } /** */ void visit(const FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); } /** */ void visit(const Finally finally_) { finally_.accept(this); } /** */ void visit(const ForStatement forStatement) { forStatement.accept(this); } /** */ void visit(const ForeachStatement foreachStatement) { foreachStatement.accept(this); } /** */ void visit(const StaticForeachDeclaration staticForeachDeclaration) { staticForeachDeclaration.accept(this); } /** */ void visit(const StaticForeachStatement staticForeachStatement) { staticForeachStatement.accept(this); } /** */ void visit(const ForeachType foreachType) { foreachType.accept(this); } /** */ void visit(const ForeachTypeList foreachTypeList) { foreachTypeList.accept(this); } /** */ void visit(const FunctionAttribute functionAttribute) { functionAttribute.accept(this); } /** */ void visit(const FunctionBody functionBody) { functionBody.accept(this); } /** */ void visit(const FunctionCallExpression functionCallExpression) { functionCallExpression.accept(this); } /** */ void visit(const FunctionContract functionContract) { functionContract.accept(this); } /** */ void visit(const FunctionDeclaration functionDeclaration) { functionDeclaration.accept(this); } /** */ void visit(const FunctionLiteralExpression functionLiteralExpression) { functionLiteralExpression.accept(this); } /** */ void visit(const GccAsmInstruction gccAsmInstruction) { gccAsmInstruction.accept(this); } /** */ void visit(const GccAsmOperandList gccAsmOperands) { gccAsmOperands.accept(this); } /** */ void visit(const GccAsmOperand gccAsmOperand) { gccAsmOperand.accept(this); } /** */ void visit(const GotoStatement gotoStatement) { gotoStatement.accept(this); } /** */ void visit(const IdentifierChain identifierChain) { identifierChain.accept(this); } /** */ void visit(const DeclaratorIdentifierList identifierList) { identifierList.accept(this); } /** */ void visit(const IdentifierOrTemplateChain identifierOrTemplateChain) { identifierOrTemplateChain.accept(this); } /** */ void visit(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { identifierOrTemplateInstance.accept(this); } /** */ void visit(const IdentityExpression identityExpression) { identityExpression.accept(this); } /** */ void visit(const IfStatement ifStatement) { ifStatement.accept(this); } /** */ void visit(const ImportBind importBind) { importBind.accept(this); } /** */ void visit(const ImportBindings importBindings) { importBindings.accept(this); } /** */ void visit(const ImportDeclaration importDeclaration) { importDeclaration.accept(this); } /** */ void visit(const ImportExpression importExpression) { importExpression.accept(this); } /** */ void visit(const IndexExpression indexExpression) { indexExpression.accept(this); } /** */ void visit(const InContractExpression inContractExpression) { inContractExpression.accept(this); } /** */ void visit(const InExpression inExpression) { inExpression.accept(this); } /** */ void visit(const InOutContractExpression inOutContractExpression) { inOutContractExpression.accept(this); } /** */ void visit(const InOutStatement inOutStatement) { inOutStatement.accept(this); } /** */ void visit(const InStatement inStatement) { inStatement.accept(this); } /** */ void visit(const Initialize initialize) { initialize.accept(this); } /** */ void visit(const Initializer initializer) { initializer.accept(this); } /** */ void visit(const InterfaceDeclaration interfaceDeclaration) { interfaceDeclaration.accept(this); } /** */ void visit(const Invariant invariant_) { invariant_.accept(this); } /** */ void visit(const IsExpression isExpression) { isExpression.accept(this); } /** */ void visit(const KeyValuePair keyValuePair) { keyValuePair.accept(this); } /** */ void visit(const KeyValuePairs keyValuePairs) { keyValuePairs.accept(this); } /** */ void visit(const LabeledStatement labeledStatement) { labeledStatement.accept(this); } /** */ void visit(const LastCatch lastCatch) { lastCatch.accept(this); } /** */ void visit(const LinkageAttribute linkageAttribute) { linkageAttribute.accept(this); } /** */ void visit(const MemberFunctionAttribute memberFunctionAttribute) { memberFunctionAttribute.accept(this); } /** */ void visit(const MissingFunctionBody missingFunctionBody) { missingFunctionBody.accept(this); } /** */ void visit(const MixinDeclaration mixinDeclaration) { mixinDeclaration.accept(this); } /** */ void visit(const MixinExpression mixinExpression) { mixinExpression.accept(this); } /** */ void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixinTemplateDeclaration.accept(this); } /** */ void visit(const MixinTemplateName mixinTemplateName) { mixinTemplateName.accept(this); } /** */ void visit(const Module module_) { module_.accept(this); } /** */ void visit(const ModuleDeclaration moduleDeclaration) { moduleDeclaration.accept(this); } /** */ void visit(const MulExpression mulExpression) { mulExpression.accept(this); } /** */ void visit(const NamespaceList namespaceList) { namespaceList.accept(this); } /** */ void visit(const NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); } /** */ void visit(const NewExpression newExpression) { newExpression.accept(this); } /** */ void visit(const NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); } /** */ void visit(const Operands operands) { operands.accept(this); } /** */ void visit(const OrExpression orExpression) { orExpression.accept(this); } /** */ void visit(const OrOrExpression orOrExpression) { orOrExpression.accept(this); } /** */ void visit(const OutContractExpression outContractExpression) { outContractExpression.accept(this); } /** */ void visit(const OutStatement outStatement) { outStatement.accept(this); } /** */ void visit(const ParameterAttribute parameterAttribute) { parameterAttribute.accept(this); } /** */ void visit(const Parameter parameter) { parameter.accept(this); } /** */ void visit(const Parameters parameters) { parameters.accept(this); } /** */ void visit(const Postblit postblit) { postblit.accept(this); } /** */ void visit(const PowExpression powExpression) { powExpression.accept(this); } /** */ void visit(const PragmaDeclaration pragmaDeclaration) { pragmaDeclaration.accept(this); } /** */ void visit(const PragmaStatement pragmaStatement) { pragmaStatement.accept(this); } /** */ void visit(const PragmaExpression pragmaExpression) { pragmaExpression.accept(this); } /** */ void visit(const PrimaryExpression primaryExpression) { primaryExpression.accept(this); } /** */ void visit(const Register register) { register.accept(this); } /** */ void visit(const RelExpression relExpression) { relExpression.accept(this); } /** */ void visit(const ReturnStatement returnStatement) { returnStatement.accept(this); } /** */ void visit(const ScopeGuardStatement scopeGuardStatement) { scopeGuardStatement.accept(this); } /** */ void visit(const SharedStaticConstructor sharedStaticConstructor) { sharedStaticConstructor.accept(this); } /** */ void visit(const SharedStaticDestructor sharedStaticDestructor) { sharedStaticDestructor.accept(this); } /** */ void visit(const ShiftExpression shiftExpression) { shiftExpression.accept(this); } /** */ void visit(const ShortenedFunctionBody shortenedFunctionBody) { shortenedFunctionBody.accept(this); } /** */ void visit(const SingleImport singleImport) { singleImport.accept(this); } /** */ void visit(const Index index) { index.accept(this); } /** */ void visit(const SpecifiedFunctionBody specifiedFunctionBody) { specifiedFunctionBody.accept(this); } /** */ void visit(const Statement statement) { statement.accept(this); } /** */ void visit(const StatementNoCaseNoDefault statementNoCaseNoDefault) { statementNoCaseNoDefault.accept(this); } /** */ void visit(const StaticAssertDeclaration staticAssertDeclaration) { staticAssertDeclaration.accept(this); } /** */ void visit(const StaticAssertStatement staticAssertStatement) { staticAssertStatement.accept(this); } /** */ void visit(const StaticConstructor staticConstructor) { staticConstructor.accept(this); } /** */ void visit(const StaticDestructor staticDestructor) { staticDestructor.accept(this); } /** */ void visit(const StaticIfCondition staticIfCondition) { staticIfCondition.accept(this); } /** */ void visit(const StorageClass storageClass) { storageClass.accept(this); } /** */ void visit(const StringLiteralList stringLiteralList) { stringLiteralList.accept(this); } /** */ void visit(const StructBody structBody) { structBody.accept(this); } /** */ void visit(const StructDeclaration structDeclaration) { structDeclaration.accept(this); } /** */ void visit(const StructInitializer structInitializer) { structInitializer.accept(this); } /** */ void visit(const StructMemberInitializer structMemberInitializer) { structMemberInitializer.accept(this); } /** */ void visit(const StructMemberInitializers structMemberInitializers) { structMemberInitializers.accept(this); } /** */ void visit(const SwitchStatement switchStatement) { switchStatement.accept(this); } /** */ void visit(const Symbol symbol) { symbol.accept(this); } /** */ void visit(const SynchronizedStatement synchronizedStatement) { synchronizedStatement.accept(this); } /** */ void visit(const TemplateAliasParameter templateAliasParameter) { templateAliasParameter.accept(this); } /** */ void visit(const TemplateArgument templateArgument) { templateArgument.accept(this); } /** */ void visit(const TemplateArgumentList templateArgumentList) { templateArgumentList.accept(this); } /** */ void visit(const TemplateArguments templateArguments) { templateArguments.accept(this); } /** */ void visit(const TemplateDeclaration templateDeclaration) { templateDeclaration.accept(this); } /** */ void visit(const TemplateInstance templateInstance) { templateInstance.accept(this); } /** */ void visit(const TemplateMixinExpression templateMixinExpression) { templateMixinExpression.accept(this); } /** */ void visit(const TemplateParameter templateParameter) { templateParameter.accept(this); } /** */ void visit(const TemplateParameterList templateParameterList) { templateParameterList.accept(this); } /** */ void visit(const TemplateParameters templateParameters) { templateParameters.accept(this); } /** */ void visit(const TemplateSingleArgument templateSingleArgument) { templateSingleArgument.accept(this); } /** */ void visit(const TemplateThisParameter templateThisParameter) { templateThisParameter.accept(this); } /** */ void visit(const TemplateTupleParameter templateTupleParameter) { templateTupleParameter.accept(this); } /** */ void visit(const TemplateTypeParameter templateTypeParameter) { templateTypeParameter.accept(this); } /** */ void visit(const TemplateValueParameter templateValueParameter) { templateValueParameter.accept(this); } /** */ void visit(const TemplateValueParameterDefault templateValueParameterDefault) { templateValueParameterDefault.accept(this); } /** */ void visit(const TernaryExpression ternaryExpression) { ternaryExpression.accept(this); } /** */ void visit(const ThrowExpression throwExpression) { throwExpression.accept(this); } /** */ void visit(const Token) { } /** */ void visit(const TraitsExpression traitsExpression) { traitsExpression.accept(this); } /** */ void visit(const TryStatement tryStatement) { tryStatement.accept(this); } /** */ void visit(const Type type) { type.accept(this); } /** */ void visit(const TypeIdentifierPart typeIdentChain) { typeIdentChain.accept(this); } /** */ void visit(const Type2 type2) { type2.accept(this); } /** */ void visit(const TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); } /** */ void visit(const TypeSuffix typeSuffix) { typeSuffix.accept(this); } /** */ void visit(const TypeidExpression typeidExpression) { typeidExpression.accept(this); } /** */ void visit(const TypeofExpression typeofExpression) { typeofExpression.accept(this); } /** */ void visit(const UnaryExpression unaryExpression) { unaryExpression.accept(this); } /** */ void visit(const UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); } /** */ void visit(const Unittest unittest_) { unittest_.accept(this); } /** */ void visit(const VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); } /** */ void visit(const Vector vector) { vector.accept(this); } /** */ void visit(const VersionCondition versionCondition) { versionCondition.accept(this); } /** */ void visit(const VersionSpecification versionSpecification) { versionSpecification.accept(this); } /** */ void visit(const WhileStatement whileStatement) { whileStatement.accept(this); } /** */ void visit(const WithStatement withStatement) { withStatement.accept(this); } /** */ void visit(const XorExpression xorExpression) { xorExpression.accept(this); } } interface ASTNode { /** */ void accept(ASTVisitor visitor) const; } template visitIfNotNull(fields ...) { static if (fields.length > 1) immutable visitIfNotNull = visitIfNotNull!(fields[0]) ~ visitIfNotNull!(fields[1..$]); else { static if (typeof(fields[0]).stringof[$ - 2 .. $] == "[]") { static if (__traits(hasMember, typeof(fields[0][0]), "classinfo")) immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") if (i !is null) visitor.visit(i);\n"; else immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") visitor.visit(i);\n"; } else static if (__traits(hasMember, typeof(fields[0]), "classinfo")) immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ " !is null) visitor.visit(" ~ fields[0].stringof ~ ");\n"; else static if (is(Unqual!(typeof(fields[0])) == Token)) immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ ` != tok!""` ~ ") visitor.visit(" ~ fields[0].stringof ~ ");\n"; else immutable visitIfNotNull = "visitor.visit(" ~ fields[0].stringof ~ ");\n"; } } mixin template OpEquals(bool print = false) { override bool opEquals(Object other) const { static if (print) pragma(msg, generateOpEquals!(typeof(this))); mixin (generateOpEquals!(typeof(this))); } } template generateOpEquals(T) { template opEqualsPart(p ...) { import std.traits : isSomeFunction, isDynamicArray; import std.algorithm : among; static if (p.length > 1) { enum opEqualsPart = opEqualsPart!(p[0 .. $/2]) ~ opEqualsPart!(p[$/2 .. $]); } else static if (p.length && !isSomeFunction!(typeof(__traits(getMember, T, p[0]))) && !p[0].among("comment", "line", "column", "endLocation", "startLocation", "index", "dotLocation")) { static if (isDynamicArray!(typeof(__traits(getMember, T, p[0])))) { enum opEqualsPart = "\tif (obj." ~ p[0] ~ ".length != " ~ p[0] ~ ".length) return false;\n" ~ "\tforeach (i; 0 .. " ~ p[0] ~ ".length)\n" ~ "\t\tif (" ~ p[0] ~ "[i] != obj." ~ p[0] ~ "[i]) return false;\n"; } else enum opEqualsPart = "\tif (obj." ~ p[0] ~ " != " ~ p[0] ~ ") return false;\n"; } else enum opEqualsPart = ""; } enum generateOpEquals = "if (auto obj = cast(" ~ T.stringof ~ ") other){\n" ~ opEqualsPart!(__traits(derivedMembers, T)) ~ "\treturn true;\n}\nreturn false;"; } abstract class BaseNode : ASTNode { /** List of tokens consumed by this AST node */ const(Token)[] tokens; abstract void accept(ASTVisitor visitor) const; } abstract class ExpressionNode : BaseNode { override void accept(ASTVisitor visitor) const { assert (false); } } mixin template BinaryExpressionBody() { ExpressionNode left; ExpressionNode right; size_t line; size_t column; } /// final class AddExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; /** */ IdType operator; mixin BinaryExpressionBody; } /// final class AliasDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(storageClasses, type, declaratorIdentifierList, initializers, parameters, memberFunctionAttributes)); } mixin OpEquals; /** */ StorageClass[] storageClasses; /** */ Type type; /** */ DeclaratorIdentifierList declaratorIdentifierList; /** */ AliasInitializer[] initializers; /** */ string comment; /** */ Parameters parameters; /** */ MemberFunctionAttribute[] memberFunctionAttributes; } /// final class AliasAssign : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, type)); } mixin OpEquals; /** */ Token identifier; /** */ Type type; /** */ string comment; } /// final class AliasInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, storageClasses, type, functionLiteralExpression)); } mixin OpEquals; /** */ Token name; /** */ StorageClass[] storageClasses; /** */ TemplateParameters templateParameters; /** */ Type type; /** */ FunctionLiteralExpression functionLiteralExpression; /** */ Parameters parameters; /** */ MemberFunctionAttribute[] memberFunctionAttributes; } /// final class AliasThisDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier)); } mixin OpEquals; /** */ Token identifier; /** */ string comment; } /// final class AlignAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } mixin OpEquals; /** */ ExpressionNode assignExpression; } /// final class AndAndExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; mixin BinaryExpressionBody; } /// final class AndExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; mixin BinaryExpressionBody; } /// final class AnonymousEnumDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(baseType, members)); } mixin OpEquals; /** */ Type baseType; /** */ AnonymousEnumMember[] members; } /// final class AnonymousEnumMember : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, name, assignExpression)); } /** */ Type type; /** */ Token name; /** */ ExpressionNode assignExpression; /** */ string comment; } /// final class ArgumentList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } mixin OpEquals; /** */ ExpressionNode[] items; /** */ size_t startLocation; /** */ size_t endLocation; } /// final class Arguments : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList)); } mixin OpEquals; /** */ ArgumentList argumentList; } /// final class ArrayInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(arrayMemberInitializations)); } mixin OpEquals; /** */ size_t startLocation; /** */ size_t endLocation; /** */ ArrayMemberInitialization[] arrayMemberInitializations; } /// final class ArrayLiteral : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList)); } mixin OpEquals; /** */ ArgumentList argumentList; } /// final class ArrayMemberInitialization : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression, nonVoidInitializer)); } mixin OpEquals; /** */ ExpressionNode assignExpression; /** */ NonVoidInitializer nonVoidInitializer; } /// final class AsmAddExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; /** */ IdType operator; mixin BinaryExpressionBody; } /// final class AsmAndExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin OpEquals; mixin BinaryExpressionBody; } /// final class AsmBrExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(asmBrExp, asmExp, asmUnaExp)); } mixin OpEquals; size_t line; size_t column; /** */ AsmBrExp asmBrExp; /** */ ExpressionNode asmExp; /** */ AsmUnaExp asmUnaExp; } /// final class AsmEqualExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; /** */ IdType operator; } /// final class AsmExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, middle, right)); } mixin OpEquals; /** */ ExpressionNode left; /** */ ExpressionNode middle; /** */ ExpressionNode right; } /// final class AsmInstruction : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrIntegerOrOpcode, asmInstruction, operands)); } mixin OpEquals; /** */ Token identifierOrIntegerOrOpcode; /** */ bool hasAlign; /** */ bool isLabel; /** */ AsmInstruction asmInstruction; /** */ Operands operands; } /// final class AsmLogAndExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmLogOrExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmMulExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmOrExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AsmPrimaryExp : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, register, asmExp, identifierChain, segmentOverrideSuffix)); } /** */ ExpressionNode asmExp; /** */ IdentifierChain identifierChain; /** */ Register register; /** */ ExpressionNode segmentOverrideSuffix; /** */ Token token; mixin OpEquals; } /// final class AsmRelExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; /** */ IdType operator; mixin OpEquals; } /// final class AsmShiftExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; /** */ IdType operator; mixin OpEquals; } /// final class AsmStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionAttributes, asmInstructions, gccAsmInstructions)); } /** */ AsmInstruction[] asmInstructions; /** */ GccAsmInstruction[] gccAsmInstructions; /** */ FunctionAttribute[] functionAttributes; mixin OpEquals; } /// final class AsmTypePrefix : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ Token left; /** */ Token right; mixin OpEquals; } /// final class AsmUnaExp : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(prefix, asmTypePrefix, asmExp, asmPrimaryExp, asmUnaExp)); } /** */ AsmTypePrefix asmTypePrefix; /** */ ExpressionNode asmExp; /** */ Token prefix; /** */ AsmPrimaryExp asmPrimaryExp; /** */ AsmUnaExp asmUnaExp; mixin OpEquals; } /// final class AsmXorExp : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class AssertArguments : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertion, message)); } /** */ ExpressionNode assertion; /** */ ExpressionNode message; mixin OpEquals; } /// final class AssertExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertArguments)); } /** */ size_t line; /** */ size_t column; /** */ AssertArguments assertArguments; mixin OpEquals; } /// final class AssignExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(ternaryExpression, expression)); } /** */ ExpressionNode ternaryExpression; /** */ ExpressionNode expression; /** */ IdType operator; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class AssocArrayLiteral : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(keyValuePairs)); } /** */ KeyValuePairs keyValuePairs; mixin OpEquals; } /// final class AtAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateInstance, argumentList)); } /** */ ArgumentList argumentList; /** */ TemplateInstance templateInstance; /** */ Token identifier; /** */ bool useParen; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class Attribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(pragmaExpression, deprecated_, atAttribute, alignAttribute, identifierChain, linkageAttribute)); } /** */ PragmaExpression pragmaExpression; /** */ Deprecated deprecated_; /** */ AtAttribute atAttribute; /** */ AlignAttribute alignAttribute; /** */ LinkageAttribute linkageAttribute; /** */ Token attribute; /** */ IdentifierChain identifierChain; mixin OpEquals; } /// final class AttributeDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(attribute)); } /** */ Attribute attribute; /** */ size_t line; mixin OpEquals; } /// final class AutoDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { foreach (sc; storageClasses) visitor.visit(sc); foreach (part; parts) visitor.visit(part); } /** */ AutoDeclarationPart[] parts; /** */ StorageClass[] storageClasses; /** */ string comment; mixin OpEquals; } final class AutoDeclarationPart : BaseNode { override void accept(ASTVisitor visitor) const { if (templateParameters !is null) visitor.visit(templateParameters); visitor.visit(initializer); } /** */ Token identifier; /** */ Initializer initializer; /** */ TemplateParameters templateParameters; } /// final class BlockStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationsAndStatements)); } /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; /** */ DeclarationsAndStatements declarationsAndStatements; mixin OpEquals; } /// final class BreakStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(label)); } /** */ Token label; mixin OpEquals; } /// final class BaseClass : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type2)); } /** */ Type2 type2; mixin OpEquals; } /// final class BaseClassList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ BaseClass[] items; mixin OpEquals; } /// final class CaseRangeStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(low, high, declarationsAndStatements)); } /** */ ExpressionNode low; /** */ ExpressionNode high; /** */ DeclarationsAndStatements declarationsAndStatements; /** */ size_t colonLocation; mixin OpEquals; } /// final class CaseStatement: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList, declarationsAndStatements)); } /** */ ArgumentList argumentList; /** */ DeclarationsAndStatements declarationsAndStatements; /** */ size_t colonLocation; mixin OpEquals; } /// final class CastExpression: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, castQualifier, unaryExpression)); } /** */ Type type; /** */ CastQualifier castQualifier; /** */ UnaryExpression unaryExpression; mixin OpEquals; } /// final class CastQualifier: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(first, second)); } /** */ Token first; /** */ Token second; mixin OpEquals; } /// final class Catches: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(catches, lastCatch)); } /** */ Catch[] catches; /** */ LastCatch lastCatch; mixin OpEquals; } /// final class Catch: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, declarationOrStatement)); } /** */ Type type; /** */ Token identifier; /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class ClassDeclaration: BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, constraint, baseClassList, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ BaseClassList baseClassList; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class CmpExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(shiftExpression, equalExpression, identityExpression, relExpression, inExpression)); } /** */ ExpressionNode shiftExpression; /** */ ExpressionNode equalExpression; /** */ ExpressionNode identityExpression; /** */ ExpressionNode relExpression; /** */ ExpressionNode inExpression; mixin OpEquals; } /// final class CompileCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(versionCondition, debugCondition, staticIfCondition)); } /** */ VersionCondition versionCondition; /** */ DebugCondition debugCondition; /** */ StaticIfCondition staticIfCondition; mixin OpEquals; } /// final class ConditionalDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(compileCondition, trueDeclarations, falseDeclarations)); } /** */ CompileCondition compileCondition; /** */ Declaration[] trueDeclarations; /** */ Declaration[] falseDeclarations; /** */ bool hasElse; /** */ DeclarationListStyle trueStyle; /** */ DeclarationListStyle falseStyle; mixin OpEquals; } /// final class ConditionalStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(compileCondition, trueStatement, falseStatement)); } /** */ CompileCondition compileCondition; /** */ DeclarationOrStatement trueStatement; /** */ DeclarationOrStatement falseStatement; mixin OpEquals; } /// final class Constraint : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ Expression expression; /** */ size_t location; mixin OpEquals; } /// final class Constructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameters, templateParameters, constraint, memberFunctionAttributes, functionBody)); } /** */ Parameters parameters; /** */ FunctionBody functionBody; /** */ Constraint constraint; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ TemplateParameters templateParameters; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class ContinueStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(label)); } /** */ Token label; mixin OpEquals; } /// final class DebugCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrInteger)); } /** */ size_t debugIndex; /** */ Token identifierOrInteger; mixin OpEquals; } /// final class DebugSpecification : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrInteger)); } /** */ Token identifierOrInteger; mixin OpEquals; } /// final class Declaration : BaseNode { override void accept(ASTVisitor visitor) const { foreach (attr; attributes) visitor.visit(attr); foreach (dec; declarations) visitor.visit(dec); foreach (Type; DeclarationTypes) { const(Type)* value = storage.peek!Type; if (value !is null) { static if (isArray!Type) foreach (item; *(cast(Type*) value)) visitor.visit(item); else if (*value !is null) visitor.visit(*(cast(Type*) value)); } } } private import std.variant:Algebraic; private import std.typetuple:TypeTuple; alias DeclarationTypes = TypeTuple!(AliasDeclaration, AliasAssign, AliasThisDeclaration, AnonymousEnumDeclaration, AttributeDeclaration, ClassDeclaration, ConditionalDeclaration, Constructor, DebugSpecification, Destructor, EnumDeclaration, EponymousTemplateDeclaration, FunctionDeclaration, ImportDeclaration, InterfaceDeclaration, Invariant, MixinDeclaration, MixinTemplateDeclaration, Postblit, PragmaDeclaration, SharedStaticConstructor, SharedStaticDestructor, StaticAssertDeclaration, StaticConstructor, StaticDestructor, StructDeclaration, TemplateDeclaration, UnionDeclaration, Unittest, VariableDeclaration, VersionSpecification, StaticForeachDeclaration); private Algebraic!(DeclarationTypes) storage; private static string generateProperty(string type, string name) { return "const(" ~ type ~ ") " ~ name ~ "() const @property { auto p = storage.peek!" ~ type ~ "; return p is null? null : *p;}\n" ~ "const(" ~ type ~ ") " ~ name ~ "(" ~ type ~ " node) @property { storage = node; return node; }"; } /** */ Attribute[] attributes; /** */ Declaration[] declarations; mixin(generateProperty("AliasDeclaration", "aliasDeclaration")); mixin(generateProperty("AliasAssign", "aliasAssign")); mixin(generateProperty("AliasThisDeclaration", "aliasThisDeclaration")); mixin(generateProperty("AnonymousEnumDeclaration", "anonymousEnumDeclaration")); mixin(generateProperty("AttributeDeclaration", "attributeDeclaration")); mixin(generateProperty("ClassDeclaration", "classDeclaration")); mixin(generateProperty("ConditionalDeclaration", "conditionalDeclaration")); mixin(generateProperty("Constructor", "constructor")); mixin(generateProperty("DebugSpecification", "debugSpecification")); mixin(generateProperty("Destructor", "destructor")); mixin(generateProperty("EnumDeclaration", "enumDeclaration")); mixin(generateProperty("EponymousTemplateDeclaration", "eponymousTemplateDeclaration")); mixin(generateProperty("FunctionDeclaration", "functionDeclaration")); mixin(generateProperty("ImportDeclaration", "importDeclaration")); mixin(generateProperty("InterfaceDeclaration", "interfaceDeclaration")); mixin(generateProperty("Invariant", "invariant_")); mixin(generateProperty("MixinDeclaration", "mixinDeclaration")); mixin(generateProperty("MixinTemplateDeclaration", "mixinTemplateDeclaration")); mixin(generateProperty("Postblit", "postblit")); mixin(generateProperty("PragmaDeclaration", "pragmaDeclaration")); mixin(generateProperty("SharedStaticConstructor", "sharedStaticConstructor")); mixin(generateProperty("SharedStaticDestructor", "sharedStaticDestructor")); mixin(generateProperty("StaticAssertDeclaration", "staticAssertDeclaration")); mixin(generateProperty("StaticConstructor", "staticConstructor")); mixin(generateProperty("StaticDestructor", "staticDestructor")); mixin(generateProperty("StructDeclaration", "structDeclaration")); mixin(generateProperty("TemplateDeclaration", "templateDeclaration")); mixin(generateProperty("UnionDeclaration", "unionDeclaration")); mixin(generateProperty("Unittest", "unittest_")); mixin(generateProperty("VariableDeclaration", "variableDeclaration")); mixin(generateProperty("VersionSpecification", "versionSpecification")); mixin(generateProperty("StaticForeachDeclaration", "staticForeachDeclaration")); override bool opEquals(Object other) const { auto otherDeclaration = cast(Declaration) other; if (otherDeclaration is null) return false; return attributes == otherDeclaration.attributes && declarations == otherDeclaration.declarations && storage == otherDeclaration.storage; } } /// final class DeclarationsAndStatements : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationsAndStatements)); } /** */ DeclarationOrStatement[] declarationsAndStatements; mixin OpEquals; } /// final class DeclarationOrStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declaration, statement)); } /** */ Declaration declaration; /** */ Statement statement; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class Declarator : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, initializer)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Initializer initializer; /** */ TypeSuffix[] cstyle; /** */ string comment; mixin OpEquals; } /// final class DeclaratorIdentifierList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifiers)); } /** */ Token[] identifiers; mixin OpEquals; } /// final class DefaultStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationsAndStatements)); } /** */ DeclarationsAndStatements declarationsAndStatements; /** */ size_t colonLocation; mixin OpEquals; } /// final class DeleteExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(unaryExpression)); } /** */ UnaryExpression unaryExpression; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class DeleteStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(deleteExpression)); } /** */ DeleteExpression deleteExpression; mixin OpEquals; } /// final class Deprecated : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class Destructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t line; /** */ size_t column; /** */ size_t index; /** */ string comment; mixin OpEquals; } /// final class DoStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; /** */ Expression expression; mixin OpEquals; } /// final class EnumBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(enumMembers)); } /** */ EnumMember[] enumMembers; /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; mixin OpEquals; } /// final class EnumDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, enumBody)); } /** */ Token name; /** */ Type type; /** */ EnumBody enumBody; /** */ string comment; mixin OpEquals; } final class EnumMemberAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(deprecated_, atAttribute)); } /** */ Deprecated deprecated_; /** */ AtAttribute atAttribute; mixin OpEquals; } /// final class EnumMember : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(enumMemberAttributes, name, type, assignExpression)); } /** */ EnumMemberAttribute[] enumMemberAttributes; /** */ Token name; /** */ Type type; /** */ ExpressionNode assignExpression; /** */ string comment; mixin OpEquals; } /// final class EponymousTemplateDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, assignExpression)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ ExpressionNode assignExpression; /** */ Type type; /** */ string comment; mixin OpEquals; } /// final class EqualExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class Expression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ ExpressionNode[] items; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class ExpressionStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ Expression expression; mixin OpEquals; } /// final class FinalSwitchStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(switchStatement)); } /** */ SwitchStatement switchStatement; mixin OpEquals; } /// final class Finally : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationOrStatement)); } /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class ForStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(initialization, test, increment, declarationOrStatement)); } /** */ DeclarationOrStatement initialization; /** */ Expression test; /** */ Expression increment; /** */ DeclarationOrStatement declarationOrStatement; /** */ size_t startIndex; mixin OpEquals; } /// final class Foreach(bool declOnly) : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(foreachType, foreachTypeList, low, high)); static if (declOnly) mixin (visitIfNotNull!(declarations)); else mixin (visitIfNotNull!(declarationOrStatement)); } /** */ IdType type; /** */ ForeachTypeList foreachTypeList; /** */ ForeachType foreachType; /** */ Expression low; /** */ Expression high; /** */ size_t startIndex; static if (declOnly) { /** */ Declaration[] declarations; /** */ DeclarationListStyle style; } else { /** */ DeclarationOrStatement declarationOrStatement; } mixin OpEquals; } /// alias StaticForeachDeclaration = Foreach!true; /// alias ForeachStatement = Foreach!false; /// final class StaticForeachStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(foreachStatement)); } /** */ ForeachStatement foreachStatement; mixin OpEquals; } /// final class ForeachType : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier)); } /** */ bool isAlias; /** */ bool isEnum; /** */ bool isRef; /** */ IdType[] typeConstructors; /** */ Type type; /** */ Token identifier; mixin OpEquals; } /// final class ForeachTypeList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ ForeachType[] items; mixin OpEquals; } /// final class FunctionAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, atAttribute)); } /** */ Token token; /** */ AtAttribute atAttribute; mixin OpEquals; } /// final class FunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(specifiedFunctionBody, missingFunctionBody, shortenedFunctionBody)); } /** */ size_t endLocation; /** */ SpecifiedFunctionBody specifiedFunctionBody; /** */ MissingFunctionBody missingFunctionBody; /** */ ShortenedFunctionBody shortenedFunctionBody; mixin OpEquals; } /// final class FunctionCallExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, unaryExpression, templateArguments, arguments)); } /** */ Type type; /** */ UnaryExpression unaryExpression; /** */ TemplateArguments templateArguments; /** */ Arguments arguments; mixin OpEquals; } /// final class FunctionContract : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(inOutContractExpression, inOutStatement)); } /** */ InOutContractExpression inOutContractExpression; /** */ InOutStatement inOutStatement; mixin OpEquals; } /// final class FunctionDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(attributes, storageClasses, returnType, parameters, templateParameters, constraint, memberFunctionAttributes, functionBody)); } /** */ bool hasAuto; /** */ bool hasRef; /** */ Type returnType; /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Parameters parameters; /** */ Constraint constraint; /** */ FunctionBody functionBody; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ string comment; /** */ Attribute[] attributes; /** */ StorageClass[] storageClasses; mixin OpEquals; } /// final class FunctionLiteralExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(returnType, parameters, functionAttributes, memberFunctionAttributes, specifiedFunctionBody, assignExpression)); } /** */ ExpressionNode assignExpression; /** */ FunctionAttribute[] functionAttributes; /** */ SpecifiedFunctionBody specifiedFunctionBody; /** */ IdType functionOrDelegate; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ Parameters parameters; /** */ Token identifier; /** */ Type returnType; /** */ bool isReturnRef; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class GccAsmInstruction : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assemblerTemplate, inputOperands, outputOperands, registers, gotos)); } /** */ Expression assemblerTemplate; /** */ GccAsmOperandList inputOperands; /** */ GccAsmOperandList outputOperands; /** */ StringLiteralList registers; /** */ DeclaratorIdentifierList gotos; mixin OpEquals; } /// final class GccAsmOperand : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, constraint, symbolicName)); } /** */ Token symbolicName; /** */ Token constraint; /** */ ExpressionNode expression; mixin OpEquals; } /// final class GccAsmOperandList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ GccAsmOperand[] items; mixin OpEquals; } /// final class GotoStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(label, expression)); } /** */ Expression expression; /** */ Token label; mixin OpEquals; } /// final class IdentifierChain : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifiers)); } /** */ Token[] identifiers; mixin OpEquals; } /// final class TypeIdentifierPart : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrTemplateInstance, typeIdentifierPart, indexer)); } /** */ bool dot; /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance; /** */ TypeIdentifierPart typeIdentifierPart ; /** */ ExpressionNode indexer; mixin OpEquals; } /// final class IdentifierOrTemplateChain : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifiersOrTemplateInstances)); } /** */ IdentifierOrTemplateInstance[] identifiersOrTemplateInstances; mixin OpEquals; } /// final class IdentifierOrTemplateInstance : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateInstance)); } /** */ Token identifier; /** */ TemplateInstance templateInstance; mixin OpEquals; } /// final class IdentityExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ bool negated; mixin BinaryExpressionBody; mixin OpEquals; } /// final class IfStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, type, expression, thenStatement, elseStatement)); } /** */ IdType[] typeCtors; /** */ Type type; /** */ Token identifier; /** */ Expression expression; /** */ DeclarationOrStatement thenStatement; /** */ DeclarationOrStatement elseStatement; /** */ size_t startIndex; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class ImportBind : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ Token left; /** */ Token right; mixin OpEquals; } /// final class ImportBindings : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(singleImport, importBinds)); } /** */ SingleImport singleImport; /** */ ImportBind[] importBinds; mixin OpEquals; } /// final class ImportDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(singleImports, importBindings)); } /** */ SingleImport[] singleImports; /** */ ImportBindings importBindings; /** */ size_t startIndex; /** */ size_t endIndex; mixin OpEquals; } /// final class ImportExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class Index : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(low, high)); } /** */ ExpressionNode low; /** */ ExpressionNode high; mixin OpEquals; } /// final class IndexExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(unaryExpression, indexes)); } /** */ UnaryExpression unaryExpression; /** */ Index[] indexes; mixin OpEquals; } /// final class InContractExpression : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertArguments)); } /** */ size_t inTokenLocation; /** */ AssertArguments assertArguments; mixin OpEquals; } /// final class InExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; bool negated; mixin OpEquals; } /// final class InOutContractExpression : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(inContractExpression, outContractExpression)); } /** */ InContractExpression inContractExpression; /** */ OutContractExpression outContractExpression; mixin OpEquals; } /// final class InOutStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(inStatement, outStatement)); } /** */ InStatement inStatement; /** */ OutStatement outStatement; mixin OpEquals; } /// final class InStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(blockStatement)); } /** */ size_t inTokenLocation; /** */ BlockStatement blockStatement; mixin OpEquals; } /// final class Initialize : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; mixin OpEquals; } /// final class Initializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(nonVoidInitializer)); } /** */ NonVoidInitializer nonVoidInitializer; mixin OpEquals; } /// final class InterfaceDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, constraint, baseClassList, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ BaseClassList baseClassList; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class Invariant : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(blockStatement, assertArguments)); } /** */ BlockStatement blockStatement; /** */ AssertArguments assertArguments; /** */ bool useParen; /** */ string comment; size_t line; size_t index; mixin OpEquals; } /// final class IsExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, typeSpecialization, templateParameterList)); } /** */ Type type; /** */ Token identifier; /** */ TypeSpecialization typeSpecialization; /** */ TemplateParameterList templateParameterList; /** */ IdType equalsOrColon; mixin OpEquals; } /// final class KeyValuePair : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(key, value)); } /** */ ExpressionNode key; /** */ ExpressionNode value; mixin OpEquals; } /// final class KeyValuePairs : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(keyValuePairs)); } /** */ KeyValuePair[] keyValuePairs; mixin OpEquals; } /// final class LabeledStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, declarationOrStatement)); } /** */ Token identifier; /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class LastCatch : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; size_t line; size_t column; mixin OpEquals; } /// final class LinkageAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, typeIdentifierPart, cppNamespaces)); } /** */ Token identifier; /** */ bool hasPlusPlus; /** */ TypeIdentifierPart typeIdentifierPart; /** */ IdType classOrStruct; /** */ NamespaceList cppNamespaces; mixin OpEquals; } /// final class MemberFunctionAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(atAttribute)); } /** */ IdType tokenType; /** */ AtAttribute atAttribute; mixin OpEquals; } /// final class MissingFunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionContracts)); } /** */ FunctionContract[] functionContracts; mixin OpEquals; } /// final class MixinDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(mixinExpression, templateMixinExpression)); } /** */ MixinExpression mixinExpression; /** */ TemplateMixinExpression templateMixinExpression; mixin OpEquals; } /// final class MixinExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(argumentList)); } /** */ ArgumentList argumentList; mixin OpEquals; } /// final class MixinTemplateDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateDeclaration)); } /** */ TemplateDeclaration templateDeclaration; mixin OpEquals; } /// final class MixinTemplateName : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(symbol, typeofExpression, identifierOrTemplateChain)); } /** */ Symbol symbol; /** */ IdentifierOrTemplateChain identifierOrTemplateChain; /** */ TypeofExpression typeofExpression; mixin OpEquals; } /// final class Module : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(scriptLine, moduleDeclaration, declarations)); } /** */ Token scriptLine; /** */ ModuleDeclaration moduleDeclaration; /** */ Declaration[] declarations; mixin OpEquals; } /// final class ModuleDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(atAttributes, deprecated_, moduleName)); } /** */ AtAttribute[] atAttributes; /** */ Deprecated deprecated_; /** */ IdentifierChain moduleName; /** */ size_t startLocation; /** */ size_t endLocation; /** */ string comment; mixin OpEquals; } /// final class MulExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class NamespaceList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } mixin OpEquals; /** */ TernaryExpression[] items; } /// final class NewAnonClassExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(allocatorArguments, constructorArguments, baseClassList, structBody)); } /** */ Arguments allocatorArguments; /** */ Arguments constructorArguments; /** */ BaseClassList baseClassList; /** */ StructBody structBody; mixin OpEquals; } /// final class NewExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(newAnonClassExpression, type, arguments, assignExpression)); } /** */ Type type; /** */ NewAnonClassExpression newAnonClassExpression; /** */ Arguments arguments; /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class StatementNoCaseNoDefault : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(labeledStatement, blockStatement, ifStatement, whileStatement, doStatement, forStatement, foreachStatement, switchStatement, finalSwitchStatement, continueStatement, breakStatement, returnStatement, gotoStatement, withStatement, synchronizedStatement, tryStatement, scopeGuardStatement, asmStatement, pragmaStatement, conditionalStatement, staticAssertStatement, versionSpecification, debugSpecification, expressionStatement, staticForeachStatement)); } /** */ LabeledStatement labeledStatement; /** */ BlockStatement blockStatement; /** */ IfStatement ifStatement; /** */ WhileStatement whileStatement; /** */ DoStatement doStatement; /** */ ForStatement forStatement; /** */ ForeachStatement foreachStatement; /** */ StaticForeachStatement staticForeachStatement; /** */ SwitchStatement switchStatement; /** */ FinalSwitchStatement finalSwitchStatement; /** */ ContinueStatement continueStatement; /** */ BreakStatement breakStatement; /** */ ReturnStatement returnStatement; /** */ GotoStatement gotoStatement; /** */ WithStatement withStatement; /** */ SynchronizedStatement synchronizedStatement; /** */ TryStatement tryStatement; /** */ ScopeGuardStatement scopeGuardStatement; /** */ AsmStatement asmStatement; /** */ PragmaStatement pragmaStatement; /** */ ConditionalStatement conditionalStatement; /** */ StaticAssertStatement staticAssertStatement; /** */ VersionSpecification versionSpecification; /** */ DebugSpecification debugSpecification; /** */ ExpressionStatement expressionStatement; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class NonVoidInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression, arrayInitializer, structInitializer)); } /** */ ExpressionNode assignExpression; /** */ ArrayInitializer arrayInitializer; /** */ StructInitializer structInitializer; mixin OpEquals; } /// final class Operands : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(operands)); } /** */ ExpressionNode[] operands; mixin OpEquals; } /// final class OrExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class OrOrExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class OutContractExpression : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameter, assertArguments)); } /** */ size_t outTokenLocation; /** */ Token parameter; /** */ AssertArguments assertArguments; mixin OpEquals; } /// final class OutStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameter, blockStatement)); } /** */ size_t outTokenLocation; /** */ Token parameter; /** */ BlockStatement blockStatement; mixin OpEquals; } final class ParameterAttribute : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(atAttribute)); } /** */ IdType idType; /** */ AtAttribute atAttribute; } /// final class Parameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, name, default_)); } /** */ ParameterAttribute[] parameterAttributes; /** */ Type type; /** */ Token name; /** */ bool vararg; /** */ ExpressionNode default_; /** */ TypeSuffix[] cstyle; mixin OpEquals; } /// final class Parameters : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(parameters)); } /** */ Parameter[] parameters; /** */ bool hasVarargs; /** */ ParameterAttribute[] varargsAttributes; mixin OpEquals; } /// final class Postblit : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionBody)); } /** */ FunctionBody functionBody; /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ size_t location; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class PowExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } /// final class PragmaDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(pragmaExpression)); } /** */ PragmaExpression pragmaExpression; mixin OpEquals; } /// final class PragmaExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, argumentList)); } /** */ Token identifier; /** */ ArgumentList argumentList; mixin OpEquals; } /// final class PragmaStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(pragmaExpression, statement, blockStatement)); } /** */ PragmaExpression pragmaExpression; /** */ Statement statement; /** */ BlockStatement blockStatement; mixin OpEquals; } /// final class PrimaryExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin(visitIfNotNull!(basicType, typeConstructor, type, primary, typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral, expression, dot, identifierOrTemplateInstance, isExpression, functionLiteralExpression,traitsExpression, mixinExpression, importExpression, vector, arguments)); } /** */ Token dot; /** */ Token primary; /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance; /** */ Token basicType; /** */ TypeofExpression typeofExpression; /** */ TypeidExpression typeidExpression; /** */ ArrayLiteral arrayLiteral; /** */ AssocArrayLiteral assocArrayLiteral; /** */ Expression expression; /** */ IsExpression isExpression; /** */ FunctionLiteralExpression functionLiteralExpression; /** */ TraitsExpression traitsExpression; /** */ MixinExpression mixinExpression; /** */ ImportExpression importExpression; /** */ Vector vector; /** */ Type type; /** */ Token typeConstructor; /** */ Arguments arguments; mixin OpEquals; } /// final class Register : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, intLiteral)); } /** */ Token identifier; /** */ Token intLiteral; /** */ bool hasIntegerLiteral; mixin OpEquals; } /// final class RelExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class ReturnStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ Expression expression; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class ScopeGuardStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, statementNoCaseNoDefault)); } /** */ Token identifier; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; mixin OpEquals; } /// final class SharedStaticConstructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class SharedStaticDestructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class ShiftExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } /** */ IdType operator; mixin BinaryExpressionBody; mixin OpEquals; } /// final class SingleImport : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(rename, identifierChain)); } /** */ Token rename; /** */ IdentifierChain identifierChain; mixin OpEquals; } /// final class SpecifiedFunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(functionContracts, blockStatement)); } /** */ FunctionContract[] functionContracts; /** */ BlockStatement blockStatement; /** */ bool hasDo; mixin OpEquals; } /// final class ShortenedFunctionBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin(visitIfNotNull!(functionContracts, expression)); } /** */ FunctionContract[] functionContracts; /** */ Expression expression; mixin OpEquals; } /// final class Statement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(statementNoCaseNoDefault, caseStatement, caseRangeStatement, defaultStatement)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; /** */ CaseStatement caseStatement; /** */ CaseRangeStatement caseRangeStatement; /** */ DefaultStatement defaultStatement; mixin OpEquals; } /// final class StaticAssertDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(staticAssertStatement)); } /** */ StaticAssertStatement staticAssertStatement; mixin OpEquals; } /// final class StaticAssertStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assertExpression)); } /** */ AssertExpression assertExpression; mixin OpEquals; } /// final class StaticConstructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class StaticDestructor : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(memberFunctionAttributes, functionBody)); } /** */ MemberFunctionAttribute[] memberFunctionAttributes; /** */ FunctionBody functionBody; /** */ size_t location; /** */ size_t line; /** */ size_t column; /** */ string comment; mixin OpEquals; } /// final class StaticIfCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(assignExpression)); } /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class StorageClass : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, alignAttribute, linkageAttribute, atAttribute, deprecated_)); } /** */ AlignAttribute alignAttribute; /** */ LinkageAttribute linkageAttribute; /** */ AtAttribute atAttribute; /** */ Deprecated deprecated_; /** */ Token token; mixin OpEquals; } /// final class StringLiteralList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ Token[] items; mixin OpEquals; } /// final class StructBody : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarations)); } /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; /** */ Declaration[] declarations; mixin OpEquals; } /// final class StructDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameters, constraint, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class StructInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(structMemberInitializers)); } /** */ StructMemberInitializers structMemberInitializers; /** */ size_t startLocation; /** */ size_t endLocation; mixin OpEquals; } /// final class StructMemberInitializer : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, nonVoidInitializer)); } /** */ Token identifier; /** */ NonVoidInitializer nonVoidInitializer; mixin OpEquals; } /// final class StructMemberInitializers : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(structMemberInitializers)); } /** */ StructMemberInitializer[] structMemberInitializers; mixin OpEquals; } /// final class SwitchStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, statement)); } /** */ Expression expression; /** */ Statement statement; mixin OpEquals; } /// final class Symbol : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifierOrTemplateChain)); } /** */ IdentifierOrTemplateChain identifierOrTemplateChain; /** */ bool dot; mixin OpEquals; } /// final class SynchronizedStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, statementNoCaseNoDefault)); } /** */ Expression expression; /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; mixin OpEquals; } /// final class TemplateAliasParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, colonType, colonExpression, assignType, assignExpression)); } /** */ Type type; /** */ Token identifier; /** */ Type colonType; /** */ ExpressionNode colonExpression; /** */ Type assignType; /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class TemplateArgument : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, assignExpression)); } /** */ Type type; /** */ ExpressionNode assignExpression; mixin OpEquals; } /// final class TemplateArgumentList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ TemplateArgument[] items; mixin OpEquals; } /// final class TemplateArguments : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateArgumentList, templateSingleArgument)); } /** */ TemplateArgumentList templateArgumentList; /** */ TemplateSingleArgument templateSingleArgument; mixin OpEquals; } /// final class TemplateDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, constraint, declarations)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ Declaration[] declarations; /** */ string comment; /** * Byte position of the opening brace */ size_t startLocation; /** * Byte position of the closing brace */ size_t endLocation; mixin OpEquals; } /// final class TemplateInstance : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateArguments)); } /** */ Token identifier; /** */ TemplateArguments templateArguments; mixin OpEquals; } /// final class TemplateMixinExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateArguments, mixinTemplateName)); } /** */ Token identifier; /** */ TemplateArguments templateArguments; /** */ MixinTemplateName mixinTemplateName; mixin OpEquals; } /// final class TemplateParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateTypeParameter, templateValueParameter, templateAliasParameter, templateTupleParameter, templateThisParameter)); } /** */ TemplateTypeParameter templateTypeParameter; /** */ TemplateValueParameter templateValueParameter; /** */ TemplateAliasParameter templateAliasParameter; /** */ TemplateTupleParameter templateTupleParameter; /** */ TemplateThisParameter templateThisParameter; mixin OpEquals; } /// final class TemplateParameterList : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(items)); } /** */ TemplateParameter[] items; mixin OpEquals; } /// final class TemplateParameters : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateParameterList)); } /** */ TemplateParameterList templateParameterList; mixin OpEquals; } /// final class TemplateSingleArgument : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token)); } /** */ Token token; mixin OpEquals; } /// final class TemplateThisParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(templateTypeParameter)); } /** */ TemplateTypeParameter templateTypeParameter; mixin OpEquals; } /// final class TemplateTupleParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier)); } /** */ Token identifier; mixin OpEquals; } /// final class TemplateTypeParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, colonType, assignType)); } /** */ Token identifier; /** */ Type colonType; /** */ Type assignType; mixin OpEquals; } /// final class TemplateValueParameter : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, identifier, assignExpression, templateValueParameterDefault)); } /** */ Type type; /** */ Token identifier; /** */ ExpressionNode assignExpression; /** */ TemplateValueParameterDefault templateValueParameterDefault; mixin OpEquals; } /// final class TemplateValueParameterDefault : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, assignExpression)); } /** */ ExpressionNode assignExpression; /** */ Token token; mixin OpEquals; } /// final class TernaryExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(orOrExpression, expression, ternaryExpression)); } /** */ ExpressionNode orOrExpression; /** */ ExpressionNode expression; /** */ ExpressionNode ternaryExpression; /// Store this so that we know where the ':' is Token colon; mixin OpEquals; } deprecated("Replaced by ExpressionStatement + ThrowExpression") alias ThrowStatement = ThrowExpression; /// final class ThrowExpression: ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression)); } /** */ ExpressionNode expression; mixin OpEquals; } /// final class TraitsExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(identifier, templateArgumentList)); } /** */ Token identifier; /** */ TemplateArgumentList templateArgumentList; mixin OpEquals; } /// final class TryStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(declarationOrStatement, catches, finally_)); } /** */ DeclarationOrStatement declarationOrStatement; /** */ Catches catches; /** */ Finally finally_; mixin OpEquals; } /// final class Type : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type2, typeSuffixes)); } /** */ IdType[] typeConstructors; /** */ TypeSuffix[] typeSuffixes; /** */ Type2 type2; mixin OpEquals; } /// final class Type2 : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(typeofExpression, typeIdentifierPart, type, traitsExpression, vector, mixinExpression)); } /** */ IdType builtinType; /** */ alias superOrThis = builtinType; /** */ TypeofExpression typeofExpression; /** */ TypeIdentifierPart typeIdentifierPart; /** */ IdType typeConstructor; /** */ Type type; /** */ TraitsExpression traitsExpression; /** */ Vector vector; /** */ MixinExpression mixinExpression; mixin OpEquals; } /// final class TypeSpecialization : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token, type)); } /** */ Token token; /** */ Type type; mixin OpEquals; } /// final class TypeSuffix : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, low, high, delegateOrFunction, parameters, memberFunctionAttributes)); } /** */ Token delegateOrFunction; /** */ Token star; /** */ bool array; /** */ Type type; /** */ ExpressionNode low; /** */ ExpressionNode high; /** */ Parameters parameters; /** */ MemberFunctionAttribute[] memberFunctionAttributes; mixin OpEquals; } /// final class TypeidExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type, expression)); } /** */ Type type; /** */ Expression expression; mixin OpEquals; } /// final class TypeofExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, return_)); } /** */ Expression expression; /** */ Token return_; mixin OpEquals; } /// final class UnaryExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { // TODO prefix, postfix, unary mixin (visitIfNotNull!(primaryExpression, newExpression, deleteExpression, castExpression, functionCallExpression, argumentList, unaryExpression, type, identifierOrTemplateInstance, assertExpression, throwExpression, indexExpression)); } /** */ Type type; /** */ PrimaryExpression primaryExpression; /** */ Token prefix; /** */ Token suffix; /** */ UnaryExpression unaryExpression; /** */ NewExpression newExpression; /** */ DeleteExpression deleteExpression; /** */ CastExpression castExpression; /** */ FunctionCallExpression functionCallExpression; /** */ ArgumentList argumentList; /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance; /** */ AssertExpression assertExpression; /** */ ThrowExpression throwExpression; /** */ IndexExpression indexExpression; /** */ size_t dotLocation; mixin OpEquals; } /// final class UnionDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(name, templateParameters, constraint, structBody)); } /** */ Token name; /** */ TemplateParameters templateParameters; /** */ Constraint constraint; /** */ StructBody structBody; /** */ string comment; mixin OpEquals; } /// final class Unittest : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(blockStatement)); } /** */ BlockStatement blockStatement; /** */ string comment; /** */ size_t location; /** */ size_t line; /** */ size_t column; mixin OpEquals; } /// final class VariableDeclaration : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(storageClasses, type, declarators, autoDeclaration)); } /** */ Type type; /** */ Declarator[] declarators; /** */ StorageClass[] storageClasses; /** */ AutoDeclaration autoDeclaration; /** */ string comment; mixin OpEquals; } /// final class Vector : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(type)); } /** */ Type type; mixin OpEquals; } /// final class VersionCondition : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token)); } /** */ size_t versionIndex; /** */ Token token; mixin OpEquals; } /// final class VersionSpecification : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(token)); } /** */ Token token; mixin OpEquals; } /// final class WhileStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, declarationOrStatement)); } /** */ Expression expression; /** */ DeclarationOrStatement declarationOrStatement; /** */ size_t startIndex; mixin OpEquals; } /// final class WithStatement : BaseNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(expression, declarationOrStatement)); } /** */ Expression expression; /** */ DeclarationOrStatement declarationOrStatement; mixin OpEquals; } /// final class XorExpression : ExpressionNode { override void accept(ASTVisitor visitor) const { mixin (visitIfNotNull!(left, right)); } mixin BinaryExpressionBody; mixin OpEquals; } unittest // issue #133 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; string src = q{module test133; void main(){}}; final class TkTest : ASTVisitor { alias visit = ASTVisitor.visit; override void visit(const Token t){assert(t.text.length);} } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); TkTest t = new TkTest; t.visit(m); } unittest // issue #165 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; string src = q{module test165; enum foo(T) = bar!T;}; final class EpoTest : ASTVisitor { bool visited; alias visit = ASTVisitor.visit; override void visit(const EponymousTemplateDeclaration){visited = true;} } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); EpoTest et = new EpoTest; et.visit(m); assert(et.visited); } unittest // issue #156 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; final class Test : ASTVisitor { bool arrIndex, arrValue, arrValueOnly, aaLiteral; alias visit = ASTVisitor.visit; override void visit(const ArrayInitializer ai) { if (ai.arrayMemberInitializations.length == 1) { arrIndex = ai.arrayMemberInitializations[0].assignExpression !is null; arrValue = ai.arrayMemberInitializations[0].nonVoidInitializer !is null; arrValueOnly = arrValue && !arrIndex; } } override void visit(const AssocArrayLiteral aal) { aaLiteral = true; } } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); { // no colon so array. string src1 = q{void main(){const arr = [[0]];}}; Module m = parseModule(ParserConfig(getTokensForParser(src1, cf, &ca), "", &ra)); Test t = new Test; t.visit(m); assert(t.arrValueOnly); } { // simple primary before colon, assume array. string src2 = q{void main(){const arr = [0:0];}}; Module m = ParserConfig(getTokensForParser(src2, cf, &ca), "", &ra).parseModule(); Test t = new Test; t.visit(m); assert(t.arrIndex); assert(t.arrValue); assert(!t.aaLiteral); } { // more complex exp before colon, assume AA. string src3 = q{void main(){const arr = [[0]:0];}}; Module m = ParserConfig(getTokensForParser(src3, cf, &ca), "", &ra).parseModule(); Test t = new Test; t.visit(m); assert(!t.arrIndex); assert(!t.arrValue); assert(t.aaLiteral); } } unittest // issue #170, issue #316 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; abstract class TestCase : ASTVisitor { string src; bool visited; this() { RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(src, cf, &ca), "", &ra).parseModule(); visit(m); assert(visited); } } class FunctionLiteralExpressionTestCase : TestCase { alias visit = ASTVisitor.visit; override void visit(const FunctionLiteralExpression){visited = true;} } class StructInitializerTestCase : TestCase { alias visit = ASTVisitor.visit; override void visit(const StructInitializer){visited = true;} } new class FunctionLiteralExpressionTestCase {this(){ TestCase.src = q{ void function() a = {call();};}; super(); }}; new class FunctionLiteralExpressionTestCase {this(){ TestCase.src = q{ const a = {int i;};}; super(); }}; new class FunctionLiteralExpressionTestCase {this(){ TestCase.src = q{ const a = {};}; super(); }}; new class StructInitializerTestCase {this(){ TestCase.src = q{A a = {member : call()};}; super(); }}; new class StructInitializerTestCase {this(){ TestCase.src = q{A a = {0};}; super(); }}; } unittest // issue #193 { import dparse.lexer, dparse.parser, dparse.rollback_allocator; final class Test193 : ASTVisitor { static string src = q{const(Type1[immutable(Type2)]) qualAarray;}; size_t tc; alias visit = ASTVisitor.visit; override void visit(const TypeIdentifierPart tip) { tip.accept(this); assert(tip.indexer is null); } override void visit(const Type type) { tc++; if (tc == 1) //const( { assert(type.type2.typeConstructor == tok!"const"); assert(type.type2.typeIdentifierPart is null); } else if (tc == 2) //const(Type1 { assert(type.typeConstructors.length == 0); assert(type.type2.typeIdentifierPart.identifierOrTemplateInstance .identifier.text == "Type1"); assert(type.typeSuffixes.length == 1); } else if (tc == 3) // immutable( { assert(type.type2.typeConstructor == tok!"immutable"); assert(type.type2.typeIdentifierPart is null); } else if (tc == 4) // immutable(Type2 { assert(type.typeConstructors.length == 0); assert(type.type2.typeIdentifierPart.identifierOrTemplateInstance .identifier.text == "Type2"); assert(type.typeSuffixes.length == 0); } type.accept(this); } } RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = ParserConfig(getTokensForParser(Test193.src, cf, &ca), "", &ra).parseModule(); Test193 t193 = new Test193; t193.visit(m); } unittest // there used to be a small regression when adding the ParserConfig { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = q{module m;}; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m1 = parseModule(getTokensForParser(src, cf, &ca), "", &ra , null); Module m2 = parseModule(getTokensForParser(src, cf, &ca), "", &ra); } unittest //#318 : used to segfault { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = q{ auto a = new TestClass( }; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); static void shut(string, size_t, size_t, string ,bool){} Module m1 = parseModule(getTokensForParser(src, cf, &ca), "", &ra , &shut); } unittest //#365 : used to segfault { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = " o[{scope(x "; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); static void shut(string, size_t, size_t, string ,bool){} Module m1 = parseModule(getTokensForParser(src, cf, &ca), "", &ra , &shut); } unittest // issue #398: Support extern(C++, <string expressions...>) { import dparse.lexer : LexerConfig; import dparse.parser : ParserConfig, parseModule; import dparse.rollback_allocator : RollbackAllocator; RollbackAllocator ra; StringCache ca = StringCache(16); const(PrimaryExpression)[] getNamespaces(const string sourceCode) { final class Test398 : ASTVisitor { alias visit = ASTVisitor.visit; const(PrimaryExpression)[] namespaces; override void visit(const LinkageAttribute link) { assert(link.identifier.text == "C"); assert(link.hasPlusPlus); assert(!link.typeIdentifierPart); assert(!link.classOrStruct); assert(link.cppNamespaces); super.visit(link); } override void visit(const NamespaceList list) { assert(list.items.length); assert(!namespaces); foreach (const entry; list.items) { const prim = cast(PrimaryExpression) entry.expression; assert(prim); namespaces ~= prim; } } } LexerConfig cf = LexerConfig("", StringBehavior.source); Module m = ParserConfig(getTokensForParser(sourceCode, cf, &ca), "", &ra).parseModule(); scope visitor = new Test398(); visitor.visit(m); return visitor.namespaces; } void checkText(const PrimaryExpression pe, const string exp) { assert(pe); const act = pe.primary.text; assert(act == exp, '<' ~ act ~ '>'); } auto ns = getNamespaces(`extern(C++, "foo") int i;`); assert(ns.length == 1); checkText(ns[0], `"foo"`); ns = getNamespaces(`extern(C++, "foo", "bar", "baz",) int i;`); assert(ns.length == 3); checkText(ns[0], `"foo"`); checkText(ns[1], `"bar"`); checkText(ns[2], `"baz"`); } unittest // Differentiate between no and empty DDOC comments, e.g. for DDOC unittests { import dparse.lexer, dparse.parser, dparse.rollback_allocator; auto src = q{ /// unittest {} /// @safe pure unittest {} /****/ unittest {} /++++/ unittest {} /// This is a comment! unittest {} unittest {} }; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = parseModule(getTokensForParser(src, cf, &ca), "", &ra); final class UnittestVisitor : ASTVisitor { alias visit = ASTVisitor.visit; bool[size_t] found; override void visit(const Unittest test) { assert(test.line !in found); found[test.line] = true; switch (test.line) { case 3, 6, 8, 10: assert(test.comment !is null); assert(test.comment == ""); break; case 13: assert(test.comment == "This is a comment!"); break; case 15: assert(test.comment is null); break; default: assert(false, format("Unknown line: %d", test.line)); } } } scope visitor = new UnittestVisitor(); visitor.visit(m); assert(visitor.found.length == 6); } unittest // Support GCC-sytle asm statements { static void verify(T)(const string code, void function(scope const T) handler) { import dparse.lexer, dparse.parser, dparse.rollback_allocator; RollbackAllocator ra; LexerConfig cf = LexerConfig("", StringBehavior.source); StringCache ca = StringCache(16); Module m = parseModule(getTokensForParser("void main() { " ~ code ~ '}', cf, &ca), "", &ra); final class AsmVisitor : ASTVisitor { alias visit = ASTVisitor.visit; bool found; override void visit(const T node) { assert(!found); found = true; handler(node); } } scope visitor = new AsmVisitor(); visitor.visit(m); assert(visitor.found); } static void first(scope const AsmStatement stmt) { assert(stmt.asmInstructions.length == 0); assert(stmt.gccAsmInstructions.length == 1); with (stmt.gccAsmInstructions[0]) { assert(assemblerTemplate); assert(assemblerTemplate.tokens.length == 1); assert(assemblerTemplate.tokens[0].type == tok!"stringLiteral"); assert(assemblerTemplate.tokens[0].text == `"mov %0, EAX"`); assert(outputOperands); assert(outputOperands.items.length == 1); with (outputOperands.items[0]) { assert(constraint.type == tok!"stringLiteral"); assert(constraint.text == `"=r"`); auto una = cast(UnaryExpression) expression; assert(una); assert(una.primaryExpression.identifierOrTemplateInstance.identifier.text == "var1"); } } } verify(q{ asm { "mov %0, EAX" : "=r" (var1) ; } }, &first); static void second(scope const AsmStatement stmt) { first(stmt); with (stmt.gccAsmInstructions[0]) { assert(inputOperands); assert(inputOperands.items.length == 2); with (inputOperands.items[0]) { assert(symbolicName.type == tok!"identifier"); assert(symbolicName.text == "xy"); assert(constraint.type == tok!"stringLiteral"); assert(constraint.text == `"=w"`); auto una = cast(UnaryExpression) expression; assert(una); assert(una.primaryExpression.identifierOrTemplateInstance.identifier.text == "var2"); } with (inputOperands.items[1]) { assert(constraint.type == tok!"stringLiteral"); assert(constraint.text == `"g"`); auto una = cast(UnaryExpression) expression; assert(una); assert(una.primaryExpression.identifierOrTemplateInstance.identifier.text == "var3"); } } } verify(q{ asm { "mov %0, EAX" : "=r" (var1) : [xy] "=w" (var2), "g" (var3); } }, &second); verify(q{ asm { "mov %0, EAX" : "=r" (var1) : [xy] "=w" (var2), "g" (var3) : "r0" ; } }, (scope const AsmStatement stmt) { second(stmt); with (stmt.gccAsmInstructions[0]) { assert(registers); assert(registers.items.length == 1); assert(registers.items[0].type == tok!"stringLiteral"); assert(registers.items[0].text == `"r0"`); } }); verify(q{ asm { "mov EBX, EAX" : : : "r0", "r1" ; } }, (scope const GccAsmInstruction instr) { with (instr) { assert(registers); assert(registers.items.length == 2); assert(registers.items[0].type == tok!"stringLiteral"); assert(registers.items[0].text == `"r0"`); assert(registers.items[1].type == tok!"stringLiteral"); assert(registers.items[1].text == `"r1"`); } }); verify(q{ asm { "jmp LEnd" : : : : LEnd ; } }, (scope const GccAsmInstruction instr) { with (instr) { assert(gotos); assert(gotos.identifiers.length == 1); assert(gotos.identifiers[0].type == tok!"identifier"); assert(gotos.identifiers[0].text == `LEnd`); } }); }