Enable nullable reference types for generated code#37758
Enable nullable reference types for generated code#37758sharwell merged 27 commits intodotnet:masterfrom
Conversation
|
@dotnet/roslyn-compiler the build errors are caused by a conflict with db84d66 that occurred in parallel. That change was arguably a breaking API change (inputs that were previously allowed now throw exceptions, even though the impacted source code is not valid C# code). The easiest way to address the code generation issue is to revert the change. Otherwise, I need to figure out how to make a non-nullable /cc @CyrusNajmabadi |
Could you give an example of an input that was previously allowed that we would want to keep allowing? |
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
|
@dotnet/roslyn-compiler this is ready for review |
src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs
Show resolved
Hide resolved
src/Compilers/CSharp/Portable/Generated/Syntax.xml.Internal.Generated.cs
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/AbstractFileWriter.cs
Outdated
Show resolved
Hide resolved
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
| WriteLine(" var {0} = ({1})this.Visit(node.{2});", CamelCase(field.Name), field.Type, field.Name); | ||
| if (!IsOptional(field) && field.Type != "SyntaxToken") | ||
| { | ||
| WriteLine(" var {0} = ({1})this.Visit(node.{2}) ?? throw new ArgumentNullException(\"{0}\");", CamelCase(field.Name), GetFieldType(field, green: false), field.Name); |
There was a problem hiding this comment.
{1} [](start = 60, length = 3)
This cast ends up coming out as ? often, which is wrong. We should not be trying to cast to a nullable reference type and throwing if it's null.
There was a problem hiding this comment.
What form would you suggest instead?
There was a problem hiding this comment.
The generated cast should not have a ? in it (for reference types, if casting to an NVT of course it needs one).
There was a problem hiding this comment.
So to clarify, you want this?
-(T?)Method() ?? throw ...
+(T)(Method() ?? throw ...)There was a problem hiding this comment.
We should not be trying to cast to a nullable reference type and throwing if it's null.
FWIW, this is exactly what we do today, you just can't see it in the code.
There was a problem hiding this comment.
That's correct. And more accurately, we cast to a regular reference type and throw if it was null.
There was a problem hiding this comment.
➡️ Since this is a cosmetic change only, I'm going to file this as a follow-up issue to clean up the generated code for this case.
src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/SourceWriter.cs
Show resolved
Hide resolved
|
Done review pass (commit 24) |
333fred
left a comment
There was a problem hiding this comment.
LGTM (commit 26). @dotnet/roslyn-compiler for a second review.
|
We need a senior compiler review @dotnet/roslyn-compiler |
| else | ||
| { | ||
| WriteLine(" var {0} = ({1})this.Visit(node.{2});", CamelCase(field.Name), field.Type, field.Name); | ||
| if (!IsOptional(field) && field.Type != "SyntaxToken") |
There was a problem hiding this comment.
field.Type != "SyntaxToken" will always be true since the previous if-check checks for "SyntaxToken" already.
| else | ||
| { | ||
| Write("{0} == null ? null : (Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax.{1}){0}.Green", CamelCase(field.Name), field.Type); | ||
| if (IsAnyList(field.Type) || IsOptional(field)) |
There was a problem hiding this comment.
IsAnyList would already have been covered by the if-checks above, right?
|
@dotnet/roslyn-compiler for a second review please. |
|
I'll look today |
|
Oh, never mind, I see that we have two reviews already. |
|
Awesome! |
Review commit-by-commit is recommended.