-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathroslyn.props
More file actions
57 lines (51 loc) · 3.5 KB
/
Copy pathroslyn.props
File metadata and controls
57 lines (51 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<Project>
<!--
The Roslyn API version the OPC UA analyzers and source generators are built
against, and the runtime assemblies that version implies.
Lives at the repository root, not under tools/, because Directory.Packages.props
imports it: a partial-copy context that only takes the root files (the sample
Dockerfiles do exactly that) must still be able to restore.
Each analyzer ships under `analyzers/dotnet/<folder>/cs`. The .NET SDK loads the
highest folder its compiler supports and silently ignores folders above it. Using a
versioned folder rather than a bare `analyzers/dotnet/cs` is deliberate: a host older
than the band below skips the analyzer instead of loading it and then failing at
generator-initialization time.
See https://learn.microsoft.com/visualstudio/extensibility/roslyn-version-support
for the Roslyn package version to Visual Studio mapping.
RoslynRuntimeVersion is the critical part. The compiler supplies
System.Collections.Immutable and System.Reflection.Metadata itself, and the version it
supplies is fixed by its Roslyn band (4.8 -> 7.x, 4.14 -> 9.x, 5.0 -> 9.x). An analyzer
must therefore reference a version at or BELOW its band's - .NET satisfies a reference
from a higher assembly version but never from a lower one - and must never ship a copy
of its own, because a second copy binds a separate ImmutableArray<T> identity and the
generator dies with MissingMethodException on its first Roslyn call. Either failure
surfaces only as warning CS8784, so the consumer silently gets no generated code.
Directory.Packages.props pins both packages to $(RoslynRuntimeVersion) and central
transitive pinning propagates that through the whole analyzer closure - the generator,
Opc.Ua.SourceGeneration.Core and Opc.Ua.Types. Keeping the pin here rather than as a
loose version literal is what stops the closure drifting above the band again.
Adding a band below the current floor is therefore not just another entry in this
file. It only stays cheap while the new band shares $(RoslynRuntimeVersion): Roslyn
4.14 and 5.0 both depend on System.Collections.Immutable 9.0.0, so one build of the
non-Roslyn part of the closure serves both. Going lower - Roslyn 4.8 wants 7.x -
would require building that whole closure, Opc.Ua.Types included, a second time
against the older runtime.
-->
<PropertyGroup>
<!-- Visual Studio 2026 18.0+ / .NET 10 SDK. -->
<RoslynApiVersionVS2026>5.0.0</RoslynApiVersionVS2026>
<!-- Visual Studio 2022 17.14+ / .NET 9 SDK. -->
<RoslynApiVersionVS2022>4.14.0</RoslynApiVersionVS2022>
<!-- System.Collections.Immutable / System.Reflection.Metadata that both
Microsoft.CodeAnalysis $(RoslynApiVersionVS2022) and $(RoslynApiVersionVS2026)
depend on. The two bands share it, so a single build of the non-Roslyn part of
the closure (Opc.Ua.SourceGeneration.Core, Opc.Ua.Types) serves both. Roslyn
4.14's csc runs on net9.0 and takes these from the shared framework, which is
9.0.0.0 - matching this pin exactly. -->
<RoslynRuntimeVersion>9.0.0</RoslynRuntimeVersion>
</PropertyGroup>
<PropertyGroup>
<RoslynAnalyzerFolderVS2026>roslyn$(RoslynApiVersionVS2026.Substring(0, $(RoslynApiVersionVS2026.LastIndexOf('.'))))</RoslynAnalyzerFolderVS2026>
<RoslynAnalyzerFolderVS2022>roslyn$(RoslynApiVersionVS2022.Substring(0, $(RoslynApiVersionVS2022.LastIndexOf('.'))))</RoslynAnalyzerFolderVS2022>
</PropertyGroup>
</Project>