Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nullability annotations #1699

Open
wants to merge 13 commits into
base: development
Choose a base branch
from
Open

Add nullability annotations #1699

wants to merge 13 commits into from

Conversation

amoerie
Copy link
Collaborator

@amoerie amoerie commented Dec 9, 2023

Please merge #1700 first

This PR adds nullability annotations. Since the code base is massive, this will be a gargantuan task, so feel free to jump in and help haha.

Checklist

  • The pull request branch is in sync with latest commit on the fo-dicom/development branch
  • I have updated API documentation
  • I have included unit tests
  • I have updated the change log
  • I am listed in the CONTRIBUTORS file

Changes proposed in this pull request:

  • included in Set up nullable annotations #1700
    • Enable nullable annotations by default
    • Immediately disable them again for every file
    • Then, enable them file by file, so we can move incrementally towards full adoption of nullability annotations
    • Add inline compiler nullability attributes because .NET Standard 2.0 does not contain them, but if we add them inline it works.
  • Add nullability attributes to DicomTag, DicomDataset and a few other core types
  • Add nullability attributes to the network layer

@gofal @mrbean-bremen I'm interested in hearing your thoughts about this. NREs have almost completely become a thing of the past in our code base at work, but here it's still a major danger. Since C# has such excellent compiler support now to avoid this, I figured I'd get things started to bring fo-dicom into a NRE-free world as well. :-)
I thought about the best approach (there really is a lot of code in fo-dicom), and enabling it globally by default and then disabling it file by file seemed like the best idea.

According to https://learn.microsoft.com/en-us/dotnet/csharp/nullable-migration-strategies, this is the best approach for libraries who are still developing new features.

@amoerie amoerie changed the title Enable and disable nullable annotations Add nullability annotations Dec 9, 2023
@@ -4,11 +4,13 @@
<Company>fo-dicom</Company>
<Copyright>Copyright © fo-dicom contributors 2012-2023</Copyright>
<Description>fo-dicom</Description>
<LangVersion>8</LangVersion>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is necessary to support nullability annotations.
While .NET Standard does not officially support C# 8, everything just works. The only unsupported feature is default interface members, which we don't use. Since our unit tests are multi-targeted and include .NET Framework, we will get compilation errors there if we ever do use default interface members or something that's not allowed.

Copy link

codecov bot commented Dec 9, 2023

Codecov Report

Attention: Patch coverage is 50.00000% with 43 lines in your changes are missing coverage. Please review.

Project coverage is 76.42%. Comparing base (b45ffe1) to head (9ba3c38).
Report is 21 commits behind head on development.

Current head 9ba3c38 differs from pull request most recent head fe4b7c7

Please upload reports for the commit fe4b7c7 to get more accurate results.

Files Patch % Lines
FO-DICOM.Core/DicomDataset.cs 51.85% 7 Missing and 6 partials ⚠️
FO-DICOM.Core/Network/DicomService.cs 36.36% 6 Missing and 1 partial ⚠️
...vanced/Connection/AdvancedDicomClientConnection.cs 20.00% 2 Missing and 2 partials ⚠️
FO-DICOM.Core/DicomTag.cs 50.00% 3 Missing ⚠️
FO-DICOM.Core/DicomItemComparer.cs 33.33% 1 Missing and 1 partial ⚠️
FO-DICOM.Core/Network/DicomPresentationContext.cs 0.00% 1 Missing and 1 partial ⚠️
FO-DICOM.Core/Network/DesktopNetworkListener.cs 0.00% 0 Missing and 1 partial ⚠️
FO-DICOM.Core/Network/DesktopNetworkStream.cs 0.00% 0 Missing and 1 partial ⚠️
...Core/Network/DicomExtendedNegotiationCollection.cs 0.00% 1 Missing ⚠️
FO-DICOM.Core/Network/DicomMessage.cs 66.66% 1 Missing ⚠️
... and 8 more
Additional details and impacted files
@@             Coverage Diff              @@
##           development    #1699   +/-   ##
============================================
  Coverage        76.42%   76.42%           
============================================
  Files              275      275           
  Lines            25410    25413    +3     
  Branches          3043     3048    +5     
