/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Analyzers/CSharp/Tests/UsePatternMatching/CSharpAsAndNullCheckTests.cs
2 106 строк
56 KB
Deepak Singh Rathore
Suppress IDE0019 when local is later passed to out/ref of nullable parameter (#83883)
26 май 2026, 19:24
Не верифицирован
26 май 2026, 19:24
81787d6
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.UsePatternMatching; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UsePatternMatching; [Trait(Traits.Feature, Traits.Features.CodeActionsInlineTypeCheck)] public sealed partial class CSharpAsAndNullCheckTests(ITestOutputHelper logger) : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor(logger) { internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => (new CSharpAsAndNullCheckDiagnosticAnalyzer(), new CSharpAsAndNullCheckCodeFixProvider()); [Theory] [InlineData("x != null", "o is string x")] [InlineData("null != x", "o is string x")] [InlineData("(object)x != null", "o is string x")] [InlineData("null != (object)x", "o is string x")] [InlineData("x is object", "o is string x")] [InlineData("x == null", "!(o is string x)")] [InlineData("null == x", "!(o is string x)")] [InlineData("(object)x == null", "!(o is string x)")] [InlineData("null == (object)x", "!(o is string x)")] [InlineData("x is null", "!(o is string x)")] [InlineData("(x = o as string) != null", "o is string x")] [InlineData("null != (x = o as string)", "o is string x")] [InlineData("(x = o as string) is object", "o is string x")] [InlineData("(x = o as string) == null", "!(o is string x)")] [InlineData("null == (x = o as string)", "!(o is string x)")] [InlineData("(x = o as string) is null", "!(o is string x)")] [InlineData("x == null", "o is not string x", LanguageVersion.CSharp9)] public async Task InlineTypeCheck1(string input, string output, LanguageVersion version = LanguageVersion.CSharp8) { await TestStatement($"if ({input}) {{ }}", $"if ({output}) {{ }}", version); await TestStatement($"var y = {input};", $"var y = {output};", version); await TestStatement($"return {input};", $"return {output};", version); } [Theory] [InlineData("(x = o as string) != null", "o is string x")] [InlineData("null != (x = o as string)", "o is string x")] [InlineData("(x = o as string) is object", "o is string x")] [InlineData("(x = o as string) == null", "!(o is string x)")] [InlineData("null == (x = o as string)", "!(o is string x)")] public async Task InlineTypeCheck2(string input, string output) => await TestStatement($"while ({input}) {{ }}", $"while ({output}) {{ }}"); private Task TestStatement(string input, string output, LanguageVersion version = LanguageVersion.CSharp8) => TestInRegularAndScriptAsync( $$""" class C { void M(object o) { [|var|] x = o as string; {{input}} } } """, $$""" class C { void M(object o) { {{output}} } } """, new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(version))); [Fact] public Task TestMissingInCSharp6() => TestMissingAsync( """ class C { void M() { [|var|] x = o as string; if (x != null) { } } } """, new TestParameters(parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6))); [Fact] public Task TestMissingInWrongName() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|var|] y = o as string; if (x != null) { } } } """); [Fact] public Task TestInSwitchSection() => TestInRegularAndScriptAsync( """ class C { void M() { switch (o) { default: [|var|] x = o as string; if (x != null) { } } } } """, """ class C { void M() { switch (o) { default: if (o is string x) { } } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] public Task TestRemoveNewLinesInSwitchStatement() => TestInRegularAndScriptAsync( """ class C { void M() { switch (o) { default: [|var|] x = o as string; //a comment if (x != null) { } } } } """, """ class C { void M() { switch (o) { default: //a comment if (o is string x) { } } } } """); [Fact] public Task TestMissingOnNonDeclaration() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|y|] = o as string; if (x != null) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25237")] public Task TestMissingOnReturnStatement() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|return;|] } } """); [Fact] public Task TestMissingOnIsExpression() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o is string; if (x != null) { } } } """); [Fact] public Task InlineTypeCheckComplexExpression1() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = (o ? z : w) as string; if (x != null) { } } } """, """ class C { void M() { if ((o ? z : w) is string x) { } } } """); [Fact] public Task TestInlineTypeCheckWithElse() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (null != x) { } else { } } } """, """ class C { void M() { if (o is string x) { } else { } } } """); [Fact] public Task TestComments1() => TestInRegularAndScriptAsync( """ class C { void M() { // prefix comment [|var|] x = o as string; if (x != null) { } } } """, """ class C { void M() { // prefix comment if (o is string x) { } } } """); [Fact] public Task TestComments2() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; // suffix comment if (x != null) { } } } """, """ class C { void M() { // suffix comment if (o is string x) { } } } """); [Fact] public Task TestComments3() => TestInRegularAndScriptAsync( """ class C { void M() { // prefix comment [|var|] x = o as string; // suffix comment if (x != null) { } } } """, """ class C { void M() { // prefix comment // suffix comment if (o is string x) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] public Task TestRemoveNewLines() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; //suffix comment if (x != null) { } } } """, """ class C { void M() { //suffix comment if (o is string x) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] public Task TestRemoveNewLinesWhereBlankLineIsNotEmpty() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; //suffix comment if (x != null) { } } } """, """ class C { void M() { //suffix comment if (o is string x) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/33345")] public Task TestRemoveNewLines2() => TestInRegularAndScriptAsync( """ class C { void M() { int a = 0; [|var|] x = o as string; //suffix comment if (x != null) { } } } """, """ class C { void M() { int a = 0; //suffix comment if (o is string x) { } } } """); [Fact] public Task InlineTypeCheckComplexCondition1() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (x != null ? 0 : 1) { } } } """, """ class C { void M() { if (o is string x ? 0 : 1) { } } } """); [Fact] public Task InlineTypeCheckComplexCondition2() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if ((x != null)) { } } } """, """ class C { void M() { if ((o is string x)) { } } } """); [Fact] public Task InlineTypeCheckComplexCondition3() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (x != null && x.Length > 0) { } } } """, """ class C { void M() { if (o is string x && x.Length > 0) { } } } """); [Fact] public Task TestDefiniteAssignment1() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (x != null && x.Length > 0) { } else if (x != null) { } } } """); [Fact] public Task TestDefiniteAssignment2() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (x != null && x.Length > 0) { } Console.WriteLine(x); } } """); [Fact] public Task TestDefiniteAssignment3() => TestInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (x != null && x.Length > 0) { } x = null; Console.WriteLine(x); } } """, """ class C { void M() { if (o is string x && x.Length > 0) { } x = null; Console.WriteLine(x); } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21097")] public Task TestDefiniteAssignment4() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|var|] s = o as string; if (s != null) { } else { if (o is int?) s = null; s.ToString(); } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24286")] public Task TestDefiniteAssignment5() => TestMissingInRegularAndScriptAsync( """ public class Test { public void TestIt(object o1, object o2) { [|var|] test = o1 as Test; if (test != null || o2 != null) { var o3 = test ?? o2; } } } """); [Fact] public Task TestDefiniteAssignment6() => TestMissingInRegularAndScriptAsync( """ class C { string Use(string x) => x; void M() { [|var|] x = o as string; if (x != null && x.Length > 0) { } Console.WriteLine(x = Use(x)); } } """); [Fact] public Task TestDefiniteAssignment7() => TestMissingInRegularAndScriptAsync( """ class C { void M() { [|var|] x = o as string; if (x != null && x.Length > 0) { } Console.WriteLine(x); x = "writeAfter"; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28821")] public Task TestDefiniteAssignment8() => TestMissingInRegularAndScriptAsync( """ class Program { static void Goo(System.Activator bar) { } static void Main(string[] args) { var a = new object(); [|var|] b = a as System.Activator; if ((b == null) && false) { } else { Goo(b); } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/28866")] public Task TestWrittenExpressionBeforeNullCheck() => TestMissingInRegularAndScriptAsync( """ class Goo { object Data { get; set; } void DoGoo() { [|var|] oldData = this.Data as string; Data = null; if (oldData != null) { // Do something } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/15957")] public Task TestTrivia1() => TestInRegularAndScriptAsync( """ class C { void M(object y) { if (y != null) { } [|var|] x = o as string; if (x != null) { } } } """, """ class C { void M(object y) { if (y != null) { } if (o is string x) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17129")] public Task TestTrivia2() => TestInRegularAndScriptAsync( """ using System; namespace N { class Program { public static void Main() { object o = null; int i = 0; [|var|] s = o as string; if (s != null && i == 0 && i == 1 && i == 2 && i == 3 && i == 4 && i == 5) { Console.WriteLine(); } } } } """, """ using System; namespace N { class Program { public static void Main() { object o = null; int i = 0; if (o is string s && i == 0 && i == 1 && i == 2 && i == 3 && i == 4 && i == 5) { Console.WriteLine(); } } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/17122")] public Task TestMissingOnNullableType() => TestMissingInRegularAndScriptAsync( """ using System; namespace N { class Program { public static void Main() { object o = null; [|var|] i = o as int?; if (i != null) Console.WriteLine(i); } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/18053")] public Task TestMissingWhenTypesDoNotMatch() => TestMissingInRegularAndScriptAsync( """ class SyntaxNode { public SyntaxNode Parent; } class BaseParameterListSyntax : SyntaxNode { } class ParameterSyntax : SyntaxNode { } public static class C { static void M(ParameterSyntax parameter) { [|SyntaxNode|] parent = parameter.Parent as BaseParameterListSyntax; if (parent != null) { parent = parent.Parent; } } } """); [Fact] public Task TestMissingOnWhileNoInline() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|string|] x = o as string; while (x != null) { } } } """); [Fact] public Task TestWhileDefiniteAssignment1() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|string|] x; while ((x = o as string) != null) { } var readAfterWhile = x; } } """); [Fact] public Task TestWhileDefiniteAssignment2() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|string|] x; while ((x = o as string) != null) { } x = "writeAfterWhile"; } } """); [Fact] public Task TestWhileDefiniteAssignment3() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|string|] x; x = "writeBeforeWhile"; while ((x = o as string) != null) { } } } """); [Fact] public Task TestWhileDefiniteAssignment4() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|string|] x = null; var readBeforeWhile = x; while ((x = o as string) != null) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23504")] public Task DoNotChangeOriginalFormatting1() => TestInRegularAndScriptAsync( """ class Program { static void Main(string[] args) { object obj = "test"; [|var|] str = obj as string; var title = str != null ? str : "; } } """, """ class Program { static void Main(string[] args) { object obj = "test"; var title = obj is string str ? str : "; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23504")] public Task DoNotChangeOriginalFormatting2() => TestInRegularAndScriptAsync( """ class Program { static void Main(string[] args) { object obj = "test"; [|var|] str = obj as string; var title = str != null ? str : "; } } """, """ class Program { static void Main(string[] args) { object obj = "test"; var title = obj is string str ? str : "; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21172")] public Task TestMissingWithDynamic() => TestMissingAsync( """ class C { void M(object o) { [|var|] x = o as dynamic; if (x != null) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/21551")] public Task TestOverloadedUserOperator() => TestMissingAsync( """ class C { public static void Main() { object o = new C(); [|var|] c = o as C; if (c != null) System.Console.WriteLine(); } public static bool operator ==(C c1, C c2) => false; public static bool operator !=(C c1, C c2) => false; } """); [Fact] public Task TestNegativeDefiniteAssignment1() => TestInRegularAndScriptAsync( """ class C { string M(object o) { [|var|] x = o as string; if (x == null) return null; return x; } } """, """ class C { string M(object o) { if (!(o is string x)) return null; return x; } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestNegativeDefiniteAssignment2() => TestInRegularAndScriptAsync( """ class C { string M(object o, bool b) { [|var|] x = o as string; if (((object)x == null) || b) { return null; } else { return x; } } } """, """ class C { string M(object o, bool b) { if ((!(o is string x)) || b) { return null; } else { return x; } } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25993")] public Task TestEmbeddedStatement1() => TestInRegularAndScriptAsync( """ class C { void M(object e) { var fe = e as C; [|var|] ae = e as C; if (fe != null) { M(fe); // fe is used } else if (ae != null) { M(ae); // ae is used } } } """, """ class C { void M(object e) { var fe = e as C; if (fe != null) { M(fe); // fe is used } else if (e is C ae) { M(ae); // ae is used } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25993")] public Task TestEmbeddedStatement2() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { var fe = e as C; [|var|] ae = e as C; if (fe != null) { M(ae); // ae is used } else if (ae != null) { M(ae); // ae is used } } } """); [Fact] public Task TestUseBeforeDeclaration() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; { { var x1 = c; if (c != null) { } } } } } """); [Fact] public Task TestPossiblyUnassigned() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; { { if (c != null) { } var x2 = c; } // out of scope var x3 = c; } } } """); [Fact] public Task TestOutOfScope() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; { { if (c != null) { } } // out of scope var x3 = c; } } } """); [Fact] public Task TestDeclarationOnOuterBlock() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; { { if (c != null) { } } } } } """, """ class C { void M(object e) { { { if (e is C c) { } } } } } """); [Fact] public Task TestConditionalExpression() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; M(c != null ? c : null); } } """, """ class C { void M(object e) { M(e is C c ? c : null); } } """); [Fact] public Task TestConditionalExpression_OppositeBranch() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; M(c != null ? c : null, c); } } """); [Fact] public Task TestForStatement_NoInlineTypeCheck() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|var|] c = e as C; for (;(c)!=null;) {} } } """); [Fact] public Task TestForStatement_InlineTypeCheck() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [|C|] c; for (; !((c = e as C)==null);) { } } } """, """ class C { void M(object e) { for (; !(!(e is C c));) { } } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestForStatement_InScope() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [|C|] c = null; for (; !((c = e as C)==null);) { M(c); } } } """, """ class C { void M(object e) { for (; !(!(e is C c));) { M(c); } } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestForStatement_NotAssignedBeforeAccess() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|C|] c = null; for (; ((c = e as C)==null);) { if (b) c = null; M(c); } } } """); [Fact] public Task TestForStatement_AssignedBeforeAccess() => TestInRegularAndScriptAsync( """ class C { void M(object e, bool b) { [|C|] c = null; for (; (c = e as C)==null;) { if (b) c = null; else c = null; M(c); } } } """, """ class C { void M(object e, bool b) { for (; !(e is C c);) { if (b) c = null; else c = null; M(c); } } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestForStatement_MultipleDeclarators() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [|C|] c = null, x = null; for (; !((c = e as C)==null);) { M(c); } } } """, """ class C { void M(object e) { C x = null; for (; !(!(e is C c));) { M(c); } } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestForStatement_UseBeforeDeclaration() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|C|] c = null, x = c; for (; !((c = e as C)==null);) { M(c); } } } """); [Fact] public Task TestForStatement_Initializer() => TestMissingInRegularAndScriptAsync( """ class C { void M(object e) { [|C|] c; for (var i = !((c = e as C)==null); i != null; ) { M(c); } } } """); [Fact] public Task TestLocalFunction() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [||]var c = e as C; C F() => c == null ? null : c; } } """, """ class C { void M(object e) { C F() => !(e is C c) ? null : c; } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestLocalFunction_UseOutOfScope() => TestMissingInRegularAndScriptAsync( """ class C { C M(object e) { [||]var c = e as C; C F() => c == null ? null : c; return c; } } """); [Fact] public Task TestExpressionLambda() => TestInRegularAndScriptAsync( """ class C { void M(object e) { [||]var c = e as C; System.Func<C> f = () => c == null ? null : c; } } """, """ class C { void M(object e) { System.Func<C> f = () => !(e is C c) ? null : c; } } """, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8))); [Fact] public Task TestExpressionLambda_UseOutOfScope() => TestMissingInRegularAndScriptAsync( """ class C { C M(object e) { [||]var c = e as C; System.Func<C> f = () => c == null ? null : c; return c; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31388")] public Task TestUseBetweenAssignmentAndIfCondition() => TestMissingInRegularAndScriptAsync( """ class C { void M(object o) { [|var|] c = o as C; M2(c != null); if (c == null) { return; } } void M2(bool b) { } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40007")] public Task TestSpaceAfterGenericType() => TestInRegularAndScriptAsync( """ #nullable enable using System.Collections.Generic; class Program { static void Goo<TKey, TValue>(object items) { [|var|] itemsAsDictionary = items as IDictionary<TKey, TValue>; SortedDictionary<TKey, TValue>? dictionary = null; if (itemsAsDictionary != null) { dictionary = new SortedDictionary<TKey, TValue>(); } return dictionary; } } """, """ #nullable enable using System.Collections.Generic; class Program { static void Goo<TKey, TValue>(object items) { SortedDictionary<TKey, TValue>? dictionary = null; if (items is IDictionary<TKey, TValue> itemsAsDictionary) { dictionary = new SortedDictionary<TKey, TValue>(); } return dictionary; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45596")] public Task TestMissingInUsingDeclaration() => TestMissingInRegularAndScriptAsync( """ class C { void M() { using [|var|] x = o as IDisposable; if (x != null) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/45596")] public Task TestMissingInUsingStatement() => TestMissingInRegularAndScriptAsync( """ class C { void M() { using ([|var|] x = o as IDisposable) { if (x != null) { } } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37398")] public Task TestPrecedingDirectiveTrivia() => TestInRegularAndScriptAsync( """ class C { public static void M(object o) { #if DEBUG Console.WriteLine("in debug"); #endif [|string|] s = o as string; if (s != null) { } } } """, """ class C { public static void M(object o) { #if DEBUG Console.WriteLine("in debug"); #endif if (o is string s) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/40006")] public Task TestArrayOfNullables() => TestInRegularAndScriptAsync( """ #nullable enable class Program { static void Set(object obj, object? item) { [|object?[]?|] arr = obj as object[]; if (arr != null) { arr[0] = item; } } } """, """ #nullable enable class Program { static void Set(object obj, object? item) { if (obj is object?[] arr) { arr[0] = item; } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55782")] public Task TestLocalReferencedAcrossScopes1() => TestMissingInRegularAndScriptAsync(""" using System.Transactions; class BaseObject { } class ObjectFactory { internal static BaseObject CreateObject(int x) { throw new NotImplementedException(); } } struct Repro { static int Main(string[] args) { int x = 0; [|BaseObject|] obj; var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) { try { if ((obj = ObjectFactory.CreateObject(x) as BaseObject) == null) { return -1; } // uses of obj in the transaction } catch (TransactionAbortedException) { return -1; } } // local used here. Console.WriteLine(obj); return 0; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55782")] public Task TestLocalReferencedAcrossScopes2() => TestInRegularAndScriptAsync(""" using System.Transactions; class BaseObject { } class ObjectFactory { internal static BaseObject CreateObject(int x) { throw new NotImplementedException(); } } struct Repro { static int Main(string[] args) { int x = 0; [|BaseObject|] obj; var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) { try { if ((obj = ObjectFactory.CreateObject(x) as BaseObject) == null) { return -1; } // uses of obj in the transaction } catch (TransactionAbortedException) { return -1; } } // not used return 0; } } """, """ using System.Transactions; class BaseObject { } class ObjectFactory { internal static BaseObject CreateObject(int x) { throw new NotImplementedException(); } } struct Repro { static int Main(string[] args) { int x = 0; var tso = new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }; using (var trans = new TransactionScope(TransactionScopeOption.Required, tso)) { try { if (ObjectFactory.CreateObject(x) is not BaseObject obj) { return -1; } // uses of obj in the transaction } catch (TransactionAbortedException) { return -1; } } // not used return 0; } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] public Task TestNullableWhenWrittenTo1() => TestInRegularAndScriptAsync(""" #nullable enable using System; class Program { static void Goo(object o1, object o2) { [|string?|] s = o1 as string; if (s == null) { } } } """, """ #nullable enable using System; class Program { static void Goo(object o1, object o2) { if (o1 is not string s) { } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] public Task TestNullableWhenWrittenTo2() => TestInRegularAndScriptAsync(""" #nullable enable using System; class Program { static void Goo(object o1, object o2) { [|string?|] s = o1 as string; if (s == null) { s = ""; } } } """, """ #nullable enable using System; class Program { static void Goo(object o1, object o2) { if (o1 is not string s) { s = ""; } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] public Task TestNullableWhenWrittenTo3() => TestMissingInRegularAndScriptAsync(""" #nullable enable using System; class Program { static void Goo(object o1, object o2) { [|string?|] s = o1 as string; if (s == null) { s = o2 as string; } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/37875")] public Task TestNullableWhenWrittenTo4() => TestMissingInRegularAndScriptAsync(""" #nullable enable using System; class Program { static void Goo(object o1, object o2) { [|string?|] s = o1 as string; if (s == null) { s = null; } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/83882")] public Task TestNullableWhenWrittenToViaOutWithNullableParam() => TestMissingInRegularAndScriptAsync(""" #nullable enable class Program { static void Goo(object o1) { [|string?|] s = o1 as string; if (s == null) { Bar(out s); } } static void Bar(out string? value) => value = null; } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/83882")] public Task TestNullableWhenWrittenToViaOutWithNonNullableParam() => TestInRegularAndScriptAsync(""" #nullable enable class Program { static void Goo(object o1) { [|string?|] s = o1 as string; if (s == null) { Bar(out s); } } static void Bar(out string value) => value = ""; } """, """ #nullable enable class Program { static void Goo(object o1) { if (o1 is not string s) { Bar(out s); } } static void Bar(out string value) => value = ""; } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/83882")] public Task TestNullableWhenWrittenToViaRefWithNullableParam() => TestMissingInRegularAndScriptAsync(""" #nullable enable class Program { static void Goo(object o1) { [|string?|] s = o1 as string; if (s == null) { Bar(ref s); } } static void Bar(ref string? value) { } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/83882")] public Task TestNullableWhenWrittenToViaGenericOutNullableParam() => TestMissingInRegularAndScriptAsync(""" #nullable enable interface IRepository { void GetAsset<T>(int id, out T? asset) where T : class; } class ReferenceLibrary { } class Program { static void Goo(IRepository repository, object child, int id) { [|ReferenceLibrary?|] library = child as ReferenceLibrary; if (library == null) { repository.GetAsset<ReferenceLibrary>(id, out library); } } } """); [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39600")] public Task TestNotWithInterveningMutation() => TestMissingInRegularAndScriptAsync(""" using System; class Program { void Goo(object[] values, int index) { [|var|] v1 = values[index++] as string; index++; if (v1 != null) { Console.WriteLine(v1); } } } """); }