提交 ce20f709 编写于 作者: C Cyrus Najmabadi

Add tests

上级 2ef034d5
......@@ -12,6 +12,7 @@
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
using Roslyn.Test.Utilities;
#if CODE_STYLE
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
......@@ -61,6 +62,66 @@ void M(int i)
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnSimpleAssignment_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(int i)
{
[||]if (true)
{
throw new System.Exception();
}
else
{
i = 1;
}
}
}",
@"
class C
{
void M(int i)
{
i = true ? throw new System.Exception() : 1;
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnSimpleAssignment_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(int i)
{
[||]if (true)
{
i = 0;
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M(int i)
{
i = true ? 0 : throw new System.Exception();
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnSimpleAssignmentNoBlocks()
{
......@@ -163,6 +224,36 @@ void M()
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnAssignmentToUndefinedField_Throw()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
[||]if (true)
{
this.i = 0;
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M()
{
this.i = true ? 0 : throw new System.Exception();
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnNonUniformTargetSyntax()
{
......@@ -255,6 +346,68 @@ void M()
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnAssignmentToAboveLocalNoInitializer_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
int i;
[||]if (true)
{
i = 0;
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M()
{
int i = true ? 0 : throw new System.Exception();
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnAssignmentToAboveLocalNoInitializer_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
int i;
[||]if (true)
{
throw new System.Exception();
}
else
{
i = 1;
}
}
}",
@"
class C
{
void M()
{
int i = true ? throw new System.Exception() : 1;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestOnAssignmentToAboveLocalLiteralInitializer()
{
......@@ -597,6 +750,26 @@ void M(int i)
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestMissingWithoutElseWithThrowStatementAfterwards()
{
await TestMissingInRegularAndScriptAsync(
@"
class C
{
void M(int i)
{
[||]if (true)
{
i = 0;
}
throw new System.Exception();
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame()
{
......@@ -629,6 +802,67 @@ void M()
}", options: s_preferImplicitTypeAlways);
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
object o;
[||]if (true)
{
throw new System.Exception();
}
else
{
o = ""b"";
}
}
}",
@"
class C
{
void M()
{
object o = true ? throw new System.Exception() : ""b"";
}
}", options: s_preferImplicitTypeAlways);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CastInsertedToKeepTypeSame_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
object o;
[||]if (true)
{
o = ""a"";
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M()
{
object o = true ? ""a"" : throw new System.Exception();
}
}", options: s_preferImplicitTypeAlways);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches()
{
......@@ -659,6 +893,68 @@ void M()
}", options: s_preferImplicitTypeAlways);
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
string s;
[||]if (true)
{
throw new System.Exception();
}
else
{
s = null;
}
}
}",
@"
class C
{
void M()
{
string s = true ? throw new System.Exception() : (string)null;
}
}", options: s_preferImplicitTypeAlways);
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CanUseVarBecauseConditionalTypeMatches_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M()
{
string s;
[||]if (true)
{
s = ""a"";
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M()
{
string s = true ? ""a"" : throw new System.Exception();
}
}", options: s_preferImplicitTypeAlways);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestConversionWithUseVarForAll_CanUseVarButRequiresCastOfConditionalBranch()
{
......@@ -900,6 +1196,84 @@ void M(int i)
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestElseIfWithBlock_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(int i)
{
if (true)
{
}
else [||]if (false)
{
throw new System.Exception();
}
else
{
i = 0;
}
}
}",
@"
class C
{
void M(int i)
{
if (true)
{
}
else
{
i = false ? throw new System.Exception() : 0;
}
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestElseIfWithBlock_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(int i)
{
if (true)
{
}
else [||]if (false)
{
i = 1;
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M(int i)
{
if (true)
{
}
else
{
i = false ? 1 : throw new System.Exception();
}
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestElseIfWithoutBlock()
{
......@@ -956,6 +1330,52 @@ void M(ref int i, ref int j)
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestRefAssignment1_Throw1()
{
await TestMissingAsync(
@"
class C
{
void M(ref int i, ref int j)
{
ref int x = ref i;
[||]if (true)
{
throw new System.Exception();
}
else
{
x = ref j;
}
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestRefAssignment1_Throw2()
{
await TestMissingAsync(
@"
class C
{
void M(ref int i, ref int j)
{
ref int x = ref i;
[||]if (true)
{
x = ref i;
}
else
{
throw new System.Exception();
}
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestTrueFalse1()
{
......@@ -985,6 +1405,66 @@ void M(bool i, int j)
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestTrueFalse_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(bool i, int j)
{
[||]if (j == 0)
{
i = true;
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M(bool i, int j)
{
i = j == 0 ? true : throw new System.Exception();
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestTrueFalse_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(bool i, int j)
{
[||]if (j == 0)
{
throw new System.Exception();
}
else
{
i = false;
}
}
}",
@"
class C
{
void M(bool i, int j)
{
i = j == 0 ? throw new System.Exception() : false;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestTrueFalse2()
{
......@@ -1011,6 +1491,66 @@ void M(bool i, int j)
{
i = j != 0;
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestFalseTrue_Throw1()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(bool i, int j)
{
[||]if (j == 0)
{
throw new System.Exception();
}
else
{
i = true;
}
}
}",
@"
class C
{
void M(bool i, int j)
{
i = j == 0 ? throw new System.Exception() : true;
}
}");
}
[WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)]
public async Task TestFalseTrue_Throw2()
{
await TestInRegularAndScriptAsync(
@"
class C
{
void M(bool i, int j)
{
[||]if (j == 0)
{
i = false;
}
else
{
throw new System.Exception();
}
}
}",
@"
class C
{
void M(bool i, int j)
{
i = j == 0 ? false : throw new System.Exception();
}
}");
}
}
......
......@@ -23,6 +23,6 @@ internal abstract class AbstractUseConditionalExpressionForAssignmentDiagnosticA
protected override bool TryMatchPattern(IConditionalOperation ifOperation)
=> UseConditionalExpressionForAssignmentHelpers.TryMatchPattern(
GetSyntaxFacts(), ifOperation, out _, out _);
GetSyntaxFacts(), ifOperation, out _, out _, out _, out _);
}
}
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Operations;
......@@ -12,11 +14,15 @@ internal static class UseConditionalExpressionForAssignmentHelpers
public static bool TryMatchPattern(
ISyntaxFacts syntaxFacts,
IConditionalOperation ifOperation,
out ISimpleAssignmentOperation trueAssignment,
out ISimpleAssignmentOperation falseAssignment)
out ISimpleAssignmentOperation? trueAssignment,
out IThrowOperation? trueThrow,
out ISimpleAssignmentOperation? falseAssignment,
out IThrowOperation? falseThrow)
{
trueAssignment = null;
trueThrow = null;
falseAssignment = null;
falseThrow = null;
var trueStatement = ifOperation.WhenTrue;
var falseStatement = ifOperation.WhenFalse;
......@@ -24,38 +30,67 @@ internal static class UseConditionalExpressionForAssignmentHelpers
trueStatement = UseConditionalExpressionHelpers.UnwrapSingleStatementBlock(trueStatement);
falseStatement = UseConditionalExpressionHelpers.UnwrapSingleStatementBlock(falseStatement);
if (!TryGetAssignment(trueStatement, out trueAssignment) ||
!TryGetAssignment(falseStatement, out falseAssignment))
if (!TryGetAssignmentOrThrow(trueStatement, out trueAssignment, out trueThrow) ||
!TryGetAssignmentOrThrow(falseStatement, out falseAssignment, out falseThrow))
{
return false;
}
// Can't convert to `x ? throw ... : throw ...` as there's no best common type between the two (even when
// throwing the same exception type).
if (trueThrow != null && falseThrow != null)
return false;
if (trueThrow != null || falseThrow != null)
{
if (!syntaxFacts.SupportsThrowExpression(ifOperation.Syntax.SyntaxTree.Options))
return false;
}
// `ref` can't be used with `throw`.
var isRef = trueAssignment?.IsRef == true || falseAssignment?.IsRef == true;
if (isRef && (trueThrow != null || falseThrow != null))
return false;
// The left side of both assignment statements has to be syntactically identical (modulo
// trivia differences).
if (!syntaxFacts.AreEquivalent(trueAssignment.Target.Syntax, falseAssignment.Target.Syntax))
if (trueAssignment != null && falseAssignment != null &&
!syntaxFacts.AreEquivalent(trueAssignment.Target.Syntax, falseAssignment.Target.Syntax))
{
return false;
}
return UseConditionalExpressionHelpers.CanConvert(
syntaxFacts, ifOperation, trueAssignment, falseAssignment);
syntaxFacts, ifOperation,
(IOperation?)trueAssignment ?? trueThrow,
(IOperation?)falseAssignment ?? falseThrow);
}
private static bool TryGetAssignment(
IOperation statement, out ISimpleAssignmentOperation assignment)
private static bool TryGetAssignmentOrThrow(
IOperation statement,
out ISimpleAssignmentOperation? assignment,
out IThrowOperation? throwOperation)
{
assignment = null;
throwOperation = null;
if (statement is IThrowOperation throwOp)
{
throwOperation = throwOp;
return true;
}
// Both the WhenTrue and WhenFalse statements must be of the form:
// target = value;
if (!(statement is IExpressionStatementOperation exprStatement) ||
!(exprStatement.Operation is ISimpleAssignmentOperation assignmentOp) ||
assignmentOp.Target == null)
if (statement is IExpressionStatementOperation exprStatement &&
exprStatement.Operation is ISimpleAssignmentOperation assignmentOp &&
assignmentOp.Target != null)
{
assignment = null;
return false;
assignment = assignmentOp;
return true;
}
assignment = assignmentOp;
return true;
return false;
}
}
}
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
......@@ -17,6 +19,7 @@
using Roslyn.Utilities;
using static Microsoft.CodeAnalysis.UseConditionalExpression.UseConditionalExpressionHelpers;
using static Microsoft.CodeAnalysis.UseConditionalExpression.UseConditionalExpressionCodeFixHelpers;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.CodeAnalysis.UseConditionalExpression
{
......@@ -58,48 +61,57 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
Document document, Diagnostic diagnostic,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
var ifStatement = diagnostic.AdditionalLocations[0].FindNode(cancellationToken);
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var ifOperation = (IConditionalOperation)semanticModel.GetOperation(ifStatement);
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var ifOperation = (IConditionalOperation)semanticModel.GetOperation(ifStatement)!;
if (!UseConditionalExpressionForAssignmentHelpers.TryMatchPattern(
syntaxFacts, ifOperation,
out var trueAssignment, out var falseAssignment))
out var trueAssignment, out var trueThrow,
out var falseAssignment, out var falseThrow))
{
return;
}
var trueSatement = ((IOperation?)trueAssignment ?? trueThrow)!;
var falseStatement = ((IOperation?)falseAssignment ?? falseThrow)!;
var conditionalExpression = await CreateConditionalExpressionAsync(
document, ifOperation, trueAssignment.Parent, falseAssignment.Parent,
trueAssignment.Value, falseAssignment.Value,
trueAssignment.IsRef, cancellationToken).ConfigureAwait(false);
document, ifOperation,
trueSatement, falseStatement,
trueAssignment?.Value ?? trueThrow?.Exception,
falseAssignment?.Value ?? falseThrow?.Exception,
trueAssignment?.IsRef == true, cancellationToken).ConfigureAwait(false);
// See if we're assigning to a variable declared directly above the if statement. If so,
// try to inline the conditional directly into the initializer for that variable.
if (!TryConvertWhenAssignmentToLocalDeclaredImmediateAbove(
if (TryConvertWhenAssignmentToLocalDeclaredImmediateAbove(
syntaxFacts, editor, ifOperation,
trueAssignment, falseAssignment, conditionalExpression))
{
// If not, just replace the if-statement with a single assignment of the new
// conditional.
ConvertOnlyIfToConditionalExpression(
editor, ifOperation, trueAssignment, conditionalExpression);
return;
}
// If not, just replace the if-statement with a single assignment of the new
// conditional.
ConvertOnlyIfToConditionalExpression(
editor, ifOperation, (trueAssignment ?? falseAssignment)!, conditionalExpression);
}
private void ConvertOnlyIfToConditionalExpression(
SyntaxEditor editor,
IConditionalOperation ifOperation,
ISimpleAssignmentOperation trueAssignment,
ISimpleAssignmentOperation assignment,
TExpressionSyntax conditionalExpression)
{
var generator = editor.Generator;
var ifStatement = (TIfStatementSyntax)ifOperation.Syntax;
var expressionStatement = (TStatementSyntax)generator.ExpressionStatement(
generator.AssignmentStatement(
trueAssignment.Target.Syntax,
assignment.Target.Syntax,
conditionalExpression)).WithTriviaFrom(ifStatement);
editor.ReplaceNode(
......@@ -109,7 +121,8 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
private bool TryConvertWhenAssignmentToLocalDeclaredImmediateAbove(
ISyntaxFactsService syntaxFacts, SyntaxEditor editor, IConditionalOperation ifOperation,
ISimpleAssignmentOperation trueAssignment, ISimpleAssignmentOperation falseAssignment,
ISimpleAssignmentOperation? trueAssignment,
ISimpleAssignmentOperation? falseAssignment,
TExpressionSyntax conditionalExpression)
{
if (!TryFindMatchingLocalDeclarationImmediatelyAbove(
......@@ -139,20 +152,40 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
}
private bool TryFindMatchingLocalDeclarationImmediatelyAbove(
IConditionalOperation ifOperation, ISimpleAssignmentOperation trueAssignment, ISimpleAssignmentOperation falseAssignment,
out IVariableDeclarationGroupOperation localDeclaration, out IVariableDeclaratorOperation declarator)
IConditionalOperation ifOperation,
ISimpleAssignmentOperation? trueAssignment,
ISimpleAssignmentOperation? falseAssignment,
[NotNullWhen(true)] out IVariableDeclarationGroupOperation? localDeclaration,
[NotNullWhen(true)] out IVariableDeclaratorOperation? declarator)
{
localDeclaration = null;
declarator = null;
// See if both assignments are to the same local.
if (!(trueAssignment.Target is ILocalReferenceOperation trueLocal) ||
!(falseAssignment.Target is ILocalReferenceOperation falseLocal) ||
!Equals(trueLocal.Local, falseLocal.Local))
ILocalSymbol? local = null;
if (trueAssignment != null)
{
return false;
if (!(trueAssignment.Target is ILocalReferenceOperation trueLocal))
return false;
local = trueLocal.Local;
}
if (falseAssignment != null)
{
if (!(falseAssignment.Target is ILocalReferenceOperation falseLocal))
return false;
// See if both assignments are to the same local.
if (local != null && !Equals(local, falseLocal.Local))
return false;
local = falseLocal.Local;
}
// We weren't assigning to a local.
if (local == null)
return false;
// If so, see if that local was declared immediately above the if-statement.
if (!(ifOperation.Parent is IBlockOperation parentBlock))
{
......@@ -190,7 +223,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
declarator = declarators[0];
var variable = declarator.Symbol;
if (!Equals(variable, trueLocal.Local))
if (!Equals(variable, local))
{
// wasn't a declaration of the local we're assigning to.
return false;
......
......@@ -52,8 +52,8 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
var ifStatement = (TIfStatementSyntax)diagnostic.AdditionalLocations[0].FindNode(cancellationToken);
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var ifOperation = (IConditionalOperation)semanticModel.GetOperation(ifStatement);
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var ifOperation = (IConditionalOperation)semanticModel.GetOperation(ifStatement)!;
if (!UseConditionalExpressionForReturnHelpers.TryMatchPattern(
syntaxFacts, ifOperation,
......@@ -66,13 +66,17 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
var trueSatement = ((IOperation?)trueReturn ?? trueThrow)!;
var falseStatement = ((IOperation?)falseReturn ?? falseThrow)!;
// `ref` can't be used with `throw`.
var isRef = IsRef(trueReturn ?? falseReturn);
if (isRef && (trueThrow != null || falseThrow != null))
return;
var conditionalExpression = await CreateConditionalExpressionAsync(
document, ifOperation,
trueSatement,
falseStatement,
trueSatement, falseStatement,
trueReturn?.ReturnedValue ?? trueThrow?.Exception,
falseReturn?.ReturnedValue ?? falseThrow?.Exception,
IsRef(trueReturn), cancellationToken).ConfigureAwait(false);
isRef, cancellationToken).ConfigureAwait(false);
var generatorInternal = document.GetRequiredLanguageService<SyntaxGeneratorInternal>();
var returnStatement = trueReturn?.Kind == OperationKind.YieldReturn
......
......@@ -37,6 +37,37 @@ class C
end class")
End Function
<WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)>
Public Async Function TestNotWithThrow1() As Task
Await TestMissingAsync(
"
class C
sub M(i as integer)
[||]if true
throw new System.Exception()
else
i = 1
end if
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)>
Public Async Function TestNotWithThrow2() As Task
Await TestMissingAsync(
"
class C
sub M(i as integer)
[||]if true
i = 0
else
throw new System.Exception()
end if
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)>
Public Async Function TestOnSimpleAssignmentNoBlocks() As Task
Await TestInRegularAndScriptAsync(
......
......@@ -37,6 +37,37 @@ class C
end class")
End Function
<WorkItem(43291, "https://github.com/dotnet/roslyn/issues/43291")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)>
Public Async Function TestNotWithThrow1() As Task
Await TestMissingAsync(
"
class C
function M() as integer
[||]if true
return 0
else
throw new System.Exception()
end if
end function
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)>
Public Async Function TestNotWithThrow2() As Task
Await TestMissingAsync(
"
class C
function M() as integer
[||]if true
throw new System.Exception()
else
return 1
end if
end function
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseConditionalExpression)>
Public Async Function TestOnSimpleReturnNoBlocks() As Task
Await TestInRegularAndScriptAsync(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册