Skip to content

Commit

Permalink
Rearrange MSBuild logic in project files
Browse files Browse the repository at this point in the history
Follow the following rules:

- SOF (_Start Of File_) Imports,
- Core properties, Package properties, build properties,
- Build items, Resource items, Content items, Misc. items,
- In-place Imports, Choose (_elements within follows outer sort order_)
- `ProjectReference` items, `PackageReference` items,
- Targets and Properties and Items close to said Targets,
- EOF (_End Of File_) Imports.

Where there's a condition by target properties, we should group them together under `Choose`.
For multiple target values, we should sort them by the order in which they are defined.
And the order in which they should be defined is either ascending or descending in terms of compatibility layering.
  • Loading branch information
Nirmal4G committed Jan 2, 2023
1 parent 51a46fd commit aef6f77
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 118 deletions.
17 changes: 8 additions & 9 deletions eng/Toolkit.Common.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

<PropertyGroup>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<ContinuousIntegrationBuild>$(TF_BUILD)</ContinuousIntegrationBuild>
<SourceLinkEnabled>$(ContinuousIntegrationBuild)</SourceLinkEnabled>
</PropertyGroup>

<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Nullable>Enable</Nullable>
<LangVersion>11.0</LangVersion>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<!--
<!--
Suppress ref safety warnings in unsafe contexts (see https://github.com/dotnet/csharplang/issues/6476).
This is used eg. to replace Unsafe.SizeOf<T>() calls with just sizeof(T). The warning is not necessary
since in order to use these APIs the caller already has to be in an unsafe context.
-->
-->
<PropertyGroup>
<NoWarn>$(NoWarn);CS8500</NoWarn>
</PropertyGroup>

Expand All @@ -24,11 +28,6 @@
<AssemblySignPublicKey>$([System.IO.File]::ReadAllText($(AssemblySignPublicKeyFile)))</AssemblySignPublicKey>
</PropertyGroup>

<PropertyGroup>
<ContinuousIntegrationBuild>$(TF_BUILD)</ContinuousIntegrationBuild>
<SourceLinkEnabled>$(ContinuousIntegrationBuild)</SourceLinkEnabled>
</PropertyGroup>

<!-- Identify projects targeting multiple Roslyn versions and add defaults -->
<PropertyGroup Condition="$(MSBuildProjectName.Contains('.Roslyn'))">
<IsCompilerTargeting>True</IsCompilerTargeting>
Expand Down
9 changes: 3 additions & 6 deletions eng/Toolkit.Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,14 @@
<PropertyGroup>
<!-- TODO: Dynamically generate Title if one wasn't set -->
<Title Condition="'$(Title)' == ''">$(Product) Asset</Title>
</PropertyGroup>

<PropertyGroup>
<PackageTags Condition="'$(PackageTags)' != ''">$(CommonTags);$(PackageTags)</PackageTags>
<PackageTags Condition="'$(PackageTags)' == ''">$(CommonTags)</PackageTags>
</PropertyGroup>

<ItemGroup Condition="$(IsPackable)">
<None Include="$(BuildToolsDirectory)Icon.png" Pack="true" PackagePath="\" Visible="False" />
<None Include="$(RepositoryDirectory)License.md" Pack="true" PackagePath="\" Visible="False" />
<None Include="$(RepositoryDirectory)ThirdPartyNotices.txt" Pack="true" PackagePath="\" Visible="False" />
<None Pack="true" PackagePath="\" Visible="False" Include="$(BuildToolsDirectory)Icon.png" />
<None Pack="true" PackagePath="\" Visible="False" Include="$(RepositoryDirectory)License.md" />
<None Pack="true" PackagePath="\" Visible="False" Include="$(RepositoryDirectory)ThirdPartyNotices.txt" />
</ItemGroup>

<!--
Expand Down
10 changes: 5 additions & 5 deletions eng/Toolkit.TextTemplates.targets
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<Project>

<!-- T4 service used by the Guard APIs -->
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>

<ItemGroup>
<None Update="Generated\Guard.Comparable.Numeric.tt">
<Generator>TextTemplatingFileGenerator</Generator>
Expand All @@ -19,11 +24,6 @@
</None>
</ItemGroup>

<!-- T4 service used by the Guard APIs -->
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>

<ItemGroup>
<Compile Update="Generated\Guard.Comparable.Numeric.g.cs">
<DesignTime>True</DesignTime>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
<PackageTags>Diagnostics;Guard;ThrowHelper;TypeInfo;Extensions;Helpers</PackageTags>
</PropertyGroup>

<!-- Necessary polyfills -->
<PropertyGroup>
<PolySharpIncludeGeneratedTypes>
System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute;
System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute;
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.StackTraceHiddenAttribute;
System.Runtime.CompilerServices.CallerArgumentExpressionAttribute;
System.Runtime.CompilerServices.SkipLocalsInitAttribute;
</PolySharpIncludeGeneratedTypes>
</PropertyGroup>

<Choose>

<!-- .NET Standard 2.0 doesn't have the Span<T> type -->
Expand All @@ -31,18 +43,6 @@
</When>
</Choose>

<!-- Necessary polyfills -->
<PropertyGroup>
<PolySharpIncludeGeneratedTypes>
System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute;
System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute;
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.StackTraceHiddenAttribute;
System.Runtime.CompilerServices.CallerArgumentExpressionAttribute;
System.Runtime.CompilerServices.SkipLocalsInitAttribute;
</PolySharpIncludeGeneratedTypes>
</PropertyGroup>

<Import Project="$(BuildToolsDirectory)Toolkit.TextTemplates.targets" />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,30 @@
<PackageTags>Parallel;Performance;Unsafe;Span;Memory;String;StringPool;Array;Stream;Buffer;Extensions;Helpers</PackageTags>
</PropertyGroup>

<!-- Necessary polyfills -->
<PropertyGroup>
<PolySharpIncludeGeneratedTypes>
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;
System.Runtime.CompilerServices.SkipLocalsInitAttribute;
</PolySharpIncludeGeneratedTypes>
</PropertyGroup>

<Choose>
<When Condition="'$(TargetFramework)' == 'netstandard2.0'">

<!-- On .NET Standard 2.0, the unit test project also needs access to internals -->
<ItemGroup>
<InternalsVisibleTo Include="CommunityToolkit.HighPerformance.UnitTests, PublicKey=$(AssemblySignPublicKey)" />
</ItemGroup>

<!-- .NET Standard 2.0 doesn't have the Span<T>, HashCode and ValueTask types -->
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
</ItemGroup>

<!-- On .NET Standard 2.0, the unit test project also needs access to internals-->
<ItemGroup>
<InternalsVisibleTo Include="CommunityToolkit.HighPerformance.UnitTests, PublicKey=$(AssemblySignPublicKey)" />
</ItemGroup>
</When>

<!-- .NET Standard 2.1 doesn't have the Unsafe type -->
Expand All @@ -50,13 +59,4 @@
</When>
</Choose>

<!-- Necessary polyfills -->
<PropertyGroup>
<PolySharpIncludeGeneratedTypes>
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;
System.Runtime.CompilerServices.SkipLocalsInitAttribute;
</PolySharpIncludeGeneratedTypes>
</PropertyGroup>

</Project>
68 changes: 36 additions & 32 deletions src/CommunityToolkit.Mvvm/CommunityToolkit.Mvvm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,39 @@
<PackageTags>MVVM;Toolkit;MVVMToolkit;INotifyPropertyChanged;Observable;IOC;DI;Dependency Injection;Object Messaging;Extensions;Helpers</PackageTags>
</PropertyGroup>

<!-- Necessary polyfills -->
<PropertyGroup>
<PolySharpIncludeGeneratedTypes>
System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute;
System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute;
System.Diagnostics.CodeAnalysis.MemberNotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;
System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute;
System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute;
System.Runtime.CompilerServices.CallerArgumentExpressionAttribute;
System.Runtime.CompilerServices.IsExternalInit;
System.Runtime.CompilerServices.SkipLocalsInitAttribute;
</PolySharpIncludeGeneratedTypes>
</PropertyGroup>

<!-- Add the [InternalsVisibleTo] attribute for the test project -->
<ItemGroup>
<InternalsVisibleTo Include="CommunityToolkit.Mvvm.Internals.UnitTests, PublicKey=$(AssemblySignPublicKey)" />
</ItemGroup>

<!--
Include the custom .targets file to check the source generator.
.NET 6 is not needed as it guarantees Roslyn 4.x.
-->
<ItemGroup>
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="build\netstandard2.0" />
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="build\netstandard2.1" />
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="buildTransitive\netstandard2.0" />
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="buildTransitive\netstandard2.1" />
</ItemGroup>

<!-- .NET Standard 2.0 doesn't have the Span<T> and IAsyncEnumerable<T> types -->
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
Expand All @@ -40,40 +73,11 @@
<ProjectReference Include="..\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn43.csproj" ReferenceOutputAssembly="false" />
</ItemGroup>

<!-- Add the [InternalsVisibleTo] attribute for the test project -->
<ItemGroup>
<InternalsVisibleTo Include="CommunityToolkit.Mvvm.Internals.UnitTests, PublicKey=$(AssemblySignPublicKey)" />
</ItemGroup>

<!-- Necessary polyfills -->
<PropertyGroup>
<PolySharpIncludeGeneratedTypes>
System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute;
System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute;
System.Diagnostics.CodeAnalysis.MemberNotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute;
System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;
System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute;
System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute;
System.Runtime.CompilerServices.CallerArgumentExpressionAttribute;
System.Runtime.CompilerServices.IsExternalInit;
System.Runtime.CompilerServices.SkipLocalsInitAttribute;
</PolySharpIncludeGeneratedTypes>
</PropertyGroup>

<ItemGroup Label="Package">

<!-- Include the custom .targets file to check the source generator (.NET 6 is not needed as it guarantees Roslyn 4.x) -->
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="buildTransitive\netstandard2.0" Pack="true" />
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="buildTransitive\netstandard2.1" Pack="true" />
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="build\netstandard2.0" Pack="true" />
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="build\netstandard2.1" Pack="true" />

<!--
<!--
Pack the source generator to the right package folders (each matching the target Roslyn version).
Roslyn will automatically load the highest version compatible with Roslyn's version in the SDK.
-->
-->
<ItemGroup>
<None Include="..\CommunityToolkit.Mvvm.SourceGenerators\bin\$(Configuration)\netstandard2.0-roslyn4.0\CommunityToolkit.Mvvm.SourceGenerators.dll" PackagePath="analyzers\dotnet\roslyn4.0\cs" Pack="true" Visible="false" />
<None Include="..\CommunityToolkit.Mvvm.SourceGenerators\bin\$(Configuration)\netstandard2.0-roslyn4.3\CommunityToolkit.Mvvm.SourceGenerators.dll" PackagePath="analyzers\dotnet\roslyn4.3\cs" Pack="true" Visible="false" />
</ItemGroup>
Expand Down
35 changes: 19 additions & 16 deletions src/CommunityToolkit.Mvvm/CommunityToolkit.Mvvm.targets
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@
AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets"
DependsOnTargets="MVVMToolkitGatherAnalyzers">

<!-- Use the CSharpCoreTargetsPath property to find the version of the compiler we are using. This is the same mechanism
MSBuild uses to find the compiler. We could check the assembly version for any compiler assembly (since they all have
the same version) but Microsoft.Build.Tasks.CodeAnalysis.dll is where MSBuild loads the compiler tasks from so if
someone is getting creative with msbuild tasks/targets this is the "most correct" assembly to check. -->
<!--
Use the CSharpCoreTargetsPath property to find the version of the compiler we are using. This is the same mechanism
MSBuild uses to find the compiler. We could check the assembly version for any compiler assembly (since they all have
the same version) but Microsoft.Build.Tasks.CodeAnalysis.dll is where MSBuild loads the compiler tasks from so if
someone is getting creative with msbuild tasks/targets this is the "most correct" assembly to check.
-->
<GetAssemblyIdentity AssemblyFiles="$([System.IO.Path]::Combine(`$([System.IO.Path]::GetDirectoryName($(CSharpCoreTargetsPath)))`,`Microsoft.Build.Tasks.CodeAnalysis.dll`))">
<Output TaskParameter="Assemblies" ItemName="MVVMToolkitCurrentCompilerAssemblyIdentity"/>
</GetAssemblyIdentity>

<PropertyGroup>

<!-- Transform the resulting item from GetAssemblyIdentity into a property representing its assembly version -->
<MVVMToolkitCurrentCompilerVersion>@(MVVMToolkitCurrentCompilerAssemblyIdentity->'%(Version)')</MVVMToolkitCurrentCompilerVersion>

Expand All @@ -35,38 +36,40 @@
<Analyzer Remove="@(MVVMToolkitAnalyzer)"/>
</ItemGroup>

<!-- If the source generators are disabled, also emit a warning. This would've been produced by MSBuild itself as well, but
emitting this manually lets us customize the message to inform developers as to why exactly the generators have been
disabled, and that the rest of the MVVM Toolkit will still keep working as intended, just without additional features. -->
<!--
If the source generators are disabled, also emit a warning. This would've been produced by MSBuild itself as well, but
emitting this manually lets us customize the message to inform developers as to why exactly the generators have been
disabled, and that the rest of the MVVM Toolkit will still keep working as intended, just without additional features.
-->
<Warning Condition ="'$(MVVMToolkitCurrentCompilerVersionIsNotNewEnough)' == 'true'" Text="The MVVM Toolkit source generators have been disabled on the current configuration, as they need Roslyn 4.x in order to work. The MVVM Toolkit will work just fine, but features relying on the source generators will not be available."/>
</Target>

<!--
Manually remove duplicate analyzers if Roslyn component versioning is not supported (ie. if a legacy .csproj project is used).
This target is only run if Roslyn 4.0 or greater is present, as otherwise all analyzers would have already been removed anyway.
Manually remove duplicate analyzers if Roslyn component versioning is not supported (ie. if a legacy .csproj project is used).
This target is only run if Roslyn 4.0 or greater is present, as otherwise all analyzers would have already been removed anyway.
-->
<Target Name="MVVMToolkitRemoveDuplicateAnalyzersWhenRoslynComponentVersioningIsNotSupported"
Condition="'$(MVVMToolkitCurrentCompilerVersionIsNotNewEnough)' != 'true' AND '$(SupportsRoslynComponentVersioning)' != 'true'"
AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets"
DependsOnTargets="MVVMToolkitRemoveAnalyzersForRoslyn3">

<!--
<!--
This switch manually implements Roslyn component versioning. That is, it checks the current version of Roslyn and
removes and removes all analyzers except the highest version that is supported. The fallback is just Roslyn 4.0.
-->
-->
<PropertyGroup>
<MVVMToolkitSelectedRoslynAnalyzerDirectoryName Condition="$([MSBuild]::VersionGreaterThanOrEquals($(MVVMToolkitCurrentCompilerVersion), 4.3))">roslyn4.3</MVVMToolkitSelectedRoslynAnalyzerDirectoryName>
<MVVMToolkitSelectedRoslynAnalyzerDirectoryName Condition="'$(MVVMToolkitSelectedRoslynAnalyzerDirectoryName)' == ''">roslyn4.0</MVVMToolkitSelectedRoslynAnalyzerDirectoryName>
</PropertyGroup>
<ItemGroup>

<!--

<!--
This condition is a bit convoluted, but it's essentially just selecting all analyzers from the NuGet package that don't have the target Roslyn directory name in their full path.
For instance, if Roslyn 4.3 is the highest supported version, the target directory name will be "roslyn 4.3", and this condition will filter out all analyzers with a path such
as: "C:\...\.nuget\...\CommunityToolkit.Mvvm\analyzers\roslyn4.0\cs\CommunityToolkit.Mvvm". The [System.String]::Concat trick is used to achieve two things: we can't directly
invoke a property function (ie. Contains in this case) on a metadata item, so we need an intermediate string to invoke it on. We could also use [System.String]::new, but using
Concat is more efficient as it'll just skip the allocation entirely if one of the two inputs is an empty string, which is the case here.
-->
-->
<ItemGroup>
<Analyzer Remove="@(MVVMToolkitAnalyzer)" Condition="!$([System.String]::Concat('', '%(MVVMToolkitAnalyzer.FullPath)').Contains('$(MVVMToolkitSelectedRoslynAnalyzerDirectoryName)'))"/>
</ItemGroup>
</Target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

<ItemGroup>
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm\CommunityToolkit.Mvvm.csproj" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn40.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="contentfiles;build" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn40.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="build;contentFiles" />
</ItemGroup>

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

<ItemGroup>
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm\CommunityToolkit.Mvvm.csproj" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn43.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="contentfiles;build" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn43.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="build;contentFiles" />
</ItemGroup>

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

<ItemGroup>
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm\CommunityToolkit.Mvvm.csproj" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn40.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="contentfiles;build" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn40.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="build;contentFiles" />
</ItemGroup>

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

<ItemGroup>
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm\CommunityToolkit.Mvvm.csproj" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn43.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="contentfiles;build" />
<ProjectReference Include="..\..\src\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.Roslyn43.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="build;contentFiles" />
</ItemGroup>

</Project>
Loading

0 comments on commit aef6f77

Please sign in to comment.