mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-16 21:02:51 +08:00
9b034f8291
# Description Nullable reference types are now enabled once, in `common.props`, and every project in the repository builds warning-clean with them. **Configuration** - `<Nullable>enable</Nullable>` lives in `common.props`. All per-project `<Nullable>` settings are removed: 178 project files (enable, annotations, and the `disable` in the three Aot test projects). - 419 per-file `#nullable enable`/`restore` directives and the 4 `#nullable disable` directives are removed. - Kept on purpose: - The 5 `<auto-generated>` schema files (`UANodeSet.cs`, `UA Type Dictionary.cs`, `OPCBinarySchema.cs`, `SecuredApplication.cs`, `PInvokeHelper.cs`) keep `#nullable enable`. The compiler ignores the project setting in generated code, so the directive is required there. - `tests/Opc.Ua.Interop.LegacyPeer` keeps `disable`. It builds against the 1.5.378 packages and does not import the repository props. - `docs/DeveloperGuide.md` and `.github/copilot-instructions.md` now describe the central setting. **Migration** (the 43 unset and 13 annotations-only projects, roughly 10k diagnostics) - **Production code: annotated at the declarations.** Covers `tools/Opc.Ua.SourceGeneration.Core`, `src/Opc.Ua.Lds.Server` and the LDS sample. - Members, parameters and returns are nullable where null actually flows. - Null-check helpers carry `[NotNullWhen]` (`IsNull`, `IsValidXmlName`, `IsMethodTypeDesign`). - `CoreUtils.Format`, `Utils.Format`, `ITemplateWriter.WriteLine` take `params object?[]`. `Template.AddReplacement` takes `string?` (rendering already skips null replacements). - `IRegisteredServerStore.RegisterAsync` returns `Task<RegistrationEntry?>`: it returns null when a registration is removed. - Dereferences backed by an invariant (for example, the validated model) use `!`, so runtime behaviour is unchanged. - **Behavioural changes in production code** (small, deliberate): - `NodeSetToModelDesign` throws `InvalidOperationException` when the file is not a NodeSet. Before, it threw a NullReferenceException on the next line. - `ModelDesignValidator` starts its lookup tables empty instead of null. A redundant `if (m_nodes == null) return;` guard is gone. - **Test code: minimal annotations.** - `?` on values that can be null, `!` where the test asserts non-null. - `= null!` for fixture members assigned in SetUp. - `TryGetStructure<T>(out T? x)` where the inferred `T?` broke the `IEncodeable` constraint. - A few redundant `== null` checks on structs (`NodeId`, `ArrayOf<T>`) folded into the adjacent `IsNull`/`Count` checks. **Notes for reviewers** - The diff is large (~1,500 files) but almost entirely mechanical: `?`, `!` and directive removal. The non-annotation changes are listed above. - Known follow-up, not done here: `IModelDesign.Namespaces/TargetNamespace/NamespaceUris` stay non-nullable even though the validator returns null before it loads a dictionary. Making them nullable would ripple through every generator call site. ## Related Issues - Fixes #4439 ## Checklist - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [ ] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received. The "no new warnings" box covers net10.0 and net48: full non-incremental builds of `UA.slnx`, `tools/SourceGeneration.slnx`, `tools/MigrationAnalyzer.slnx` and the Aot test projects finished with 0 warnings and 0 errors under the repository's warnings-as-errors settings. net9.0 and net8.0 also had no nullable diagnostics, but they were not rebuilt after the final fixes. Tests have not been run locally yet. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
151 lines
7.4 KiB
XML
151 lines
7.4 KiB
XML
<Project>
|
|
<PropertyGroup>
|
|
<Product>OPC UA .NET Standard Library</Product>
|
|
<RepositoryUrl>https://github.com/OPCFoundation/UA-.NETStandard</RepositoryUrl>
|
|
<VersionPrefix>2.0</VersionPrefix>
|
|
<VersionSuffix>preview-$([System.DateTime]::Now.ToString("yyyyMMdd"))</VersionSuffix>
|
|
<Copyright>Copyright © 2004-2025 OPC Foundation, Inc</Copyright>
|
|
<PackagePrefix>OPCFoundation.NetStandard</PackagePrefix>
|
|
<AssemblyPrefix>Opc.Ua</AssemblyPrefix>
|
|
<Company>OPC Foundation</Company>
|
|
<Authors>OPC Foundation</Authors>
|
|
<NeutralLanguage>en-US</NeutralLanguage>
|
|
<HighEntropyVA>true</HighEntropyVA>
|
|
<IsPackable>false</IsPackable>
|
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
|
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
|
|
<LangVersion>14.0</LangVersion>
|
|
<!--
|
|
Nullable reference types are enabled for every project in the repository.
|
|
Do not add per-project <Nullable> settings or per-file '#nullable enable'
|
|
directives; a project or file that must opt out does so explicitly with
|
|
<Nullable>disable</Nullable> / '#nullable disable' and says why.
|
|
-->
|
|
<Nullable>enable</Nullable>
|
|
<!-- to enable package validation, uncomment here -->
|
|
<!--<EnablePackageValidation>true</EnablePackageValidation>-->
|
|
<!-- to check the package validation on a release build, uncomment here -->
|
|
<!--<PackageValidationBaselineVersion>1.5.374.27</PackageValidationBaselineVersion>-->
|
|
<!-- to regenerate the compatibility suppression file, uncomment here -->
|
|
<!--<GenerateCompatibilitySuppressionFile>true</GenerateCompatibilitySuppressionFile>-->
|
|
<NuGetAuditMode>all</NuGetAuditMode>
|
|
<NuGetAudit>true</NuGetAudit>
|
|
</PropertyGroup>
|
|
<PropertyGroup>
|
|
<AccelerateBuildsInVisualStudio>true</AccelerateBuildsInVisualStudio>
|
|
<EnableNETAnalyzers>true</EnableNETAnalyzers>
|
|
<RunAnalyzersDuringBuild Condition="'$(RunAnalyzersDuringBuild)' == ''">true</RunAnalyzersDuringBuild>
|
|
<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
|
|
<AnalysisLevel>preview</AnalysisLevel>
|
|
<AnalysisMode>all</AnalysisMode>
|
|
<AnalysisModeStyle>default</AnalysisModeStyle>
|
|
</PropertyGroup>
|
|
<PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
|
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
|
</PropertyGroup>
|
|
<ItemGroup Condition="'$(NoRoslynatorAnalzers)' == ''">
|
|
<PackageReference Include="Roslynator.Analyzers" PrivateAssets="All" />
|
|
<PackageReference Include="Roslynator.Formatting.Analyzers" PrivateAssets="All" />
|
|
</ItemGroup>
|
|
<PropertyGroup>
|
|
<NoWarn>$(NoWarn);NU1510</NoWarn>
|
|
<PackageIcon>images/logo.jpg</PackageIcon>
|
|
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
|
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
|
<!--
|
|
Every package ships the OPC Foundation MIT License 1.00 as a license
|
|
file. Do NOT replace this with
|
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>: the SPDX `MIT`
|
|
license is a different text than the OPC Foundation one, and NuGet
|
|
rejects a project that carries both an expression and a license file
|
|
(NU5033). `Directory.Build.targets` enforces this.
|
|
-->
|
|
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
|
|
<PackageReleaseNotes>$(RepositoryUrl)/releases</PackageReleaseNotes>
|
|
<!--
|
|
Every package ships its own package-local README (`NugetREADME.md`
|
|
next to the csproj, or the established `McpREADME.md` for the
|
|
command-line tool package). Per-package READMEs are wired in each
|
|
csproj via <PackageReadmeFile> + a matching <None Include=...
|
|
Pack="true">. A generic shared README at this `common.props`
|
|
level was deliberately removed in favor of per-package READMEs
|
|
because it was misleading on nuget.org (every package described
|
|
itself identically).
|
|
-->
|
|
<PackageTags>OPCFoundation OPC UA ios linux dotnet net netcore</PackageTags>
|
|
</PropertyGroup>
|
|
<PropertyGroup Condition="'$(SignAssembly)' == 'true'">
|
|
<!-- OPC Foundation public key -->
|
|
<PublicKey>0024000004800000940000000602000000240000</PublicKey>
|
|
<PublicKey>$(PublicKey)525341310004000001000100d987b12f068b3580</PublicKey>
|
|
<PublicKey>$(PublicKey)429f3dde01397508880fc7e62621397618456ca1</PublicKey>
|
|
<PublicKey>$(PublicKey)549aeacfbdb90c62adfe918f05ce3677b390f783</PublicKey>
|
|
<PublicKey>$(PublicKey)57b8745cb6e1334655afce1a9527ac92fc829ff5</PublicKey>
|
|
<PublicKey>$(PublicKey)85ea79f007e52ba0f83ead627e3edda40bec5ae5</PublicKey>
|
|
<PublicKey>$(PublicKey)74128fc9342cb57cb8285aa4e5b589c0ebef3be5</PublicKey>
|
|
<PublicKey>$(PublicKey)71b5c8f2ab1067f7c880e8f8882a73c80a12a1ef</PublicKey>
|
|
</PropertyGroup>
|
|
<Choose>
|
|
<When Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net5.0'))">
|
|
<PropertyGroup>
|
|
<!-- Disable strongname warning as that's not been enforced since .net 5.-->
|
|
<NoWarn>$(NoWarn);CS8002</NoWarn>
|
|
</PropertyGroup>
|
|
</When>
|
|
<Otherwise>
|
|
<PropertyGroup>
|
|
<!-- Disable nullable warning as it is not as meaningful on .net framework as on .net -->
|
|
<NoWarn>$(NoWarn);nullable</NoWarn>
|
|
</PropertyGroup>
|
|
</Otherwise>
|
|
</Choose>
|
|
<PropertyGroup Condition="'$(TargetFramework)' == 'net48'">
|
|
<!--
|
|
The Microsoft.Extensions.* graph used across the stack (Http.Resilience and
|
|
its transitive Telemetry / AmbientMetadata / Diagnostics packages) ships
|
|
net462 assets that build and run on .NET Framework, but their buildTransitive
|
|
support targets still emit "doesn't support net48" warnings. These are
|
|
benign on net462-compatible TFMs, so suppress them once here for all projects
|
|
instead of scattering per-project SuppressTfmSupportBuildWarnings blocks.
|
|
TODO: remove when the library matrix drops .NET Framework or the packages stop warning.
|
|
-->
|
|
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
|
|
</PropertyGroup>
|
|
<ItemGroup Condition="'$(IsPackable)' != 'false'">
|
|
<None
|
|
Include="$(MSBuildThisFileDirectory)/LICENSE.txt"
|
|
Pack="true"
|
|
PackagePath="$(PackageLicenseFile)"
|
|
/>
|
|
<None
|
|
Include="$(MSBuildThisFileDirectory)/nuget/logo.jpg"
|
|
Pack="true"
|
|
PackagePath="$(PackageIcon)"
|
|
/>
|
|
<!--
|
|
Each NuGet package owns its own package-local README -
|
|
`NugetREADME.md` next to the csproj, or the established
|
|
`McpREADME.md` for the command-line tool package. Each csproj
|
|
wires its README via <PackageReadmeFile> and packs the file at
|
|
the package root with
|
|
<None Include="..." Pack="true" PackagePath="\" />.
|
|
A generic shared README would be misleading on nuget.org because
|
|
every package would describe itself identically.
|
|
-->
|
|
</ItemGroup>
|
|
<ItemGroup Condition="'$(NBGV_PublicRelease)' != ''">
|
|
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
|
|
</ItemGroup>
|
|
<!-- Deterministic build is currently not supported for code coverage tests. -->
|
|
<PropertyGroup Condition="'$(CollectCoverage)' != 'true' AND ('$(TF_BUILD)' == 'true' OR '$(GITHUB_ACTIONS)' == 'true')">
|
|
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
|
</PropertyGroup>
|
|
<PropertyGroup>
|
|
<IncludeSymbols>true</IncludeSymbols>
|
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
|
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
|
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
|
</PropertyGroup>
|
|
</Project>
|