// Ċ // Ġ( C ) ĠCopyright Ġ 2 0 1 8 ĠMartin ĠE . ĠN ord berg ĠIII Ċ // ĠApache Ġ 2 . 0 ĠLicense Ċ // Ċ Ċ package Ġl zero . domain . generating . builders Ċ Ċ //---------------------------------------------------------------- ------------------------------------------------ ----- Ċ Ċ /** Ċ Ġ* ĠWrap s Ġa Ġstring Ġbuilder Ġto Ġsupport Ġindentation Ġand Ġtrial Ġoutput Ġthat Ġis Ġline Ġlength Ġlimited . Ċ Ġ*/ Ċ class ĠCode StringBuilder ( ĊĠĠĠ Ġprivate Ġval Ġindent WhiteSpace : ĠString Ġ= Ġ" Ġ Ġ", ĊĠĠĠ Ġprivate Ġval Ġmax Line Length : ĠInt Ġ= Ġ 1 0 0 Ċ ) Ġ{ ĊĊĠĠĠ Ġ/** ĠThe Ġcode Ġoutput Ġso Ġfar , Ġexcept Ġfor Ġthe Ġlatest Ġline Ġunder Ġconstruction . Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġbuilder Ġ= ĠStringBuilder () ĊĊĠĠĠ Ġ/** ĠThe Ġcode Ġof Ġthe Ġlast Ġline Ġbeing Ġoutput . Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġcurrent Line Ġ= ĠStringBuilder () ĊĊĠĠĠ Ġ/** ĠThe Ġcurrent Ġindentation Ġlevel . Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġindentation Level Ġ= Ġ 0 ĊĊĠĠĠ Ġ/** ĠThe Ġwhite Ġspace Ġcorresponding Ġto Ġthe Ġcurrent Ġindentation Ġlevel . Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġindent Spaces Ġ= Ġ"" ĊĊĠĠĠ Ġ/** ĠIf Ġgreater Ġthan Ġzero , Ġa Ġline Ġexceed ing Ġmax Line Length Ġwill Ġtrigger Ġa ĠLine Length Exceeded Exception . Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġline Length Limit ed Count Ġ= Ġ 0 ; ĊĊĠĠĠ Ġ//// ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠMov es Ġthe Ġcurrent Ġline Ġfrom Ġits Ġholding Ġpoint Ġto Ġthe Ġstring Ġbuilder Ġoutput . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġaccept Current Line () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠCapture Ġthe Ġcurrent Ġline Ġfrom Ġits Ġbuilder . ĊĠĠĠĠĠĠĠ Ġvar Ġcode Ġ= Ġcurrent Line . toString (). trim End (' Ġ', Ġ'\ t ') ĊĠĠĠĠĠĠĠ Ġcurrent Line . clear () ĊĊĠĠĠĠĠĠĠ Ġ// ĠDe al Ġwith Ġoptional Ġline Ġbreaks . ĊĠĠĠĠĠĠĠ Ġif Ġ( code . contains ( SOFT _ HY P HEN )) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Line . length Ġ+ Ġcode . length Ġ> Ġmax Line Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( line Length Limit ed Count Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠLine Length Exceeded Exception () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend ( code . replace ( SOFT _ HY P HEN , Ġ"\ n ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcode Ġ= Ġcode . replace ( SOFT _ HY P HEN , Ġ"") ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( line Length Limit ed Count Ġ> Ġ 0 Ġ&& Ġcode . length Ġ> Ġmax Line Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠLine Length Exceeded Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠMove Ġthe Ġcurrent Ġline Ġinto Ġthe Ġfinished Ġoutput . ĊĠĠĠĠĠĠĠ Ġbuilder . append ( code ) ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends Ġa Ġgiven Ġ[ snippet ] Ġto Ġthe Ġoutput Ġcode . ĠHandles Ġindentation Ġfor Ġnew Ġlines . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġappend ( snippet : ĠString ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġvar Ġline StartIndex Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġline End Index Ġ= Ġsnippet . indexOf ('\ n ') ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( true ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠOnce Ġno Ġnew Ġline Ġcharacters Ġremain , Ġcomplete Ġsimpler Ġoutput Ġthen Ġquit . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( line End Index Ġ< Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremainder Ġ= Ġsnippet . substring ( line StartIndex ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend To Current Line ( remainder ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbreak ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDetermine Ġthe Ġnext Ġline Ġof Ġoutput . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġline Ġ= Ġsnippet . substring ( line StartIndex , Ġline End Index ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMove Ġthings Ġfrom Ġthe Ġcurrent Ġline Ġto Ġthe Ġmain Ġstring Ġbuilder ; Ġclear Ġout Ġthe Ġcurrent Ġline . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġappend To Current Line ( line ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMove Ġthe Ġcurrent Ġline Ġinto Ġthe Ġfinished Ġoutput . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaccept Current Line () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . append ('\ n ') ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAdv ance Ġto Ġthe Ġnext Ġline . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġline StartIndex Ġ= Ġline End Index Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġline End Index Ġ= Ġsnippet . indexOf ('\ n ', Ġline StartIndex ) ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends Ġan Ġexplicit Ġnew Ġline Ġto Ġthe Ġoutput . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġappend NewLine () Ġ= ĊĠĠĠĠĠĠĠ Ġappend ("\ n ") ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠApp ends Ġa Ġ[ fragment ] Ġof Ġcode Ġ( known Ġto Ġhave Ġno Ġnew Ġline Ġcharacters ) Ġto Ġthe Ġcurrent Ġline . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġappend To Current Line ( fragment : ĠString ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠInd ent Ġif Ġthe Ġline Ġis Ġempty Ġand Ġthe Ġadded Ġcode Ġis Ġnot . ĊĠĠĠĠĠĠĠ Ġif Ġ( current Line . isEmpty () Ġ&& Ġfragment . trim End (' Ġ', Ġ'\ t '). isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Line . append ( indent Spaces ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Line . append ( fragment . trim Start (' Ġ', Ġ'\ t ')) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Line . append ( fragment ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( line Length Limit ed Count Ġ> Ġ 0 Ġ&& Ġcurrent Line . length Ġ> Ġmax Line Length ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠLine Length Exceeded Exception () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIn crements Ġthe Ġindentation Ġlevel Ġby Ġone Ġfor Ġoutput Ġoccur ring Ġafter Ġthis Ġcall . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġindent () Ġ{ ĊĠĠĠĠĠĠĠ Ġindentation Level Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠ Ġindent Spaces Ġ+= Ġindent WhiteSpace ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExec utes Ġthe Ġgiven Ġ[ output ] Ġwith Ġthe Ġindentation Ġlevel Ġincreased Ġby Ġone . ĊĠĠĠĠ Ġ* Ġ@ param Ġoutput Ġthe Ġclosure Ġto Ġcall Ġfor Ġindent ed Ġoutput . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġindent ed ( output : ĠCode StringBuilder . () Ġ-> ĠUnit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . indent () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . output () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . un indent () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġline Length Limit ed ( write Code : ĠCode StringBuilder . () Ġ-> ĠUnit ): ĠBoolean Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠMark Ġwhere Ġwe Ġstarted Ġfrom ĊĠĠĠĠĠĠĠ Ġval Ġlength Before Trial Ġ= Ġbuilder . length ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Line Before Trial Ġ= Ġcurrent Line . toString () ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġtry Ġwriting Ġthe Ġcode Ġwith Ġline Ġlength Ġlimited ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . line Length Limit ed Count Ġ+= Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . write Code () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcatch Ġ( e : ĠLine Length Exceeded Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRestore Ġour Ġoutput Ġto Ġits Ġoriginal Ġcondition ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . set Length ( length Before Trial ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Line . clear () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Line . append ( current Line Before Trial ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠReturn Ġfailure . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . line Length Limit ed Count Ġ-= Ġ 1 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠConverts Ġthe Ġcode Ġbuilder Ġoutput Ġto Ġa Ġsimple Ġstring . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġbuilder . toString () ĊĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġthis Ġdoes Ġnot Ġaccount Ġfor Ġsoft Ġhy phen Ġbehavior Ġin Ġlast / current Ġline ĊĠĠĠĠĠĠĠ Ġif Ġ( current Line . length Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ+= Ġcurrent Line . toString (). trim End (' Ġ', Ġ'\ t ') ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDec re ments Ġthe Ġindentation Ġlevel Ġby Ġone . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġun indent () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġcheck ( this . indentation Level Ġ> Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġindentation Level Ġ-= Ġ 1 ĊĊĠĠĠĠĠĠĠ Ġindent Spaces Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 1 .. indentation Level ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġindent Spaces Ġ+= Ġindent WhiteSpace ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( current Line . isBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Line . clear () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ//// ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ/** ĠRepresents Ġa Ġplace Ġto Ġput Ġan Ġoptional Ġline Ġbreak Ġin Ġorder Ġto Ġreduce Ġline Ġwidth ; Ġotherwise Ġomitted . Ġ*/ ĊĠĠĠĠĠĠĠ Ġval ĠS OFT _ HY P HEN Ġ= Ġ"\ u 0 0 AD " ĊĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ //---------------------------------------------------------------- ------------------------------------------------ ----- ĊĊ