public void ExplodedGraph_SwitchExpressionVisit() { const string testInput = @" namespace Namespace { public class SwitchExpression { public int Main(string str) { return str switch { null => 1, """" => 2, _ => 3}; } } }"; var context = new ExplodedGraphContext(TestHelper.Compile(testInput)); var strParameter = context.MainMethod.ParameterList.Parameters.First(); var strSymbol = context.SemanticModel.GetDeclaredSymbol(strParameter); context.ExplodedGraph.InstructionProcessed += (sender, args) => { var instruction = args.Instruction.ToString(); switch (instruction) { case "1": args.ProgramState.GetSymbolValue(strSymbol).Should().NotBe(SymbolicValue.Null); strSymbol.HasConstraint(ObjectConstraint.Null, args.ProgramState).Should().BeTrue(); break; case "2": args.ProgramState.GetSymbolValue(strSymbol).Should().NotBe(SymbolicValue.Null); strSymbol.HasConstraint(ObjectConstraint.NotNull, args.ProgramState).Should().BeTrue(); break; case "3": args.ProgramState.GetSymbolValue(strSymbol).Should().NotBe(SymbolicValue.Null); strSymbol.HasConstraint(ObjectConstraint.NotNull, args.ProgramState).Should().BeTrue(); break; } }; context.WalkWithExitBlocks(7, 3); }
public void ExplodedGraph_CoalesceAssignmentOnProperty() { var context = new ExplodedGraphContext("return options.Property ??= 1"); context.ExplodedGraph.InstructionProcessed += (sender, args) => { var instruction = args.Instruction.ToString(); if (instruction != "options.Property ??= 1") { return; } // The symbolic value corresponding to the expression result should have the NotNull constraint an all branches. args.ProgramState.HasConstraint(args.ProgramState.PeekValue(), ObjectConstraint.NotNull).Should().BeTrue(); }; context.WalkWithExitBlocks(5, 2); }