Skip to content

Commit a826907

Browse files
committed
Define convention to include analyzers in ref pack
Fixes #61321 Until now we required source libraries to define ProjectReferences when an analyzer should be part of the shared framework. That strategy causes analyzer projects to leak into the ProjectReference closure and by that into a solution file. As an example: When another library references the source library that references the analyzer, the analyzer is part of the dependency closure even though it might not be required. This change makes it possible to define the shared framework analyzer projects in the NetCoreAppLibrary.props file for both the .NETCoreApp, and the AspNetCoreApp shared framework. Out-of-band projects which ship analyzers inside their produced package, continue to reference the analyzers via the `AnalyzerProject` item.
1 parent 96f3a5a commit a826907

File tree

20 files changed

+118
-91
lines changed

20 files changed

+118
-91
lines changed

docs/coding-guidelines/libraries-packaging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ In some occasions we may want to include a library in the shared framework, but
1414

1515
Libraries included in the shared framework should ensure all direct and transitive assembly references are also included in the shared framework. This will be validated as part of the build and errors raised if any dependencies are unsatisfied.
1616

17-
Source generators and analyzers can be included in the shared framework by specifying `IsNetCoreAppAnalyzer`. These projects should specify `AnalyzerLanguage` as mentioned [below](#analyzers--source-generators).
17+
Source generators and analyzers can be included in the shared framework by adding their project name into the NetCoreAppLibrary.props file under the `NetCoreAppLibraryGenerator` section. These projects should specify `AnalyzerLanguage` as mentioned [below](#analyzers--source-generators).
1818

1919
Removing a library from the shared framework is a breaking change and should be avoided.
2020

docs/coding-guidelines/project-guidelines.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ All test outputs should be under
188188

189189
## gen
190190
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.
191+
To consume a source generator, add an `<AnalyzerReference Include="..." />` item to the project, usually next to the `References` and `ProjectReferences` items.
191192

192193
## Facades
193194
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.

eng/generators.targets

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,6 @@
5252
Include="$(CoreLibSharedDir)System\Runtime\InteropServices\StringMarshalling.cs" />
5353
</ItemGroup>
5454

55-
<ItemGroup>
56-
<EnabledGenerators Include="RegexGenerator" Condition="'$(EnableRegexGenerator)' == 'true'" />
57-
</ItemGroup>
58-
59-
<!-- Use this complex ItemGroup-based filtering to add the ProjectReference to make sure dotnet/runtime stays compatible with NuGet Static Graph Restore. -->
60-
<ItemGroup Condition="'@(EnabledGenerators)' != ''
61-
and @(EnabledGenerators->AnyHaveMetadataValue('Identity', 'RegexGenerator'))">
62-
<ProjectReference
63-
Include="$(LibrariesProjectRoot)System.Text.RegularExpressions/gen/System.Text.RegularExpressions.Generator.csproj"
64-
OutputItemType="Analyzer"
65-
ReferenceOutputAssembly="false" />
66-
</ItemGroup>
67-
6855
<Target Name="ConfigureGenerators"
6956
DependsOnTargets="ConfigureLibraryImportGenerator"
7057
BeforeTargets="CoreCompile" />

eng/packaging.targets

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,12 @@
137137
</ItemGroup>
138138
</Target>
139139

140-
<Target Name="IncludeAnalyzersInPackage" Condition="'@(AnalyzerReference)' != ''">
141-
<!-- Call a target in the analyzer project to get all the files it would normally place in a package.
142-
These will be returned as items with identity pointing to the built file, and PackagePath metadata
143-
set to their location in the package. IsSymbol metadata will be set to distinguish symbols. -->
144-
<MSBuild Projects="@(AnalyzerReference)"
140+
<!-- Call a target in the analyzer project to get all the files it would normally place in a package.
141+
These will be returned as items with identity pointing to the built file, and PackagePath metadata
142+
set to their location in the package. IsSymbol metadata will be set to distinguish symbols. -->
143+
<Target Name="IncludeAnalyzersInPackage"
144+
Condition="'@(AnalyzerReference)' != '' and @(AnalyzerReference->AnyHaveMetadataValue('Pack', 'true'))">
145+
<MSBuild Projects="@(AnalyzerReference->WithMetadataValue('Pack', 'true'))"
145146
Targets="GetAnalyzerPackFiles">
146147
<Output TaskParameter="TargetOutputs" ItemName="_AnalyzerFile" />
147148
</MSBuild>

src/libraries/Directory.Build.targets

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
<IsNETCoreAppRef Condition="('$(IsReferenceAssemblyProject)' == 'true' or '$(IsRuntimeAndReferenceAssembly)' == 'true') and
4848
$(NetCoreAppLibrary.Contains('$(AssemblyName);')) and
4949
!$(NetCoreAppLibraryNoReference.Contains('$(AssemblyName);'))">true</IsNETCoreAppRef>
50+
<IsNETCoreAppAnalyzer Condition="'$(IsGeneratorProject)' == 'true' and
51+
$(NetCoreAppLibraryGenerator.Contains('$(MSBuildProjectName);'))">true</IsNETCoreAppAnalyzer>
5052
<!-- By default, disable implicit framework references for NetCoreAppCurrent libraries. -->
5153
<DisableImplicitFrameworkReferences Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and
5254
$([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '$(NETCoreAppCurrentVersion)')) and
@@ -201,23 +203,11 @@
201203
</When>
202204
</Choose>
203205

204-
<PropertyGroup>
205-
<BuildAnalyzerReferences>$(BuildProjectReferences)</BuildAnalyzerReferences>
206-
<BuildAnalyzerReferences Condition="'$(BuildingInsideVisualStudio)' == 'true'">false</BuildAnalyzerReferences>
207-
</PropertyGroup>
208-
209206
<ItemGroup>
210-
<!-- Ensure AnalyzerReference items are restored and built
211-
The target framework of Analyzers has no relationship to that of the refrencing project,
212-
so we don't apply TargetFramework filters nor do we pass in TargetFramework.
213-
When BuildProjectReferences=false we make sure to set BuildReference=false to make
214-
sure not to try to call GetTargetPath in the outerbuild of the analyzer project. -->
215207
<ProjectReference Include="@(AnalyzerReference)"
216-
SkipGetTargetFrameworkProperties="true"
217-
UndefineProperties="TargetFramework"
208+
OutputItemType="Analyzer"
218209
ReferenceOutputAssembly="false"
219-
PrivateAssets="all"
220-
BuildReference="$(BuildAnalyzerReferences)" />
210+
Pack="false" />
221211
</ItemGroup>
222212

223213
<Target Name="GetAnalyzerPackFiles"

src/libraries/Microsoft.Extensions.Logging.Abstractions/src/Microsoft.Extensions.Logging.Abstractions.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ Microsoft.Extensions.Logging.Abstractions.NullLogger</PackageDescription>
3838

3939
<ItemGroup>
4040
<AnalyzerReference Include="..\gen\Microsoft.Extensions.Logging.Generators.Roslyn3.11.csproj"
41+
Pack="true"
4142
Condition="'$(DotNetBuildFromSource)' != 'true'" />
42-
<AnalyzerReference Include="..\gen\Microsoft.Extensions.Logging.Generators.Roslyn4.0.csproj" />
43+
<AnalyzerReference Include="..\gen\Microsoft.Extensions.Logging.Generators.Roslyn4.0.csproj"
44+
Pack="true" />
4345
</ItemGroup>
4446

4547
</Project>

src/libraries/Microsoft.Internal.Runtime.AspNetCore.Transport/src/Microsoft.Internal.Runtime.AspNetCore.Transport.proj

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818
<ItemGroup>
1919
<!-- Requires Private=true to calculate ReferenceCopyLocalPaths items. Also share System.Net.Quic which isn't part of aspnetcore's shared framework but which is needed by them. -->
2020
<ProjectReference Include="@(AspNetCoreAppLibrary->'$(LibrariesProjectRoot)%(Identity)\src\%(Identity).csproj');
21-
$(LibrariesProjectRoot)System.Net.Quic\src\System.Net.Quic.csproj" PrivateAssets="all" Pack="true" Private="true" IncludeReferenceAssemblyInPackage="true" />
22-
<!-- TODO: Find a better way to include source generators without hardcoding them. -->
21+
$(LibrariesProjectRoot)System.Net.Quic\src\System.Net.Quic.csproj"
22+
Pack="true"
23+
PrivateAssets="all"
24+
Private="true"
25+
IncludeReferenceAssemblyInPackage="true" />
2326
<!-- Only include the 4.0 version in the ref pack, since targeting net6.0 requires Roslyn 4.0 -->
24-
<AnalyzerReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Logging.Abstractions\gen\Microsoft.Extensions.Logging.Generators.Roslyn4.0.csproj" />
27+
<AnalyzerReference Include="$(LibrariesProjectRoot)Microsoft.Extensions.Logging.Abstractions\gen\Microsoft.Extensions.Logging.Generators.Roslyn4.0.csproj"
28+
Pack="true" />
2529
</ItemGroup>
2630
</Project>

src/libraries/NetCoreAppLibrary.props

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@
183183
System.Private.Xml;
184184
System.Private.Xml.Linq;
185185
</NetCoreAppLibraryNoReference>
186+
<!-- List .NETCoreApp shared framework generator project names below. -->
187+
<NetCoreAppLibraryGenerator>
188+
LibraryImportGenerator;
189+
System.Text.Json.SourceGeneration.Roslyn4.0;
190+
System.Text.RegularExpressions.Generator;
191+
</NetCoreAppLibraryGenerator>
186192
<AspNetCoreAppLibrary>
187193
Microsoft.Extensions.Caching.Abstractions;
188194
Microsoft.Extensions.Caching.Memory;
@@ -245,6 +251,7 @@
245251
<NetFxReference Include="$(NetFxReference)" />
246252
<NetCoreAppLibrary Include="$(NetCoreAppLibrary)" />
247253
<NetCoreAppLibraryNoReference Include="$(NetCoreAppLibraryNoReference)" />
254+
<NetCoreAppLibraryGenerator Include="$(NetCoreAppLibraryGenerator)" />
248255
<AspNetCoreAppLibrary Include="$(AspNetCoreAppLibrary)" />
249256
<WindowsDesktopCoreAppLibrary Include="$(WindowsDesktopCoreAppLibrary)" />
250257
</ItemGroup>

src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3+
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
34
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
45
<IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
5-
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
6-
<EnableRegexGenerator>true</EnableRegexGenerator>
76
</PropertyGroup>
7+
88
<ItemGroup>
99
<ILLinkSubstitutionsXmls Include="$(ILLinkDirectory)ILLink.Substitutions.xml" />
1010
</ItemGroup>
11+
1112
<ItemGroup>
1213
<Compile Include="MS\Internal\Xml\Linq\ComponentModel\XComponentModel.cs" />
1314
<Compile Include="System\ComponentModel\ArrayConverter.cs" />
@@ -238,7 +239,9 @@
238239
<Compile Include="System\ComponentModel\ComponentResourceManager.cs" />
239240
<Compile Include="System\Security\Authentication\ExtendedProtection\ExtendedProtectionPolicyTypeConverter.cs" />
240241
</ItemGroup>
242+
241243
<ItemGroup>
244+
<AnalyzerReference Include="$(LibrariesProjectRoot)System.Text.RegularExpressions\gen\System.Text.RegularExpressions.Generator.csproj" />
242245
<Reference Include="System.Collections" />
243246
<Reference Include="System.Collections.NonGeneric" />
244247
<Reference Include="System.Collections.Specialized" />

src/libraries/System.Private.DataContractSerialization/src/System.Private.DataContractSerialization.csproj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3+
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
34
<NoWarn>$(NoWarn);1634;1691;649</NoWarn>
45
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5-
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
66
<!-- Too much private reflection. Do not bother with trimming -->
77
<ILLinkTrimAssembly>false</ILLinkTrimAssembly>
8-
<EnableRegexGenerator>true</EnableRegexGenerator>
98
</PropertyGroup>
9+
1010
<PropertyGroup>
1111
<RuntimeSerializationSources>System\Runtime\Serialization</RuntimeSerializationSources>
1212
<JsonSources>System\Runtime\Serialization\Json</JsonSources>
1313
<XmlSources>System\Xml</XmlSources>
1414
<TextSources>System\Text</TextSources>
1515
</PropertyGroup>
16+
1617
<ItemGroup>
1718
<Compile Include="$(CommonPath)System\NotImplemented.cs"
1819
Link="Common\System\NotImplemented.cs" />
@@ -149,7 +150,9 @@
149150
<Compile Include="System\Xml\XmlCanonicalWriter.cs" />
150151
<Compile Include="System\Xml\XmlSigningNodeWriter.cs" />
151152
</ItemGroup>
153+
152154
<ItemGroup>
155+
<AnalyzerReference Include="$(LibrariesProjectRoot)System.Text.RegularExpressions\gen\System.Text.RegularExpressions.Generator.csproj" />
153156
<Reference Include="System.Collections" />
154157
<Reference Include="System.Collections.Concurrent" />
155158
<Reference Include="System.Collections.NonGeneric" />

src/libraries/System.Private.Xml/src/System.Private.Xml.csproj

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3+
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)</TargetFrameworks>
34
<RootNamespace>System.Xml</RootNamespace>
45
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5-
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)</TargetFrameworks>
6-
<EnableRegexGenerator>true</EnableRegexGenerator>
76
</PropertyGroup>
7+
88
<ItemGroup>
99
<Compile Include="$(CommonPath)System\Text\StringBuilderCache.cs" Link="Common\System\StringBuilderCache.cs" />
1010
<Compile Include="$(CommonPath)System\HexConverter.cs" Link="Common\System\HexConverter.cs" />
@@ -515,6 +515,7 @@
515515
<Compile Include="System\Xml\Serialization\Configuration\DateTimeSerializationSection.cs" />
516516
<Compile Include="System\Xml\Serialization\Globals.cs" />
517517
</ItemGroup>
518+
518519
<!-- Embedded DTD files -->
519520
<ItemGroup>
520521
<EmbeddedResource Include="Utils\DTDs\XHTML10\no_comments\xhtml1-strict.dtd">
@@ -539,34 +540,7 @@
539540
<LogicalName>rss-0.91.dtd</LogicalName>
540541
</EmbeddedResource>
541542
</ItemGroup>
542-
<ItemGroup>
543-
<Reference Include="System.Reflection.Emit" />
544-
<Reference Include="System.Reflection.Emit.ILGeneration" />
545-
<Reference Include="System.Reflection.Emit.Lightweight" />
546-
</ItemGroup>
547-
<ItemGroup>
548-
<Reference Include="System.Collections" />
549-
<Reference Include="System.Collections.Concurrent" />
550-
<Reference Include="System.Collections.NonGeneric" />
551-
<Reference Include="System.Collections.Specialized" />
552-
<Reference Include="System.Console" />
553-
<Reference Include="System.Diagnostics.TraceSource" />
554-
<Reference Include="System.Diagnostics.Tracing" />
555-
<Reference Include="System.Linq.Expressions" />
556-
<Reference Include="System.Memory" />
557-
<Reference Include="System.Net.Http" />
558-
<Reference Include="System.Net.Primitives" />
559-
<Reference Include="System.ObjectModel" />
560-
<Reference Include="System.Reflection.Primitives" />
561-
<Reference Include="System.Runtime" />
562-
<Reference Include="System.Runtime.InteropServices" />
563-
<Reference Include="System.Runtime.Loader" />
564-
<Reference Include="System.Security.Cryptography" />
565-
<Reference Include="System.Text.Encoding.Extensions" />
566-
<Reference Include="System.Text.RegularExpressions" />
567-
<Reference Include="System.Threading" />
568-
<Reference Include="System.Threading.Thread" />
569-
</ItemGroup>
543+
570544
<ItemGroup>
571545
<Compile Include="System\Xml\Xsl\IlGen\GenerateHelper.cs" />
572546
<Compile Include="System\Xml\Xsl\IlGen\IteratorDescriptor.cs" />
@@ -775,11 +749,41 @@
775749
<Compile Include="$(CommonPath)System\Text\ValueStringBuilder.cs" Link="Common\System\Text\ValueStringBuilder.cs" />
776750
<Compile Include="$(CommonPath)System\Text\ValueStringBuilder.AppendSpanFormattable.cs" Link="Common\System\Text\ValueStringBuilder.AppendSpanFormattable.cs" />
777751
</ItemGroup>
752+
778753
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'windows'">
779754
<Compile Include="System\Xml\Xsl\Runtime\XmlCollation.Windows.cs" />
780755
</ItemGroup>
756+
781757
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == ''">
782758
<Compile Include="System\Xml\Xsl\Runtime\XmlCollation.Unix.cs" />
783759
<Compile Include="System\Xml\Core\XmlTextReaderImpl.Unix.cs" />
784760
</ItemGroup>
761+
762+
<ItemGroup>
763+
<AnalyzerReference Include="$(LibrariesProjectRoot)System.Text.RegularExpressions\gen\System.Text.RegularExpressions.Generator.csproj" />
764+
<Reference Include="System.Collections" />
765+
<Reference Include="System.Collections.Concurrent" />
766+
<Reference Include="System.Collections.NonGeneric" />
767+
<Reference Include="System.Collections.Specialized" />
768+
<Reference Include="System.Console" />
769+
<Reference Include="System.Diagnostics.TraceSource" />
770+
<Reference Include="System.Diagnostics.Tracing" />
771+
<Reference Include="System.Linq.Expressions" />
772+
<Reference Include="System.Memory" />
773+
<Reference Include="System.Net.Http" />
774+
<Reference Include="System.Net.Primitives" />
775+
<Reference Include="System.ObjectModel" />
776+
<Reference Include="System.Reflection.Emit" />
777+
<Reference Include="System.Reflection.Emit.ILGeneration" />
778+
<Reference Include="System.Reflection.Emit.Lightweight" />
779+
<Reference Include="System.Reflection.Primitives" />
780+
<Reference Include="System.Runtime" />
781+
<Reference Include="System.Runtime.InteropServices" />
782+
<Reference Include="System.Runtime.Loader" />
783+
<Reference Include="System.Security.Cryptography" />
784+
<Reference Include="System.Text.Encoding.Extensions" />
785+
<Reference Include="System.Text.RegularExpressions" />
786+
<Reference Include="System.Threading" />
787+
<Reference Include="System.Threading.Thread" />
788+
</ItemGroup>
785789
</Project>

