@@ -80,6 +80,36 @@ public override void Initialize(AnalysisContext context)
8080 context . RegisterCompilationAction ( AnalyzeProject ) ;
8181 }
8282
83+ private static bool IsDiagnosticLoggingEnabled ( CompilationAnalysisContext context )
84+ {
85+ // Check if diagnostic logging is enabled via .editorconfig
86+ // Default to enabled since we're not production ready yet
87+ if ( ! context . Compilation . SyntaxTrees . Any ( ) )
88+ {
89+ return true ;
90+ }
91+
92+ SyntaxTree tree = context . Compilation . SyntaxTrees . First ( ) ;
93+ AnalyzerConfigOptions analyzerConfigOptions = context . Options . AnalyzerConfigOptionsProvider . GetOptions ( tree ) ;
94+
95+ if ( analyzerConfigOptions . TryGetValue ( "dotnet_code_quality.PH2155.enable_debug_logging" , out var value ) )
96+ {
97+ return ! string . Equals ( value , "false" , StringComparison . OrdinalIgnoreCase ) ;
98+ }
99+
100+ // Default to enabled for now since we're far from production ready
101+ return true ;
102+ }
103+
104+ private static void ReportDebugDiagnostic ( CompilationAnalysisContext context , string message )
105+ {
106+ if ( IsDiagnosticLoggingEnabled ( context ) )
107+ {
108+ var diagnostic = Diagnostic . Create ( InfoDiagnostic , Location . None , message ) ;
109+ context . ReportDiagnostic ( diagnostic ) ;
110+ }
111+ }
112+
83113 private void AnalyzeProject ( CompilationAnalysisContext context )
84114 {
85115 // Skip analysis for test projects to avoid noise during development
@@ -90,6 +120,10 @@ private void AnalyzeProject(CompilationAnalysisContext context)
90120
91121 try
92122 {
123+ // Report .editorconfig debug logging status
124+ var loggingEnabled = IsDiagnosticLoggingEnabled ( context ) ;
125+ ReportDebugDiagnostic ( context , $ "LicenseAnalyzer debug logging: { ( loggingEnabled ? "enabled" : "disabled" ) } (configure via dotnet_code_quality.PH2155.enable_debug_logging=false)") ;
126+
93127 // Load custom allowed licenses from additional files
94128 HashSet < string > allowedLicenses = GetAllowedLicenses ( context . Options . AdditionalFiles ) ;
95129
@@ -104,8 +138,7 @@ private void AnalyzeProject(CompilationAnalysisContext context)
104138 catch ( Exception ex )
105139 {
106140 // Report diagnostic about the error instead of silently failing
107- var diagnostic = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Failed to analyze package licenses: { ex . Message } ") ;
108- context . ReportDiagnostic ( diagnostic ) ;
141+ ReportDebugDiagnostic ( context , $ "Failed to analyze package licenses: { ex . Message } ") ;
109142 }
110143 }
111144
@@ -130,8 +163,7 @@ private void AnalyzePackagesFromAssetsFile(CompilationAnalysisContext context, H
130163 if ( string . IsNullOrEmpty ( assetsFilePath ) || ! File . Exists ( assetsFilePath ) )
131164 {
132165 // Report diagnostic that project.assets.json was not found
133- var diagnostic = Diagnostic . Create ( InfoDiagnostic , Location . None , "Could not find project.assets.json file for license analysis" ) ;
134- context . ReportDiagnostic ( diagnostic ) ;
166+ ReportDebugDiagnostic ( context , "Could not find project.assets.json file for license analysis" ) ;
135167 return ;
136168 }
137169
@@ -145,8 +177,7 @@ private void AnalyzePackagesFromAssetsFile(CompilationAnalysisContext context, H
145177 catch ( Exception ex )
146178 {
147179 // Report diagnostic about parsing failure instead of silently failing
148- var diagnostic = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Failed to parse project.assets.json: { ex . Message } ") ;
149- context . ReportDiagnostic ( diagnostic ) ;
180+ ReportDebugDiagnostic ( context , $ "Failed to parse project.assets.json: { ex . Message } ") ;
150181 return ;
151182 }
152183
@@ -189,80 +220,113 @@ private void AnalyzePackagesFromAssetsFile(CompilationAnalysisContext context, H
189220
190221 private static string TryFindAssetsFileFromSourcePaths ( CompilationAnalysisContext context )
191222 {
192- // For .NET Standard 2.0 compatibility, use alternative approaches to find project.assets.json
193- // Try common locations relative to the current working directory
223+ // Search for project.assets.json using actual source file paths from the compilation
224+ // instead of Directory.GetCurrentDirectory() which points to VS install directory
225+
226+ var sourceDirectories = context . Compilation . SyntaxTrees
227+ . Where ( tree => ! string . IsNullOrEmpty ( tree . FilePath ) )
228+ . Select ( tree => Path . GetDirectoryName ( tree . FilePath ) )
229+ . Where ( dir => ! string . IsNullOrEmpty ( dir ) )
230+ . Distinct ( StringComparer . OrdinalIgnoreCase )
231+ . ToList ( ) ;
232+
233+ ReportDebugDiagnostic ( context , $ "Found { sourceDirectories . Count } unique source directories from compilation") ;
234+
235+ // Search in each source directory and its parent directories
236+ foreach ( var sourceDir in sourceDirectories )
237+ {
238+ ReportDebugDiagnostic ( context , $ "Searching from source directory: { sourceDir } ") ;
239+
240+ var foundPath = SearchForAssetsFile ( context , sourceDir ) ;
241+ if ( foundPath != null )
242+ {
243+ ReportDebugDiagnostic ( context , $ "Found { ProjectAssetsFileName } at: { foundPath } ") ;
244+ return foundPath ;
245+ }
246+ }
247+
248+ // Fallback to current directory search if source paths didn't work
194249 var currentDir = Directory . GetCurrentDirectory ( ) ;
250+ ReportDebugDiagnostic ( context , $ "Source directory search failed, falling back to current directory: { currentDir } ") ;
195251
196- // Report debug information about search starting point
197- var diagnostic = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Searching for { ProjectAssetsFileName } starting from directory: { currentDir } ") ;
198- context . ReportDiagnostic ( diagnostic ) ;
252+ var fallbackPath = SearchForAssetsFile ( context , currentDir ) ;
253+ if ( fallbackPath != null )
254+ {
255+ ReportDebugDiagnostic ( context , $ "Found { ProjectAssetsFileName } via fallback at: { fallbackPath } ") ;
256+ return fallbackPath ;
257+ }
199258
200- // Look for project.assets.json in common locations
259+ ReportDebugDiagnostic ( context , $ "Exhaustive search completed, { ProjectAssetsFileName } not found") ;
260+ return null ;
261+ }
262+
263+ private static string SearchForAssetsFile ( CompilationAnalysisContext context , string startDirectory )
264+ {
265+ // Look for project.assets.json in common locations relative to the start directory
201266 var possiblePaths = new [ ]
202267 {
203- Path . Combine ( currentDir , "obj" , ProjectAssetsFileName ) ,
204- Path . Combine ( currentDir , ".." , "obj" , ProjectAssetsFileName ) ,
205- Path . Combine ( currentDir , ".." , ".." , "obj" , ProjectAssetsFileName )
268+ Path . Combine ( startDirectory , "obj" , ProjectAssetsFileName ) ,
269+ Path . Combine ( startDirectory , ".." , "obj" , ProjectAssetsFileName ) ,
270+ Path . Combine ( startDirectory , ".." , ".." , "obj" , ProjectAssetsFileName )
206271 } ;
207272
208- // Report each path being checked
273+ // Check each possible path
209274 foreach ( var path in possiblePaths )
210275 {
211- var exists = File . Exists ( path ) ;
212- var diagnostic2 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Checking path: { path } - Exists: { exists } " ) ;
213- context . ReportDiagnostic ( diagnostic2 ) ;
214- }
276+ try
277+ {
278+ var exists = File . Exists ( path ) ;
279+ ReportDebugDiagnostic ( context , $ "Checking path: { path } - Exists: { exists } " ) ;
215280
216- var foundPath = possiblePaths . Where ( File . Exists ) . FirstOrDefault ( ) ;
217- if ( foundPath != null )
218- {
219- var diagnostic3 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Found { ProjectAssetsFileName } at: { foundPath } ") ;
220- context . ReportDiagnostic ( diagnostic3 ) ;
221- return foundPath ;
281+ if ( exists )
282+ {
283+ return path ;
284+ }
285+ }
286+ catch ( Exception ex )
287+ {
288+ ReportDebugDiagnostic ( context , $ "Exception checking path { path } : { ex . Message } ") ;
289+ }
222290 }
223291
224- // If not found in common locations, search in current directory tree
292+ // If not found in common locations, search up the directory tree
225293 try
226294 {
227- var diagnostic4 = Diagnostic . Create ( InfoDiagnostic , Location . None , "Common paths failed, searching directory tree..." ) ;
228- context . ReportDiagnostic ( diagnostic4 ) ;
229-
230- var searchDir = currentDir ;
295+ var searchDir = startDirectory ;
231296 for ( var i = 0 ; i < 5 ; i ++ ) // Limit search depth
232297 {
233298 var assetsPath = Path . Combine ( searchDir , "obj" , ProjectAssetsFileName ) ;
234- var exists = File . Exists ( assetsPath ) ;
235299
236- var diagnostic5 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Tree search depth { i } : checking { assetsPath } - Exists: { exists } ") ;
237- context . ReportDiagnostic ( diagnostic5 ) ;
300+ try
301+ {
302+ var exists = File . Exists ( assetsPath ) ;
303+ ReportDebugDiagnostic ( context , $ "Tree search depth { i } : checking { assetsPath } - Exists: { exists } ") ;
238304
239- if ( exists )
305+ if ( exists )
306+ {
307+ return assetsPath ;
308+ }
309+ }
310+ catch ( Exception ex )
240311 {
241- var diagnostic6 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Found { ProjectAssetsFileName } via tree search at: { assetsPath } ") ;
242- context . ReportDiagnostic ( diagnostic6 ) ;
243- return assetsPath ;
312+ ReportDebugDiagnostic ( context , $ "Exception during tree search at { assetsPath } : { ex . Message } ") ;
244313 }
245314
246315 DirectoryInfo parentDir = Directory . GetParent ( searchDir ) ;
247316 if ( parentDir == null )
248317 {
249- var diagnostic7 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Reached root directory at depth { i } , stopping search") ;
250- context . ReportDiagnostic ( diagnostic7 ) ;
318+ ReportDebugDiagnostic ( context , $ "Reached root directory at depth { i } , stopping search") ;
251319 break ;
252320 }
321+
253322 searchDir = parentDir . FullName ;
254323 }
255324 }
256325 catch ( Exception ex )
257326 {
258- // Report diagnostic about directory traversal failure
259- var diagnostic8 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "Directory traversal failed: { ex . Message } ") ;
260- context . ReportDiagnostic ( diagnostic8 ) ;
261- return null ;
327+ ReportDebugDiagnostic ( context , $ "Exception during directory tree search: { ex . Message } ") ;
262328 }
263329
264- var diagnostic9 = Diagnostic . Create ( InfoDiagnostic , Location . None , $ "{ ProjectAssetsFileName } not found after exhaustive search") ;
265- context . ReportDiagnostic ( diagnostic9 ) ;
266330 return null ;
267331 }
268332
0 commit comments