using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
public static class Extensions{
public static bool IsNotNull(this TypeInfo info)
Console.WriteLine(info.Nullability.FlowState);
if (info.Nullability.FlowState == NullableFlowState.NotNull)
public static bool IsNotNull(this ExpressionSyntax expr, SemanticModel model)
var info = model.GetTypeInfo(expr);
public static void Main()
var code = @"using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
bool ToTemp<T>(T e, [NotNullIfNotNull(""e"")] out T t)
var x = ToTemp(Eval(""A""), out temp) switch
_ when temp is {} xxx => ""Something"",
var tree = SyntaxTree(ParseCompilationUnit(code));
var compOptions = new CSharpCompilationOptions(
outputKind: OutputKind.DynamicallyLinkedLibrary,
nullableContextOptions: NullableContextOptions.Enable
var refApi = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var com = CSharpCompilation.Create("something", new []{ tree }, new []{refApi}, options: compOptions);
var model = com.GetSemanticModel(tree);
var switchExpr =com.SyntaxTrees.First().GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First()
.DescendantNodes().OfType<MethodDeclarationSyntax>().First().Body.Statements.Skip(3).First()
.DescendantNodes().OfType<SwitchExpressionSyntax>().First();
var tempOutVar = switchExpr.GoverningExpression.DescendantNodes().OfType<ArgumentSyntax>().Skip(2).First().Expression;
Console.WriteLine($"eval: {tempOutVar}");
var isNotNull1 = tempOutVar.IsNotNull(model);
var tempVar = switchExpr.Arms.First().DescendantNodes().OfType<IdentifierNameSyntax>().First();
Console.WriteLine($"eval: {tempVar}");
var isNotNull2 = tempVar.IsNotNull(model);