Skip to content

Commit

Permalink
Add support for TreatAsUsed metadata (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfederm authored Oct 1, 2024
1 parent a2a1e3c commit ca7ecac
Show file tree
Hide file tree
Showing 20 changed files with 207 additions and 7 deletions.
40 changes: 37 additions & 3 deletions src/Tasks/CollectDeclaredReferencesTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public sealed class CollectDeclaredReferencesTask : MSBuildTask
};

private const string NoWarn = "NoWarn";
private const string TreatAsUsed = "TreatAsUsed";

[Required]
public string? OutputFile { get; set; }
Expand Down Expand Up @@ -86,7 +87,7 @@ public override bool Execute()
}

// Ignore suppressions
if (reference.GetMetadata(NoWarn).Contains("RT0001"))
if (IsSuppressed(reference, "RT0001"))
{
continue;
}
Expand Down Expand Up @@ -130,7 +131,7 @@ public override bool Execute()
foreach (ITaskItem projectReference in ProjectReferences)
{
// Ignore suppressions
if (projectReference.GetMetadata(NoWarn).Contains("RT0002"))
if (IsSuppressed(projectReference, "RT0002"))
{
continue;
}
Expand Down Expand Up @@ -158,7 +159,7 @@ public override bool Execute()
foreach (ITaskItem packageReference in PackageReferences)
{
// Ignore suppressions
if (packageReference.GetMetadata(NoWarn).Contains("RT0003"))
if (IsSuppressed(packageReference, "RT0003"))
{
continue;
}
Expand Down Expand Up @@ -375,6 +376,39 @@ private HashSet<string> GetTargetFrameworkAssemblyNames()
return null;
}

private static bool IsSuppressed(ITaskItem item, string warningId)
{
ReadOnlySpan<char> warningIdSpan = warningId.AsSpan();
ReadOnlySpan<char> remainingNoWarn = item.GetMetadata(NoWarn).AsSpan();
while (!remainingNoWarn.IsEmpty)
{
ReadOnlySpan<char> currentNoWarn;
int idx = remainingNoWarn.IndexOf(';');
if (idx == -1)
{
currentNoWarn = remainingNoWarn;
remainingNoWarn = ReadOnlySpan<char>.Empty;
}
else
{
currentNoWarn = remainingNoWarn.Slice(0, idx);
remainingNoWarn = remainingNoWarn.Slice(idx + 1);
}

if (currentNoWarn.Trim().Equals(warningIdSpan, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}

if (item.GetMetadata(TreatAsUsed).Equals("True", StringComparison.OrdinalIgnoreCase))
{
return true;
}

return false;
}

private sealed class PackageInfoBuilder
{
private List<string>? _compileTimeAssemblies;
Expand Down
42 changes: 42 additions & 0 deletions src/Tests/E2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ public Task UnusedProjectReferenceNoWarn()
expectedWarnings: []);
}

[TestMethod]
public Task UnusedProjectReferenceTreatAsUsed()
{
return RunMSBuildAsync(
projectFile: "Library/Library.csproj",
expectedWarnings: Array.Empty<Warning>());
}

[TestMethod]
public Task UnusedProjectReferenceSuppressed()
{
Expand Down Expand Up @@ -184,6 +192,19 @@ await RunMSBuildAsync(
expectedWarnings: []);
}

[TestMethod]
public async Task UnusedReferenceHintPathTreatAsUsed()
{
// For direct references, MSBuild can't determine build order so we need to ensure the dependency is already built
await RunMSBuildAsync(
projectFile: "Dependency/Dependency.csproj",
expectedWarnings: Array.Empty<Warning>());

await RunMSBuildAsync(
projectFile: "Library/Library.csproj",
expectedWarnings: Array.Empty<Warning>());
}

[TestMethod]
public async Task UnusedReferenceItemSpec()
{
Expand Down Expand Up @@ -222,6 +243,19 @@ await RunMSBuildAsync(
expectedWarnings: []);
}

[TestMethod]
public async Task UnusedReferenceItemSpecTreatAsUsed()
{
// For direct references, MSBuild can't determine build order so we need to ensure the dependency is already built
await RunMSBuildAsync(
projectFile: "Dependency/Dependency.csproj",
expectedWarnings: Array.Empty<Warning>());

await RunMSBuildAsync(
projectFile: "Library/Library.csproj",
expectedWarnings: Array.Empty<Warning>());
}

[TestMethod]
public async Task UnusedReferenceFromGac()
{
Expand Down Expand Up @@ -288,6 +322,14 @@ public Task UnusedPackageReferenceNoWarn()
expectedWarnings: []);
}

[TestMethod]
public Task UnusedPackageReferenceTreatAsUsed()
{
return RunMSBuildAsync(
projectFile: "Library/Library.csproj",
expectedWarnings: []);
}

[TestMethod]
public Task UnusedPackageReferenceDocDisabled()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" NoWarn="RT0003"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" NoWarn="Foo; rt0003 ; Bar"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Library
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" TreatAsUsed="true"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../Dependency/Dependency.csproj" NoWarn="RT0002" />
<ProjectReference Include="../Dependency/Dependency.csproj" NoWarn="Foo; rt0002 ; Bar" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Dependency
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Library
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../Dependency/Dependency.csproj" TreatAsUsed="true" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ItemGroup>
<Reference Include="Dependency">
<HintPath>..\Dependency\$(OutputPath)\Dependency.dll</HintPath>
<NoWarn>RT0001</NoWarn>
<NoWarn>Foo; rt0001 ; Bar</NoWarn>
</Reference>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Dependency
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Library
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Reference Include="Dependency">
<HintPath>..\Dependency\$(OutputPath)\Dependency.dll</HintPath>
<TreatAsUsed>true</TreatAsUsed>
</Reference>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<Reference Include="..\Dependency\$(OutputPath)\Dependency.dll" NoWarn="RT0001"/>
<Reference Include="..\Dependency\$(OutputPath)\Dependency.dll" NoWarn="Foo; rt0001 ; Bar"/>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Dependency
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Library
{
public static class Foo
{
public static string Bar() => "Baz";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net472</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Reference Include="..\Dependency\$(OutputPath)\Dependency.dll" TreatAsUsed="true" />
</ItemGroup>

</Project>

0 comments on commit ca7ecac

Please sign in to comment.