Skip to content

Commit 6841667

Browse files
authored
Fix additional duplicate LineIds for attributes (#12597)
1 parent 45c9080 commit 6841667

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

tools/apiview/parsers/csharp-api-parser/CSharpAPIParser/Program.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,22 @@ public static async Task<string> ExtractNugetDependencies(List<DependencyInfo> d
229229
NullLogger.Instance,
230230
CancellationToken.None))
231231
{
232+
packageStream.Seek(0, SeekOrigin.Begin);
232233
using PackageArchiveReader reader = new PackageArchiveReader(packageStream);
233234
NuspecReader nuspec = reader.NuspecReader;
234235
var file = reader.GetFiles().FirstOrDefault(f => f.EndsWith(dep.Name + ".dll"));
235236
if (file != null)
236237
{
237238
var fileInfo = new FileInfo(file);
238239
var path = Path.Combine(tempFolder, dep.Name, fileInfo.Name);
239-
var tmp = reader.ExtractFile(file, path, NullLogger.Instance);
240+
var directory = Path.GetDirectoryName(path);
241+
if (!string.IsNullOrEmpty(directory))
242+
{
243+
Directory.CreateDirectory(directory);
244+
}
245+
using Stream entryStream = reader.GetStream(file);
246+
await using FileStream destinationStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
247+
await entryStream.CopyToAsync(destinationStream).ConfigureAwait(false);
240248
}
241249
}
242250
}

tools/apiview/parsers/csharp-api-parser/CSharpAPIParser/TreeToken/CodeFileBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public static void BuildInternalsVisibleToAttributes(List<ReviewLine> reviewLine
137137
if (!String.IsNullOrEmpty(param))
138138
{
139139
var firstComma = param?.IndexOf(',');
140-
param = firstComma > 0 ? param?[..(int)firstComma] : param;
140+
param = firstComma > 0 ? param?[..(int)firstComma] + "_" + param?[^5..] : param;
141141
reviewLines.Add(new ReviewLine()
142142
{
143143
LineId = attribute.AttributeClass?.Name + "_" + param,
@@ -475,13 +475,13 @@ private void BuildAttributes(List<ReviewLine> reviewLines, ImmutableArray<Attrib
475475
continue;
476476
}
477477

478-
var arg = attribute.ConstructorArguments.FirstOrDefault();
478+
string args = String.Join(", ", attribute.ConstructorArguments.Select(a => GetTypedConstantValue(a)));
479479

480480
var attributeLine = new ReviewLine()
481481
{
482482
// GetId() is not unique for attribute class. for e.g. attribute class id is something like "System.FlagsAttribute"
483483
// So, using a unique id for attribute line
484-
LineId = $"{attribute.AttributeClass.GetId()}({GetTypedConstantValue(arg)}).{relatedTo}",
484+
LineId = $"{attribute.AttributeClass.GetId()}({args}).{relatedTo}",
485485
IsHidden = isHidden
486486
};
487487

tools/apiview/parsers/csharp-api-parser/CSharpAPIParserTests/CodeFileTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,5 +483,44 @@ public IEnumerable<ISymbol> OrderMembers(IEnumerable<ISymbol> members)
483483
}
484484
}
485485
}
486+
487+
[Fact]
488+
public void TestInternalsVisibleToAttributes_WithDuplicateAssemblyUniquePublicKeys()
489+
{
490+
// Arrange
491+
var lineIds = new HashSet<string>();
492+
var sourceCode = @"
493+
using System.Runtime.CompilerServices;
494+
495+
[assembly: InternalsVisibleTo(""Microsoft.Azure.Cosmos.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9"")]
496+
[assembly: InternalsVisibleTo(""Microsoft.Azure.Cosmos.Client, PublicKey=0024000004800000940000000602000000240000525341310004000001000100197c25d0a04f73cb271e8181dba1c0c713df8deebb25864541a66670500f34896d280484b45fe1ff6c29f2ee7aa175d8bcbd0c83cc23901a894a86996030f6292ce6eda6e6f3e6c74b3c5a3ded4903c951e6747e6102969503360f7781bf8bf015058eb89b7621798ccc85aaca036ff1bc1556bb7f62de15908484886aa8bbae"")]
497+
498+
namespace TestNamespace
499+
{
500+
public class TestClass { }
501+
}";
502+
503+
var syntaxTree = Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(sourceCode);
504+
var compilation = Microsoft.CodeAnalysis.CSharp.CSharpCompilation.Create(
505+
"TestAssembly",
506+
new[] { syntaxTree },
507+
new[] { Microsoft.CodeAnalysis.MetadataReference.CreateFromFile(typeof(object).Assembly.Location) },
508+
new Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions(Microsoft.CodeAnalysis.OutputKind.DynamicallyLinkedLibrary));
509+
510+
var assemblySymbol = compilation.Assembly;
511+
var reviewLines = new List<APIView.Model.V2.ReviewLine>();
512+
513+
// Act
514+
CSharpAPIParser.TreeToken.CodeFileBuilder.BuildInternalsVisibleToAttributes(reviewLines, assemblySymbol);
515+
516+
foreach (var line in reviewLines)
517+
{
518+
if (!string.IsNullOrEmpty(line.LineId))
519+
{
520+
// Assert
521+
Assert.True(lineIds.Add(line.LineId), $"Duplicate LineId found: {line.LineId}");
522+
}
523+
}
524+
}
486525
}
487526
}

0 commit comments

Comments
 (0)