============================================
+ Hits             19419    19423    +4     
+ Misses            5062     5056    -6     
- Partials           929      934    +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@mrbean-bremen
Copy link
Collaborator

I applaud this. NREs are indeed a PITA and this will mostly address them, though, as you wrote, it's a lot of work.
I haven't done anything in C# for quite a while (working mostly with C++ and Python at the moment), so I'm not sure if I'm the right person here, but I will see if I can get back to it some time soon.
I would suggest that after this first PR (which will add a lot of ignores) you may write a corresponding issue with a list of modules / groups of classes that could be tackled in separate PRs, so we can then handle them in separate PRs. I realize that this is also not a small task, but it would help to compartmentalize the work.

@amoerie
Copy link
Collaborator Author

amoerie commented Dec 11, 2023

I think I have the whole network layer (this is my comfort zone) covered, including its unit tests. I tried to just "describe the truth" in the annotations without making any real changes, but the annotations did uncover a few places where null might make its way through that we didn't handle yet, so in those places I added a null check or whatever was required to deal with the null value.
I also fixed typos or changed interpolated log messages to constant strings here and there, but everything else is pure annotations.

So far, my experience has been that you do need some "domain knowledge" to annotate things properly. For example, DicomService.Association is nullable because it is indeed null in the very beginning, but after the association handshake it is always not null, so any method that is only invoked after the association handshake can safely call this.Association without concern. For the nullability annotations, this means "this.Association!" because the property could technically be null, but we know it won't be.

I'm still fairly confident in some parts of the code that deal with parsing & writing DICOM to a file or a stream, but when we get into rendering territory I'm a bit more of an amateur there.

So I like the idea of making issues for the different "departments" in the code, I think I will require help from you or @gofal though for the rendering parts.

@amoerie amoerie marked this pull request as ready for review December 11, 2023 09:36
@amoerie amoerie requested review from mrbean-bremen and gofal and removed request for mrbean-bremen December 11, 2023 10:09
@mrbean-bremen
Copy link
Collaborator

I'm still fairly confident in some parts of the code that deal with parsing & writing DICOM to a file or a stream

Same here. This is actually my only comfort zone in the code - I'm rather weak with the network part, and pratcically don't know the drawing part, as I have not been using it at all.

@amoerie amoerie mentioned this pull request Dec 15, 2023
5 tasks
@amoerie amoerie marked this pull request as draft December 15, 2023 09:06
@amoerie
Copy link
Collaborator Author

amoerie commented Dec 15, 2023

@mrbean-bremen I've made a separate PR #1700 that sets up the necessary infrastructure to have nullability annotations. That PR does not contain any actual code changes, and can safely be merged.

Then, it should be a lot easier to review this PR.

@mrbean-bremen
Copy link
Collaborator

I will try to review this over the weekend - won't have time before.

@amoerie
Copy link
Collaborator Author

amoerie commented Dec 16, 2023

No rush. This will take time anyway. 😉

@amoerie amoerie marked this pull request as ready for review December 18, 2023 14:44
@gofal
Copy link
Contributor

gofal commented Dec 21, 2023

Hi, another big modification ... fo-dicom should be considered as mature and stable.
Sure, there are still some changes, but things like "hey, lets rework the complete codebase" does not produce joy in the first place. The benefit has to overrule the risks.
I will take a closer look, but if this is just about putting attributes to the methods and properties, then the risk is low. if it means that larger parts of code has to be changed, then I would be very cautious.

Give me some time, to get into the topic and to see, what changes are necessary for this nullable-feature.

@amoerie
Copy link
Collaborator Author

amoerie commented Dec 21, 2023

Hi, another big modification ... fo-dicom should be considered as mature and stable. Sure, there are still some changes, but things like "hey, lets rework the complete codebase" does not produce joy in the first place. The benefit has to overrule the risks. I will take a closer look, but if this is just about putting attributes to the methods and properties, then the risk is low. if it means that larger parts of code has to be changed, then I would be very cautious.

Give me some time, to get into the topic and to see, what changes are necessary for this nullable-feature.

I agree with your assessment @gofal, and I think the risks vs benefits are very okay in this specific instance.

@amoerie
Copy link
Collaborator Author

amoerie commented Mar 12, 2024

@mrbean-bremen @gofal Any chance this could get another review? Thanks in advance :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants