99using System . Collections . Generic ;
1010using System . Threading . Tasks ;
1111using CSharpParser . model ;
12+ using System . Xml . Linq ;
1213
1314namespace CSharpParser
1415{
1516 class Program
1617 {
17- //private readonly CsharpDbContext _context;
1818 private static List < string > _rootDir ;
19- private static string _buildDir = "" ;
2019 private static string _buildDirBase = "" ;
2120 private static string _connectionString = "" ;
2221
@@ -28,11 +27,10 @@ static int Main(string[] args)
2827 try
2928 {
3029 _connectionString = args [ 0 ] . Replace ( "'" , "" ) ;
31- _buildDir = args [ 1 ] . Replace ( "'" , "" ) ;
32- _buildDirBase = args [ 2 ] . Replace ( "'" , "" ) ;
33- threadNum = int . Parse ( args [ 3 ] ) ;
30+ _buildDirBase = args [ 1 ] . Replace ( "'" , "" ) ; //indexes
31+ threadNum = int . Parse ( args [ 2 ] ) ;
3432
35- for ( int i = 4 ; i < args . Length ; ++ i )
33+ for ( int i = 3 ; i < args . Length ; ++ i )
3634 {
3735 _rootDir . Add ( args [ i ] . Replace ( "'" , "" ) ) ;
3836 }
@@ -42,44 +40,6 @@ static int Main(string[] args)
4240 WriteLine ( "Error in parsing command!" ) ;
4341 return 1 ;
4442 }
45- /*if (args.Length < 3)
46- {
47- WriteLine("Missing command-line arguments in CSharpParser!");
48- return 1;
49- }
50- else if (args.Length == 3)
51- {
52- _connectionString = args[0].Replace("'", "");
53- _rootDir = args[1].Replace("'", "");
54- _buildDir = args[2].Replace("'", "");
55- }
56- else if (args.Length == 4)
57- {
58- _connectionString = args[0].Replace("'", "");
59- _rootDir = args[1].Replace("'", "");
60- _buildDir = args[2].Replace("'", "");
61- bool success = int.TryParse(args[3], out threadNum);
62- if (!success){
63- WriteLine("Invalid threadnumber argument! Multithreaded parsing disabled!");
64- }
65- }
66- else if (args.Length == 5)
67- {
68- _connectionString = args[0].Replace("'", "");
69- _rootDir = args[1].Replace("'", "");
70- _buildDir = args[2].Replace("'", "");
71- _buildDirBase = args[3].Replace("'", "");
72- bool success = int.TryParse(args[4], out threadNum);
73- if (!success)
74- {
75- WriteLine("Invalid threadnumber argument! Multithreaded parsing disabled!");
76- }
77- }
78- else if (args.Length > 5)
79- {
80- WriteLine("Too many command-line arguments in CSharpParser!");
81- return 1;
82- }*/
8343
8444 //Converting the connectionstring into entiy framwork style connectionstring
8545 string csharpConnectionString = transformConnectionString ( ) ;
@@ -91,21 +51,67 @@ static int Main(string[] args)
9151 CsharpDbContext _context = new CsharpDbContext ( options ) ;
9252 _context . Database . Migrate ( ) ;
9353
54+
9455 List < string > allFiles = new List < string > ( ) ;
56+ // This dictionary will remember which file belongs to which DLL
57+ Dictionary < string , string > fileToTargetDll = new Dictionary < string , string > ( ) ;
58+
9559 foreach ( var p in _rootDir )
9660 {
97- Console . WriteLine ( p ) ;
98- allFiles . AddRange ( GetSourceFilesFromDir ( p , ".cs" ) ) ;
61+ // We find all .csproj files
62+ var csprojFiles = Directory . GetFiles ( p , "*.csproj" , SearchOption . AllDirectories ) ;
63+ foreach ( var csproj in csprojFiles )
64+ {
65+ string projectDir = Path . GetDirectoryName ( csproj ) ;
66+ // Default DLL name based on project file name
67+ string targetDll = Path . GetFileNameWithoutExtension ( csproj ) + ".dll" ;
68+
69+ // we try to read the real AssemblyName from the XML
70+ try {
71+ XDocument doc = XDocument . Load ( csproj ) ;
72+ var assemblyNameNode = doc . Descendants ( "AssemblyName" ) . FirstOrDefault ( ) ;
73+ if ( assemblyNameNode != null && ! string . IsNullOrWhiteSpace ( assemblyNameNode . Value ) )
74+ {
75+ targetDll = assemblyNameNode . Value + ".dll" ;
76+ }
77+ } catch { /* If we cannot read the XML, the default name will remain.*/ }
78+
79+ // search for C# files belonging to the project (filtering out the garbage)
80+ var csFiles = Directory . GetFiles ( projectDir , "*.cs" , SearchOption . AllDirectories )
81+ . Where ( f => ! f . Contains ( "/obj/" ) && ! f . Contains ( "\\ obj\\ " ) &&
82+ ! f . Contains ( "/bin/" ) && ! f . Contains ( "\\ bin\\ " ) ) ;
83+
84+ foreach ( var cs in csFiles )
85+ {
86+ // if a file is not already in it (to avoid duplication)
87+ if ( ! fileToTargetDll . ContainsKey ( cs ) )
88+ {
89+ fileToTargetDll [ cs ] = targetDll ;
90+ allFiles . Add ( cs ) ;
91+ }
92+ }
93+ }
9994 }
95+ allFiles = allFiles . Distinct ( ) . ToList ( ) ;
10096
10197 foreach ( var f in allFiles )
10298 {
10399 WriteLine ( f ) ;
104100 }
105- IEnumerable < string > assemblies = GetSourceFilesFromDir ( _buildDir , ".dll" ) ;
106- IEnumerable < string > assemblies_base = assemblies ;
107- if ( args . Length == 5 )
108- assemblies_base = GetSourceFilesFromDir ( _buildDirBase , ".dll" ) ;
101+
102+
103+ IEnumerable < string > assemblies_base = GetSourceFilesFromDir ( _buildDirBase , ".dll" ) ; //loading basic dlls
104+
105+ List < string > assemblies = new List < string > ( ) ;
106+ foreach ( var p in _rootDir )
107+ {
108+ // We search for all .dll files in all input directories
109+ assemblies . AddRange ( GetSourceFilesFromDir ( p , ".dll" ) ) ;
110+ }
111+ // Let's keep only one of each DLL based on the file name!
112+ assemblies = assemblies . GroupBy ( x => System . IO . Path . GetFileName ( x ) )
113+ . Select ( g => g . First ( ) )
114+ . ToList ( ) ;
109115
110116 List < SyntaxTree > trees = new List < SyntaxTree > ( ) ;
111117 foreach ( string file in allFiles )
@@ -129,14 +135,14 @@ static int Main(string[] args)
129135 compilation = compilation . AddReferences ( MetadataReference . CreateFromFile ( file ) ) ;
130136 }
131137
132- var runtask = ParalellRun ( csharpConnectionString , threadNum , trees , compilation ) ;
138+ var runtask = ParalellRun ( csharpConnectionString , threadNum , trees , compilation , fileToTargetDll ) ;
133139 int ret = runtask . Result ;
134140
135141 return 0 ;
136142 }
137143
138144 private static async Task < int > ParalellRun ( string csharpConnectionString , int threadNum ,
139- List < SyntaxTree > trees , CSharpCompilation compilation )
145+ List < SyntaxTree > trees , CSharpCompilation compilation , Dictionary < string , string > fileToTargetDll )
140146 {
141147 var options = new DbContextOptionsBuilder < CsharpDbContext > ( )
142148 . UseNpgsql ( csharpConnectionString )
@@ -156,7 +162,7 @@ private static async Task<int> ParalellRun(string csharpConnectionString, int th
156162 WriteLine ( threadNum ) ;
157163 for ( int i = 0 ; i < maxThread ; i ++ )
158164 {
159- ParsingTasks . Add ( ParseTree ( contextList [ i ] , trees [ i ] , compilation , i ) ) ;
165+ ParsingTasks . Add ( ParseTree ( contextList [ i ] , trees [ i ] , compilation , i , fileToTargetDll ) ) ;
160166 }
161167
162168 int nextTreeIndex = maxThread ;
@@ -169,7 +175,7 @@ private static async Task<int> ParalellRun(string csharpConnectionString, int th
169175 if ( nextTreeIndex < trees . Count )
170176 {
171177 ParsingTasks . Add ( ParseTree ( contextList [ nextContextIndex ] ,
172- trees [ nextTreeIndex ] , compilation , nextContextIndex ) ) ;
178+ trees [ nextTreeIndex ] , compilation , nextContextIndex , fileToTargetDll ) ) ;
173179 ++ nextTreeIndex ;
174180 }
175181 }
@@ -183,15 +189,20 @@ private static async Task<int> ParalellRun(string csharpConnectionString, int th
183189 }
184190
185191 private static async Task < int > ParseTree ( CsharpDbContext context ,
186- SyntaxTree tree , CSharpCompilation compilation , int index )
192+ SyntaxTree tree , CSharpCompilation compilation , int index ,
193+ Dictionary < string , string > fileToTargetDll )
187194 {
188195 var ParsingTask = Task . Run ( ( ) =>
189196 {
190197 WriteLine ( "ParallelRun " + tree . FilePath ) ;
191198 SemanticModel model = compilation . GetSemanticModel ( tree ) ;
192199 var visitor = new AstVisitor ( context , model , tree ) ;
193- visitor . Visit ( tree . GetCompilationUnitRoot ( ) ) ;
194- WriteLine ( ( visitor . FullyParsed ? "+" : "-" ) + tree . FilePath ) ;
200+ visitor . Visit ( tree . GetCompilationUnitRoot ( ) ) ;
201+
202+ // Find the DLL name and append a | to the filename.
203+ string target = fileToTargetDll . ContainsKey ( tree . FilePath ) ? fileToTargetDll [ tree . FilePath ] : "Unknown.dll" ;
204+ WriteLine ( ( visitor . FullyParsed ? "+" : "-" ) + tree . FilePath + "|" + target ) ;
205+
195206 return index ;
196207 } ) ;
197208 return await ParsingTask ;
0 commit comments