diff --git a/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyAnalyzer.cs b/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyAnalyzer.cs index 1845c27d82dcbe62af791027274d3ae590640441..8d3e48427f762ce239b3a69206bddb83d0f7d9a7 100644 --- a/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyAnalyzer.cs +++ b/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyAnalyzer.cs @@ -56,8 +56,7 @@ protected override bool SupportsPropertyInitializer(Compilation compilation) if (member is PropertyDeclarationSyntax propertyDeclaration) { - var property = (IPropertySymbol)context.SemanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken); - AnalyzeProperty(context, property, analysisResults); + AnalyzeProperty(context, propertyDeclaration, analysisResults); } } diff --git a/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs b/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs index 16ca0b66982c88fefada3ebfae27bc7624cc8f20..42e3250a294c278a05e3ab529aa0f3d9285bdf51 100644 --- a/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs +++ b/src/EditorFeatures/CSharp/UseAutoProperty/UseAutoPropertyCodeFixProvider.cs @@ -36,7 +36,6 @@ protected override SyntaxNode GetNodeToRemove(VariableDeclaratorSyntax declarato var sourceText = await propertyDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var getAccessor = propertyDeclaration.AccessorList.Accessors.First(d => d.IsKind(SyntaxKind.GetAccessorDeclaration)); - var isSingleLine = sourceText.AreOnSameLine(getAccessor.GetFirstToken(), getAccessor.GetLastToken()); var updatedProperty = propertyDeclaration.WithAccessorList(UpdateAccessorList(propertyDeclaration.AccessorList)); @@ -63,10 +62,7 @@ protected override SyntaxNode GetNodeToRemove(VariableDeclaratorSyntax declarato .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); } - if (isSingleLine) - { - updatedProperty = updatedProperty.WithAdditionalAnnotations(SpecializedFormattingAnnotation); - } + updatedProperty = updatedProperty.WithAdditionalAnnotations(SpecializedFormattingAnnotation); return updatedProperty; } diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs index ae8dd3bd1812b29f2287f05d2b3d40e3bd5477cc..453285d2f4687cc01554de54421cd77bd97120d4 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/UseAutoProperty/UseAutoPropertyTests.cs @@ -35,9 +35,7 @@ int P @"class Class { - int P - { - get; } + int P { get; } }"); } @@ -60,9 +58,7 @@ public int P @"class Class { - public int P - { - get; private set; } + public int P { get; private set; } }", CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp5)); } @@ -104,9 +100,7 @@ int P @"class Class { - int P - { - get; } = 1; + int P { get; } = 1; }"); } @@ -147,9 +141,7 @@ public async Task TestSingleGetterFromProperty() @"class Class { - int P - { - get; } + int P { get; } }"); } @@ -195,9 +187,7 @@ int P @"class Class { - int P - { - get; set; } + int P { get; set; } }"); } @@ -220,9 +210,7 @@ int P @"class Class { - int P - { - get; } + int P { get; } }"); } @@ -268,9 +256,7 @@ int P @"class Class { - int P - { - get; set; } + int P { get; set; } }"); } @@ -503,9 +489,7 @@ int P { int j, k; - int P - { - get; } + int P { get; } }"); } @@ -529,9 +513,7 @@ int P { int i, k; - int P - { - get; } + int P { get; } }"); } @@ -555,9 +537,7 @@ int P { int i, j; - int P - { - get; } + int P { get; } }"); } @@ -586,9 +566,7 @@ int P partial class Class { - int P - { - get; } + int P { get; } }"); } @@ -635,9 +613,7 @@ public Class() @"class Class { - int P - { - get; } + int P { get; } public Class() { @@ -670,9 +646,7 @@ public Class(int P) @"class Class { - int P - { - get; } + int P { get; } public Class(int P) { @@ -705,9 +679,7 @@ public Class() @"class Class { - int P - { - get; } + int P { get; } public Class() { @@ -740,9 +712,7 @@ public void Goo() @"class Class { - int P - { - get; set; } + int P { get; set; } public void Goo() { @@ -775,9 +745,7 @@ public void Goo() @"class Class { - public int P - { - get; private set; } + public int P { get; private set; } public void Goo() { @@ -877,9 +845,7 @@ public async Task Tuple_SingleGetterFromField() @"class Class { - (int, string) P - { - get; } + (int, string) P { get; } }"); } @@ -902,9 +868,7 @@ public async Task TupleWithNames_SingleGetterFromField() @"class Class { - (int a, string b) P - { - get; } + (int a, string b) P { get; } }"); } @@ -945,9 +909,7 @@ public async Task TupleWithOneName_SingleGetterFromField() @"class Class { - (int a, string) P - { - get; } + (int a, string) P { get; } }"); } @@ -970,9 +932,7 @@ public async Task Tuple_Initializer() @"class Class { - (int, string) P - { - get; } = (1, ""hello""); + (int, string) P { get; } = (1, ""hello""); }"); } @@ -1000,9 +960,42 @@ public async Task Tuple_GetterAndSetter() @"class Class { - (int, string) P + (int, string) P { get; set; } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseAutoProperty)] + public async Task TestFixAllInDocument() + { + await TestInRegularAndScriptAsync( +@"class Class +{ + {|FixAllInDocument:int i|}; + + int P { - get; set; } + get + { + return i; + } + } + + int j; + + int Q + { + get + { + return j; + } + } +}", +@"class Class +{ + + int P { get; } + + int Q { get; } }"); } } diff --git a/src/EditorFeatures/VisualBasic/UseAutoProperty/UseAutoPropertyAnalyzer.vb b/src/EditorFeatures/VisualBasic/UseAutoProperty/UseAutoPropertyAnalyzer.vb index 99395ed8efd268822983a9ce91aa3d70b883a997..545e719ff2d842e0521069e33e02a56f53cd1764 100644 --- a/src/EditorFeatures/VisualBasic/UseAutoProperty/UseAutoPropertyAnalyzer.vb +++ b/src/EditorFeatures/VisualBasic/UseAutoProperty/UseAutoPropertyAnalyzer.vb @@ -53,8 +53,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UseAutoProperty Dim propertyDeclaration = TryCast(member, PropertyBlockSyntax) If propertyDeclaration IsNot Nothing Then - Dim [property] = context.SemanticModel.GetDeclaredSymbol(propertyDeclaration, context.CancellationToken) - AnalyzeProperty(context, [property], analysisResults) + AnalyzeProperty(context, propertyDeclaration, analysisResults) End If End Sub diff --git a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs index cbadd0f101aa58871cc3dfdef684b1e10fda7be0..da9f27ec7ecbffed599930167a4f9928ddb641d8 100644 --- a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs +++ b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs @@ -10,11 +10,6 @@ namespace Microsoft.CodeAnalysis.UseAutoProperty { - internal static class Constants - { - public const string SymbolEquivalenceKey = nameof(SymbolEquivalenceKey); - } - internal abstract class AbstractUseAutoPropertyAnalyzer : AbstractCodeStyleDiagnosticAnalyzer where TPropertyDeclaration : SyntaxNode @@ -31,7 +26,7 @@ protected AbstractUseAutoPropertyAnalyzer() } public override bool OpenFileOnly(Workspace workspace) => false; - public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.ProjectAnalysis; + public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticSpanAnalysis; protected abstract void RegisterIneligibleFieldsAction( List analysisResults, HashSet ineligibleFields, @@ -62,8 +57,17 @@ private void AnalyzeSemanticModel(SemanticModelAnalysisContext context) protected abstract void AnalyzeCompilationUnit(SemanticModelAnalysisContext context, SyntaxNode root, List analysisResults); - protected void AnalyzeProperty(SemanticModelAnalysisContext context, IPropertySymbol property, List analysisResults) + protected void AnalyzeProperty(SemanticModelAnalysisContext context, TPropertyDeclaration propertyDeclaration, List analysisResults) { + var cancellationToken = context.CancellationToken; + var semanticModel = context.SemanticModel; + + var property = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken) as IPropertySymbol; + if (property == null) + { + return; + } + if (property.IsIndexer) { return; @@ -104,14 +108,6 @@ protected void AnalyzeProperty(SemanticModelAnalysisContext context, IPropertySy return; } - var cancellationToken = context.CancellationToken; - var propertyDeclaration = property.DeclaringSyntaxReferences[0].GetSyntax(cancellationToken).FirstAncestorOrSelf(); - if (propertyDeclaration == null) - { - return; - } - - var semanticModel = context.SemanticModel; var getterField = GetGetterField(semanticModel, property.GetMethod, cancellationToken); if (getterField == null) { @@ -272,9 +268,6 @@ private void Process(AnalysisResult result, SemanticModelAnalysisContext context var variableDeclarator = result.VariableDeclarator; var nodeToFade = GetNodeToFade(result.FieldDeclaration, variableDeclarator); - var properties = ImmutableDictionary.Empty.Add( - Constants.SymbolEquivalenceKey, result.SymbolEquivalenceKey); - // Fade out the field/variable we are going to remove. var diagnostic1 = Diagnostic.Create(UnnecessaryWithoutSuggestionDescriptor, nodeToFade.GetLocation()); context.ReportDiagnostic(diagnostic1); @@ -284,10 +277,10 @@ private void Process(AnalysisResult result, SemanticModelAnalysisContext context // them when performing the code fix. IEnumerable additionalLocations = new Location[] { propertyDeclaration.GetLocation(), variableDeclarator.GetLocation() }; - var diagnostic2 = Diagnostic.Create(HiddenDescriptor, propertyDeclaration.GetLocation(), additionalLocations, properties); + var diagnostic2 = Diagnostic.Create(HiddenDescriptor, propertyDeclaration.GetLocation(), additionalLocations); context.ReportDiagnostic(diagnostic2); - var diagnostic3 = Diagnostic.Create(HiddenDescriptor, nodeToFade.GetLocation(), additionalLocations, properties); + var diagnostic3 = Diagnostic.Create(HiddenDescriptor, nodeToFade.GetLocation(), additionalLocations); context.ReportDiagnostic(diagnostic3); } diff --git a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs index bf732cac31d20c009a3c44cf0677f181bd49bc4d..c97e8f1cd8549e0b3b17ce487cc9f0781d3f5a15 100644 --- a/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/Core/Portable/UseAutoProperty/AbstractUseAutoPropertyCodeFixProvider.cs @@ -46,20 +46,17 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { foreach (var diagnostic in context.Diagnostics) { - var equivalenceKey = diagnostic.Properties[Constants.SymbolEquivalenceKey]; - context.RegisterCodeFix( new UseAutoPropertyCodeAction( FeaturesResources.Use_auto_property, - c => ProcessResult(context, diagnostic, c), - equivalenceKey), + c => ProcessResultAsync(context, diagnostic, c)), diagnostic); } return SpecializedTasks.EmptyTask; } - private async Task ProcessResult(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken) + private async Task ProcessResultAsync(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken) { var locations = diagnostic.AdditionalLocations; var propertyLocation = locations[0]; @@ -238,8 +235,8 @@ private async Task FormatAsync(SyntaxNode newRoot, Document document private class UseAutoPropertyCodeAction : CodeAction.SolutionChangeAction { - public UseAutoPropertyCodeAction(string title, Func> createChangedSolution, string equivalenceKey) - : base(title, createChangedSolution, equivalenceKey) + public UseAutoPropertyCodeAction(string title, Func> createChangedSolution) + : base(title, createChangedSolution, title) { } }