44using Microsoft . CodeAnalysis . CSharp . Syntax ;
55using Microsoft . CodeAnalysis . CSharp ;
66using Microsoft . CodeAnalysis ;
7- using System . Linq ;
87using CSharpToJavaScript . Utils ;
98using System . Collections . Immutable ;
109
@@ -45,16 +44,41 @@ public static FileData[] Translate(FileData[] files, MetadataReference[]? refere
4544
4645 for ( int i = 0 ; i < files . Length ; i ++ )
4746 {
48- trees [ i ] = CSharpSyntaxTree . ParseText ( files [ i ] . SourceStr ) ;
47+ trees [ i ] = CSharpSyntaxTree . ParseText ( files [ i ] . SourceStr , path : files [ i ] . FileName ) ;
4948 }
5049
51- trees [ 0 ] = AddGlobalUsings ( trees [ 0 ] ) ;
52-
50+ trees [ 0 ] = AddGlobalUsings ( trees [ 0 ] ) . WithFilePath ( files [ 0 ] . FileName ) ;
51+
5352 CSharpCompilation compilation = CSharpCompilation
5453 . Create ( "HelloWorld" )
5554 . AddReferences ( references )
5655 . AddSyntaxTrees ( trees ) ;
5756
57+
58+ Dictionary < string , List < string > > _exportedClasses = new ( ) ;
59+
60+ //Enable modules if, more than 2 files.
61+ if ( files . Length >= 2 )
62+ {
63+ for ( int i = 0 ; i < files . Length ; i ++ )
64+ {
65+ if ( files [ i ] . OptionsForFile . EnableModules == 1 )
66+ files [ i ] . OptionsForFile . EnableModules = 2 ;
67+ }
68+ }
69+
70+ for ( int i = 0 ; i < files . Length ; i ++ )
71+ {
72+ if ( files [ i ] . OptionsForFile . EnableModules >= 2 )
73+ {
74+ SemanticModel _model = compilation . GetSemanticModel ( trees [ i ] ) ;
75+
76+ ExportClassesWalker _exportClassesWalker = new ( _model , ref _exportedClasses ) ;
77+ SyntaxNode _root = trees [ i ] . GetRoot ( ) ;
78+ _exportClassesWalker . Visit ( _root ) ;
79+ }
80+ }
81+
5882 for ( int i = 0 ; i < files . Length ; i ++ )
5983 {
6084 if ( files [ i ] . OptionsForFile . TranslateFile == false )
@@ -80,7 +104,7 @@ public static FileData[] Translate(FileData[] files, MetadataReference[]? refere
80104
81105 SyntaxNode _root = trees [ i ] . GetRoot ( ) ;
82106
83- WithSemanticRewriter _withSemanticRewriter = new ( _model , files [ i ] . OptionsForFile ) ;
107+ WithSemanticRewriter _withSemanticRewriter = new ( _model , files [ i ] . OptionsForFile , _exportedClasses ) ;
84108 WithoutSemanticRewriter _withoutSemanticRewriter = new ( files [ i ] . OptionsForFile ) ;
85109
86110 StringBuilderWalker _stringBuilderWalker = new ( ) ;
@@ -111,7 +135,47 @@ public static FileData[] Translate(FileData[] files, MetadataReference[]? refere
111135 }
112136
113137 _stringBuilderWalker . JSSB . Append ( files [ i ] . OptionsForFile . AddSBAtTheTop ) ;
138+
139+ //Import modules
140+ if ( files [ i ] . OptionsForFile . EnableModules >= 2 )
141+ {
142+ Dictionary < string , List < string > > . KeyCollection _keys = _withSemanticRewriter . ImportClasses . Keys ;
143+
144+ foreach ( string _filename in _keys )
145+ {
146+ _stringBuilderWalker . JSSB . AppendLine ( ) ;
147+ _stringBuilderWalker . JSSB . Append ( "import { " ) ;
148+ for ( int j = 0 ; j < _withSemanticRewriter . ImportClasses [ _filename ] . Count ; j ++ )
149+ {
150+ if ( j == _withSemanticRewriter . ImportClasses [ _filename ] . Count - 1 )
151+ _stringBuilderWalker . JSSB . Append ( $ "{ _withSemanticRewriter . ImportClasses [ _filename ] [ j ] } ") ;
152+ else
153+ _stringBuilderWalker . JSSB . Append ( $ "{ _withSemanticRewriter . ImportClasses [ _filename ] [ j ] } , ") ;
154+ }
155+ _stringBuilderWalker . JSSB . AppendLine ( $ " }} from './{ _filename } ';") ;
156+ }
157+ }
158+
114159 _stringBuilderWalker . Visit ( _root ) ;
160+
161+ //Export modules
162+ if ( files [ i ] . OptionsForFile . EnableModules >= 2 )
163+ {
164+ if ( _exportedClasses . TryGetValue ( files [ i ] . FileName , out List < string > ? _value ) )
165+ {
166+ _stringBuilderWalker . JSSB . AppendLine ( ) ;
167+ _stringBuilderWalker . JSSB . Append ( "export { " ) ;
168+ for ( int j = 0 ; j < _value . Count ; j ++ )
169+ {
170+ if ( j == _value . Count - 1 )
171+ _stringBuilderWalker . JSSB . Append ( $ "{ _value [ j ] } ") ;
172+ else
173+ _stringBuilderWalker . JSSB . Append ( $ "{ _value [ j ] } , ") ;
174+ }
175+ _stringBuilderWalker . JSSB . AppendLine ( " };" ) ;
176+ }
177+ }
178+
115179 _stringBuilderWalker . JSSB . Append ( files [ i ] . OptionsForFile . AddSBAtTheBottom ) ;
116180
117181 files [ i ] . TranslatedStr = _stringBuilderWalker . JSSB . ToString ( ) ;
@@ -226,12 +290,8 @@ private static MetadataReference[] GetReferences(CSTOJSOptions options)
226290 private static SyntaxTree AddGlobalUsings ( SyntaxTree tree )
227291 {
228292 CompilationUnitSyntax root = tree . GetCompilationUnitRoot ( ) ;
229- UsingDirectiveSyntax [ ] oldUsing = root . Usings . ToArray ( ) ;
230293
231- //https://stackoverflow.com/a/72938702
232- root = root . WithUsings
233- (
234- SyntaxFactory . List < UsingDirectiveSyntax >
294+ SyntaxList < UsingDirectiveSyntax > newUsing = SyntaxFactory . List < UsingDirectiveSyntax >
235295 (
236296 new UsingDirectiveSyntax [ ]
237297 {
@@ -377,8 +437,10 @@ private static SyntaxTree AddGlobalUsings(SyntaxTree tree)
377437 SyntaxFactory . Token ( SyntaxKind . GlobalKeyword )
378438 )
379439 }
380- )
381- ) . AddUsings ( oldUsing ) ;
440+ ) . AddRange ( root . Usings ) ;
441+
442+ //https://stackoverflow.com/a/72938702
443+ root = root . WithUsings ( newUsing ) ;
382444
383445 return root . SyntaxTree ;
384446 }
@@ -389,6 +451,10 @@ private static SyntaxTree AddGlobalUsings(SyntaxTree tree)
389451/// </summary>
390452public class FileData
391453{
454+ /// <summary>
455+ /// Full JS filename. Needed for modules.
456+ /// </summary>
457+ public string FileName { get ; set ; } = string . Empty ;
392458 /// <summary>
393459 /// Options for a translation.
394460 /// </summary>
0 commit comments