Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ImplementInterfaceCodeFixProvider.cs « ImplementInterface « MonoDevelop.CSharp.CodeFixes « CSharpBinding « addins « src « main - github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a9eb6c8d2f82f18d0694cc3a98cbc016da4d72fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 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.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis;
using ICSharpCode.NRefactory6.CSharp.Features.ImplementInterface;
using ICSharpCode.NRefactory6.CSharp;

namespace MonoDevelop.CSharp.CodeFixes.ImplementInterface
{
	[ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.ImplementInterface), Shared]
	[ExtensionOrder(After = PredefinedCodeFixProviderNames.ImplementAbstractClass)]
	internal class ImplementInterfaceCodeFixProvider : CodeFixProvider
	{
		private readonly Func<TypeSyntax, bool> _interfaceName = n => n.Parent is BaseTypeSyntax && n.Parent.Parent is BaseListSyntax && ((BaseTypeSyntax)n.Parent).Type == n;
		private readonly Func<IEnumerable<CodeAction>, bool> _codeActionAvailable = actions => actions != null && actions.Any();

		internal const string CS0535 = "CS0535"; // 'Program' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'
		internal const string CS0737 = "CS0737"; // 'Class' does not implement interface member 'IInterface.M()'. 'Class.M()' cannot implement an interface member because it is not public.
		internal const string CS0738 = "CS0738"; // 'C' does not implement interface member 'I.Method1()'. 'B.Method1()' cannot implement 'I.Method1()' because it does not have the matching return type of 'void'.

		public sealed override ImmutableArray<string> FixableDiagnosticIds
		{
			get { return ImmutableArray.Create(CS0535, CS0737, CS0738); }
		}
		static CSharpImplementInterfaceService service = new CSharpImplementInterfaceService();

		public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
		{
			var document = context.Document;
			var span = context.Span;
			var cancellationToken = context.CancellationToken;

			var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

			var token = root.FindToken(span.Start);
			if (!token.Span.IntersectsWith(span))
			{
				return;
			}

			var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
			if (model.IsFromGeneratedCode (cancellationToken))
				return;

			var actions = token.Parent.GetAncestorsOrThis<TypeSyntax>()
				.Where(_interfaceName)
				.Select(n => service.GetCodeActions(document, model, n, cancellationToken))
				.FirstOrDefault(_codeActionAvailable);

			if (_codeActionAvailable(actions))
			{
				context.RegisterFixes(actions, context.Diagnostics);
			}
		}

		public sealed override FixAllProvider GetFixAllProvider()
		{
			return WellKnownFixAllProviders.BatchFixer;
		}
	}
}