@@ -69,6 +69,7 @@ class SourceFile {
6969 ) ;
7070 }
7171
72+ @memoize
7273 get contractsInScope ( ) : Record < string , SourceContract > {
7374 return contractsInScope ( this ) ;
7475 }
@@ -78,16 +79,22 @@ class SourceFile {
7879 }
7980}
8081
81- const scopeCache = new WeakMap < SourceFile , Record < string , SourceContract > > ( ) ;
82-
83- function contractsInScope ( file : SourceFile ) : Record < string , SourceContract > {
84- if ( scopeCache . has ( file ) ) {
85- return scopeCache . get ( file ) ! ;
82+ function contractsInScope (
83+ file : SourceFile ,
84+ stack = new Set < SourceFile > ( ) ,
85+ aliasedImport = false ,
86+ ) : Record < string , SourceContract > {
87+ if ( stack . has ( file ) ) {
88+ if ( aliasedImport ) {
89+ throw new Error ( 'Circular dependency detected: aliased imports not supported' ) ;
90+ } else {
91+ return { } ;
92+ }
8693 }
8794
88- const scope : Record < string , SourceContract > = { } ;
95+ stack . add ( file ) ;
8996
90- scopeCache . set ( file , scope ) ;
97+ const scope : Record < string , SourceContract > = { } ;
9198
9299 for ( const c of file . contracts ) {
93100 scope [ c . name ] = c ;
@@ -96,15 +103,18 @@ function contractsInScope(file: SourceFile): Record<string, SourceContract> {
96103 const imports = file . ast . nodes . filter ( isImportDirective ) ;
97104 for ( const i of imports ) {
98105 const importedFile = file . source . fileById ( i . sourceUnit ) ;
106+ const importedScope = contractsInScope ( importedFile , stack , aliasedImport || i . symbolAliases . length > 0 ) ;
99107 if ( i . symbolAliases . length === 0 ) {
100- Object . assign ( scope , importedFile . contractsInScope ) ;
108+ Object . assign ( scope , importedScope ) ;
101109 } else {
102110 for ( const a of i . symbolAliases ) {
103- scope [ a . local ?? a . foreign . name ] = importedFile . contractsInScope [ a . foreign . name ] ;
111+ scope [ a . local ?? a . foreign . name ] = importedScope [ a . foreign . name ] ;
104112 }
105113 }
106114 } ;
107115
116+ stack . delete ( file ) ;
117+
108118 return scope ;
109119}
110120
0 commit comments