Problems figuring out nullable reference types from SemanticModel #82058
-
|
I'm trying to figure out whether a type in a source code is nullable reference or not, but I constantly get "NotAnnotated" instead. <ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
<PackageReference Include="Basic.Reference.Assemblies.Net100" Version="1.8.4" />
</ItemGroup>and running on Linux targeting .net10.0. I'm sure I'm missing something obvious, or? const string Source = """
string nonNullable = "Hello";
string? nullable = null;
""";
var syntaxTree = CSharpSyntaxTree.ParseText(Source);
var compilation = CSharpCompilation.Create("TestCase")
.AddReferences(Net100.References.All)
.AddSyntaxTrees(syntaxTree)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithNullableContextOptions(NullableContextOptions.Enable));
var diags = compilation.GetDiagnostics();
if (diags.Any(d => d.Severity == DiagnosticSeverity.Error))
{
foreach (var d in diags)
{
Console.WriteLine(CSharpDiagnosticFormatter.Instance.Format(d));
}
}
var sm = compilation.GetSemanticModel(syntaxTree);
var nonNullableVar = syntaxTree.GetRoot().DescendantNodes()
.OfType<VariableDeclarationSyntax>().First();
var nullableVar = syntaxTree.GetRoot().DescendantNodes()
.OfType<VariableDeclarationSyntax>().Skip(1).First();
// Get type info for the variable types.
var nonNullableTypeInfo = sm.GetTypeInfo(nonNullableVar.Type!);
var nullableTypeInfo = sm.GetTypeInfo(nullableVar.Type!);
// Check nullability annotations.
Console.WriteLine(nonNullableTypeInfo.Type!.NullableAnnotation); // Output: NotAnnotated
Console.WriteLine(nullableTypeInfo.Type!.NullableAnnotation); Output: Annotated |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
This comment has been hidden.
This comment has been hidden.
-
|
Here's the issue: you're holding it wrong (sorry). #:package Microsoft.CodeAnalysis.CSharp@5.0.0
#:package Basic.Reference.Assemblies.Net100@1.8.4
using Basic.Reference.Assemblies;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
const string Source = """
string? nullable = "test";
_ = nullable;
""";
var syntaxTree = CSharpSyntaxTree.ParseText(Source);
var compilation = CSharpCompilation.Create("TestCase")
.AddReferences(Net100.References.All)
.AddSyntaxTrees(syntaxTree)
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithNullableContextOptions(NullableContextOptions.Enable));
var diags = compilation.GetDiagnostics();
if (diags.Any(d => d.Severity == DiagnosticSeverity.Error))
{
foreach (var d in diags)
{
Console.WriteLine(CSharpDiagnosticFormatter.Instance.Format(d));
}
}
var sm = compilation.GetSemanticModel(syntaxTree);
var nullableVar = syntaxTree.GetRoot().DescendantNodes()
.OfType<VariableDeclarationSyntax>().Single();
// Get declared symbol for the variable types.
var nullableLocalSymbol = (ILocalSymbol)sm.GetDeclaredSymbol(nullableVar.Variables[0])!;
// Check nullability annotations.
Console.WriteLine(nullableLocalSymbol.NullableAnnotation); // Output: Annotated
// Check flow state at the usage site.
var usage = syntaxTree.GetRoot().DescendantNodes()
.OfType<IdentifierNameSyntax>()
.First(id => id.Identifier.ValueText == "nullable" && id.Parent is not VariableDeclaratorSyntax);
var usageInfo = sm.GetTypeInfo(usage);
Console.WriteLine(usageInfo.Type!.NullableAnnotation); // Output: NotAnnotated |
Beta Was this translation helpful? Give feedback.
Here's the issue: you're holding it wrong (sorry).
GetTypeInfois something you call on an expression, not on a type syntax. What you wanted to do was callGetDeclaredSymbolon the local declaration; that will give the symbol that corresponds to the local, and you can then check the annotation (orType.Annotation, either works) for the declared nullability. As an example: