diff options
14 files changed, 674 insertions, 96 deletions
diff --git a/main/src/addins/CSharpBinding/CSharpBinding.csproj b/main/src/addins/CSharpBinding/CSharpBinding.csproj index cc169a2018..b91a8cab8d 100644 --- a/main/src/addins/CSharpBinding/CSharpBinding.csproj +++ b/main/src/addins/CSharpBinding/CSharpBinding.csproj @@ -782,6 +782,16 @@ <Compile Include="MonoDevelop.CSharp.CodeRefactorings\CSharpSyntaxContext.cs" /> <Compile Include="MonoDevelop.CSharp.CodeRefactorings\TypeGuessing.cs" /> <Compile Include="MonoDevelop.CSharp.CodeRefactorings\Resources.cs" /> + <Compile Include="MonoDevelop.CSharp.Features\EncapsulateField\AbstractEncapsulateFieldRefactoringProvider.cs" /> + <Compile Include="MonoDevelop.CSharp.Features\EncapsulateField\AbstractEncapsulateFieldService.cs" /> + <Compile Include="MonoDevelop.CSharp.Features\EncapsulateField\EncapsulateFieldCodeAction.cs" /> + <Compile Include="MonoDevelop.CSharp.Features\EncapsulateField\EncapsulateFieldResult.cs" /> + <Compile Include="MonoDevelop.CSharp.CodeFixes\EncapsulateField\EncapsulateFieldCodeRefactoringProvider.cs" /> + <Compile Include="MonoDevelop.CSharp.CodeFixes\EncapsulateField\AbstractEncapsulateFieldRefactoringProvider.cs" /> + <Compile Include="MonoDevelop.CSharp.Features\EncapsulateField\CSharpEncapsulateFieldService.cs" /> + <Compile Include="Util\ConflictResolver.cs" /> + <Compile Include="Util\AccessibilityUtilities.cs" /> + <Compile Include="Util\Glyph.cs" /> </ItemGroup> <ItemGroup> <None Include="Makefile.am" /> @@ -790,10 +800,6 @@ <None Include="MonoDevelop.CSharp.Completion\ArrayTypeParameterDataProvider.cs" /> <None Include="MonoDevelop.CSharp.Completion\AbstractParameterDataProvider.cs" /> <None Include="MonoDevelop.CSharp.CodeRefactorings\ConvertToEnum\ConvertToEnumCodeRefactoringProvider.cs" /> - <None Include="MonoDevelop.CSharp.Features\EncapsulateField\AbstractEncapsulateFieldRefactoringProvider.cs" /> - <None Include="MonoDevelop.CSharp.Features\EncapsulateField\AbstractEncapsulateFieldService.cs" /> - <None Include="MonoDevelop.CSharp.Features\EncapsulateField\EncapsulateFieldCodeAction.cs" /> - <None Include="MonoDevelop.CSharp.Features\EncapsulateField\EncapsulateFieldResult.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> @@ -838,5 +844,6 @@ <Folder Include="MonoDevelop.CSharp.CodeFixes\RemoveUnnecessaryCast\" /> <Folder Include="MonoDevelop.CSharp.Diagnostics\MonoTODO\" /> <Folder Include="MonoDevelop.CSharp.CodeRefactorings\ConvertToEnum\" /> + <Folder Include="MonoDevelop.CSharp.CodeFixes\EncapsulateField\" /> </ItemGroup> </Project> diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs new file mode 100644 index 0000000000..dcda5767d2 --- /dev/null +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.CodeRefactorings.EncapsulateField +{ + internal abstract class AbstractEncapsulateFieldRefactoringProvider : CodeRefactoringProvider + { + CSharpEncapsulateFieldService service = new CSharpEncapsulateFieldService (); + + public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) + { + var actions = await service.GetEncapsulateFieldCodeActionsAsync(context.Document, context.Span, context.CancellationToken).ConfigureAwait(false); + foreach (var action in actions) + context.RegisterRefactoring(action); + } + } +} diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/EncapsulateField/EncapsulateFieldCodeRefactoringProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/EncapsulateField/EncapsulateFieldCodeRefactoringProvider.cs new file mode 100644 index 0000000000..b65d232c50 --- /dev/null +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeFixes/EncapsulateField/EncapsulateFieldCodeRefactoringProvider.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeRefactorings; + +namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField +{ + [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = "Encapsulate Field"), Shared] + internal class EncapsulateFieldRefactoringProvider : AbstractEncapsulateFieldRefactoringProvider + { + } +} diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/Resources.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/Resources.cs index 7856a0cda4..0f4728caa5 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/Resources.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.CodeRefactorings/Resources.cs @@ -89,6 +89,10 @@ namespace ICSharpCode.NRefactory6.CSharp public static string RemoveAndSortUsingsWithAccelerator = "Remove _and Sort Usings"; public static string SortUsingsWithAccelerator = "_Sort Usings"; public static string RemoveUnnecessaryUsingsWithAccelerator = "_Remove Unnecessary Usings"; + public static string EncapsulateFieldsUsages = "Encapsulate fields (and use property)"; + public static string EncapsulateFields = "Encapsulate fields (but still use field)"; + public static string EncapsulateFieldUsages = "Encapsulate field: '{0}' (and use property)"; + public static string EncapsulateField = "Encapsulate field: '{0}' (but still use field)"; } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/CodeGeneration/CSharpCodeGenerationService.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/CodeGeneration/CSharpCodeGenerationService.cs index 7a86c7f5c2..fda0ff8cd7 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/CodeGeneration/CSharpCodeGenerationService.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/CodeGeneration/CSharpCodeGenerationService.cs @@ -100,6 +100,11 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeGeneration addMethodAsync = abstractServiceType.GetMethod ("AddMethodAsync", BindingFlags.Instance | BindingFlags.Public); if (addMethodAsync == null) throw new InvalidOperationException ("AddMethodAsync not found."); + addPropertyAsync = abstractServiceType.GetMethod ("AddPropertyAsync", BindingFlags.Instance | BindingFlags.Public); + if (addPropertyAsync == null) + throw new InvalidOperationException ("AddPropertyAsync not found."); + + addMembersAsync = abstractServiceType.GetMethod ("AddMembersAsync", BindingFlags.Instance | BindingFlags.Public, null, new [] { typeof(Solution), typeof(INamedTypeSymbol), typeof(IEnumerable<ISymbol>), CodeGenerationOptions.typeInfo, typeof(CancellationToken) }, null); if (addMembersAsync == null) @@ -260,6 +265,16 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeGeneration } } + public Task<Document> AddPropertyAsync(Solution solution, INamedTypeSymbol destination, IPropertySymbol property, CodeGenerationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) + { + try { + return (Task<Document>)addPropertyAsync.Invoke (instance, new object[] { solution, destination, property, options != null ? options.Instance : null, cancellationToken }); + } catch (TargetInvocationException ex) { + ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); + return null; + } + } + /// <summary> /// Adds all the provided members into destination. /// </summary> @@ -274,6 +289,7 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeGeneration } static MethodInfo addFieldAsync; + static MethodInfo addPropertyAsync; public Task<Document> AddFieldAsync(Solution solution, INamedTypeSymbol destination, IFieldSymbol field, CodeGenerationOptions options, CancellationToken cancellationToken) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs index aa12ce004d..474515d928 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldRefactoringProvider.cs @@ -9,10 +9,12 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField { public abstract class AbstractEncapsulateFieldRefactoringProvider : CodeRefactoringProvider { + CSharpEncapsulateFieldService service = new CSharpEncapsulateFieldService (); + public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { - var service = context.Document.GetLanguageService<AbstractEncapsulateFieldService>(); var actions = await service.GetEncapsulateFieldCodeActionsAsync(context.Document, context.Span, context.CancellationToken).ConfigureAwait(false); + context.RegisterRefactorings(actions); } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldService.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldService.cs index 9e37d0bfc3..badf36e8bb 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldService.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/AbstractEncapsulateFieldService.cs @@ -18,11 +18,19 @@ using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; using Microsoft.CodeAnalysis; using ICSharpCode.NRefactory6.CSharp.CodeGeneration; +using System.Globalization; +using System.Reflection; +using Microsoft.CodeAnalysis.Options; namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField { - public abstract class AbstractEncapsulateFieldService : ILanguageService + internal abstract class AbstractEncapsulateFieldService : ILanguageService { + static AbstractEncapsulateFieldService() + { + renameSymbolMethod = typeof (Renamer).GetMethod ("RenameSymbolAsync", new Type [] { typeof(Solution), typeof(ISymbol), typeof(string), typeof(OptionSet), typeof(Func<Location, bool>), typeof(Func<IEnumerable<ISymbol>, bool?>), typeof(CancellationToken) }); + } + public async Task<EncapsulateFieldResult> EncapsulateFieldAsync(Document document, TextSpan span, bool useDefaultBehavior, CancellationToken cancellationToken) { var fields = await GetFieldsAsync(document, span, cancellationToken).ConfigureAwait(false); @@ -92,6 +100,7 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField private async Task<Result> SingleEncapsulateFieldResultAsync(Document document, TextSpan span, int index, bool updateReferences, CancellationToken cancellationToken) { var fields = (await GetFieldsAsync(document, span, cancellationToken).ConfigureAwait(false)).ToImmutableArrayOrEmpty(); + //Contract.Requires(fields.Length > index); var field = fields[index]; var result = await EncapsulateFieldAsync(field, document, updateReferences, cancellationToken).ConfigureAwait(false); @@ -109,6 +118,7 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField var failedFieldSymbols = new List<IFieldSymbol>(); var fields = await GetFieldsAsync(document, span, cancellationToken).ConfigureAwait(false); + //Contract.Requires(fields.Any()); // For now, build up the multiple field case by encapsulating one at a time. Result result = null; @@ -155,7 +165,7 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField var fieldDeclaration = field.DeclaringSyntaxReferences.First(); var declarationAnnotation = new SyntaxAnnotation(); document = document.WithSyntaxRoot(fieldDeclaration.SyntaxTree.GetRoot(cancellationToken).ReplaceNode(fieldDeclaration.GetSyntax(cancellationToken), - fieldDeclaration.GetSyntax(cancellationToken).WithAdditionalAnnotations(declarationAnnotation))); + fieldDeclaration.GetSyntax(cancellationToken).WithAdditionalAnnotations(declarationAnnotation))); var solution = document.Project.Solution; @@ -180,7 +190,8 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var compilation = semanticModel.Compilation; field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol; - Solution solutionNeedingProperty = null; + + var solutionNeedingProperty = solution; // We couldn't resolve field after annotating its declaration. Bail if (field == null) @@ -188,53 +199,9 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField return null; } - if (updateReferences) - { - var locationsToIgnore = SpecializedCollections.EmptySet<TextSpan>(); - var optionSet = document.Project.Solution.Workspace.Options; - - if (field.IsReadOnly) - { - var locationSet = await RenameLocationSet.FindAsync(field, document.Project.Solution, optionSet, cancellationToken).ConfigureAwait(false); - var constructorSyntaxes = GetConstructorNodes(field.ContainingType); - var locations = locationSet.Locations.Where(l => constructorSyntaxes.Any(c => c.Span.IntersectsWith(l.Location.SourceSpan))); - - if (locations.Any()) - { - locationsToIgnore = locations.Select(l => l.Location.SourceSpan).ToSet(); - locationSet = new RenameLocationSet(locations.ToSet(), field, document.Project.Solution, locationSet.ReferencedSymbols, locationSet.ImplicitLocations); - - var resolution = await ConflictResolver.ResolveConflictsAsync(locationSet, field.Name, finalFieldName, optionSet, cancellationToken).ConfigureAwait(false); - document = resolution.NewSolution.GetDocument(document.Id); - - semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - compilation = semanticModel.Compilation; - field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol; - } - } - - var renameLocationSet = await RenameLocationSet.FindAsync(field, document.Project.Solution, optionSet, cancellationToken).ConfigureAwait(false); - renameLocationSet = new RenameLocationSet(renameLocationSet.Locations.Where(l => !locationsToIgnore.Contains(l.Location.SourceSpan)).ToSet(), - renameLocationSet.Symbol, renameLocationSet.Solution, renameLocationSet.ReferencedSymbols, renameLocationSet.ImplicitLocations); - - if (renameLocationSet.Locations.Any() || renameLocationSet.ImplicitLocations.Any()) - { - var conflictResolution = await ConflictResolver.ResolveConflictsAsync(renameLocationSet, field.Name, generatedPropertyName, optionSet, cancellationToken).ConfigureAwait(false); - - if (!conflictResolution.ReplacementTextValid) - { - return null; - } - - solutionNeedingProperty = conflictResolution.NewSolution; - document = solutionNeedingProperty.GetDocument(document.Id); - } - } - else - { - solutionNeedingProperty = document.Project.Solution; - document = solutionNeedingProperty.GetDocument(document.Id); - } + solutionNeedingProperty = await UpdateReferencesAsync( + updateReferences, solution, document, field, finalFieldName, generatedPropertyName, cancellationToken).ConfigureAwait(false); + document = solutionNeedingProperty.GetDocument(document.Id); var markFieldPrivate = field.DeclaredAccessibility != Accessibility.Private; var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, document, declarationAnnotation, cancellationToken).ConfigureAwait(false); @@ -261,9 +228,49 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField var generatedProperty = GenerateProperty(generatedPropertyName, finalFieldName, originalField.DeclaredAccessibility, originalField, field.ContainingType, new SyntaxAnnotation(), document, cancellationToken); + var codeGenerationService = new CSharpCodeGenerationService (document.Project.Solution.Workspace); var solutionWithProperty = await AddPropertyAsync(document, document.Project.Solution, field, generatedProperty, cancellationToken).ConfigureAwait(false); - return new Result(solutionWithProperty, originalField.ToDisplayString(), originalField); + return new Result(solutionWithProperty, originalField.ToDisplayString(), Glyph.FieldPublic); + } + + static Task<Solution> RenameSymbolAsync (Solution solution, ISymbol symbol, string newName, OptionSet options, Func<Location, bool> filter, Func<IEnumerable<ISymbol>, bool?> hasConflict = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return (Task<Solution>)renameSymbolMethod.Invoke (null, new object [] { solution, symbol, newName, options, filter, hasConflict, cancellationToken }); + } + + private async Task<Solution> UpdateReferencesAsync( + bool updateReferences, Solution solution, Document document, IFieldSymbol field, string finalFieldName, string generatedPropertyName, CancellationToken cancellationToken) + { + if (!updateReferences) + { + return solution; + } + + if (field.IsReadOnly) + { + // Inside the constructor we want to rename references the field to the final field name. + var constructorSyntaxes = GetConstructorNodes(field.ContainingType).ToSet(); + if (finalFieldName != field.Name && constructorSyntaxes.Count > 0) + { + solution = await RenameSymbolAsync(solution, field, finalFieldName, solution.Workspace.Options, + location => constructorSyntaxes.Any(c => c.Span.IntersectsWith(location.SourceSpan)), cancellationToken: cancellationToken).ConfigureAwait(false); + document = solution.GetDocument(document.Id); + + var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + + field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol; + } + + // Outside the constructor we want to rename references to the field to final property name. + return await RenameSymbolAsync(solution, field, generatedPropertyName, solution.Workspace.Options, + location => !constructorSyntaxes.Any(c => c.Span.IntersectsWith(location.SourceSpan)), cancellationToken: cancellationToken).ConfigureAwait(false); + } + else + { + // Just rename everything. + return await Renamer.RenameSymbolAsync(solution, field, generatedPropertyName, solution.Workspace.Options, cancellationToken).ConfigureAwait(false); + } } internal abstract IEnumerable<SyntaxNode> GetConstructorNodes(INamedTypeSymbol containingType); @@ -273,11 +280,11 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField var codeGenerationService = new CSharpCodeGenerationService (document.Project.Solution.Workspace); var fieldDeclaration = field.DeclaringSyntaxReferences.First(); - var options = new CodeGenerationOptions(contextLocation: fieldDeclaration.SyntaxTree.GetLocation(fieldDeclaration.Span), generateDefaultAccessibility:false); + var options = new CodeGenerationOptions(contextLocation: fieldDeclaration.SyntaxTree.GetLocation(fieldDeclaration.Span)); var destination = field.ContainingType; var updatedDocument = await codeGenerationService.AddPropertyAsync(destinationSolution, destination, property, options, cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(false); updatedDocument = await Formatter.FormatAsync(updatedDocument, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false); updatedDocument = await Simplifier.ReduceAsync(updatedDocument, cancellationToken: cancellationToken).ConfigureAwait(false); @@ -285,20 +292,20 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField return updatedDocument.Project.Solution; } - protected IPropertySymbol GenerateProperty(string propertyName, string fieldName, Accessibility accessiblity, IFieldSymbol field, INamedTypeSymbol containingSymbol, SyntaxAnnotation annotation, Document document, CancellationToken cancellationToken) + protected IPropertySymbol GenerateProperty(string propertyName, string fieldName, Accessibility accessibility, IFieldSymbol field, INamedTypeSymbol containingSymbol, SyntaxAnnotation annotation, Document document, CancellationToken cancellationToken) { var factory = document.GetLanguageService<SyntaxGenerator>(); var propertySymbol = annotation.AddAnnotationToSymbol(CodeGenerationSymbolFactory.CreatePropertySymbol(containingType: containingSymbol, - attributes: SpecializedCollections.EmptyList<AttributeData>(), - accessibility: ComputeAccesibility(accessiblity, field.Type), - modifiers: new DeclarationModifiers(isStatic: field.IsStatic, isReadOnly: field.IsReadOnly, isUnsafe: field.IsUnsafe()), - type: field.Type, - explicitInterfaceSymbol: null, - name: propertyName, - parameters: SpecializedCollections.EmptyList<IParameterSymbol>(), - getMethod: CreateGet(fieldName, field, factory), - setMethod: field.IsReadOnly || field.IsConst ? null : CreateSet(fieldName, field, factory))); + attributes: SpecializedCollections.EmptyList<AttributeData>(), + accessibility: ComputeAccessibility(accessibility, field.Type), + modifiers: new DeclarationModifiers().WithIsStatic (field.IsStatic).WithIsReadOnly (field.IsReadOnly).WithIsUnsafe (field.IsUnsafe()), + type: field.Type, + explicitInterfaceSymbol: null, + name: propertyName, + parameters: SpecializedCollections.EmptyList<IParameterSymbol>(), + getMethod: CreateGet(fieldName, field, factory), + setMethod: field.IsReadOnly || field.IsConst ? null : CreateSet(fieldName, field, factory))); return Simplifier.Annotation.AddAnnotationToSymbol( Formatter.Annotation.AddAnnotationToSymbol(propertySymbol)); @@ -306,26 +313,26 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField protected abstract Tuple<string, string> GeneratePropertyAndFieldNames(IFieldSymbol field); - protected Accessibility ComputeAccesibility(Accessibility accessibility, ITypeSymbol type) + protected Accessibility ComputeAccessibility(Accessibility accessibility, ITypeSymbol type) { - var computedAccessbility = accessibility; + var computedAccessibility = accessibility; if (accessibility == Accessibility.NotApplicable || accessibility == Accessibility.Private) { - computedAccessbility = Accessibility.Public; + computedAccessibility = Accessibility.Public; } var returnTypeAccessibility = type.DetermineMinimalAccessibility(); - return CommonAccessibilityUtilities.Minimum(computedAccessbility, returnTypeAccessibility); + return AccessibilityUtilities.Minimum(computedAccessibility, returnTypeAccessibility); } protected IMethodSymbol CreateSet(string originalFieldName, IFieldSymbol field, SyntaxGenerator factory) { var assigned = !field.IsStatic - ? factory.MemberAccessExpression( - factory.ThisExpression(), - factory.IdentifierName(originalFieldName)) - : factory.IdentifierName(originalFieldName); + ? factory.MemberAccessExpression( + factory.ThisExpression(), + factory.IdentifierName(originalFieldName)) + : factory.IdentifierName(originalFieldName); var body = factory.ExpressionStatement( factory.AssignmentStatement( @@ -333,8 +340,8 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField factory.IdentifierName("value"))); return CodeGenerationSymbolFactory.CreateAccessorSymbol(SpecializedCollections.EmptyList<AttributeData>(), - Accessibility.NotApplicable, - new[] { body }.ToList()); + Accessibility.NotApplicable, + new[] { body }.ToList()); } protected IMethodSymbol CreateGet(string originalFieldName, IFieldSymbol field, SyntaxGenerator factory) @@ -343,8 +350,8 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField factory.IdentifierName(originalFieldName)); return CodeGenerationSymbolFactory.CreateAccessorSymbol(SpecializedCollections.EmptyList<AttributeData>(), - Accessibility.NotApplicable, - new[] { body }.ToList()); + Accessibility.NotApplicable, + new[] { body }.ToList()); } private static readonly char[] s_underscoreCharArray = new[] { '_' }; @@ -366,37 +373,42 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField baseName = fieldName; } - // Make uppercase the first letter - return char.ToUpper(baseName[0]).ToString() + baseName.Substring(1); + // Make the first character upper case using the "en-US" culture. See discussion at + // https://github.com/dotnet/roslyn/issues/5524. + var firstCharacter = EnUSCultureInfo.TextInfo.ToUpper(baseName[0]); + return firstCharacter.ToString() + baseName.Substring(1); } + internal static readonly CultureInfo EnUSCultureInfo = new CultureInfo("en-US"); + static MethodInfo renameSymbolMethod; + protected abstract Task<SyntaxNode> RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken); protected abstract Task<IEnumerable<IFieldSymbol>> GetFieldsAsync(Document document, TextSpan span, CancellationToken cancellationToken); - public class Result + internal class Result { - public Result(Solution solutionWithProperty, string name, IFieldSymbol glyph) + public Result(Solution solutionWithProperty, string name, Glyph glyph) { this.Solution = solutionWithProperty; this.Name = name; this.Glyph = glyph; } - public Result(Solution solutionWithProperty, string name, IFieldSymbol glyph, List<IFieldSymbol> failedFieldSymbols) : + public Result(Solution solutionWithProperty, string name, Glyph glyph, List<IFieldSymbol> failedFieldSymbols) : this(solutionWithProperty, name, glyph) { this.FailedFields = failedFieldSymbols.ToImmutableArrayOrEmpty(); } public Result(Solution originalSolution, params IFieldSymbol[] fields) : - this(originalSolution, string.Empty, null) + this(originalSolution, string.Empty, Glyph.Error) { this.FailedFields = fields.ToImmutableArrayOrEmpty(); } public Solution Solution { get; } public string Name { get; } - public IFieldSymbol Glyph { get; } + public Glyph Glyph { get; } public ImmutableArray<IFieldSymbol> FailedFields { get; } public Result WithFailedFields(List<IFieldSymbol> failedFieldSymbols) diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/CSharpEncapsulateFieldService.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/CSharpEncapsulateFieldService.cs new file mode 100644 index 0000000000..7d11fd3d2c --- /dev/null +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/CSharpEncapsulateFieldService.cs @@ -0,0 +1,193 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Composition; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeGeneration; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using ICSharpCode.NRefactory6.CSharp.CodeGeneration; +using Microsoft.CodeAnalysis.CSharp; + +namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField +{ + internal class CSharpEncapsulateFieldService : AbstractEncapsulateFieldService + { + protected async override Task<SyntaxNode> RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken) + { + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + var declarator = root.GetAnnotatedNodes<VariableDeclaratorSyntax>(declarationAnnotation).FirstOrDefault(); + + // There may be no field to rewrite if this document is part of a set of linked files + // and the declaration is not conditionally compiled in this document's project. + if (declarator == null) + { + return root; + } + + var tempAnnotation = new SyntaxAnnotation(); + var newIdentifier = SyntaxFactory.Identifier(originalFieldName) + .WithTrailingTrivia(declarator.Identifier.TrailingTrivia) + .WithLeadingTrivia(declarator.Identifier.LeadingTrivia); + + var updatedDeclarator = declarator.WithIdentifier(newIdentifier).WithAdditionalAnnotations(tempAnnotation); + + root = root.ReplaceNode(declarator, updatedDeclarator); + document = document.WithSyntaxRoot(root); + + var declaration = root.GetAnnotatedNodes<SyntaxNode>(tempAnnotation).First().Parent as VariableDeclarationSyntax; + + if (declaration.Variables.Count == 1) + { + var fieldSyntax = declaration.Parent as FieldDeclarationSyntax; + + var modifierKinds = new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword, SyntaxKind.PublicKeyword }; + + if (makePrivate) + { + var modifiers = SpecializedCollections.SingletonEnumerable(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)) + .Concat(fieldSyntax.Modifiers.Where(m => !modifierKinds.Contains(m.Kind()))); + + root = root.ReplaceNode(fieldSyntax, fieldSyntax.WithModifiers( + SyntaxFactory.TokenList(modifiers)) + .WithAdditionalAnnotations(Formatter.Annotation) + .WithLeadingTrivia(fieldSyntax.GetLeadingTrivia()) + .WithTrailingTrivia(fieldSyntax.GetTrailingTrivia())); + } + } + else if (declaration.Variables.Count > 1 && makePrivate) + { + document = document.WithSyntaxRoot(root); + var codeGenService = new CSharpCodeGenerationService (document.Project.Solution.Workspace.Services.GetLanguageServices (LanguageNames.CSharp)); + var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + + root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + declarator = root.GetAnnotatedNodes<VariableDeclaratorSyntax>(tempAnnotation).First(); + declaration = declarator.Parent as VariableDeclarationSyntax; + + var field = semanticModel.GetDeclaredSymbol(declarator, cancellationToken) as IFieldSymbol; + + var fieldToAdd = declarationAnnotation.AddAnnotationToSymbol(CodeGenerationSymbolFactory.CreateFieldSymbol( + field.GetAttributes(), + Accessibility.Private, + new DeclarationModifiers().WithIsStatic (field.IsStatic).WithIsReadOnly(field.IsReadOnly).WithIsConst(field.IsConst), + field.Type, + field.Name, + field.HasConstantValue, + field.ConstantValue, + declarator.Initializer)); + + var withField = await codeGenService.AddFieldAsync(document.Project.Solution, field.ContainingType, fieldToAdd, new CodeGenerationOptions(), cancellationToken).ConfigureAwait(false); + root = await withField.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + declarator = root.GetAnnotatedNodes<VariableDeclaratorSyntax>(tempAnnotation).First(); + declaration = declarator.Parent as VariableDeclarationSyntax; + + return root.RemoveNode(declarator, SyntaxRemoveOptions.KeepNoTrivia); + } + + return root; + } + + protected override async Task<IEnumerable<IFieldSymbol>> GetFieldsAsync(Document document, TextSpan span, CancellationToken cancellationToken) + { + var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + var fields = root.DescendantNodes(d => d.Span.IntersectsWith(span)) + .OfType<FieldDeclarationSyntax>() + .Where(n => n.Span.IntersectsWith(span)); + + var declarations = fields.Where(CanEncapsulate).Select(f => f.Declaration); + + IEnumerable<VariableDeclaratorSyntax> declarators; + if (span.IsEmpty) + { + // no selection, get all variables + declarators = declarations.SelectMany(d => d.Variables); + } + else + { + // has selection, get only the ones that are included in the selection + declarators = declarations.SelectMany(d => d.Variables.Where(v => v.Span.IntersectsWith(span))); + } + + return declarators.Select(d => semanticModel.GetDeclaredSymbol(d, cancellationToken) as IFieldSymbol) + .WhereNotNull() + .Where(f => f.Name.Length != 0); + } + + private bool CanEncapsulate(FieldDeclarationSyntax field) + { + return field.Parent is TypeDeclarationSyntax; + } + + protected override Tuple<string, string> GeneratePropertyAndFieldNames(IFieldSymbol field) + { + // Special case: if the field is "new", we will preserve its original name and the new keyword. + if (field.DeclaredAccessibility == Accessibility.Private || IsNew(field)) + { + // Create some capitalized version of the field name for the property + return Tuple.Create(field.Name, MakeUnique(GeneratePropertyName(field.Name), field.ContainingType)); + } + else + { + // Generate the new property name using the rules from 695042 + var newPropertyName = GeneratePropertyName(field.Name); + + if (newPropertyName == field.Name) + { + // If we wind up with the field's old name, give the field the unique version of its current name. + return Tuple.Create(MakeUnique(GenerateFieldName(field, field.Name), field.ContainingType), newPropertyName); + } + + // Otherwise, ensure the property's name is unique. + newPropertyName = MakeUnique(newPropertyName, field.ContainingType); + var newFieldName = GenerateFieldName(field, newPropertyName); + + // If converting the new property's name into a field name results in the old field name, we're done. + if (newFieldName == field.Name) + { + return Tuple.Create(newFieldName, newPropertyName); + } + + // Otherwise, ensure the new field name is unique. + return Tuple.Create(MakeUnique(newFieldName, field.ContainingType), newPropertyName); + } + } + + private bool IsNew(IFieldSymbol field) + { + return field.DeclaringSyntaxReferences.Any(d => d.GetSyntax().GetAncestor<FieldDeclarationSyntax>().Modifiers.Any(SyntaxKind.NewKeyword)); + } + + private string GenerateFieldName(IFieldSymbol field, string correspondingPropertyName) + { + return char.ToLower(correspondingPropertyName[0]).ToString() + correspondingPropertyName.Substring(1); + } + + protected string MakeUnique(string baseName, INamedTypeSymbol containingType, bool considerBaseMembers = true) + { + var containingTypeMemberNames = containingType.GetAccessibleMembersInThisAndBaseTypes<ISymbol>(containingType).Select(m => m.Name); + return NameGenerator.GenerateUniqueName(baseName, containingTypeMemberNames.ToSet(), StringComparer.Ordinal); + } + + internal override IEnumerable<SyntaxNode> GetConstructorNodes(INamedTypeSymbol containingType) + { + return containingType.Constructors.SelectMany(c => c.DeclaringSyntaxReferences.Select(d => d.GetSyntax())); + } + } +} diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldCodeAction.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldCodeAction.cs index ff257d7045..84c0c5123e 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldCodeAction.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldCodeAction.cs @@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis; namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField { - public class EncapsulateFieldCodeAction : CodeAction + class EncapsulateFieldCodeAction : CodeAction { private EncapsulateFieldResult _result; private string _title; diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldResult.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldResult.cs index 286e5e2cab..dac9827496 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldResult.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/EncapsulateField/EncapsulateFieldResult.cs @@ -8,7 +8,7 @@ using Microsoft.CodeAnalysis; namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField { - public class EncapsulateFieldResult + class EncapsulateFieldResult { private readonly Func<CancellationToken, Task<AbstractEncapsulateFieldService.Result>> _resultGetter; @@ -22,12 +22,12 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeRefactorings.EncapsulateField var result = await _resultGetter(cancellationToken).ConfigureAwait(false); return result.Name; } -// -// public async Task<Glyph> GetGlyphAsync(CancellationToken cancellationToken) -// { -// var result = await _resultGetter(cancellationToken).ConfigureAwait(false); -// return result.Glyph; -// } + + public async Task<Glyph> GetGlyphAsync(CancellationToken cancellationToken) + { + var result = await _resultGetter(cancellationToken).ConfigureAwait(false); + return result.Glyph; + } public async Task<Solution> GetSolutionAsync(CancellationToken cancellationToken) { diff --git a/main/src/addins/CSharpBinding/Util/AccessibilityUtilities.cs b/main/src/addins/CSharpBinding/Util/AccessibilityUtilities.cs new file mode 100644 index 0000000000..f0c0560f3d --- /dev/null +++ b/main/src/addins/CSharpBinding/Util/AccessibilityUtilities.cs @@ -0,0 +1,67 @@ +// +// AccessibilityUtilities.cs +// +// Author: +// Mike Krüger <mkrueger@xamarin.com> +// +// Copyright (c) 2015 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Microsoft.CodeAnalysis; + +namespace ICSharpCode.NRefactory6.CSharp +{ + internal static class AccessibilityUtilities + { + public static Accessibility Minimum(Accessibility accessibility1, Accessibility accessibility2) + { + if (accessibility1 == Accessibility.Private || accessibility2 == Accessibility.Private) + { + return Accessibility.Private; + } + + if (accessibility1 == Accessibility.ProtectedAndInternal || accessibility2 == Accessibility.ProtectedAndInternal) + { + return Accessibility.ProtectedAndInternal; + } + + if (accessibility1 == Accessibility.Protected || accessibility2 == Accessibility.Protected) + { + return Accessibility.Protected; + } + + if (accessibility1 == Accessibility.Internal || accessibility2 == Accessibility.Internal) + { + return Accessibility.Internal; + } + + if (accessibility1 == Accessibility.ProtectedOrInternal || accessibility2 == Accessibility.ProtectedOrInternal) + { + return Accessibility.ProtectedOrInternal; + } + + return Accessibility.Public; + } + } +} + diff --git a/main/src/addins/CSharpBinding/Util/ConflictResolver.cs b/main/src/addins/CSharpBinding/Util/ConflictResolver.cs new file mode 100644 index 0000000000..03c541b703 --- /dev/null +++ b/main/src/addins/CSharpBinding/Util/ConflictResolver.cs @@ -0,0 +1,114 @@ +// +// ConflictResolver.cs +// +// Author: +// Mike Krüger <mkrueger@xamarin.com> +// +// Copyright (c) 2015 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Utilities; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Text; +using Roslyn.Utilities; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using System; +using Microsoft.CodeAnalysis.Options; +using System.Threading.Tasks; +using System.Reflection; +using System.Runtime.ExceptionServices; + +namespace ICSharpCode.NRefactory6.CSharp +{ + class ConflictResolution + { + static Type typeInfo; + internal object instance; + + static ConflictResolution () + { + typeInfo = Type.GetType ("Microsoft.CodeAnalysis.Rename.ConflictEngine.ConflictResolution" + ReflectionNamespaces.WorkspacesAsmName, true); + + } + + public ConflictResolution (object instance) + { + this.instance = instance; + } + + } + + class RenameLocations + { + static Type typeInfo; + internal object instance; + + static RenameLocations () + { + typeInfo = Type.GetType ("Microsoft.CodeAnalysis.Rename.RenameLocations" + ReflectionNamespaces.WorkspacesAsmName, true); + + } + + public RenameLocations (object instance) + { + this.instance = instance; + } + + } + + + class ConflictResolver + { + static MethodInfo resolveConflictsAsyncMethod; + static Type typeInfo; + + static ConflictResolver () + { + typeInfo = Type.GetType ("Microsoft.CodeAnalysis.Rename.ConflictEngine.ConflictResolver" + ReflectionNamespaces.WorkspacesAsmName, true); + resolveConflictsAsyncMethod = typeInfo.GetMethod ("ResolveConflictsAsync"); + + } + + public static Task<ConflictResolution> ResolveConflictsAsync( + RenameLocations renameLocationSet, + string originalText, + string replacementText, + OptionSet optionSet, + Func<IEnumerable<ISymbol>, bool?> hasConflict, + CancellationToken cancellationToken) + { + try { + var task = resolveConflictsAsyncMethod.Invoke (null, new object [] { renameLocationSet.instance, originalText, replacementText, optionSet, hasConflict, cancellationToken }); + var propertyInfo = task.GetType ().GetProperty ("Result"); + return Task.FromResult (new ConflictResolution (propertyInfo.GetValue (task))); + } catch (TargetInvocationException ex) { + ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); + return null; + } + } + } +} + diff --git a/main/src/addins/CSharpBinding/Util/Glyph.cs b/main/src/addins/CSharpBinding/Util/Glyph.cs new file mode 100644 index 0000000000..912aa81f84 --- /dev/null +++ b/main/src/addins/CSharpBinding/Util/Glyph.cs @@ -0,0 +1,130 @@ +// +// Glyph.cs +// +// Author: +// Mike Krüger <mkrueger@xamarin.com> +// +// Copyright (c) 2015 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +namespace ICSharpCode.NRefactory6.CSharp +{ + internal enum Glyph + { + Assembly, + + BasicFile, + BasicProject, + + ClassPublic, + ClassProtected, + ClassPrivate, + ClassInternal, + + CSharpFile, + CSharpProject, + + ConstantPublic, + ConstantProtected, + ConstantPrivate, + ConstantInternal, + + DelegatePublic, + DelegateProtected, + DelegatePrivate, + DelegateInternal, + + EnumPublic, + EnumProtected, + EnumPrivate, + EnumInternal, + + EnumMember, + + Error, + + EventPublic, + EventProtected, + EventPrivate, + EventInternal, + + ExtensionMethodPublic, + ExtensionMethodProtected, + ExtensionMethodPrivate, + ExtensionMethodInternal, + + FieldPublic, + FieldProtected, + FieldPrivate, + FieldInternal, + + InterfacePublic, + InterfaceProtected, + InterfacePrivate, + InterfaceInternal, + + Intrinsic, + + Keyword, + + Label, + + Local, + + Namespace, + + MethodPublic, + MethodProtected, + MethodPrivate, + MethodInternal, + + ModulePublic, + ModuleProtected, + ModulePrivate, + ModuleInternal, + + OpenFolder, + + Operator, + + Parameter, + + PropertyPublic, + PropertyProtected, + PropertyPrivate, + PropertyInternal, + + RangeVariable, + + Reference, + + StructurePublic, + StructureProtected, + StructurePrivate, + StructureInternal, + + TypeParameter, + + Snippet, + + CompletionWarning + } +} + diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CSharpSuppressionFixProvider.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CSharpSuppressionFixProvider.cs index 486589b7d0..5ec493b3bd 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CSharpSuppressionFixProvider.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CSharpSuppressionFixProvider.cs @@ -83,7 +83,7 @@ namespace MonoDevelop.CodeIssues public FixAllProvider GetFixAllProvider () { - return (FixAllProvider)canBeSuppressedOrUnsuppressedMethod.Invoke (instance, new object[0]); + return (FixAllProvider)canBeSuppressedOrUnsuppressedMethod.Invoke (instance, null); } public Task<IEnumerable<CodeFix>> GetSuppressionsAsync (Project project, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken) |