1+ import type { CompilationSource , AstNode } from '@remix-project/remix-solidity'
2+
13const IMPORT_SOLIDITY_REGEX = / ^ \s * i m p o r t ( \s + ) .* $ / gm;
24const SPDX_SOLIDITY_REGEX = / ^ \s * \/ \/ S P D X - L i c e n s e - I d e n t i f i e r : .* $ / gm;
35
4- export function getDependencyGraph ( ast , target ) {
6+ type Visited = { [ key : string ] : number }
7+ export function getDependencyGraph ( ast : { [ name : string ] : CompilationSource } , target : string , remappings : string [ ] ) {
58 const graph = tsort ( ) ;
69 const visited = { } ;
710 visited [ target ] = 1 ;
8- _traverse ( graph , visited , ast , target ) ;
11+ _traverse ( graph , visited , ast , target , remappings ) ;
912 return graph ;
1013}
1114
@@ -21,32 +24,31 @@ export function concatSourceFiles(files: any[], sources: any) {
2124 return concat ;
2225}
2326
24- function _traverse ( graph , visited , ast , name ) {
27+ function _traverse ( graph : Graph , visited : Visited , ast : { [ name : string ] : CompilationSource } , name : string , remappings : string [ ] ) {
2528 let currentAst = null
2629 currentAst = ast [ name ] . ast
2730 const dependencies = _getDependencies ( currentAst ) ;
2831 for ( const dependency of dependencies ) {
29- const path = resolve ( name , dependency ) ;
32+ const path = resolve ( name , dependency , remappings ) ;
3033 if ( path in visited ) {
3134 // continue; // fixes wrong ordering of source in flattened file
3235 }
3336 visited [ path ] = 1 ;
3437 graph . add ( name , path ) ;
35- _traverse ( graph , visited , ast , path ) ;
38+ _traverse ( graph , visited , ast , path , remappings ) ;
3639 }
3740}
3841
39- function _getDependencies ( ast ) {
42+ function _getDependencies ( ast : AstNode ) {
4043 const dependencies = ast ?. nodes
4144 . filter ( node => node ?. nodeType === 'ImportDirective' )
4245 . map ( node => node ?. file ) ;
4346 return dependencies ;
4447}
4548
46-
4749// TSORT
4850
49- function tsort ( initial ?: any ) {
51+ function tsort ( initial ?: any ) : Graph {
5052 const graph = new Graph ( ) ;
5153
5254 if ( initial ) {
@@ -58,78 +60,88 @@ function tsort(initial?: any) {
5860 return graph ;
5961}
6062
63+ class Graph {
64+ nodes : { [ key : string ] : any }
65+ constructor ( ) {
66+ this . nodes = { }
67+ }
6168
62- function Graph ( ) {
63- this . nodes = { } ;
64- }
65-
66- // Add sorted items to the graph
67- Graph . prototype . add = function ( ) {
68- const self = this ;
69- // eslint-disable-next-line prefer-rest-params
70- let items = [ ] . slice . call ( arguments ) ;
71-
72- if ( items . length === 1 && Array . isArray ( items [ 0 ] ) )
73- items = items [ 0 ] ;
74-
75- items . forEach ( function ( item ) {
76- if ( ! self . nodes [ item ] ) {
77- self . nodes [ item ] = [ ] ;
69+ // Add sorted items to the graph
70+ add ( name , path ) {
71+ const self = this ;
72+ // eslint-disable-next-line prefer-rest-params
73+ let items = [ ] . slice . call ( arguments ) ;
74+
75+ if ( items . length === 1 && Array . isArray ( items [ 0 ] ) )
76+ items = items [ 0 ] ;
77+
78+ items . forEach ( function ( item ) {
79+ if ( ! self . nodes [ item ] ) {
80+ self . nodes [ item ] = [ ] ;
81+ }
82+ } ) ;
83+
84+ for ( let i = 1 ; i < items . length ; i ++ ) {
85+ const from = items [ i ] ;
86+ const to = items [ i - 1 ] ;
87+
88+ self . nodes [ from ] . push ( to ) ;
7889 }
79- } ) ;
80-
81- for ( let i = 1 ; i < items . length ; i ++ ) {
82- const from = items [ i ] ;
83- const to = items [ i - 1 ] ;
84-
85- self . nodes [ from ] . push ( to ) ;
90+
91+ return self ;
8692 }
8793
88- return self ;
89- } ;
90-
91- // Depth first search
92- // As given in http://en.wikipedia.org/wiki/Topological_sorting
93- Graph . prototype . sort = function ( ) {
94- const self = this ;
95- const nodes = Object . keys ( this . nodes ) ;
96-
97- const sorted = [ ] ;
98- const marks = { } ;
99-
100- for ( let i = 0 ; i < nodes . length ; i ++ ) {
101- const node = nodes [ i ] ;
102-
103- if ( ! marks [ node ] ) {
104- visit ( node ) ;
94+ // Depth first search
95+ // As given in http://en.wikipedia.org/wiki/Topological_sorting
96+ sort ( ) {
97+ const self = this ;
98+ const nodes = Object . keys ( this . nodes ) ;
99+
100+ const sorted = [ ] ;
101+ const marks = { } ;
102+
103+ for ( let i = 0 ; i < nodes . length ; i ++ ) {
104+ const node = nodes [ i ] ;
105+
106+ if ( ! marks [ node ] ) {
107+ visit ( node ) ;
108+ }
109+ }
110+
111+ return sorted ;
112+
113+ function visit ( node ) {
114+ if ( marks [ node ] === 'temp' )
115+ throw new Error ( "There is a cycle in the graph. It is not possible to derive a topological sort." ) ;
116+ else if ( marks [ node ] )
117+ return ;
118+
119+ marks [ node ] = 'temp' ;
120+ self . nodes [ node ] . forEach ( visit ) ;
121+ marks [ node ] = 'perm' ;
122+
123+ sorted . push ( node ) ;
105124 }
106125 }
107126
108- return sorted ;
109-
110- function visit ( node ) {
111- if ( marks [ node ] === 'temp' )
112- throw new Error ( "There is a cycle in the graph. It is not possible to derive a topological sort." ) ;
113- else if ( marks [ node ] )
114- return ;
115-
116- marks [ node ] = 'temp' ;
117- self . nodes [ node ] . forEach ( visit ) ;
118- marks [ node ] = 'perm' ;
119-
120- sorted . push ( node ) ;
127+ isEmpty ( ) {
128+ const nodes = Object . keys ( this . nodes ) ;
129+ return nodes . length === 0 ;
121130 }
122- } ;
123-
124- Graph . prototype . isEmpty = function ( ) {
125- const nodes = Object . keys ( this . nodes ) ;
126- return nodes . length === 0 ;
127131}
128132
129-
130133// PATH
131134
132- function resolve ( parentPath , childPath ) {
135+ function resolve ( parentPath , childPath , remappings : string [ ] ) {
136+ if ( remappings && remappings . length ) {
137+ for ( const mapping of remappings ) {
138+ if ( mapping . indexOf ( '=' ) !== - 1 ) {
139+ const split = mapping . split ( '=' )
140+ childPath = childPath . replace ( split [ 0 ] . trim ( ) , split [ 1 ] . trim ( ) )
141+ }
142+ }
143+ }
144+
133145 if ( _isAbsolute ( childPath ) ) {
134146 return childPath ;
135147 }
0 commit comments