package Ġorg . pl ank . analyzer . resolver Ċ Ċ import Ġorg . pl ank . shared . Graph Ċ import Ġorg . pl ank . shared . depth First Search Ċ import Ġorg . pl ank . syntax . element . Decl Ċ import Ġorg . pl ank . syntax . element . Identifier Ċ import Ġorg . pl ank . syntax . element . Pl ank File Ċ import Ġorg . pl ank . syntax . element . Stmt Ċ Ċ data Ġclass ĠModule ( val Ġname : ĠIdentifier , Ġval Ġcontent : ĠList < Stmt >) Ġ{ ĊĠ Ġlateinit Ġvar Ġscope : ĠResolver Scope ĊĊĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Module ($ name , Ġscope : Ġ$ scope )" Ċ } Ċ Ċ class ĠModule Tree ( scopes : ĠList < Resolver Scope > Ġ= Ġempty List ()) Ġ{ ĊĠ Ġprivate Ġval Ġ_ modules : ĠMutable Map < Identifier , ĠModule > Ġ= Ġmutable Map Of () ĊĊĠ Ġval Ġmodules : ĠMap < Identifier , ĠModule > Ġget () Ġ= Ġ_ modules ĊĊĠ Ġval Ġdependencies Ġ= ĠGraph < Identifier >(). apply Ġ{ ĊĠĠĠ Ġscopes . map ( Resolver Scope :: name ). forEach ( this :: add Vertex ) ĊĠ Ġ} ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġscopes . forEach Ġ{ Ġfile Ġ-> ĊĠĠĠĠĠ Ġ_ modules [ file . name ] Ġ= ĠModule ( file . name , Ġfile . content ). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġscope Ġ= Ġfile . enc lose ( Global Scope ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġfind Files (): ĠList < Pl ank File > Ġ{ ĊĠĠĠ Ġreturn Ġ_ modules . values ĊĠĠĠĠĠ Ġ. map ( Module :: scope ) ĊĠĠĠĠĠ Ġ. filter Is Instance < File Scope >() ĊĠĠĠĠĠ Ġ. map ( File Scope :: file ) ĊĠ Ġ} ĊĊĠ Ġfun Ġadd Dependency ( scope : ĠResolver Scope , Ġon : ĠResolver Scope ) Ġ{ ĊĠĠĠ Ġdependencies . add Edge ( scope . name , Ġon . name ) ĊĠ Ġ} ĊĊĠ Ġfun Ġcreate Module ( module : ĠModule ): ĠModule Ġ{ ĊĠĠĠ Ġdependencies . add Vertex ( module . name ) ĊĊĠĠĠ Ġ_ modules [ module . name ] Ġ= Ġmodule ĊĊĠĠĠ Ġreturn Ġmodule ĊĠ Ġ} ĊĊĠ Ġfun Ġcreate Module ( name : ĠIdentifier , Ġen closing : ĠResolver Scope , Ġcontent : ĠList < Decl >): ĠModule Ġ{ ĊĠĠĠ Ġdependencies . add Vertex ( name ) ĊĊĠĠĠ Ġval Ġmodule Ġ= ĠModule ( name , Ġcontent ). apply Ġ{ ĊĠĠĠĠĠ Ġscope Ġ= ĠModule Scope ( name , Ġcontent , Ġen closing , Ġthis @ Module Tree ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ_ modules [ name ] Ġ= Ġmodule ĊĊĠĠĠ Ġreturn Ġmodule ĊĠ Ġ} ĊĊĠ Ġfun Ġfind Module ( name : ĠIdentifier ): ĠModule ? Ġ{ ĊĠĠĠ Ġreturn Ġdependencies . depth First Search ( name ). first OrNull ()?. let (_ modules :: get ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠ Ġval Ġunsigned HashCode Ġ= ĠhashCode (). to Long () Ġand Ġ 0 xffffffff L ĊĠĠĠ Ġval ĠhashCode Str Ġ= Ġunsigned HashCode . toString ( 1 6 ) ĊĊĠĠĠ Ġreturn Ġ" Module Tree @ $ hashCode Str " ĊĠ Ġ} ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġfun Ġcreate ( files : ĠList < Pl ank File >): ĠModule Tree Ġ{ ĊĠĠĠĠĠ Ġreturn Ġfiles ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠModule ( it . module , Ġit . program ). apply Ġ{ Ġscope Ġ= ĠFile Scope ( it , ĠGlobal Scope ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . scope Ġ} ĊĠĠĠĠĠĠĠ Ġ. let (:: Module Tree ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcreate ( var arg Ġfiles : ĠPl ank File ): ĠModule Tree Ġ{ ĊĠĠĠĠĠ Ġreturn Ġcreate ( files . toList ()) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