src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/LibraryImportGenerator.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
<PackageProjectUrl>https://github.com/dotnet/runtime/tree/main/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator</PackageProjectUrl>
2222
<Description>LibraryImportGenerator</Description>
2323
<PackageTags>LibraryImportGenerator, analyzers</PackageTags>
24-
<IsNETCoreAppAnalyzer>true</IsNETCoreAppAnalyzer>
2524
</PropertyGroup>
2625

2726
<ItemGroup>

src/libraries/System.Runtime.InteropServices/src/System.Runtime.InteropServices.csproj

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
43
<TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
4+
<IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
55
</PropertyGroup>
6+
67
<ItemGroup>
78
<Compile Include="System\Runtime\CompilerServices\IDispatchConstantAttribute.cs" />
89
<Compile Include="System\Runtime\CompilerServices\IUnknownConstantAttribute.cs" />
@@ -47,13 +48,9 @@
4748
<Compile Include="System\Security\SecureStringMarshal.cs" />
4849
<Compile Include="$(CommonPath)System\Obsoletions.cs" Link="Common\System\Obsoletions.cs" />
4950
</ItemGroup>
51+
5052
<ItemGroup>
5153
<ProjectReference Include="$(CoreLibProject)" />
5254
</ItemGroup>
53-
<ItemGroup>
54-
<!-- Add the source generator as an analyzer reference so that it gets included in the ref pack.
55-
See https://github.com/dotnet/runtime/issues/61321 -->
56-
<AnalyzerReference Include="..\gen\LibraryImportGenerator\LibraryImportGenerator.csproj" />
57-
</ItemGroup>
5855

5956
</Project>

0 commit comments

Comments
 (0)