11
11
using Microsoft . CodeAnalysis ;
12
12
using Microsoft . CodeAnalysis . MSBuild ;
13
13
14
+ #nullable enable
15
+
14
16
namespace Docfx . Dotnet ;
15
17
16
18
internal class ExtractMetadataWorker : IDisposable
@@ -29,7 +31,7 @@ public ExtractMetadataWorker(ExtractMetadataConfig config, DotnetApiOptions opti
29
31
_options = options ;
30
32
_files = config . Files ? . Select ( s => new FileInformation ( s ) )
31
33
. GroupBy ( f => f . Type )
32
- . ToDictionary ( s => s . Key , s => s . Distinct ( ) . ToList ( ) ) ;
34
+ . ToDictionary ( s => s . Key , s => s . Distinct ( ) . ToList ( ) ) ?? new ( ) ;
33
35
34
36
var msbuildProperties = config . MSBuildProperties ?? new Dictionary < string , string > ( ) ;
35
37
if ( ! msbuildProperties . ContainsKey ( "Configuration" ) )
@@ -55,7 +57,7 @@ public void Dispose()
55
57
56
58
public async Task ExtractMetadataAsync ( )
57
59
{
58
- if ( _files . TryGetValue ( FileType . NotSupported , out List < FileInformation > unsupportedFiles ) )
60
+ if ( _files . TryGetValue ( FileType . NotSupported , out var unsupportedFiles ) )
59
61
{
60
62
foreach ( var file in unsupportedFiles )
61
63
{
@@ -152,33 +154,25 @@ await LoadCompilationFromProject(project.AbsolutePath) is { } compilation)
152
154
}
153
155
154
156
Logger . LogInfo ( $ "Creating output...") ;
155
- Dictionary < string , MetadataItem > allMembers ;
156
- Dictionary < string , ReferenceItem > allReferences ;
157
- using ( new PerformanceScope ( "MergeMetadata" ) )
158
- {
159
- allMembers = MergeYamlProjectMetadata ( projectMetadataList ) ;
160
- }
157
+ var allMembers = new Dictionary < string , MetadataItem > ( ) ;
158
+ var allReferences = new Dictionary < string , ReferenceItem > ( ) ;
159
+ MergeMembers ( allMembers , projectMetadataList ) ;
160
+ MergeReferences ( allReferences , projectMetadataList ) ;
161
161
162
- using ( new PerformanceScope ( "MergeReference" ) )
163
- {
164
- allReferences = MergeYamlProjectReferences ( projectMetadataList ) ;
165
- }
166
-
167
- if ( allMembers == null || allMembers . Count == 0 )
162
+ if ( allMembers . Count == 0 )
168
163
{
169
164
var value = StringExtension . ToDelimitedString ( projectMetadataList . Select ( s => s . Name ) ) ;
170
165
Logger . Log ( LogLevel . Warning , $ "No .NET API detected for { value } .") ;
166
+ return ;
171
167
}
172
- else
168
+
169
+ using ( new PerformanceScope ( "ResolveAndExport" ) )
173
170
{
174
- using ( new PerformanceScope ( "ResolveAndExport" ) )
175
- {
176
- ResolveAndExportYamlMetadata ( allMembers , allReferences ) ;
177
- }
171
+ ResolveAndExportYamlMetadata ( allMembers , allReferences ) ;
178
172
}
179
173
}
180
174
181
- private async Task < Compilation > LoadCompilationFromProject ( string path )
175
+ private async Task < Compilation ? > LoadCompilationFromProject ( string path )
182
176
{
183
177
var project = _workspace . CurrentSolution . Projects . FirstOrDefault (
184
178
p => FilePathComparer . OSPlatformSensitiveRelativePathComparer . Equals ( p . FilePath , path ) ) ;
@@ -272,9 +266,9 @@ private static void AddMemberToIndexer(MetadataItem memberModel, string outputPa
272
266
}
273
267
else
274
268
{
275
- TreeIterator . Preorder ( memberModel , null , s => s . Items , ( member , parent ) =>
269
+ TreeIterator . Preorder ( memberModel , null , s => s ! . Items , ( member , parent ) =>
276
270
{
277
- if ( indexer . TryGetValue ( member . Name , out string path ) )
271
+ if ( indexer . TryGetValue ( member ! . Name , out var path ) )
278
272
{
279
273
Logger . LogWarning ( $ "{ member . Name } already exists in { path } , the duplicate one { outputPath } will be ignored.") ;
280
274
}
@@ -287,94 +281,55 @@ private static void AddMemberToIndexer(MetadataItem memberModel, string outputPa
287
281
}
288
282
}
289
283
290
- private static Dictionary < string , MetadataItem > MergeYamlProjectMetadata ( List < MetadataItem > projectMetadataList )
284
+ private static void MergeMembers ( Dictionary < string , MetadataItem > result , List < MetadataItem > items )
291
285
{
292
- if ( projectMetadataList == null || projectMetadataList . Count == 0 )
286
+ foreach ( var item in items )
293
287
{
294
- return null ;
288
+ MergeNode ( item ) ;
295
289
}
296
290
297
- Dictionary < string , MetadataItem > namespaceMapping = new ( ) ;
298
- Dictionary < string , MetadataItem > allMembers = new ( ) ;
299
-
300
- foreach ( var project in projectMetadataList )
291
+ bool MergeNode ( MetadataItem node )
301
292
{
302
- if ( project . Items != null )
293
+ if ( node . Type is MemberType . Assembly )
303
294
{
304
- foreach ( var ns in project . Items )
295
+ foreach ( var item in node . Items ?? new ( ) )
305
296
{
306
- if ( ns . Type == MemberType . Namespace )
307
- {
308
- if ( namespaceMapping . TryGetValue ( ns . Name , out MetadataItem nsOther ) )
309
- {
310
- if ( ns . Items != null )
311
- {
312
- nsOther . Items ??= new List < MetadataItem > ( ) ;
313
-
314
- foreach ( var i in ns . Items )
315
- {
316
- if ( ! nsOther . Items . Any ( s => s . Name == i . Name ) )
317
- {
318
- nsOther . Items . Add ( i ) ;
319
- }
320
- else
321
- {
322
- Logger . Log ( LogLevel . Info , $ "{ i . Name } already exists in { nsOther . Name } , ignore current one") ;
323
- }
324
- }
325
- }
326
- }
327
- else
328
- {
329
- namespaceMapping . Add ( ns . Name , ns ) ;
330
- }
331
- }
297
+ MergeNode ( item ) ;
298
+ }
299
+ return false ;
300
+ }
332
301
333
- if ( ! allMembers . ContainsKey ( ns . Name ) )
334
- {
335
- allMembers . Add ( ns . Name , ns ) ;
336
- }
302
+ if ( ! result . TryGetValue ( node . Name , out var existingNode ) )
303
+ {
304
+ result . Add ( node . Name , node ) ;
305
+ foreach ( var item in node . Items ?? new ( ) )
306
+ {
307
+ MergeNode ( item ) ;
308
+ }
309
+ return true ;
310
+ }
337
311
338
- ns . Items ? . ForEach ( s =>
312
+ if ( node . Type is MemberType . Namespace or MemberType . Class )
313
+ {
314
+ foreach ( var item in node . Items ?? new ( ) )
315
+ {
316
+ if ( MergeNode ( item ) )
339
317
{
340
- if ( allMembers . TryGetValue ( s . Name , out MetadataItem existingMetadata ) )
341
- {
342
- Logger . Log ( LogLevel . Warning , $ "Duplicate member { s . Name } is found from { existingMetadata . Source ? . Path } and { s . Source ? . Path } , use the one in { existingMetadata . Source ? . Path } and ignore the one from { s . Source ? . Path } ") ;
343
- }
344
- else
345
- {
346
- allMembers . Add ( s . Name , s ) ;
347
- }
348
-
349
- s . Items ? . ForEach ( s1 =>
350
- {
351
- if ( allMembers . TryGetValue ( s1 . Name , out MetadataItem existingMetadata1 ) )
352
- {
353
- Logger . Log ( LogLevel . Warning , $ "Duplicate member { s1 . Name } is found from { existingMetadata1 . Source ? . Path } and { s1 . Source ? . Path } , use the one in { existingMetadata1 . Source ? . Path } and ignore the one from { s1 . Source ? . Path } ") ;
354
- }
355
- else
356
- {
357
- allMembers . Add ( s1 . Name , s1 ) ;
358
- }
359
- } ) ;
360
- } ) ;
318
+ existingNode . Items ??= new ( ) ;
319
+ existingNode . Items . Add ( item ) ;
320
+ }
361
321
}
322
+ return false ;
362
323
}
363
- }
364
324
365
- return allMembers ;
325
+ Logger . Log ( LogLevel . Warning , $ "Ignore duplicated member { node . Type } :{ node . Name } from { node . Source ? . Path } as it already exist in { existingNode . Source ? . Path } .") ;
326
+ return false ;
327
+ }
366
328
}
367
329
368
- private static Dictionary < string , ReferenceItem > MergeYamlProjectReferences ( List < MetadataItem > projectMetadataList )
330
+ private static void MergeReferences ( Dictionary < string , ReferenceItem > result , List < MetadataItem > items )
369
331
{
370
- if ( projectMetadataList == null || projectMetadataList . Count == 0 )
371
- {
372
- return null ;
373
- }
374
-
375
- var result = new Dictionary < string , ReferenceItem > ( ) ;
376
-
377
- foreach ( var project in projectMetadataList )
332
+ foreach ( var project in items )
378
333
{
379
334
if ( project . References != null )
380
335
{
@@ -391,7 +346,5 @@ private static Dictionary<string, ReferenceItem> MergeYamlProjectReferences(List
391
346
}
392
347
}
393
348
}
394
-
395
- return result ;
396
349
}
397
350
}
0 commit comments