diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs
index d39049e97648fa31041574fa384f0c5c76389adb..5922c22010c33fa5120f3dd537b6b3d0d677e145 100644
--- a/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs
+++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.Designer.cs
@@ -395,15 +395,6 @@ internal class CSharpFeaturesResources {
}
}
- ///
- /// Looks up a localized string similar to Implement Abstract Class.
- ///
- internal static string Implement_Abstract_Class {
- get {
- return ResourceManager.GetString("Implement_Abstract_Class", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to <implicit array creation>.
///
diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx
index a6ead4e6be7e94d315104d659ac6c96b116c6625..f59d3a746bcf7684f92e783e5966a209036929b0 100644
--- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx
+++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx
@@ -117,9 +117,6 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- Implement Abstract Class
-
Inline temporary variable
diff --git a/src/Features/CSharp/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.cs
index aaceb986a8786d81030d4024522d2e4813582b46..83e96d329c23c3ffc3b88f485b9640eba4850543 100644
--- a/src/Features/CSharp/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.cs
+++ b/src/Features/CSharp/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.cs
@@ -1,90 +1,21 @@
// 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.Immutable;
using System.Composition;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CodeFixes.ImplementAbstractClass;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.ImplementAbstractClass;
-using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.ImplementAbstractClass
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.ImplementAbstractClass), Shared]
[ExtensionOrder(After = PredefinedCodeFixProviderNames.GenerateType)]
- internal class ImplementAbstractClassCodeFixProvider : CodeFixProvider
+ internal class ImplementAbstractClassCodeFixProvider :
+ AbstractImplementAbstractClassCodeFixProvider
{
private const string CS0534 = nameof(CS0534); // 'Program' does not implement inherited abstract member 'Foo.bar()'
- public sealed override ImmutableArray FixableDiagnosticIds =>
- ImmutableArray.Create(CS0534);
-
- public sealed override FixAllProvider GetFixAllProvider() =>
- WellKnownFixAllProviders.BatchFixer;
-
- public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
- {
- var cancellationToken = context.CancellationToken;
- var document = context.Document;
-
- var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
-
- var token = root.FindToken(context.Span.Start);
- if (!token.Span.IntersectsWith(context.Span))
- {
- return;
- }
-
- var classNode = token.Parent as ClassDeclarationSyntax;
- if (classNode == null)
- {
- return;
- }
-
- var service = document.GetLanguageService();
-
- if (await service.CanImplementAbstractClassAsync(
- document,
- classNode,
- cancellationToken).ConfigureAwait(false))
- {
- var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
-
- var classSymbol = semanticModel.GetDeclaredSymbol(classNode);
- var abstractType = classSymbol.BaseType;
- var id = GetCodeActionId(abstractType.ContainingAssembly.Name, abstractType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
- context.RegisterCodeFix(
- new MyCodeAction(
- c => ImplementAbstractClassAsync(document, classNode, c),
- id),
- context.Diagnostics);
- }
- }
-
- // internal for testing purposes.
- internal static string GetCodeActionId(string assemblyName, string abstractTypeFullyQualifiedName)
- {
- return CSharpFeaturesResources.Implement_Abstract_Class + ";" +
- assemblyName + ";" +
- abstractTypeFullyQualifiedName;
- }
-
- private Task ImplementAbstractClassAsync(
- Document document, ClassDeclarationSyntax classNode, CancellationToken cancellationToken)
- {
- var service = document.GetLanguageService();
- return service.ImplementAbstractClassAsync(document, classNode, cancellationToken);
- }
-
- private class MyCodeAction : CodeAction.DocumentChangeAction
+ public ImplementAbstractClassCodeFixProvider() : base(CS0534)
{
- public MyCodeAction(Func> createChangedDocument, string id) :
- base(CSharpFeaturesResources.Implement_Abstract_Class, createChangedDocument, id)
- {
- }
}
}
}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/CodeFixes/ImplementAbstractClass/AbstractImplementAbstractClassCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/ImplementAbstractClass/AbstractImplementAbstractClassCodeFixProvider.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2a5de8341d0408635ab3477824e55b2c5d802042
--- /dev/null
+++ b/src/Features/Core/Portable/CodeFixes/ImplementAbstractClass/AbstractImplementAbstractClassCodeFixProvider.cs
@@ -0,0 +1,95 @@
+// 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.Immutable;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.ImplementAbstractClass;
+using Microsoft.CodeAnalysis.Shared.Extensions;
+
+namespace Microsoft.CodeAnalysis.CodeFixes.ImplementAbstractClass
+{
+ internal abstract class AbstractImplementAbstractClassCodeFixProvider : CodeFixProvider
+ where TClassNode : SyntaxNode
+ {
+ public sealed override ImmutableArray FixableDiagnosticIds { get; }
+
+ public sealed override FixAllProvider GetFixAllProvider() =>
+ WellKnownFixAllProviders.BatchFixer;
+
+ protected AbstractImplementAbstractClassCodeFixProvider(string diagnosticId)
+ {
+ FixableDiagnosticIds = ImmutableArray.Create(diagnosticId);
+ }
+
+ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ var cancellationToken = context.CancellationToken;
+ var document = context.Document;
+
+ var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
+
+ var token = root.FindToken(context.Span.Start);
+ if (!token.Span.IntersectsWith(context.Span))
+ {
+ return;
+ }
+
+ var classNode = token.Parent.GetAncestorOrThis();
+ if (classNode == null)
+ {
+ return;
+ }
+
+ var service = document.GetLanguageService();
+
+ var canImplement = await service.CanImplementAbstractClassAsync(
+ document,
+ classNode,
+ cancellationToken).ConfigureAwait(false);
+ if (!canImplement)
+ {
+ return;
+ }
+ var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+
+ var classSymbol = semanticModel.GetDeclaredSymbol(classNode) as INamedTypeSymbol;
+ if (classSymbol == null)
+ {
+ return;
+ }
+
+ var abstractType = classSymbol.BaseType;
+ var id = GetCodeActionId(abstractType.ContainingAssembly.Name, abstractType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
+ context.RegisterCodeFix(
+ new MyCodeAction(
+ c => ImplementAbstractClassAsync(document, classNode, c),
+ id),
+ context.Diagnostics);
+ }
+
+ // internal for testing purposes.
+ internal static string GetCodeActionId(string assemblyName, string abstractTypeFullyQualifiedName)
+ {
+ return FeaturesResources.Implement_Abstract_Class + ";" +
+ assemblyName + ";" +
+ abstractTypeFullyQualifiedName;
+ }
+
+ private Task ImplementAbstractClassAsync(
+ Document document, TClassNode classNode, CancellationToken cancellationToken)
+ {
+ var service = document.GetLanguageService();
+ return service.ImplementAbstractClassAsync(document, classNode, cancellationToken);
+ }
+
+ private class MyCodeAction : CodeAction.DocumentChangeAction
+ {
+ public MyCodeAction(Func> createChangedDocument, string id) :
+ base(FeaturesResources.Implement_Abstract_Class, createChangedDocument, id)
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Features/Core/Portable/Features.csproj b/src/Features/Core/Portable/Features.csproj
index 3e52b2072220449459c5d718ebb68575aaed2ccc..c86072923b3aa2e2293254ab7a28e4f6e89ede2d 100644
--- a/src/Features/Core/Portable/Features.csproj
+++ b/src/Features/Core/Portable/Features.csproj
@@ -119,6 +119,7 @@
+
@@ -652,4 +653,4 @@
-
+
\ No newline at end of file
diff --git a/src/Features/Core/Portable/FeaturesResources.Designer.cs b/src/Features/Core/Portable/FeaturesResources.Designer.cs
index 8ee89a72d4a6a360efb8c075d61df66f0202ce6c..7eceaeb0f24765a29a708085600ab3f869117382 100644
--- a/src/Features/Core/Portable/FeaturesResources.Designer.cs
+++ b/src/Features/Core/Portable/FeaturesResources.Designer.cs
@@ -1314,6 +1314,15 @@ internal class FeaturesResources {
}
}
+ ///
+ /// Looks up a localized string similar to Implement Abstract Class.
+ ///
+ internal static string Implement_Abstract_Class {
+ get {
+ return ResourceManager.GetString("Implement_Abstract_Class", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Implement interface.
///
diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx
index e81918e95442e27db02799edb242525bbf0c4299..ebc539cc6c7bec1ccafad20431dee7a58f2b80bd 100644
--- a/src/Features/Core/Portable/FeaturesResources.resx
+++ b/src/Features/Core/Portable/FeaturesResources.resx
@@ -1061,4 +1061,7 @@ This version used in: {2}
(Unknown)
+
+ Implement Abstract Class
+
\ No newline at end of file
diff --git a/src/Features/VisualBasic/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.vb
index d664eb420d53d6b0a416ee37797d1e626df99677..20e536802484b16c07d1ba0214c355fac8781f92 100644
--- a/src/Features/VisualBasic/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.vb
+++ b/src/Features/VisualBasic/Portable/CodeFixes/ImplementAbstractClass/ImplementAbstractClassCodeFixProvider.vb
@@ -1,87 +1,21 @@
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-Imports System.Collections.Immutable
-Imports System.Threading
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
-Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
-Imports Microsoft.CodeAnalysis.ImplementAbstractClass
Imports System.Composition
+Imports Microsoft.CodeAnalysis.CodeFixes.ImplementAbstractClass
Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.ImplementAbstractClass
Friend Class ImplementAbstractClassCodeFixProvider
- Inherits CodeFixProvider
+ Inherits AbstractImplementAbstractClassCodeFixProvider(Of ClassBlockSyntax)
Friend Const BC30610 As String = "BC30610" ' Class 'foo' must either be declared 'MustInherit' or override the following inherited 'MustOverride' member(s):
- Public NotOverridable Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String)
- Get
- Return ImmutableArray.Create(BC30610)
- End Get
- End Property
-
- Public NotOverridable Overrides Function GetFixAllProvider() As FixAllProvider
- Return WellKnownFixAllProviders.BatchFixer
- End Function
-
- Public NotOverridable Overrides Async Function RegisterCodeFixesAsync(context As CodeFixContext) As Task
- Dim cancellationToken = context.CancellationToken
- Dim document = context.Document
-
- Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False)
-
- Dim token = root.FindToken(context.Span.Start)
- If Not token.Span.IntersectsWith(context.Span) Then
- Return
- End If
-
- Dim classNode = token.GetAncestors(Of ClassBlockSyntax)() _
- .FirstOrDefault(Function(c) c.Span.IntersectsWith(context.Span))
-
- If classNode Is Nothing Then
- Return
- End If
-
- Dim service = document.GetLanguageService(Of IImplementAbstractClassService)()
-
- If Await service.CanImplementAbstractClassAsync(
- document, classNode, cancellationToken).ConfigureAwait(False) Then
-
- Dim model = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False)
- Dim classSymbol = model.GetDeclaredSymbol(classNode)
-
- Dim typeName = classSymbol.BaseType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)
- Dim id = GetCodeActionId(classSymbol.BaseType.ContainingAssembly.Name, typeName)
- context.RegisterCodeFix(
- New MyCodeAction(
- Function(c) ImplementAbstractClassAsync(document, classNode, c),
- id),
- context.Diagnostics)
- Return
- End If
- End Function
-
- Friend Shared Function GetCodeActionId(assemblyName As String, abstractTypeFullyQualifiedName As String) As String
- Return VBFeaturesResources.Implement_Abstract_Class + ";" +
- assemblyName + ";" +
- abstractTypeFullyQualifiedName
- End Function
-
- Private Function ImplementAbstractClassAsync(
- document As Document, classBlock As ClassBlockSyntax, cancellationToken As CancellationToken) As Task(Of Document)
- Dim service = document.GetLanguageService(Of IImplementAbstractClassService)()
- Return service.ImplementAbstractClassAsync(document, classBlock, cancellationToken)
- End Function
-
- Private Class MyCodeAction
- Inherits CodeAction.DocumentChangeAction
-
- Public Sub New(createChangedDocument As Func(Of CancellationToken, Task(Of Document)), id As String)
- MyBase.New(VBFeaturesResources.Implement_Abstract_Class, createChangedDocument, id)
- End Sub
- End Class
+ Public Sub New()
+ MyBase.New(BC30610)
+ End Sub
End Class
End Namespace
\ No newline at end of file
diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb
index e13c9fc4cc4796ba5b1c5c52f710e8d98dd7cc24..bba803109ba8ae2729ad7508f1a6a818b0134b51 100644
--- a/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb
+++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.Designer.vb
@@ -1141,16 +1141,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources
"ocedure", resourceCulture)
End Get
End Property
-
- '''
- ''' Looks up a localized string similar to Implement Abstract Class.
- '''
- Friend ReadOnly Property Implement_Abstract_Class() As String
- Get
- Return ResourceManager.GetString("Implement_Abstract_Class", resourceCulture)
- End Get
- End Property
-
+
'''
''' Looks up a localized string similar to Implicit member access can't be included in the selection without containing statement.
'''
diff --git a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx
index 91ad0beaaaf19c936f18bcce9d1edbff07a84509..079ff97243d66e48cb91e3c9f9280bbce0b4a3d5 100644
--- a/src/Features/VisualBasic/Portable/VBFeaturesResources.resx
+++ b/src/Features/VisualBasic/Portable/VBFeaturesResources.resx
@@ -210,9 +210,6 @@
Mid statement
-
- Implement Abstract Class
-
Fix Incorrect Function Return Type