From 751260b0b6f29c77cc04aa16f366f13f0fb4caa0 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Fri, 25 Nov 2022 11:49:40 +0100 Subject: [PATCH] Update convention on how to ref and pack analyzers d3af4921f36dba8dde35ade7dff59a3a192edddb made it possible to reference and package an analyzer via the same msbuild item by setting custom metadata. While reviewing other places that could use the AnalyzerReference item, I realized that using this custom item doesn't provide much value and creates an artificial difference to the rest of the stack and our customers [as we don't adhere to our own documentation](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/#hello-world-source-generator-edition). Instead, IMHO it makes much more sense to keep using a `ProjectReference` item with the documented set of required metadata, to reference an analyzer and just define an additional custom metadata to support packaging the analyzer: `PackAsAnalyzer`. The reason for that is that the additional metadata explains how the reference works (no assembly output reference, added as an Analyzer output item) vs. the `AnalyzerReference` which is a repo custom item that doesn't tell you that behind the scenes it actually gets converted to a `ProjectReference` with the same metadata as if you would declare that yourself as a P2P. To summarize the change: 1. Consume an analyzer ```xml ``` 2. Pack an analyzer and consume it ```xml ``` 3. Pack an analyzer without consuming it ```xml ``` --- docs/coding-guidelines/libraries-packaging.md | 9 ++++++--- docs/coding-guidelines/project-guidelines.md | 2 +- eng/generators.targets | 14 +++---------- eng/packaging.targets | 8 ++++---- ...oft.Extensions.Logging.Abstractions.csproj | 20 +++++++++---------- ...Internal.Runtime.AspNetCore.Transport.proj | 6 +++--- ...System.ComponentModel.TypeConverter.csproj | 4 +++- ...m.Private.DataContractSerialization.csproj | 4 +++- .../src/System.Private.Xml.csproj | 4 +++- .../tests/System.Runtime.Tests.csproj | 4 +++- .../src/System.Text.Json.csproj | 13 +++++++++--- 11 files changed, 49 insertions(+), 39 deletions(-) diff --git a/docs/coding-guidelines/libraries-packaging.md b/docs/coding-guidelines/libraries-packaging.md index 3c03ab64398918..2d6968bce65000 100644 --- a/docs/coding-guidelines/libraries-packaging.md +++ b/docs/coding-guidelines/libraries-packaging.md @@ -28,7 +28,7 @@ Such transport packages represent the set of libraries which are produced in dot To add a library to the target's shared framework, that library should be listed in the `AspNetCoreAppLibrary` or `WindowsDesktopAppLibrary` section in `NetCoreAppLibrary.props`. -Source generators and analyzers can be included in the package by adding them to the `Microsoft.Internal.Runtime.**TARGET**.Transport.proj` as an AnalyzerReference. The analyzer projects should specify `AnalyzerLanguage` as mentioned [below](#analyzers--source-generators). +Source generators and analyzers can be included in the package by adding them to the `Microsoft.Internal.Runtime.**TARGET**.Transport.proj` as a ProjectReference with the `ReferenceOutputAssembly=false` and `PackAsAnalyzer=true` metadata set. The analyzer projects should specify `AnalyzerLanguage` as mentioned [below](#analyzers--source-generators). Libraries included in this transport package should ensure all direct and transitive assembly references are also included in either the target's shared framework or the Microsoft.NETCore.App shared framework. This is not validated in dotnet/runtime at the moment: https://github.com/dotnet/runtime/issues/52562 @@ -70,10 +70,13 @@ Build props and targets may be needed in NuGet packages. To define these, author Some packages may wish to include a companion analyzer or source-generator with their library. Analyzers are much different from normal library contributors: their dependencies shouldn't be treated as nuget package dependencies, their TargetFramework isn't applicable to the project they are consumed in (since they run in the compiler). To facilitate this, we've defined some common infrastructure for packaging Analyzers. -To include an analyzer in a package, simply add an `AnalyzerReference` item to the project that produces the package that should contain the analyzer and set the `Pack` metadata to true. If you just want to include the analyzer but not consume it, set the `ReferenceAnalyzer` metadata to false. +To include an analyzer in a package, simply add a `ProjectReference` item to the project that produces the package that should contain the analyzer and set the `ReferenceOutputAssembly` metadata to false and the `PackAsAnalyzer` metadata to true. If you also want to consume the analyzer, set the `OutputItemType` metadata to `Analyzer`. ```xml - + + + + ``` diff --git a/docs/coding-guidelines/project-guidelines.md b/docs/coding-guidelines/project-guidelines.md index 24be3d0707be4a..de3b7d14fc6ed2 100644 --- a/docs/coding-guidelines/project-guidelines.md +++ b/docs/coding-guidelines/project-guidelines.md @@ -188,7 +188,7 @@ All test outputs should be under ## gen In the gen directory any source generator related to the assembly should exist. This does not mean the source generator is only used for that assembly only that it is conceptually apart of that assembly. For example, the assembly may provide attributes or low-level types the source generator uses. -To consume a source generator, simply add an `` item to the project, usually next to the `References` and `ProjectReferences` items. +To consume a source generator, simply add a `` item to the project, usually next to the `Reference` and `ProjectReference` items. ## Facades Facade are unique in that they don't have any code and instead are generated by finding a contract reference assembly with the matching identity and generating type forwards for all the types to where they live in the implementation assemblies (aka facade seeds). There are also partial facades which contain some type forwards as well as some code definitions. All the various build configurations should be contained in the one csproj file per library. diff --git a/eng/generators.targets b/eng/generators.targets index ac01adc5cc4c4a..e1c4b2dfe94853 100644 --- a/eng/generators.targets +++ b/eng/generators.targets @@ -41,18 +41,10 @@ That is required as the EnabledGenerators condition checks on the Reference and ProjectReference items and hence can't be a property condition. --> - - - - - - - + OutputItemType="Analyzer" /> - + @@ -161,8 +161,8 @@ AnyHaveMetadataValue('PackAsAnalyzer', 'true')) and '$(IncludeMultiTargetRoslynComponentTargets)' == 'true'" DependsOnTargets="GenerateMultiTargetRoslynComponentTargetsFile"> diff --git a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj index e95fbc0ac99167..a0d6afcf116987 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj +++ b/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj @@ -38,16 +38,16 @@ Microsoft.Extensions.Logging.Abstractions.NullLogger - - - + + + diff --git a/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj b/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj index 821ac035123f48..3e71ad82f29ffb 100644 --- a/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj +++ b/src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj @@ -27,8 +27,8 @@ Private="true" IncludeReferenceAssemblyInPackage="true" /> - + diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj index bd04566e216f23..8f2c6d09fe0f9b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj @@ -246,7 +246,9 @@ - + diff --git a/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj b/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj index 3d28f1475535c3..c2b707ca50c120 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj +++ b/src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj @@ -150,7 +150,9 @@ - + diff --git a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj index 74006bda8d1337..18f51320fd483b 100644 --- a/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj +++ b/src/libraries/System.Private.Xml/src/System.Private.Xml.csproj @@ -758,7 +758,9 @@ - + diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index 91d560c81a8d8c..c0ebafed457e9b 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -322,7 +322,9 @@ - + diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index bcd039e90cbfa7..b35802fc1187f0 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -388,8 +388,15 @@ The System.Text.Json library is built-in as part of the shared framework in .NET - - - + + +