/* Ċ Ġ* ĠCopyright Ġ 2 0 1 0 - 2 0 1 7 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġorg . jetbrains . kotlin . daemon Ċ Ċ import Ġcom . intellij . openapi . application . Application Manager Ċ import Ġorg . jetbrains . kotlin . cli . common . Compiler System Properties Ċ import Ġorg . jetbrains . kotlin . cli . common . arguments . K 2 JVM Compiler Arguments Ċ import Ġorg . jetbrains . kotlin . cli . common . messages . Compiler Message Severity Ċ import Ġorg . jetbrains . kotlin . cli . common . messages . Compiler Message Source Location Ċ import Ġorg . jetbrains . kotlin . cli . common . messages . Message Collector Ċ import Ġorg . jetbrains . kotlin . cli . common . messages . Output Message Util Ċ import Ġorg . jetbrains . kotlin . cli . jvm . K 2 JVM Compiler Ċ import Ġorg . jetbrains . kotlin . config . Services Ċ import Ġorg . jetbrains . kotlin . daemon . client . Daemon Reporting Targets Ċ import Ġorg . jetbrains . kotlin . daemon . client . Kotlin Compiler Client Ċ import Ġorg . jetbrains . kotlin . daemon . common .* Ċ import Ġorg . jetbrains . kotlin . integration . Kotlin Integration TestBase Ċ import Ġorg . jetbrains . kotlin . test . Kotlin TestUtils Ċ import Ġorg . jetbrains . kotlin . test . test Framework . reset Application To Null Ċ import Ġorg . jetbrains . kotlin . test . util . Kt TestUtil Ċ import Ġorg . junit . Assert Ċ import Ġjava . io . ByteArray OutputStream Ċ import Ġjava . io . File Ċ import Ġjava . io . Print Stream Ċ import Ġjava . net . URL ClassLoader Ċ import Ġjava . nio . file . Path Ċ import Ġkotlin . io . path . Experimental Path Api Ċ import Ġkotlin . io . path . create TempFile Ċ import Ġkotlin . io . path . delete IfExists Ċ Ċ @ Opt In ( Experimental Path Api :: class ) Ċ class ĠCompiler Api Test Ġ: ĠKotlin Integration TestBase () Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġcompiler Lib Dir Ġ= Ġget Compiler Lib () ĊĊĠĠĠ Ġval Ġcompiler Class Path Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( compiler Lib Dir , Ġ" kotlin - compiler . jar "), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( compiler Lib Dir , Ġ" kotlin - daemon . jar ") ĊĠĠĠ Ġ) ĊĠĠĠ Ġval Ġcompiler Id Ġby Ġlazy ( Lazy Thread Safety Mode . NONE ) Ġ{ ĠCompiler Id . make Compiler Id ( compiler Class Path ) Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcompile Loc ally ( message Collector : ĠTest Message Collector , Ġvar arg Ġargs : ĠString ): ĠPair < Int , ĠCollection < Output Message Util . Output >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġapplication Ġ= ĠApplication Manager . getApplication () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcode Ġ= ĠK 2 JVM Compiler (). exec ( message Collector , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠServices . EMPTY , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK 2 JVM Compiler Arguments (). apply Ġ{ ĠK 2 JVM Compiler (). parse Arguments ( args , Ġthis ) Ġ}). code ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutputs Ġ= Ġmessage Collector . messages . filter Ġ{ Ġit . severity Ġ== ĠCompiler Message Severity . OUTPUT Ġ}. map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠOutput Message Util . parse Output Message ( it . message )?. let Ġ{ Ġout s Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout s . outputFile ?. let Ġ{ ĠOutput Message Util . Output ( outs . source Files , Ġit ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcode Ġto Ġoutputs ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreset Application To Null ( application ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcompile On Daemon ( client Alive File : ĠFile , Ġcompiler Id : ĠCompiler Id , Ġdaemon JVM Options : ĠDa emon JVM Options , Ġdaemon Options : ĠDa emon Options , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Collector : ĠMessage Collector , Ġvar arg Ġargs : ĠString ): ĠPair < Int , ĠCollection < Output Message Util . Output >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdaemon Ġ= ĠKotlin Compiler Client . connect To Compile Service ( compiler Id , Ġclient Alive File , Ġdaemon JVM Options , Ġdaemon Options , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDa emon Reporting Targets ( message Collector Ġ= Ġmessage Collector ), Ġaut ost art Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ ĠassertNotNull (" failed Ġto Ġconnect Ġdaemon ", Ġdaemon ) ĊĊĠĠĠĠĠĠĠ Ġdaemon ?. register Client ( client Alive File . absolute Path ) ĊĊĠĠĠĠĠĠĠ Ġval Ġoutputs Ġ= Ġarray ListOf < Output Message Util . Output >() ĊĊĠĠĠĠĠĠĠ Ġval Ġcode Ġ= ĠKotlin Compiler Client . compile ( daemon !! , ĠCompile Service . NO _ SESSION , ĠCompile Service . Target Platform . JVM , Ġargs , Ġmessage Collector , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġout File , Ġsrc Files Ġ-> Ġoutputs . add ( Output Message Util . Output ( src Files , Ġout File )) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Severity Ġ= ĠReport Severity . DEBUG ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcode Ġto Ġoutputs ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Hello App Base Dir (): ĠString Ġ= ĠK t TestUtil . get TestData Path Base () Ġ+ Ġ"/ integration / smoke / hello App " ĊĠĠĠ Ġprivate Ġfun Ġget Simple Script Base Dir (): ĠString Ġ= ĠK t TestUtil . get TestData Path Base () Ġ+ Ġ"/ integration / smoke / simple Script " ĊĊĠĠĠ Ġprivate Ġfun Ġrun ( base Dir : ĠString , Ġlog Name : ĠString , Ġvar arg Ġargs : ĠString ): ĠInt Ġ= Ġrun Java ( base Dir , Ġlog Name , Ġ* args ) ĊĊĠĠĠ Ġprivate Ġfun Ġrun Script With Args ( testData Dir : ĠString , Ġlog Name : ĠString ?, Ġscript ClassName : ĠString , Ġclasspath : ĠList < File >, Ġvar arg Ġarguments : ĠString ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġcl Ġ= ĠURL ClassLoader ( classpath . map Ġ{ Ġit . to URI (). to URL () Ġ}. to Typed Array ()) ĊĠĠĠĠĠĠĠ Ġval Ġscript Class Ġ= Ġcl . load Class ( script ClassName ) ĊĊĠĠĠĠĠĠĠ Ġval Ġscript Out Ġ= Ġcapture Out Ġ{ Ġscript Class . construct ors . first (). newInstance ( arguments ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( log Name Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpected File Ġ= ĠFile ( testData Dir , Ġlog Name Ġ+ Ġ". expected ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnormalized Content Ġ= Ġnormalize Output ( File ( testData Dir ), Ġ" OUT :\ n $ script Out \ n Return Ġcode : Ġ 0 ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠKotlin TestUtils . assertEquals ToFile ( expected File , Ġnormalized Content ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtest Hello App Local () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Collector Ġ= ĠTest Message Collector () ĊĠĠĠĠĠĠĠ Ġval Ġjar Ġ= Ġtmp dir . absolute Path Ġ+ ĠFile . separator Ġ+ Ġ" hello . jar " ĊĠĠĠĠĠĠĠ Ġval Ġ( code , Ġoutputs ) Ġ= Ġcompile Loc ally ( message Collector , Ġ"- include - runtime ", ĠFile ( get Hello App Base Dir (), Ġ" hello . kt "). absolute Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"- d ", Ġjar , Ġ"- X report - output - files ") ĊĠĠĠĠĠĠĠ Ġif Ġ( code Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . fail (" Result Ġcode : Ġ$ code \ n ${ message Collector . messages . join ToString ("\ n ") }") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠAssert . assertTrue ( outputs . isNotEmpty ()) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( jar , Ġoutputs . first (). outputFile ?. absolute Path ) ĊĠĠĠĠĠĠĠ Ġrun ( get Hello App Base Dir (), Ġ" hello . run ", Ġ"- cp ", Ġjar , Ġ" Hello . Hello Kt ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtest Hello App () Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Flag File ( getTest Name ( true ), Ġ". alive ") Ġ{ Ġflag File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdaemon Options Ġ= ĠDa emon Options ( run Files Path Ġ= ĠFile ( tmpdir , Ġget Test Name ( true )). absolute Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġverbose Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Perf Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog File : ĠPath Ġ= Ġcreate TempFile (" kotlin - daemon - test .", Ġ". log ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdaemon JVM Options Ġ= Ġconfigure Daemon JVM Options (" D ${ Compiler System Properties . COMPILE _ DA EM ON _ LOG _ PATH _ PROPERTY . property } =\" ${ log File . logger Compatible Path } \"", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinherit Memory Limits Ġ= Ġfalse , Ġinherit Other Jvm Options Ġ= Ġfalse , Ġinherit Additional Properties Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjar Ġ= Ġtmp dir . absolute Path Ġ+ ĠFile . separator Ġ+ Ġ" hello . jar " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( code , Ġoutputs ) Ġ= Ġcompile On Daemon ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflag File , Ġcompiler Id , Ġdaemon JVM Options , Ġdaemon Options , ĠTest Message Collector (), Ġ"- include - runtime ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( get Hello App Base Dir (), Ġ" hello . kt "). absolute Path , Ġ"- d ", Ġjar , Ġ"- X report - output - files " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 0 , Ġcode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . assertTrue ( outputs . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . assertEquals ( jar , Ġoutputs . first (). outputFile ?. absolute Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun ( get Hello App Base Dir (), Ġ" hello . run ", Ġ"- cp ", Ġjar , Ġ" Hello . Hello Kt ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠKotlin Compiler Client . shutdown Compile Service ( compiler Id , Ġdaemon Options ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ Ġlog File . delete IfExists () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Failure Ġ{ Ġe Ġ-> Ġprintln (" Failed Ġto Ġdelete Ġlog Ġfile : Ġ$ e ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtest Simple Script Local () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Collector Ġ= ĠTest Message Collector () ĊĠĠĠĠĠĠĠ Ġval Ġ( code , Ġoutputs ) Ġ= Ġcompile Loc ally ( message Collector , ĠFile ( getSimple Script Base Dir (), Ġ" script . k ts "). absolute Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"- d ", Ġtmp dir . absolute Path , Ġ"- X report - output - files ") ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 0 , Ġcode ) ĊĠĠĠĠĠĠĠ ĠAssert . assertTrue ( outputs . isNotEmpty ()) ĊĠĠĠĠĠĠĠ ĠAssert . assertEquals ( File ( tmpdir , Ġ" Script . class "). absolute Path , Ġoutputs . first (). outputFile ?. absolute Path ) ĊĠĠĠĠĠĠĠ Ġrun Script With Args ( getSimple Script Base Dir (), Ġ" script ", Ġ" Script ", ĠlistOf ( tmpdir ), Ġ" hi ", Ġ" there ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtest Simple Script () Ġ{ ĊĠĠĠĠĠĠĠ Ġwith Flag File ( getTest Name ( true ), Ġ". alive ") Ġ{ Ġflag File Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdaemon Options Ġ= ĠDa emon Options ( run Files Path Ġ= ĠFile ( tmpdir , Ġget Test Name ( true )). absolute Path , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġverbose Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport Perf Ġ= Ġtrue ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog File : ĠPath Ġ= Ġcreate TempFile (" kotlin - daemon - test .", Ġ". log ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdaemon JVM Options Ġ= Ġconfigure Daemon JVM Options (" D ${ Compiler System Properties . COMPILE _ DA EM ON _ LOG _ PATH _ PROPERTY . property } =\" ${ log File . logger Compatible Path } \"", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinherit Memory Limits Ġ= Ġfalse , Ġinherit Other Jvm Options Ġ= Ġfalse , Ġinherit Additional Properties Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( code , Ġoutputs ) Ġ= Ġcompile On Daemon ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflag File , Ġcompiler Id , Ġdaemon JVM Options , Ġdaemon Options , ĠTest Message Collector (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFile ( getSimple Script Base Dir (), Ġ" script . k ts "). absolute Path , Ġ"- X report - output - files ", Ġ"- d ", Ġtmp dir . absolute Path ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . assertEquals ( 0 , Ġcode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . assertTrue ( outputs . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssert . assertEquals ( File ( tmpdir , Ġ" Script . class "). absolute Path , Ġoutputs . first (). outputFile ?. absolute Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Script With Args ( getSimple Script Base Dir (), Ġ" script ", Ġ" Script ", ĠlistOf ( tmpdir ), Ġ" hi ", Ġ" there ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠKotlin Compiler Client . shutdown Compile Service ( compiler Id , Ġdaemon Options ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrun Catch ing Ġ{ Ġlog File . delete IfExists () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. on Failure Ġ{ Ġe Ġ-> Ġprintln (" Failed Ġto Ġdelete Ġlog Ġfile : Ġ$ e ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠTest Message Collector Ġ: ĠMessage Collector Ġ{ ĊĠĠĠ Ġdata Ġclass ĠMessage ( val Ġseverity : ĠCompiler Message Severity , Ġval Ġmessage : ĠString , Ġval Ġlocation : ĠCompiler Message Source Location ?) ĊĊĠĠĠ Ġval Ġmessages Ġ= Ġarray ListOf < Message >() ĊĊĠĠĠ Ġoverride Ġfun Ġclear () Ġ{ ĊĠĠĠĠĠĠĠ Ġmessages . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġreport ( severity : ĠCompiler Message Severity , Ġmessage : ĠString , Ġlocation : ĠCompiler Message Source Location ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġmessages . add ( Message ( severity , Ġmessage , Ġlocation )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġhas Errors (): ĠBoolean Ġ= Ġmessages . any Ġ{ Ġit . severity Ġ== ĠCompiler Message Severity . EXCEPTION Ġ|| Ġit . severity Ġ== ĠCompiler Message Severity . ERROR Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġmessages . join ToString ("\ n ") Ġ{ Ġ"${ it . severity }: Ġ${ it . message }${ it . location ?. let {" Ġat Ġ$ it "} Ġ?: Ġ"" }" Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠTest Message Collector . assert Has Message ( msg : ĠString , Ġdesired Severity : ĠCompiler Message Severity ? Ġ= Ġnull ) Ġ{ ĊĠĠĠ Ġassert ( messages . any Ġ{ Ġit . message . contains ( msg ) Ġ&& Ġ( desired Severity Ġ== Ġnull Ġ|| Ġit . severity Ġ== Ġdesired Severity ) Ġ}) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Expecting Ġmessage Ġ\"$ msg \" Ġwith Ġseverity Ġ${ desired Severity ?. toString () Ġ?: Ġ" Any "}, Ġactual :\ n " Ġ+ ĊĠĠĠĠĠĠĠ Ġmessages . join ToString ("\ n ") Ġ{ Ġit . severity . toString () Ġ+ Ġ": Ġ" Ġ+ Ġit . message Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ internal Ġfun Ġcapture Out ( body : Ġ() Ġ-> ĠUnit ): ĠString Ġ{ ĊĠĠĠ Ġval Ġout Stream Ġ= ĠByteArrayOutputStream () ĊĠĠĠ Ġval Ġprev Out Ġ= ĠSystem . out ĊĠĠĠ ĠSystem . set Out ( Print Stream ( out Stream )) ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġbody () ĊĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠ ĠSystem . out . flush () ĊĠĠĠĠĠĠĠ ĠSystem . set Out ( prev Out ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġout Stream . toString () Ċ } ĊĊ