package Ġcom . gab ri elle eg 1 . pl ank . analyzer Ċ Ċ import Ġcom . gab ri elle eg 1 . pl ank . grammar . element . Decl Ċ import Ġcom . gab ri elle eg 1 . pl ank . grammar . element . Identifier Ċ import Ġcom . gab ri elle eg 1 . pl ank . grammar . element . Pl ank File Ċ import Ġcom . gab ri elle eg 1 . pl ank . shared . Graph Ċ import Ġcom . gab ri elle eg 1 . pl ank . shared . depth First Search Ċ Ċ data Ġclass ĠModule ( val Ġname : ĠIdentifier , Ġval Ġcontent : ĠList < Decl >) Ġ{ ĊĠ Ġlateinit Ġvar Ġscope : ĠScope ĊĊĠ Ġval Ġtype : ĠModule Type ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠ Ġval Ġvariables Ġ= Ġscope . variables . map Ġ{ Ġ( name , Ġvariable ) Ġ-> ĊĠĠĠĠĠĠĠ ĠStruct Property ( variable . mutable , Ġname , Ġvariable . value . type ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġreturn ĠModule Type ( name , Ġvariables ) ĊĠĠĠ Ġ} ĊĊĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġ" Module ($ name , Ġ${ scope :: class . simple Name })" Ċ } Ċ Ċ class ĠModule Tree ( files : ĠList < Pl ank File > Ġ= Ġempty List ()) Ġ{ ĊĠ Ġprivate Ġval Ġmodules Ġ= Ġmutable Map Of < Identifier , ĠModule >() ĊĊĠ Ġinit Ġ{ ĊĠĠĠ Ġfiles . forEach Ġ{ Ġfile Ġ-> ĊĠĠĠĠĠ Ġmodules [ file . module ] Ġ= ĠModule ( file . module , Ġfile . program ). apply Ġ{ ĊĠĠĠĠĠĠĠ Ġscope Ġ= ĠFile Scope ( file ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġval Ġdependencies Ġ= ĠGraph < Identifier >(). apply Ġ{ ĊĠĠĠ Ġfiles . map ( Pl ank File :: module ). forEach ( this :: add Vertex ) ĊĠ Ġ} ĊĊĠ Ġ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 : ĠScope , Ġon : ĠScope ) Ġ{ ĊĠĠĠ Ġdependencies . add Edge ( scope . name , Ġon . name ) ĊĠ Ġ} ĊĊĠ Ġfun Ġcreate Module ( name : ĠIdentifier , Ġen closing : ĠScope , Ġcontent : ĠList < Decl >): ĠModule Ġ{ ĊĠĠĠ Ġdependencies . add Vertex ( name ) ĊĊĠĠĠ Ġval Ġmodule Ġ= ĠModule ( name , Ġcontent ). apply Ġ{ ĊĠĠĠĠĠ Ġscope Ġ= ĠModule Scope ( this , Ġen closing , ĠModule Tree ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġmodules [ name ] Ġ= Ġmodule ĊĊĠĠĠ Ġreturn Ġmodule ĊĠ Ġ} ĊĊĠ Ġfun Ġfind Module ( name : ĠIdentifier ): ĠModule ? Ġ{ ĊĠĠĠ Ġreturn Ġdependencies . depth First Search ( name ). first OrNull ()?. let ( modules :: get ) ĊĠ Ġ} Ċ } Ċ