未验证 提交 fbf2e40f 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #42254 from CyrusNajmabadi/doNotGenerateReadOnlyWhenInsideLocalFunction

Do not generate read-only when inside local function
......@@ -11,7 +11,6 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.GenerateVariable;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Options;
......@@ -9270,5 +9269,51 @@ public void Method(int goo)
void M1(int a);
}", index: ParameterAndOverrides);
}
[WorkItem(26502, "https://github.com/dotnet/roslyn/issues/26502")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public async Task TestNoReadOnlyMembersWhenInLambdaInConstructor()
{
await TestExactActionSetOfferedAsync(
@"using System;
class C
{
public C()
{
Action a = () =>
{
this.[|Field|] = 1;
};
}
}", new[]
{
string.Format(FeaturesResources.Generate_property_1_0, "Field", "C"),
string.Format(FeaturesResources.Generate_field_1_0, "Field", "C"),
});
}
[WorkItem(26502, "https://github.com/dotnet/roslyn/issues/26502")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public async Task TestNoReadOnlyMembersWhenInLocalFunctionInConstructor()
{
await TestExactActionSetOfferedAsync(
@"using System;
class C
{
public C()
{
void Goo()
{
this.[|Field|] = 1;
};
}
}", new[]
{
string.Format(FeaturesResources.Generate_property_1_0, "Field", "C"),
string.Format(FeaturesResources.Generate_field_1_0, "Field", "C"),
});
}
}
}
......@@ -32,7 +32,6 @@ private partial class State
// Just the name of the method. i.e. "Goo" in "Goo" or "X.Goo"
public SyntaxToken IdentifierToken { get; private set; }
public TSimpleNameSyntax SimpleNameOpt { get; private set; }
// The entire expression containing the name. i.e. "X.Goo"
public TExpressionSyntax SimpleNameOrMemberAccessExpressionOpt { get; private set; }
......@@ -209,7 +208,6 @@ internal bool CanGenerateParameter()
return false;
}
SimpleNameOpt = simpleName;
IdentifierToken = identifierToken;
SimpleNameOrMemberAccessExpressionOpt = simpleNameOrMemberAccessExpression;
IsInExecutableBlock = isInExecutableBlock;
......@@ -267,9 +265,10 @@ internal bool CanGenerateParameter()
IsInOutContext = semanticFacts.IsInOutContext(semanticModel, SimpleNameOrMemberAccessExpressionOpt, cancellationToken);
IsWrittenTo = semanticFacts.IsWrittenTo(semanticModel, SimpleNameOrMemberAccessExpressionOpt, cancellationToken);
IsOnlyWrittenTo = semanticFacts.IsOnlyWrittenTo(semanticModel, SimpleNameOrMemberAccessExpressionOpt, cancellationToken);
IsInConstructor = DetermineIsInConstructor(semanticDocument);
IsInMemberContext = SimpleNameOpt != SimpleNameOrMemberAccessExpressionOpt ||
syntaxFacts.IsObjectInitializerNamedAssignmentIdentifier(SimpleNameOrMemberAccessExpressionOpt);
IsInConstructor = DetermineIsInConstructor(semanticDocument, simpleName);
IsInMemberContext =
simpleName != SimpleNameOrMemberAccessExpressionOpt ||
syntaxFacts.IsObjectInitializerNamedAssignmentIdentifier(SimpleNameOrMemberAccessExpressionOpt);
ContainingMethod = semanticModel.GetEnclosingSymbol<IMethodSymbol>(IdentifierToken.SpanStart, cancellationToken);
......@@ -428,15 +427,18 @@ private int GetStatementIndex(ChildSyntaxList children, SyntaxNode statement)
}
}
private bool DetermineIsInConstructor(SemanticDocument semanticDocument)
private bool DetermineIsInConstructor(SemanticDocument semanticDocument, SyntaxNode simpleName)
{
if (!ContainingType.OriginalDefinition.Equals(TypeToGenerateIn.OriginalDefinition))
{
return false;
}
var syntaxFacts = semanticDocument.Document.GetLanguageService<ISyntaxFactsService>();
return syntaxFacts.IsInConstructor(SimpleNameOpt);
// If we're in an lambda/local function we're not actually 'in' the constructor.
// i.e. we can't actually write to read-only fields here.
var syntaxFacts = semanticDocument.Document.GetRequiredLanguageService<ISyntaxFactsService>();
if (simpleName.AncestorsAndSelf().Any(n => syntaxFacts.IsAnonymousOrLocalFunction(n)))
return false;
return syntaxFacts.IsInConstructor(simpleName);
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册