|
// 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.
#nullable disable
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.EditAndContinue;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.Debugging;
[Trait(Traits.Feature, Traits.Features.DebuggingBreakpoints)]
public class BreakpointSpansTests
{
#region Helpers
private static void TestSpan(string markup, ParseOptions options = null)
=> Test(markup, isMissing: false, isLine: false, options: options);
private static void TestMissing(string markup)
=> Test(markup, isMissing: true, isLine: false);
private static void TestLine(string markup)
=> Test(markup, isMissing: false, isLine: true);
private static void Test(string markup, bool isMissing, bool isLine, ParseOptions options = null)
{
MarkupTestFile.GetPositionAndSpan(
markup, out var source, out var position, out TextSpan? expectedSpan);
var tree = SyntaxFactory.ParseSyntaxTree(source, options);
var hasBreakpoint = BreakpointSpans.TryGetBreakpointSpan(
tree, position.Value, CancellationToken.None, out var breakpointSpan);
if (isLine)
{
Assert.True(hasBreakpoint);
Assert.True(breakpointSpan.Length == 0);
}
else if (isMissing)
{
Assert.False(hasBreakpoint);
}
else
{
Assert.True(hasBreakpoint);
AssertEx.AreEqual(
expectedSpan.Value,
breakpointSpan,
message: $"Expected: [|{source.Substring(expectedSpan.Value.Start, expectedSpan.Value.Length)}|], Actual: [|{source.Substring(breakpointSpan.Start, breakpointSpan.Length)}|]");
}
}
/// <summary>
/// Verifies all breakpoint spans of the declaration node marked by $$ in <paramref name="markup"/>
/// and it's breakpoint span envelope (span that contains all breakpoint span of the declaration).
///
/// Only test declarations that have a single possible body (e.g. <see cref="VariableDeclaratorSyntax"/>,
/// not <see cref="FieldDeclarationSyntax"/> or <see cref="VariableDeclarationSyntax"/>).
/// </summary>
private static void VerifyAllSpansInDeclaration<TDeclaration>(string markup)
where TDeclaration : SyntaxNode
{
MarkupTestFile.GetPositionAndSpans(markup, out var source, out var position, out var expectedSpans);
var tree = SyntaxFactory.ParseSyntaxTree(source);
var root = tree.GetRoot();
var declarationNode = root.FindToken(position).Parent.FirstAncestorOrSelf<TDeclaration>();
var actualSpans = GetBreakpointSequence(declarationNode, position).ToArray();
AssertEx.Equal(expectedSpans, actualSpans,
itemSeparator: "\r\n",
itemInspector: span => "[|" + source.Substring(span.Start, span.Length) + "|]");
var expectedEnvelope = expectedSpans.IsEmpty ? default : TextSpan.FromBounds(expectedSpans[0].Start, expectedSpans[^1].End);
Assert.NotNull(declarationNode);
var actualEnvelope = SyntaxUtilities.TryGetDeclarationBody(declarationNode, symbol: null)?.Envelope ?? default;
Assert.Equal(expectedEnvelope, actualEnvelope);
}
public static IEnumerable<TextSpan> GetBreakpointSequence(SyntaxNode root, int position)
{
TextSpan lastSpan = default;
var endPosition = root.Span.End;
for (var p = position; p < endPosition; p++)
{
if (BreakpointSpans.TryGetClosestBreakpointSpan(root, p, minLength: 0, out var span) && span.Start > lastSpan.Start)
{
lastSpan = span;
yield return span;
}
}
}
#endregion
[Fact]
public void GetBreakpointSequence1()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$void Goo()
[|{|]
[|int d = 5;|]
[|int a = 1|], [|b = 2|], [|c = 3|];
for ([|int i = 0|], [|j = 1|], [|k = 2|]; [|i < 10|]; [|i++|], [|j++|], [|k--|])
[|while (b > 0)|]
[|{|]
[|if (c < b)|]
try
[|{|]
[|System.Console.WriteLine(a);|]
[|}|]
[|catch (Exception e)|]
[|{|]
[|System.Console.WriteLine(e);|]
[|}|]
finally
[|{|]
[|}|]
else [|if (b < 10)|]
[|System.Console.WriteLine(b);|]
else
[|System.Console.WriteLine(c);|]
[|}|]
[|}|]
}");
}
[Fact]
public void GetBreakpointSequence2()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$void Goo()
[|{|]
do
[|{|]
label:
[|i++;|]
[|var l = new List<int>()
{
F(),
F(),
};|]
[|break;|]
[|continue;|]
[|}|]
[|while (a);|]
[|goto label;|]
[|}|]
}");
}
[Fact]
public void GetBreakpointSequence3()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$int Goo()
[|{|]
[|switch(a)|]
{
case 1:
case 2:
[|break;|]
case 3:
[|goto case 4;|]
case 4:
[|throw new Exception();|]
[|goto default;|]
default:
[|return 1;|]
}
[|return 2;|]
[|}|]
}");
}
[Fact]
public void GetBreakpointSequence4()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$IEnumerable<int> Goo()
[|{|]
[|yield return 1;|]
[|foreach|] ([|var f|] [|in|] [|Goo()|])
[|{|]
[|using (z)|]
using ([|var q = null|])
using ([|var u = null|], [|v = null|])
[|{|]
[|while (a)|] [|yield return 2;|]
[|}|]
[|}|]
fixed([|int* a = new int[1]|], [|b = new int[1]|], [|c = new int[1]|]) [|{|][|}|]
[|yield break;|]
[|}|]
}");
}
[Fact]
public void GetBreakpointSequence5()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$IEnumerable<int> Goo()
[|{|][|while(t)|][|{|][|}|][|}|]
}");
}
[Fact]
public void GetBreakpointSequence6()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$IEnumerable<int> Goo()
[|{|]
checked
[|{|]
const int a = 1;
const int b = 2;
unchecked
[|{|]
unsafe
[|{|]
[|lock(l)|]
[|{|]
[|;|]
[|}|]
[|}|]
[|}|]
[|}|]
[|}|]
}");
}
[Fact]
public void GetBreakpointSequence_StaticContructor_NoBody()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(@"
class Class
{
static Clas$$s()
}");
}
[Fact]
public void GetBreakpointSequence_Method_NoBody()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class Class
{
int F$$unction()
}");
}
#region Switch Expression
[Fact]
public void SwitchExpression_All()
{
VerifyAllSpansInDeclaration<MethodDeclarationSyntax>(@"
class C
{
$$IEnumerable<int> Goo()
[|{|]
[|_ = M2(
c
switch
{
(1) _ [|when f|] => [|M(0)|],
(3) _ [|when f|] => [|M(1)|],
(1, 2) _ [|when f|] => [|M(0)|],
(3, 4) _ [|when f|] => [|M(2)|],
_ => [|M(4)|],
},
M(5));|]
[|}|]
}");
}
[Fact]
public void SwitchExpression01()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|_ = e switch
{
1 when f => 2,
3 when g => 4,
_ => 5,
};|]
}
}");
}
[Fact]
public void SwitchExpression02()
{
TestSpan(
@"class C
{
void Goo()
{
[|_ = e switch
$${
1 when f => 2,
3 when g => 4,
_ => 5,
};|]
}
}");
}
[Fact]
public void SwitchExpression03()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{$$
1 [|when f|] => 2,
3 when g => 4,
_ => 5,
};
}
}");
}
[Fact]
public void SwitchExpression04()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 [|when f|] $$=> 2,
3 when g => 4,
_ => 5,
};
}
}");
}
[Fact]
public void SwitchExpression05()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f =$$> [|2|],
3 when g => 4,
_ => 5,
};
}
}");
}
[Fact]
public void SwitchExpression06()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f => [|2|],$$
3 when g => 4,
_ => 5,
};
}
}");
}
[Fact]
public void SwitchExpression07()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f => 2,
$$ 3 [|when g|] => 4,
_ => 5,
};
}
}");
}
[Fact]
public void SwitchExpression08()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f => 2,
3 when g => [|4|],$$
_ => 5,
};
}
}");
}
[Fact]
public void SwitchExpression09()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f => 2,
3 when g => 4,
$$ _ => [|5|],
};
}
}");
}
[Fact]
public void SwitchExpression10()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f => 2,
3 when g => 4,
_ => [|5|],$$
};
}
}");
}
[Fact]
public void SwitchExpression11()
{
TestSpan(
@"class C
{
void Goo()
{
_ = e switch
{
1 when f => 2,
3 when g => 4,
_ => [|5|],
$$};
}
}");
}
[Fact]
public void SwitchExpression12()
{
TestSpan(
@"class C
{
void Goo()
{
[|_ = e switch
{
1 when f => 2,
3 when g => 4,
_ => 5,
}$$;|]
}
}");
}
#endregion
#region For and ForEach
[Fact]
public void ForStatementInitializer1a()
{
TestSpan(
@"class C
{
void Goo()
{
$$ for ([|i = 0|], j = 0; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void ForStatementInitializer1b()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or ([|i = 0|], j = 0; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void ForStatementInitializer1c()
{
TestSpan(
@"class C
{
void Goo()
{
for ([|i $$= 0|], j = 0; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void ForStatementInitializer1d()
{
TestSpan(
@"class C
{
void Goo()
{
for
$$ (
[|i = 0|], j = 0; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void ForStatementInitializer2()
{
TestSpan(
@"class C
{
void Goo()
{
for (i = 0, [|$$j = 0|]; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void ForStatementInitializer3()
=> TestSpan("class C { void M() { for([|i = 0$$|]; ; }; }");
[Fact]
public void ForStatementCondition()
{
TestSpan(
@"class C
{
void Goo()
{
for (i = 0, j = 0; [|i < 10 && j < $$10|]; i++, j++)
{
}
}
}");
}
[Fact]
public void ForStatementIncrementor1()
{
TestSpan(
@"class C
{
void Goo()
{
for (i = 0, j = 0; i < 10 && j < 10; [|i+$$+|], j++)
{
}
}
}");
}
[Fact]
public void ForStatementIncrementor2()
{
TestSpan(
@"class C
{
void Goo()
{
for (i = 0, j = 0; i < 10 && j < 10; i++, [|$$j++|])
{
}
}
}");
}
[Fact]
public void ForEachStatementExpression()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v in [|Goo().B$$ar()|])
{
}
}
}");
}
[Fact]
public void ForEachDeconstructionStatementExpression()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y) in [|Goo().B$$ar()|])
{
}
}
}");
}
#endregion
#region Lambdas
[Fact]
public void SimpleLambdaBody()
{
TestSpan(
@"class C
{
void Goo()
{
Func<string> f = s => [|G$$oo()|];
}
}");
}
[Fact]
public void ParenthesizedLambdaBody()
{
TestSpan(
@"class C
{
void Goo()
{
Func<string> f = (s, i) => [|G$$oo()|];
}
}");
}
[Fact]
public void AnonymousMethod1()
{
TestSpan(
@"class C
{
void Goo()
{
Func<int> f = delegate [|$${|] return 1; };
}
}");
}
[Fact]
public void AnonymousMethod2()
{
TestSpan(
@"class C
{
void Goo()
{
Func<int> f = delegate { [|$$return 1;|] };
}
}");
}
#endregion
#region Queries
[Fact]
public void FirstFromClauseExpression()
{
TestSpan(
@"class C
{
void Goo()
{
[|var q = from x in bl$$ah()
from y in quux().z()
select y;|]
}
}");
}
[Fact]
public void SecondFromClauseExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
from y in [|quux().z$$()|]
select y;
}
}");
}
[Fact]
public void FromInQueryContinuation1()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
from y in quux().z()
group x by y into g
from m in [|g.C$$ount()|]
select m.Blah();
}
}");
}
[Fact]
public void FromInQueryContinuation2()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
from y in quux().z()
group x by y into g
$$ from m in [|g.Count()|]
select m.Blah();
}
}");
}
[Fact]
public void JoinClauseLeftExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on [|left().exp$$r()|] equals right().expr()
select y;
}
}");
}
[Fact]
public void JoinClauseRightExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals [|righ$$t().expr()|]
select y;
}
}");
}
[Fact]
public void LetClauseExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
let a = [|expr().$$expr()|]
select y;
}
}");
}
[Fact]
public void WhereClauseExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
where [|expr().$$expr()|]
select y;
}
}");
}
[Fact]
public void WhereClauseKeyword()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
whe$$re [|expr().expr()|]
select y;
}
}");
}
[Fact]
public void SimpleOrdering1()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby [|expr().$$expr()|]
select y;
}
}");
}
[Fact]
public void SimpleOrdering2()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, [|expr().$$expr()|]
select y;
}
}");
}
[Fact]
public void AscendingOrdering1()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby [|expr().$$expr()|] ascending
select y;
}
}");
}
[Fact]
public void AscendingOrdering2()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, [|expr().$$expr()|] ascending
select y;
}
}");
}
[Fact]
public void DescendingOrdering1()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby [|expr().$$expr()|] descending
select y;
}
}");
}
[Fact]
public void DescendingOrdering2()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, [|expr().$$expr()|] descending
select y;
}
}");
}
[Fact]
public void OrderByKeyword()
=> TestSpan("class C { void M() { from string s in null ord$$erby [|s.A|] ascending } }");
[Fact]
public void AscendingKeyword()
=> TestSpan("class C { void M() { from string s in null orderby [|s.A|] $$ascending } }");
[Fact]
public void SelectExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
select [|y.$$blah()|];
}
}");
}
[Fact]
public void AnonymousTypeAfterSelect()
{
TestSpan(
@"class C
{
public void ()
{
var q =
from c in categories
join p in products on c equals p.Category into ps
select [|new { Category = c, $$Products = ps }|];
}
}");
}
[Fact]
public void GroupExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group [|bar()$$.goo()|] by blah().zap()
select y.blah();
}
}");
}
[Fact]
public void GroupByKeyword()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group [|bar().goo()|] b$$y blah().zap()
select y.blah();
}
}");
}
[Fact]
public void GroupByExpression()
{
TestSpan(
@"class C
{
void Goo()
{
var q = from x in blah()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group bar().goo() by [|blah()$$.zap()|]
select y.blah();
}
}");
}
[Fact]
public void InFrontOfFirstFromClause()
{
TestSpan(
@"class C
{
void Goo()
{
[|var q =
$$ from x in blah()
from y in zap()
let m = quux()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group bar().goo() by blah().zap() into g
select y.blah();|]
}
}");
}
[Fact]
public void InFrontOfSecondFromClause()
{
TestSpan(
@"class C
{
void Goo()
{
var q =
from x in blah()
$$ from y in [|zap()|]
let m = quux()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group bar().goo() by blah().zap() into g
select y.blah();
}
}");
}
[Fact]
public void InFrontOfLetClause()
{
TestSpan(
@"class C
{
void Goo()
{
var q =
from x in blah()
from y in zap()
$$ let m = [|quux()|]
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group bar().goo() by blah().zap() into g
select y.blah();
}
}");
}
[Fact]
public void InFrontOfJoinClause()
{
TestSpan(
@"class C
{
void Goo()
{
var q =
from x in blah()
from y in zap()
let m = quux()
$$ join a in alpha on [|left().expr()|] equals right.expr()
orderby goo, expr().expr() descending
group bar().goo() by blah().zap() into g
select y.blah();
}
}");
}
[Fact]
public void InFrontOfOrderByClause()
{
TestSpan(
@"class C
{
void Goo()
{
var q =
from x in blah()
from y in zap()
let m = quux()
join a in alpha on left().expr() equals right.expr()
$$ orderby [|goo|], expr().expr() descending
group bar().goo() by blah().zap() into g
select y.blah();
}
}");
}
[Fact]
public void InFrontOfGroupByClause()
{
TestSpan(
@"class C
{
void Goo()
{
var q =
from x in blah()
from y in zap()
let m = quux()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
$$ group [|bar().goo()|] by blah().zap() into g
select y.blah();
}");
}
[Fact]
public void InFrontOfSelectClause()
{
TestSpan(
@"class C
{
void Goo()
{
var q =
from x in blah()
from y in zap()
let m = quux()
join a in alpha on left().expr() equals right.expr()
orderby goo, expr().expr() descending
group bar().goo() by blah().zap() into g
$$ select [|y.blah()|];
}");
}
[Fact]
public void Select1()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => from x in new[] { 1 } select [|$$x|];
}
");
}
[Fact]
public void Select_NoLambda1()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => [|from x in new[] { 1 } where x > 0 select $$x|];
}
");
}
[Fact]
public void Select_NoLambda2()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => [|from x in new[] { 1 } select x into y orderby y select $$y|];
}
");
}
[Fact]
public void GroupBy1()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => from x in new[] { 1 } group x by [|$$x|];
}
");
}
[Fact]
public void GroupBy_NoLambda1()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => [|from x in new[] { 1 } group $$x by x|];
}
");
}
[Fact]
public void GroupBy_NoLambda2()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => [|from x in new[] { 1 } group $$x by x + 1 into y group y by y.Key + 2|];
}
");
}
[Fact]
public void GroupBy_NoLambda3()
{
TestSpan(
@"class C
{
IEnumerable<int> Goo() => [|from x in new[] { 1 } group x by x + 1 into y group $$y by y.Key + 2|];
}
");
}
#endregion
#region Field and Variable Declarators
[Fact]
public void FieldDeclarator_WithoutInitializer_All()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
int $$i, j;
}");
}
[Fact]
public void FieldDeclarator_WithoutInitializer1()
{
TestMissing(
@"class C
{
int $$i;
}");
}
[Fact]
public void FieldDeclarator_WithoutInitializer2()
{
TestMissing(
@"class C
{
pri$$vate int i;
}");
}
[Fact]
public void FieldDeclarator_SingleVariable_Initializer_All1()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
private int $$i;
}");
}
[Fact]
public void FieldDeclarator_SingleVariable_Initializer_All2()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
[|int $$i = 0;|]
}");
}
[Fact]
public void FieldDeclarator_SingleVariable_Initializer_All3()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
[|private int $$i = 0;|]
}");
}
[Fact]
public void FieldDeclarator_MultiVariable_Initializer_All1()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
[|private int $$i = 0|], j = 2;
}");
}
[Fact]
public void FieldDeclarator_MultiVariable_Initializer_All2()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
[|int $$i = 0|], j = 2;
}");
}
[Fact]
public void FieldDeclarator_MultiVariable_Initializer_All3()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
private int i = 0, [|$$j = 0|];
}");
}
[Fact]
public void FieldDeclarator_Initializer1()
{
TestSpan(
@"class C
{
[|int $$i = 1;|]
}");
}
[Fact]
public void FieldDeclarator_Initializer2()
{
TestSpan(
@"class C
{
[|private int $$i = 1;|]
}");
}
[Fact]
public void FieldDeclarator_Initializer3()
{
TestSpan(
@"class C
{
[Goo]
[|private int $$i = 0;|]
}");
}
[Fact]
public void FieldDeclarator_Initializer4()
{
TestSpan(
@"class C
{
[|pri$$vate int i = 1;|]
}");
}
[Fact]
public void FieldDeclarator_Initializer5()
{
TestSpan(
@"class C
{
$$ [|private int i = 3;|]
}");
}
[Fact]
public void ConstVariableDeclarator0()
=> TestMissing("class C { void Goo() { const int a = $$1; } }");
[Fact]
public void ConstVariableDeclarator1()
=> TestMissing("class C { void Goo() { const $$int a = 1; } }");
[Fact]
public void ConstVariableDeclarator2()
=> TestMissing("class C { void Goo() { $$const int a = 1; } }");
[Fact]
public void ConstFieldVariableDeclarator_All()
{
VerifyAllSpansInDeclaration<VariableDeclaratorSyntax>(
@"class C
{
[Goo]
private const int i = 0, j, $$k = 0;
}");
}
[Fact]
public void ConstFieldVariableDeclarator0()
=> TestMissing("class C { const int a = $$1; }");
[Fact]
public void ConstFieldVariableDeclarator1()
=> TestMissing("class C { const $$int a = 1; }");
[Fact]
public void ConstFieldVariableDeclarator2()
=> TestMissing("class C { $$const int a = 1; }");
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538777")]
public void VariableDeclarator0()
=> TestMissing("class C { void Goo() { int$$ } }");
[Fact]
public void VariableDeclarator1()
{
TestMissing(
@"class C
{
void Goo()
{
int $$i;
}
}");
}
[Fact]
public void VariableDeclarator2a()
{
TestSpan(
@"class C
{
void Goo()
{
[|int $$i = 0;|]
}
}");
}
[Fact]
public void VariableDeclarator2b()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|int i = 0;|]
}
}");
}
[Fact]
public void VariableDeclarator2c()
{
TestSpan(
@"class C
{
void Goo()
{
[|$$int i = 0;|]
}
}");
}
[Fact]
public void VariableDeclarator3a()
{
TestSpan(
@"class C
{
void Goo()
{
int i = 0, [|$$j = 3|];
}
}");
}
[Fact]
public void VariableDeclarator3b()
{
TestSpan(
@"class C
{
void Goo()
{
[|int i = 0|], $$j;
}
}");
}
[Fact]
public void VariableDeclarator3c()
{
TestSpan(
@"class C
{
void Goo()
{
int $$i, [|j = 0|];
}
}");
}
[Fact]
public void VariableDeclarator4()
{
TestSpan(
@"class C
{
void Goo()
{
int i = 0, [|j = $$1|];
}
}");
}
[Fact]
public void VariableDeclarator5()
{
TestSpan(
@"class C
{
[|int $$i = 0;|]
}");
}
[Fact]
public void VariableDeclarator6()
{
TestSpan(
@"class C
{
[|int i = 0|], $$j;
}");
}
[Fact]
public void VariableDeclarator7()
{
TestSpan(
@"class C
{
private int i = 0, [|j = $$1|];
}");
}
[Fact]
public void VariableDeclarator8()
{
TestSpan(
@"class C
{
[|priv$$ate int i = 0|], j = 1;
}");
}
[Fact]
public void VariableDeclarator9()
{
TestSpan(
@"class C
{
$$ [|private int i = 0|], j = 1;
}");
}
[Fact]
public void VariableDeclarator10()
=> TestSpan("class C { void M() { [|int i = 0$$;|] } }");
[Fact]
public void VariableDeclarator_Separators0()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|int i = 0|], j = 1, k = 2;
}
}");
}
[Fact]
public void VariableDeclarator_Separators1()
{
TestSpan(
@"class C
{
void Goo()
{
[|int i = 0|]$$, j = 1, k = 2;
}
}");
}
[Fact]
public void VariableDeclarator_Separators2()
{
TestSpan(
@"class C
{
void Goo()
{
int i = 0, [|j = 1|]$$, k = 2;
}
}");
}
[Fact]
public void VariableDeclarator_Separators3()
{
TestSpan(
@"class C
{
void Goo()
{
int i = 0, j = 1,$$ [|k = 2|];
}
}");
}
[Fact]
public void VariableDeclarator_Separators4()
{
TestSpan(
@"class C
{
void Goo()
{
int i = 0, j = 1, [|k = 2|]$$;
}
}");
}
[Fact]
public void VariableDeclarator_Separators5()
{
TestSpan(
@"class C
{
void Goo()
{
[|int i = 0|], j = 1, k = 2;$$
}
}");
}
[Fact]
public void VariableDeclarator_Separators6()
{
TestSpan(
@"class C
{
void Goo()
{
int i = 1, j, $$k, [|l = 2|];
}
}");
}
[Fact]
public void VariableDeclarator_Separators7()
{
TestSpan(
@"class C
{
void Goo()
{
int i$$, j, k, [|l = 2|];
}
}");
}
[Fact]
public void VariableDeclarator_Separators8()
{
TestSpan(
@"class C
{
void Goo()
{
[|int i = 2|], j, k, l$$;
}
}");
}
[Fact]
public void VariableDeclarator_Separators9()
{
TestSpan(
@"class C
{
void Goo()
{
int i, j, [|k = 1|], m, l = 2;$$
}
}");
}
[Fact]
public void EventFieldDeclarator1()
{
TestSpan(
@"class C
{
$$ [|public event EventHandler MyEvent = delegate { };|]
}");
}
[Fact]
public void EventFieldDeclarator2()
{
TestSpan(
@"class C
{
[|pub$$lic event EventHandler MyEvent = delegate { };|]
}");
}
[Fact]
public void EventFieldDeclarator3()
{
TestSpan(
@"class C
{
[|public ev$$ent EventHandler MyEvent = delegate { };|]
}");
}
[Fact]
public void EventFieldDeclarator4()
{
TestSpan(
@"class C
{
[|public event EventHan$$dler MyEvent = delegate { };|]
}");
}
[Fact]
public void EventFieldDeclarator5()
{
TestSpan(
@"class C
{
[|public event EventHandler MyE$$vent = delegate { };|]
}");
}
[Fact]
public void EventFieldDeclarator6()
{
TestSpan(
@"class C
{
[|public event EventHandler MyEvent $$= delegate { };|]
}");
}
[Fact]
public void EventFieldDeclarator7()
{
TestSpan(
@"class C
{
[|public event EventHandler MyEvent = del$$egate { };|]
}");
}
[Fact]
public void EventFieldDeclarator8()
{
TestSpan(
@"class C
{
public event EventHandler MyEvent = delegate [|{|] $$ };
}");
}
#endregion
[Fact]
public void EventAccessorAdd()
=> TestSpan("class C { eve$$nt Action Goo { add [|{|] } remove { } } }");
[Fact]
public void EventAccessorAdd2()
=> TestSpan("class C { event Action Goo { ad$$d [|{|] } remove { } } }");
[Fact]
public void EventAccessorRemove()
=> TestSpan("class C { event Action Goo { add { } $$remove [|{|] } } }");
[Fact]
public void ElseClauseWithBlock()
{
TestSpan(
@"class C
{
void Goo()
{
if (bar)
{
}
el$$se
[|{|]
}
}
}");
}
[Fact]
public void ElseClauseWithStatement()
{
TestSpan(
@"class C
{
void Goo()
{
if (bar)
{
}
el$$se
[|Goo();|]
}
}");
}
[Fact]
public void ElseIf()
{
TestSpan(
@"class C
{
void Goo()
{
if (bar)
{
}
el$$se [|if (baz)|]
Goo();
}
}");
}
[Fact]
public void EmptyCatch()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
[|cat$$ch|]
{
}
}
}");
}
[Fact]
public void CatchWithType()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
[|cat$$ch(Exception)|]
{
}
}
}");
}
[Fact]
public void CatchWithTypeInType()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
[|catch(Exce$$ption)|]
{
}
}
}");
}
[Fact]
public void CatchWithTypeAndNameInType()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
[|catch(Exce$$ption e)|]
{
}
}
}");
}
[Fact]
public void CatchWithTypeAndNameInName()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
[|catch(Exception $$e)|]
{
}
}
}");
}
[Fact]
public void Filter1()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
$$catch(Exception e) [|when (e.Message != null)|]
{
}
}
}");
}
[Fact]
public void Filter3()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
catch(Exception e)$$ [|when (e.Message != null)|]
{
}
}
}");
}
[Fact]
public void Filter4()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
catch(Exception e) [|when$$ (e.Message != null)|]
{
}
}
}");
}
[Fact]
public void Filter5()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
catch(Exception e) [|when (e.Message != null)|] $$
{
}
}
}");
}
[Fact]
public void SimpleFinally()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
final$$ly
[|{|]
}
}
}");
}
[Fact]
public void FinallyWithCatch()
{
TestSpan(
@"class C
{
void Goo()
{
try
{
}
catch
{
}
final$$ly
[|{|]
}
}
}");
}
[Fact]
public void SwitchLabelWithBlock()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
case $$1:
[|{|]
}
}
}
}");
}
[Fact]
public void SwitchLabelWithStatement()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
cas$$e 1:
[|goo();|]
}
}
}");
}
[Fact]
public void SwitchLabelWithStatement2()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
cas$$e 1:
[|goo();|]
bar();
}
}
}");
}
[Fact]
public void SwitchLabelWithoutStatement()
=> TestSpan("class C { void M() { [|switch |]{ case 1$$: } } }");
[Fact]
public void MultipleLabelsOnFirstLabel()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
cas$$e 1:
case 2:
[|goo();|]
case 3:
default:
bar();
}
}
}");
}
[Fact]
public void MultipleLabelsOnSecondLabel()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
case 1:
cas$$e 2:
[|goo();|]
case 3:
default:
bar();
}
}
}");
}
[Fact]
public void MultipleLabelsOnLabelWithDefault()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
case 1:
case 2:
goo();
cas$$e 3:
default:
[|bar();|]
}
}
}");
}
[Fact]
public void MultipleLabelsOnDefault()
{
TestSpan(
@"class C
{
void Goo()
{
switch (goo)
{
case 1:
case 2:
goo();
case 3:
default:$$
[|bar();|]
}
}
}");
}
[Fact]
public void BlockBeforeStartToken()
{
TestSpan(
@"class C
{
void Goo()
[|$${|]
}
}");
}
[Fact]
public void BlockBeforeStartToken2()
{
TestSpan(
@"class C
{
void Goo()
$$ [|{|]
}
}");
}
[Fact]
public void BlockAfterStartToken()
{
TestSpan(
@"class C
{
void Goo()
[|{$$|]
}
}");
}
[Fact]
public void BlockAfterStartToken2()
{
TestSpan(
@"class C
{
void Goo()
[|{|] $$
}
}");
}
[Fact]
public void BlockBeforeEndToken1()
{
TestSpan(
@"class C
{
void Goo()
{
$$[|}|]
}");
}
[Fact]
public void BlockBeforeEndToken2()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|}|]
}");
}
[Fact]
public void BlockAfterEndToken1()
{
TestSpan(
@"class C
{
void Goo()
{
[|}|]$$
}");
}
[Fact]
public void BlockAfterEndToken2()
{
TestSpan(
@"class C
{
void Goo()
{
[|}|] $$
}");
}
[Fact]
public void SingleDeclarationOnType()
{
TestMissing(
@"class C
{
void Goo()
{
i$$nt i;
}
}");
}
[Fact]
public void MultipleDeclarationsOnType()
{
TestSpan(
@"class C
{
void Goo()
{
[|i$$nt i = 0|], j = 1;
}
}");
}
[Fact]
public void Label()
{
TestSpan(
@"class C
{
void Goo()
{
go$$o:
[|bar();|]
}
}");
}
[Fact]
public void WhileInWhile()
{
TestSpan(
@"class C
{
void Goo()
{
[|w$$hile (expr)|]
{
}
}
}");
}
[Fact]
public void WhileInExpr()
{
TestSpan(
@"class C
{
void Goo()
{
[|while (ex$$pr)|]
{
}
}
}");
}
[Fact]
public void OnWhileBlock()
{
TestSpan(
@"class C
{
void Goo()
{
while (expr)
$$ [|{|]
}
}
}");
}
[Fact]
public void OnDoKeyword()
{
TestSpan(
@"class C
{
void Goo()
{
d$$o
[|{|]
}
while(expr);
}
}");
}
[Fact]
public void OnDoBlock()
{
TestSpan(
@"class C
{
void Goo()
{
do
$$ [|{|]
}
while(expr);
}
}");
}
[Fact]
public void OnDoWhile()
{
TestSpan(
@"class C
{
void Goo()
{
do
{
}
[|wh$$ile(expr);|]
}
}");
}
[Fact]
public void OnDoWhile_MissingSemicolon()
{
TestSpan(
@"class C
{
void Goo()
{
do
{
}
[|wh$$ile(expr)|]
}
}");
}
[Fact]
public void OnDoExpression()
{
TestSpan(
@"class C
{
void Goo()
{
do
{
}
[|while(ex$$pr);|]
}
}");
}
[Fact]
public void OnForWithDeclaration1()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or ([|int i = 0|], j = 1; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void OnForWithDeclaration2()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or ([|int i = 0|]; i < 10 && j < 10; i++, j++)
{
}
}
}");
}
[Fact]
public void OnForWithCondition()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or (; [|i < 10 && j < 10|]; i++, j++)
{
}
}
}");
}
[Fact]
public void OnForWithIncrementor1()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or (; ; [|i++|], j++)
{
}
}
}");
}
[Fact]
public void OnForWithIncrementor2()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or (; ; [|i++|])
{
}
}
}");
}
[Fact]
public void OnEmptyFor()
{
TestSpan(
@"class C
{
void Goo()
{
f$$or (; ; )
[|{|]
}
}
}");
}
[Fact]
public void OnForEachKeyword1()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|foreach|] (var v in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachKeyword2()
{
TestSpan(
@"class C
{
void Goo()
{
[|fo$$reach|] (var v in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachKeyword3()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|] $$
(var v in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachKeyword4()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|]
$$ (var v in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachKeyword5()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|] $$(var v in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachType1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach ( $$
[|var v|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachType2()
{
TestSpan(
@"class C
{
void Goo()
{
foreach ([|v$$ar v|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachIdentifier()
{
TestSpan(
@"class C
{
void Goo()
{
foreach ([|var v$$v|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachIn1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v [|i$$n|] expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachIn2()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v
$$ [|in|] expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachIn3()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v
[|in|] $$
expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachExpr1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v in [|expr($$).blah()|])
{
}
}
}");
}
[Fact]
public void OnForEachExpr2()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v in [|expr().blah()|]
$$ )
{
}
}
}");
}
[Fact]
public void OnForEachExpr3()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v in
$$ [|expr().blah()|]
)
{
}
}
}");
}
[Fact]
public void OnForEachStatement()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|](var v in expr().blah()) $$
{
}
}
}");
}
[Fact]
public void OnForEachBlock1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var v in expr().blah())
$$ [|{|]
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword1()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|foreach|] (var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword2()
{
TestSpan(
@"class C
{
void Goo()
{
[|fo$$reach|] (var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword3()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|] $$
(var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword4()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|]
$$ (var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword5()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|] $$(var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionType1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach ( $$
[|var (x, y)|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionType2()
{
TestSpan(
@"class C
{
void Goo()
{
foreach ([|v$$ar (x, y)|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIdentifier()
{
TestSpan(
@"class C
{
void Goo()
{
foreach ([|var (v$$v, y)|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIn1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y) [|i$$n|] expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIn2()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y)
$$ [|in|] expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIn3()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y)
[|in|] $$
expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionExpr1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y) in [|expr($$).blah()|])
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionExpr2()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y) in [|expr().blah()|]
$$ )
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionExpr3()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y) in
$$ [|expr().blah()|]
)
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionStatement()
{
TestSpan(
@"class C
{
void Goo()
{
[|foreach|](var (x, y) in expr().blah()) $$
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionBlock1()
{
TestSpan(
@"class C
{
void Goo()
{
foreach (var (x, y) in expr().blah())
$$ [|{|]
}
}
}");
}
[Fact]
public void OnUsingWithDecl1()
{
TestSpan(
@"class C
{
void Goo()
{
us$$ing ([|var v = goo()|])
{
}
}
}");
}
[Fact]
public void OnUsingWithDecl2()
{
TestSpan(
@"class C
{
void Goo()
{
us$$ing ([|var v = goo()|], x = bar())
{
}
}
}");
}
[Fact]
public void OnUsingWithDeclType()
{
TestSpan(
@"class C
{
void Goo()
{
using ([|v$$ar v = goo()|])
{
}
}
}");
}
[Fact]
public void OnUsingWithDeclIdentifier1()
{
TestSpan(
@"class C
{
void Goo()
{
using ([|var v$$v = goo()|])
{
}
}
}");
}
[Fact]
public void OnUsingWithDeclIdentifier2()
{
TestSpan(
@"class C
{
void Goo()
{
using ([|var vv = goo()|]) $$
{
}
}
}");
}
[Fact]
public void OnUsingWithDeclIdentifier3()
{
TestSpan(
@"class C
{
void Goo()
{
$$ using ([|var vv = goo()|])
{
}
}
}");
}
[Fact]
public void OnUsingWithDeclExpression()
{
TestSpan(
@"class C
{
void Goo()
{
using ([|var vv = go$$o()|])
{
}
}
}");
}
[Fact]
public void OnUsingWithExpression1()
{
TestSpan(
@"class C
{
void Goo()
{
[|usi$$ng (goo().bar())|]
{
}
}
}");
}
[Fact]
public void OnUsingWithExpression2()
{
TestSpan(
@"class C
{
void Goo()
{
[|using (goo$$().bar())|]
{
}
}
}");
}
[Fact]
public void OnFixed1()
{
TestSpan(
@"class C
{
void Goo()
{
fi$$xed ([|int* i = &j|])
{
}
}
}");
}
[Fact]
public void OnFixed2()
{
TestSpan(
@"class C
{
void Goo()
{
fi$$xed ([|int* i = &j|], k = &m)
{
}
}
}");
}
[Fact]
public void OnFixed3()
{
TestSpan(
@"class C
{
void Goo()
{
fixed ([|i$$nt* i = &j|])
{
}
}
}");
}
[Fact]
public void OnFixed4()
{
TestSpan(
@"class C
{
void Goo()
{
fixed ([|int* $$i = &j|])
{
}
}
}");
}
[Fact]
public void OnFixed5()
{
TestSpan(
@"class C
{
void Goo()
{
fixed ([|int* i $$= &j|])
{
}
}
}");
}
[Fact]
public void OnFixed6()
{
TestSpan(
@"class C
{
void Goo()
{
fixed ([|int* i = &$$j|])
{
}
}
}");
}
[Fact]
public void OnChecked1()
{
TestSpan(
@"class C
{
void Goo()
{
che$$cked
[|{|]
}
}
}");
}
[Fact]
public void OnUnchecked1()
{
TestSpan(
@"class C
{
void Goo()
{
unche$$cked
[|{|]
}
}
}");
}
[Fact]
public void OnUnsafe1()
{
TestSpan(
@"class C
{
void Goo()
{
uns$$afe
[|{|]
}
}
}");
}
[Fact]
public void OnLock1()
{
TestSpan(
@"class C
{
void Goo()
{
[|lo$$ck (expr)|]
{
}
}
}");
}
[Fact]
public void OnLock2()
{
TestSpan(
@"class C
{
void Goo()
{
[|lock (ex$$pr)|]
{
}
}
}");
}
[Fact]
public void OnIf1()
{
TestSpan(
@"class C
{
void Goo()
{
[|i$$f (goo().bar())|]
{
}
}
}");
}
[Fact]
public void OnIf2()
{
TestSpan(
@"class C
{
void Goo()
{
[|if (go$$o().bar())|]
{
}
}
}");
}
[Fact]
public void OnIfBlock()
{
TestSpan(
@"class C
{
void Goo()
{
if (goo().bar())
$$ [|{|]
}
}
}");
}
[Fact]
public void OnSwitch1()
{
TestSpan(
@"class C
{
void Goo()
{
[|swi$$tch (expr)|]
{
default:
goo();
}
}
}");
}
[Fact]
public void OnSwitch2()
{
TestSpan(
@"class C
{
void Goo()
{
[|switch (ex$$pr)|]
{
default:
goo();
}
}
}");
}
[Fact]
public void OnSwitch3()
{
TestSpan(
@"class C
{
void Goo()
{
[|switch (expr)|]
$$ {
default:
goo();
}
}
}");
}
[Fact]
public void OnSwitch4()
{
TestSpan(
@"class C
{
void Goo()
{
[|switch (expr)|]
{
default:
goo();
$$ }
}
}");
}
[Fact]
public void OnTry1()
{
TestSpan(
@"class C
{
void Goo()
{
t$$ry
[|{|]
}
finally
{
}
}
}");
}
[Fact]
public void OnTry2()
{
TestSpan(
@"class C
{
void Goo()
{
try
$$ [|{|]
}
finally
{
}
}
}");
}
[Fact]
public void OnGotoStatement1()
{
TestSpan(
@"class C
{
void Goo()
{
[|g$$oto goo;|]
}
}");
}
[Fact]
public void OnGotoStatement2()
{
TestSpan(
@"class C
{
void Goo()
{
[|goto go$$o;|]
}
}");
}
[Fact]
public void OnGotoCaseStatement1()
{
TestSpan(
@"class C
{
void Goo()
{
switch (expr)
{
case 1:
[|go$$to case 2;|]
}
}
}");
}
[Fact]
public void OnGotoCaseStatement2()
{
TestSpan(
@"class C
{
void Goo()
{
switch (expr)
{
case 1:
[|goto ca$$se 2;|]
}
}
}");
}
[Fact]
public void OnGotoCaseStatement3()
{
TestSpan(
@"class C
{
void Goo()
{
switch (expr)
{
case 1:
[|goto case $$2;|]
}
}
}");
}
[Fact]
public void OnGotoDefault1()
{
TestSpan(
@"class C
{
void Goo()
{
switch (expr)
{
case 1:
[|go$$to default;|]
}
}
}");
}
[Fact]
public void OnGotoDefault2()
{
TestSpan(
@"class C
{
void Goo()
{
switch (expr)
{
case 1:
[|goto defau$$lt;|]
}
}
}");
}
[Fact]
public void OnBreak1()
{
TestSpan(
@"class C
{
void Goo()
{
while (true)
{
[|bre$$ak;|]
}
}
}");
}
[Fact]
public void OnContinue1()
{
TestSpan(
@"class C
{
void Goo()
{
while (true)
{
[|cont$$inue;|]
}
}
}");
}
[Fact]
public void OnReturn1()
{
TestSpan(
@"class C
{
void Goo()
{
[|retu$$rn;|]
}
}");
}
[Fact]
public void OnReturn2()
{
TestSpan(
@"class C
{
void Goo()
{
[|retu$$rn expr();|]
}
}");
}
[Fact]
public void OnReturn3()
{
TestSpan(
@"class C
{
void Goo()
{
[|return expr$$().bar();|]
}
}");
}
[Fact]
public void OnYieldReturn1()
{
TestSpan(
@"class C
{
void Goo()
{
[|yi$$eld return goo().bar();|]
}
}");
}
[Fact]
public void OnYieldReturn2()
{
TestSpan(
@"class C
{
void Goo()
{
[|yield re$$turn goo().bar();|]
}
}");
}
[Fact]
public void OnYieldReturn3()
{
TestSpan(
@"class C
{
void Goo()
{
[|yield return goo()$$.bar();|]
}
}");
}
[Fact]
public void OnYieldBreak1()
{
TestSpan(
@"class C
{
void Goo()
{
[|yi$$eld break;|]
}
}");
}
[Fact]
public void OnYieldBreak2()
{
TestSpan(
@"class C
{
void Goo()
{
[|yield brea$$k;|]
}
}");
}
[Fact]
public void OnThrow1()
{
TestSpan(
@"class C
{
void Goo()
{
[|th$$row;|]
}
}");
}
[Fact]
public void OnThrow2()
{
TestSpan(
@"class C
{
void Goo()
{
[|thr$$ow new Goo();|]
}
}");
}
[Fact]
public void OnThrow3()
{
TestSpan(
@"class C
{
void Goo()
{
[|throw ne$$w Goo();|]
}
}");
}
[Fact]
public void OnThrow4()
{
TestSpan(
@"class C
{
void Goo()
{
[|throw new Go$$o();|]
}
}");
}
[Fact]
public void OnExpressionStatement1()
{
TestSpan(
@"class C
{
void Goo()
{
[|goo().$$bar();|]
}
}");
}
[Fact]
public void OnEmptyStatement1()
{
TestSpan(
@"class C
{
void Goo()
{
[|$$;|]
}
}");
}
[Fact]
public void OnEmptyStatement2()
{
TestSpan(
@"class C
{
void Goo()
{
while (true)
{
$$ [|;|]
}
}
}");
}
[Fact]
public void OnPropertyAccessor1()
{
TestSpan(
@"class C
{
int Goo
{
g$$et
[|{|]
}
}
}");
}
[Fact]
public void OnPropertyAccessor2()
{
TestSpan(
@"class C
{
int Goo
{
[|g$$et;|]
}
}");
}
[Fact]
public void OnPropertyAccessor3()
{
TestSpan(
@"class C
{
int Goo
{
get
{
}
s$$et
[|{|]
}
}
}");
}
[Fact]
public void OnPropertyAccessor4()
{
TestSpan(
@"class C
{
int Goo
{
[|s$$et;|]
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/48504")]
public void OnPropertyAccessor5()
{
TestSpan(
@"class C
{
int Goo
{
[|in$$it;|]
}
}");
}
[Fact]
public void OnProperty1()
{
TestSpan(
@"class C
{
int G$$oo
{
get
[|{|]
}
set
{
}
}
}");
}
[Fact]
public void OnProperty2()
{
TestSpan(
@"class C
{
int G$$oo
{
[|get;|]
set {}
}
}");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/932711")]
public void OnPropertyWithInitializer()
{
TestSpan(
@"class C
{
public int Id { get; set; } = [|int.Pa$$rse(""42"")|];
}");
TestSpan(
@"class C
{
public int$$ Id { [|get;|] set; } = int.Parse(""42"");
}");
TestSpan(
@"class C
{
public int Id { get; [|set;|] $$} = int.Parse(""42"");
}");
TestSpan(
@"class C
{
public int Id { get; [|set;|] }$$ = int.Parse(""42"");
}");
TestSpan(
@"class C
{
public int Id { get; set; } =$$ [|int.Parse(""42"")|];
}");
}
[Fact]
public void OnPropertyExpressionBody1()
{
TestSpan(
@"class C
{
public int Id => [|12$$3|];
}");
}
[Fact]
public void OnPropertyExpressionBody2()
{
TestSpan(
@"class C
{
public int Id $$=> [|123|];
}");
}
[Fact]
public void OnPropertyExpressionBody3()
{
TestSpan(
@"class C
{
$$public int Id => [|123|];
}");
}
[Fact]
public void OnPropertyExpressionBody4()
{
TestSpan(
@"class C
{
public int Id => [|123|]; $$
}");
}
[Fact]
public void OnIndexerExpressionBody1()
{
TestSpan(
@"class C
{
public int this[int a] => [|12$$3|];
}");
}
[Fact]
public void OnIndexer1()
{
TestSpan(
@"class C
{
int this[int$$ a]
{
get
[|{|]
}
set
{
}
}
}");
}
[Fact]
public void OnIndexer2()
{
TestSpan(
@"class C
{
int this[int$$ a]
{
[|get;|]
set { }
}
}");
}
[Fact]
public void OnIndexerExpressionBody2()
{
TestSpan(
@"class C
{
public int this[int a] $$=> [|123|];
}");
}
[Fact]
public void OnIndexerExpressionBody3()
{
TestSpan(
@"class C
{
$$public int this[int a] => [|123|];
}");
}
[Fact]
public void OnIndexerExpressionBody4()
{
TestSpan(
@"class C
{
public int this[int a] => [|123|]; $$
}");
}
[Fact]
public void OnIndexerExpressionBody5()
{
TestSpan(
@"class C
{
public int this[int $$a] => [|123|];
}");
}
[Fact]
public void OnMethod1()
{
TestSpan(
@"class C
{
v$$oid Goo()
[|{|]
}
}");
}
[Fact]
public void OnMethod2()
{
TestSpan(
@"class C
{
void G$$oo()
[|{|]
}
}");
}
[Fact]
public void OnMethod3()
{
TestSpan(
@"class C
{
void Goo(in$$t i)
[|{|]
}
}");
}
[Fact]
public void OnMethod4()
{
TestSpan(
@"class C
{
void Goo(int $$i)
[|{|]
}
}");
}
[Fact]
public void OnMethod5()
{
TestSpan(
@"class C
{
void Goo(int i = g$$oo)
[|{|]
}
}");
}
[Fact]
public void OnMethodWithExpressionBody1()
{
TestSpan(
@"class C
{
v$$oid Goo() => [|123|];
}");
}
[Fact]
public void OnMethodWithExpressionBody2()
{
TestSpan(
@"class C
{
void Goo() =>$$ [|123|];
}");
}
[Fact]
public void OnMethodWithExpressionBody3()
{
TestSpan(
@"class C
{
void Goo() => [|123|]; $$
}");
}
[Fact]
public void OnMethodWithExpressionBody4()
{
TestSpan(
@"class C
{
void Goo() => [|12$$3|];
}");
}
[Fact]
public void MissingOnMethod()
{
TestMissing(
@"class C
{
void Goo($$);
}");
}
#region Constructors
[Fact]
public void InstanceConstructor_NoInitializer_BlockBody_All()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(
@"class C
{
[Attribute1, Attribute2][Attribute3][|$$public C()|] [|{|] [|}|]
}");
}
[Fact]
public void InstanceConstructor_NoInitializer_BlockBody()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
[|pub$$lic C()|]
{
}
}");
}
[Fact]
public void InstanceConstructor_NoBody()
{
TestSpan(
@"class Class
{
[|Cla$$ss()|]
}");
}
[Fact]
public void InstanceConstructor_NoInitializer_ExpressionBody_All()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(
@"class C
{
[Attribute1, Attribute2][Attribute3][|$$public C()|] => [|x = 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody1()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
[|pub$$lic C()|] => F();
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody2()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
[|public C()|] $$=> x = 1);
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody3()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
public C() =$$> [|x = 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody4()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
public C() => [|$$x = 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody5()
{
TestSpan(
@"class C
{
public C() => [|x =$$ 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody6()
{
TestSpan(
@"class C
{
public C() => [|x = 1|]$$;
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void InstanceConstructor_NoInitializer_ExpressionBody7()
{
TestSpan(
@"class C
{
public C() => [|x = 1|];$$
}");
}
[Fact]
public void InstanceConstructor_NoInitializer_Attributes()
{
TestSpan(
@"class C
{
[Attribute1,$$ Attribute2]
[Attribute3]
[|public
C()|]
{
}
}");
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ImplicitBaseInitializer_OutsideOfIdentifierAndNonEmptyParameters(
[CombinatorialValues("class", "struct", "record", "record struct")] string keyword,
[CombinatorialValues(
"$$[A]class [|C()|];",
"$$class [|C()|];",
"class$$ [|C()|];",
"class [|C($$)|];",
"$$class [|C(int a)|];",
"$$class [|C(int a, int b)|];",
"class [|C(int a, int b)|]$$;",
"class [|C(int a, int b)|]$$ { }",
"class [|C(int a, int b)|]$$ : B { }",
"class [|C(int a, int b)|] : B$$ { }",
"class [|C(int a, int b)|] : B, $$I { }",
"class [|C<T>(int a, int b)|]$$ where T : notnull;",
"class [|C<T>(int a, int b)|] where $$T : notnull;",
"class [|C<T>(int a, int b)|] where T : notnull$$;",
"class [|C<T>(int a, int b)|] where T : notnull$$ { }")] string source)
{
TestSpan(source.Replace("class", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ImplicitBaseInitializer_OnIdentifierOrNonEmptyParameters_NonRecord(
[CombinatorialValues("class", "struct")] string keyword,
[CombinatorialValues(
"class [|$$C(int a, int b)|];",
"class [|C$$(int a, int b)|];",
"class [|C$$<T>(int a, int b)|];",
"class [|C<$$T>(int a, int b)|];",
"class [|C<$$[A]T>(int a, int b)|];",
"class [|C<T>$$(int a, int b)|];",
"class [|C<T>($$int a, int b)|];",
"class [|C<T>($$[A]int a, int b)|];",
"class [|C<T>(int a, int b$$)|];")] string source)
{
TestSpan(source.Replace("class", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ImplicitBaseInitializer_OnIdentifierOrNonEmptyParameters_Record(
[CombinatorialValues("record", "record struct")] string keyword,
[CombinatorialValues(
"record [|$$C|](int a, int b);", // copy-ctor
"record [|C$$|](int a, int b);", // copy-ctor
"record [|C$$<T>|](int a, int b);", // copy-ctor
"record [|C<$$T>|](int a, int b);", // copy-ctor
"record [|C<$$[A]T>|](int a, int b);", // copy-ctor
"record [|C<T>$$|](int a, int b);", // copy-ctor
"record C<T>([|$$int a|], int b);", // property getter and setter
"record C<T>($$[A][|int a|], int b);", // property getter and setter
"record C<T>($$ [A][|int a|], int b);", // property getter and setter
"record C<T>(int a, [|int b$$|]);", // property getter and setter
"record C<T>(int a, $$ [|int b|]);", // property getter and setter
"record C<T>(int a, [|params int[] b|] $$);", // property getter and setter
"record C<T>(int a, [|int b|] = default$$);")] string source) // property getter and setter
{
TestSpan(source.Replace("record", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ImplicitBaseInitializer_NoBreakpoint(
[CombinatorialValues("class", "struct", "record", "record struct")] string keyword,
[CombinatorialValues(
"$$[A]class C;",
"$$class C;",
"class C$$;",
"class C;$$",
"class C(int a, int b);$$",
"class C(int a, int b) : B;$$",
"class C(int a, int b) : B { }$$")] string source)
{
TestMissing(source.Replace("class", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ExplicitBaseInitializer_OutsideOfIdentifierAndNonEmptyParameters(
[CombinatorialValues("class", "struct", "record", "record struct")] string keyword,
[CombinatorialValues(
"$$[A]class C() : [|B()|];",
"$$class C() : [|B()|];",
"$$class C(int a) : [|B()|];",
"$$class C(int a, int b) : [|B()|];",
"class C(int a, int b)$$ : [|B()|];",
"class C(int a, int b) :$$ [|B()|];",
"class C(int a, int b) : [|$$B()|];",
"class C(int a, int b) : [|B($$)|];",
"class C(int a, int b) : [|B()$$|];",
"class C(int a, int b) : [|B()|] $$;",
"class C(int a, int b) : [|B()|] $$ {}",
"class C(int a, int b) : [|B()|], $$I {}",
"class C(int a, int b) : [|B()|], I$$ {}",
"class C<T>(int a, int b) : [|B()|] $$ where T : notnull;",
"class C<T>(int a, int b) : [|B()|], $$I where T : notnull { }",
"class C<T>(int a, int b) : [|B()|], I$$ where T : notnull { }",
"class C<T>(int a, int b) : [|B()|] where $$T : notnull;",
"class C<T>(int a, int b) : [|B()|] where T : notnull$$;",
"class C<T>(int a, int b) : [|B()|] where T : notnull$$ { }")] string source)
{
TestSpan(source.Replace("class", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ExplicitBaseInitializer_OnIdentifierOrNonEmptyParameters_NonRecord(
[CombinatorialValues("class", "struct")] string keyword,
[CombinatorialValues(
"class $$C(int a, int b) : [|B()|];",
"class C$$(int a, int b) : [|B()|];",
"class C<$$[A]T>(int a, int b) : [|B()|];",
"class C<T>$$(int a, int b) : [|B()|];",
"class C<T>($$int a, int b) : [|B()|];",
"class C<T>(int a, $$int b) : [|B()|];",
"class C<T>(int a, int b =$$ 1) : [|B()|];")] string source)
{
TestSpan(source.Replace("class", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ExplicitBaseInitializer_OnIdentifierOrNonEmptyParameters_Record(
[CombinatorialValues("record", "record struct")] string keyword,
[CombinatorialValues(
"record [|$$C|](int a, int b) : B();", // copy-constructor
"record [|C$$|](int a, int b) : B();", // copy-constructor
"record [|C<$$[A]T>|](int a, int b) : B();", // copy-constructor
"record [|C<T>$$|](int a, int b) : B();", // copy-constructor
"record C<T>([|$$int a|], int b) : B();", // property getter and setter
"record C<T>(int a, [|$$int b|]) : B();", // property getter and setter
"record C<T>(int a, [|$$int b|] = 1) : B();")] string source) // property getter and setter
{
TestSpan(source.Replace("record", keyword));
}
[Theory, CombinatorialData]
public void InstanceConstructor_Primary_ExplicitBaseInitializer_NoBreakpoint(
[CombinatorialValues("class", "struct", "record", "record struct")] string keyword,
[CombinatorialValues(
"class C(int a, int b) : B() {$$ }",
"class C(int a, int b) : B();$$",
"class C(int a, int b) : B() { }$$",
"class C(int a, int b) : B {$$ }",
"class C(int a, int b) : B(), I { }$$")] string source)
{
TestMissing(source.Replace("class", keyword));
}
[Fact]
public void InstanceConstructor_BaseInitializer_BlockBody_All()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(
@"class C
{
[Attribute1, Attribute2][Attribute3]$$public C() : [|base(42)|] [|{|][|}|]
}");
}
[Fact]
public void InstanceConstructor_BaseInitializer_BlockBody()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
pub$$lic C()
: [|base(42)|]
{
}
}");
}
[Fact]
public void InstanceConstructor_BaseInitializer_ExpressionBody_All()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(
@"class C
{
[Attribute1, Attribute2][Attribute3]$$public C() : [|base(42)|] => [|x = 1|];
}");
}
[Fact]
public void InstanceConstructor_BaseInitializer_ExpressionBody1()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
pub$$lic C() : [|base(42)|] => F();
}");
}
[Fact]
public void InstanceConstructor_BaseInitializer_ExpressionBody2()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
public C() : [|base(42)|] $$=> F();
}");
}
[Fact]
public void InstanceConstructor_BaseInitializer_ExpressionBody3()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
public C() : base(42) =$$> [|F()|];
}");
}
[Fact]
public void InstanceConstructor_BaseInitializer_ExpressionBody4()
{
// a sequence point for base constructor call
TestSpan(
@"class C
{
public C() : base(42) => [|$$F()|];
}");
}
[Fact]
public void InstanceConstructor_ThisInitializer()
{
// a sequence point for this constructor call
TestSpan(
@"class C
{
pub$$lic C()
: [|this(42)|]
{
}
}");
}
[Fact]
public void StaticConstructor_BlockBody_All()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(
@"class C
{
[Attribute1, Attribute2][Attribute3]$$static public C() [|{|] [|}|]
}");
}
[Fact]
public void StaticConstructor_BlockBody()
{
TestSpan(
@"class C
{
$$static C()
[|{|]
}
}");
}
[Fact]
public void StaticConstructor_ExpressionBody_All()
{
VerifyAllSpansInDeclaration<ConstructorDeclarationSyntax>(
@"class C
{
[Attribute1, Attribute2][Attribute3]$$static public C() => [|x = 1|];
}");
}
[Fact]
public void StaticConstructor_ExpressionBody()
{
TestSpan(
@"class C
{
static C() => [|$$F()|];
}");
}
[Fact]
public void StaticConstructor_NoBody()
{
TestMissing(
@"class Class
{
static Cla$$ss()
}");
}
[Fact]
public void InstanceConstructorInitializer()
{
// a sequence point for this constructor call
TestSpan(
@"class Derived : Base
{
public Derived()
: [|this($$42)|]
{
}
}");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543968")]
public void ConstructorInitializer()
{
// a sequence point for base constructor call
TestSpan(
@"class Derived : Base
{
public Derived()
: [|base($$42)|]
{
}
}
");
}
[Fact]
public void OnStaticConstructor()
{
TestSpan(
@"class C
{
st$$atic C()
[|{|]
}
}");
}
#endregion
[Fact]
public void OnDestructor()
{
TestSpan(
@"class C
{
~C$$()
[|{|]
}
}");
}
[Fact]
public void OnOperator()
{
TestSpan(
@"class C
{
public static int op$$erator+(C c1, C c2)
[|{|]
}
}");
}
[Fact]
public void OnOperatorWithExpressionBody1()
{
TestSpan(
@"class C
{
public static int op$$erator+(C c1, C c2) => [|c1|];
}");
}
[Fact]
public void OnOperatorWithExpressionBody2()
{
TestSpan(
@"class C
{
public static int operator+(C c1, C c2) =>$$ [|c1|];
}");
}
[Fact]
public void OnOperatorWithExpressionBody3()
{
TestSpan(
@"class C
{
public static int operator+(C c1, C c2) => [|c1|]; $$
}");
}
[Fact]
public void OnOperatorWithExpressionBody4()
{
TestSpan(
@"class C
{
public static int operator+(C c1, C c2) => [|c$$1|];
}");
}
[Fact]
public void OnConversionOperator()
{
TestSpan(
@"class C
{
public static op$$erator DateTime(C c1)
[|{|]
}
}");
}
[Fact]
public void OnConversionOperatorWithExpressionBody1()
{
TestSpan(
@"class C
{
public static op$$erator DateTime(C c1) => [|DataTime.Now|];
}");
}
[Fact]
public void OnConversionOperatorWithExpressionBody2()
{
TestSpan(
@"class C
{
public static operator DateTime(C c1) =>$$ [|DataTime.Now|];
}");
}
[Fact]
public void OnConversionOperatorWithExpressionBody3()
{
TestSpan(
@"class C
{
public static operator DateTime(C c1) => [|DataTime.Now|];$$
}");
}
[Fact]
public void OnConversionOperatorWithExpressionBody4()
{
TestSpan(
@"class C
{
public static operator DateTime(C c1) => [|DataTime$$.Now|];
}");
}
[Fact, WorkItem(3557, "DevDiv_Projects/Roslyn")]
public void InFrontOfAttribute()
{
TestSpan(
@"class C
{
$$ [method: Obsolete]
void Goo()
[|{|]
}
}");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538058")]
public void InInactivePPRegion()
{
TestLine(
@"
#if blahblah
$$gooby
#endif");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538777")]
public void WithIncompleteDeclaration()
{
TestMissing(
@"
clas C
{
void Goo()
{
$$ int
}
}");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/937290")]
public void OnGetter()
{
TestSpan(
@"class C
{
public int $$Id { [|get;|] set; }
}");
TestSpan(
@"class C
{
public int Id { [|g$$et;|] set; }
}");
TestSpan(
@"class C
{
public int Id { g$$et [|{|] return 42; } set {} }
}");
TestSpan(
@"class C
{
public int$$ Id { get [|{|] return 42; } set {} }
}");
}
[Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/937290")]
public void OnSetter()
{
TestSpan(
@"class C
{
public int Id { get; [|se$$t;|] }
}");
TestSpan(
@"class C
{
public int Id { get; [|set;|] $$ }
}");
TestSpan(
@"class C
{
public int $$Id { [|set;|] get; }
}");
TestSpan(
@"class C
{
public int Id { get { return 42; } s$$et [|{|] } }
}");
TestSpan(
@"class C
{
public int Id { get { return 42; } set { [|}|] $$}
}");
}
[Fact]
public void WhenClause_1()
{
TestSpan(
@"class C
{
string s;
bool b;
void Goo()
{
switch (s)
{
$$ case string s [|when b|]:
break;
}
}
}");
}
[Fact]
public void WhenClause_2()
{
TestSpan(
@"class C
{
string s;
bool b;
void Goo()
{
switch (s)
{
case string s [|whe$$n b|]:
break;
}
}
}");
}
[Fact]
public void WhenClause_3()
{
TestSpan(
@"class C
{
string s;
bool b;
void Goo()
{
switch (s)
{
case string s [|when b|]:$$
break;
}
}
}");
}
[Fact]
public void PatternSwitchCase_1()
{
TestSpan(
@"class C
{
string s;
bool b;
void Goo()
{
switch (s)
{
$$ case string s:
default:
[|break;|]
}
}
}");
}
[Fact]
public void PatternSwitchCase_2()
{
TestSpan(
@"class C
{
string s;
bool b;
void Goo()
{
switch (s)
{
$$case string s:
default:
[|break;|]
}
}
}");
}
[Fact]
public void PatternSwitchCase_3()
{
TestSpan(
@"class C
{
string s;
bool b;
void Goo()
{
switch (s)
{
case string s:$$
default:
[|break;|]
}
}
}");
}
[Fact]
public void DeconstructionDeclarationStatement_1()
{
TestSpan(
@"class C
{
void Goo()
{
$$ [|var (x, y) = (1, 2);|]
}
}");
}
[Fact]
public void DeconstructionDeclarationStatement_2()
{
TestSpan(
@"class C
{
void Goo()
{
[|var (x, y) = $$(1, 2);|]
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody1()
{
TestSpan(
@"class C
{
public int Id { get => [|12$$3|]; }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody2()
{
TestSpan(
@"class C
{
public int Id { get $$=> [|123|]; }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody3()
{
TestSpan(
@"class C
{
$$public int Id { get => [|123|]; }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody4()
{
TestSpan(
@"class C
{
public int Id { get => [|123|]; $$ }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody5()
{
TestSpan(
@"class C
{
$$ public event Action Goo { add => [|123|]; remove => 456; }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody6()
{
TestSpan(
@"class C
{
public event Action Goo { add => [|123|];$$ remove => 456; }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody7()
{
TestSpan(
@"class C
{
public event Action Goo { add => 123; $$remove => [|456|]; }
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody8()
{
TestSpan(
@"class C
{
public event Action Goo { add => 123; remove => [|456|]; }$$
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody1()
{
TestSpan(
@"class C
{
$$ public ~C() => [|x = 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody2()
{
TestSpan(
@"class C
{
public ~C() => $$[|x = 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody3()
{
TestSpan(
@"class C
{
public ~C() => [|x =$$ 1|];
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody4()
{
TestSpan(
@"class C
{
public ~C() => [|x = 1|]$$;
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody5()
{
TestSpan(
@"class C
{
public ~C() => [|x = 1|];$$
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_1()
{
TestSpan(
@"class C
{
static void M()
{
$$ int Local(object[] a)
[|{|]
return a.Length;
}
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_2()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object[] a)$$
[|{|]
return a.Length;
}
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_3()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object[] a)
$$ [|{|]
return a.Length;
}
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_4()
{
TestSpan(
@"class C
{
static void M()
{
$$ int Local(object[] a) => [|a.Length|];
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_5()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object$$[] a) => [|a.Length|];
}
}");
}
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_6()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object[] a) => [|a.Length|];$$
}
}");
}
[Fact, WorkItem("https://developercommunity.visualstudio.com/content/problem/98990/cant-set-breakpoint.html")]
public void IncompleteExpressionStatement()
{
TestSpan(
@"class C
{
void Goo()
{
[|$$aaa|]
}
}");
}
#region Top Level Statements
[Fact]
public void TopLevelStatements()
{
VerifyAllSpansInDeclaration<CompilationUnitSyntax>(@"
$$[|int d = 5;|]
[|int a = 1|], [|b = 2|], [|c = 3|];
for ([|int i = 0|], [|j = 1|], [|k = 2|]; [|i < 10|]; [|i++|], [|j++|], [|k--|])
[|while (b > 0)|]
[|{|]
[|if (c < b)|]
try
[|{|]
[|System.Console.WriteLine(a);|]
[|}|]
[|catch (Exception e)|]
[|{|]
[|System.Console.WriteLine(e);|]
[|}|]
finally
[|{|]
[|}|]
else [|if (b < 10)|]
[|System.Console.WriteLine(b);|]
else
[|System.Console.WriteLine(c);|]
[|}|]
");
}
#endregion
}
|