From 3a06d09cb5353278887a827104ad738fb1ecd5d6 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Sun, 10 Jun 2018 13:03:03 -0700 Subject: [PATCH] Recommend 'this' inside local functions --- .../ThisKeywordRecommenderTests.cs | 73 +++++++++++++++++++ .../ContextQuery/SyntaxTreeExtensions.cs | 7 ++ 2 files changed, 80 insertions(+) diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs index ee0c00f012719..3a6418d0c8f73 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/ThisKeywordRecommenderTests.cs @@ -269,6 +269,79 @@ await VerifyKeywordAsync( static int Goo($$"); } + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + [WorkItem(27028, "https://github.com/dotnet/roslyn/issues/27028")] + public async Task TestInLocalFunction() + { + await VerifyKeywordAsync( +@"class C +{ + int Method() + { + void local() + { + $$ + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + [WorkItem(27028, "https://github.com/dotnet/roslyn/issues/27028")] + public async Task TestInNestedLocalFunction() + { + await VerifyKeywordAsync( +@"class C +{ + int Method() + { + void local() + { + void nested() + { + $$ + } + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + [WorkItem(27028, "https://github.com/dotnet/roslyn/issues/27028")] + public async Task TestInLocalFunctionInStaticMethod() + { + await VerifyAbsenceAsync( +@"class C { + static int Method() + { + void local() + { + $$ + } + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + [WorkItem(27028, "https://github.com/dotnet/roslyn/issues/27028")] + public async Task TestInNestedLocalFunctionInStaticMethod() + { + await VerifyAbsenceAsync( +@"class C +{ + static int Method() + { + void local() + { + void nested() + { + $$ + } + } + } +}"); + } + [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] public async Task TestAfterAttribute() { diff --git a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs index e5b2d9924070b..cc1497d8d8dae 100644 --- a/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs +++ b/src/Workspaces/CSharp/Portable/Extensions/ContextQuery/SyntaxTreeExtensions.cs @@ -1771,6 +1771,13 @@ public static bool IsInstanceContext(this SyntaxTree syntaxTree, SyntaxToken tar #endif var enclosingSymbol = semanticModel.GetEnclosingSymbol(targetToken.SpanStart, cancellationToken); + + while (enclosingSymbol is IMethodSymbol method && method.MethodKind == MethodKind.LocalFunction) + { + // It is allowed to reference the instance (`this`) within a local function, as long as the containing method allows it + enclosingSymbol = method.ContainingSymbol; + } + return !enclosingSymbol.IsStatic; }