提交 0e878b14 编写于 作者: C CyrusNajmabadi

Share implementation of ImplementAbstractClass.

上级 be4f77ad
......@@ -395,15 +395,6 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Implement Abstract Class.
/// </summary>
internal static string Implement_Abstract_Class {
get {
return ResourceManager.GetString("Implement_Abstract_Class", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;implicit array creation&gt;.
/// </summary>
......
......@@ -117,9 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Implement_Abstract_Class" xml:space="preserve">
<value>Implement Abstract Class</value>
</data>
<data name="Inline_temporary_variable" xml:space="preserve">
<value>Inline temporary variable</value>
</data>
......
// 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<ClassDeclarationSyntax>
{
private const string CS0534 = nameof(CS0534); // 'Program' does not implement inherited abstract member 'Foo.bar()'
public sealed override ImmutableArray<string> 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<IImplementAbstractClassService>();
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<Document> ImplementAbstractClassAsync(
Document document, ClassDeclarationSyntax classNode, CancellationToken cancellationToken)
{
var service = document.GetLanguageService<IImplementAbstractClassService>();
return service.ImplementAbstractClassAsync(document, classNode, cancellationToken);
}
private class MyCodeAction : CodeAction.DocumentChangeAction
public ImplementAbstractClassCodeFixProvider() : base(CS0534)
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument, string id) :
base(CSharpFeaturesResources.Implement_Abstract_Class, createChangedDocument, id)
{
}
}
}
}
\ No newline at end of file
// 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<TClassNode> : CodeFixProvider
where TClassNode : SyntaxNode
{
public sealed override ImmutableArray<string> 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<TClassNode>();
if (classNode == null)
{
return;
}
var service = document.GetLanguageService<IImplementAbstractClassService>();
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<Document> ImplementAbstractClassAsync(
Document document, TClassNode classNode, CancellationToken cancellationToken)
{
var service = document.GetLanguageService<IImplementAbstractClassService>();
return service.ImplementAbstractClassAsync(document, classNode, cancellationToken);
}
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument, string id) :
base(FeaturesResources.Implement_Abstract_Class, createChangedDocument, id)
{
}
}
}
}
\ No newline at end of file
......@@ -119,6 +119,7 @@
<Compile Include="CodeFixes\CodeFixCollection.cs" />
<Compile Include="CodeFixes\FirstDiagnosticResult.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\IFixMultipleOccurrencesService.cs" />
<Compile Include="CodeFixes\ImplementAbstractClass\AbstractImplementAbstractClassCodeFixProvider.cs" />
<Compile Include="CodeFixes\Qualify\AbstractFullyQualifyCodeFixProvider.SymbolResult.cs" />
<Compile Include="CodeFixes\Qualify\AbstractFullyQualifyCodeFixProvider.cs" />
<Compile Include="CodeFixes\GenerateMember\AbstractGenerateMemberCodeFixProvider.cs" />
......@@ -652,4 +653,4 @@
<ItemGroup />
<Import Project="..\..\..\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems" Label="Shared" />
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -1314,6 +1314,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Implement Abstract Class.
/// </summary>
internal static string Implement_Abstract_Class {
get {
return ResourceManager.GetString("Implement_Abstract_Class", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Implement interface.
/// </summary>
......
......@@ -1061,4 +1061,7 @@ This version used in: {2}</value>
<data name="paren_Unknown_paren" xml:space="preserve">
<value>(Unknown)</value>
</data>
<data name="Implement_Abstract_Class" xml:space="preserve">
<value>Implement Abstract Class</value>
</data>
</root>
\ No newline at end of file
' 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
<ExportCodeFixProvider(LanguageNames.VisualBasic,
Name:=PredefinedCodeFixProviderNames.ImplementAbstractClass), [Shared]>
<ExtensionOrder(After:=PredefinedCodeFixProviderNames.GenerateType)>
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
......@@ -1141,16 +1141,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources
"ocedure", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Implement Abstract Class.
'''</summary>
Friend ReadOnly Property Implement_Abstract_Class() As String
Get
Return ResourceManager.GetString("Implement_Abstract_Class", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Implicit member access can&apos;t be included in the selection without containing statement.
'''</summary>
......
......@@ -210,9 +210,6 @@
<data name="Mid_statement" xml:space="preserve">
<value>Mid statement</value>
</data>
<data name="Implement_Abstract_Class" xml:space="preserve">
<value>Implement Abstract Class</value>
</data>
<data name="Fix_Incorrect_Function_Return_Type" xml:space="preserve">
<value>Fix Incorrect Function Return Type</value>
</data>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册