提交 778f4700 编写于 作者: C CyrusNajmabadi

Use subclassing with our code actions.

上级 ad93cafc
// 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.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSyntax>
{
private class MetadataSymbolReferenceCodeAction : SymbolReferenceCodeAction
{
/// <summary>
/// If we're adding <see cref="_portableExecutableReferenceFilePathToAdd"/> then this
/// is the id for the <see cref="Project"/> we can find that <see cref="PortableExecutableReference"/>
/// referenced from.
/// </summary>
private readonly ProjectId _portableExecutableReferenceProjectId;
/// <summary>
/// If we want to add a <see cref="PortableExecutableReference"/> metadata reference, this
/// is the <see cref="PortableExecutableReference.FilePath"/> for it.
/// </summary>
private readonly string _portableExecutableReferenceFilePathToAdd;
public MetadataSymbolReferenceCodeAction(
Document contextDocument,
ImmutableArray<TextChange> textChanges,
string title, ImmutableArray<string> tags,
CodeActionPriority priority,
ProjectId portableExecutableReferenceProjectId,
string portableExecutableReferenceFilePathToAdd)
: base(contextDocument, textChanges, title, tags, priority)
{
_portableExecutableReferenceProjectId = portableExecutableReferenceProjectId;
_portableExecutableReferenceFilePathToAdd = portableExecutableReferenceFilePathToAdd;
}
protected override Project UpdateProject(Project project)
{
var projectWithReference = project.Solution.GetProject(_portableExecutableReferenceProjectId);
var reference = projectWithReference.MetadataReferences
.OfType<PortableExecutableReference>()
.First(pe => pe.FilePath == _portableExecutableReferenceFilePathToAdd);
return project.AddMetadataReference(reference);
}
}
}
}
\ 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.Collections.Immutable;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSyntax>
{
private class ProjectSymbolReferenceCodeAction : SymbolReferenceCodeAction
{
/// <summary>
/// The optional id for a <see cref="Project"/> we'd like to add a reference to.
/// </summary>
private readonly ProjectId _projectReferenceToAdd;
public ProjectSymbolReferenceCodeAction(
Document contextDocument,
ImmutableArray<TextChange> textChanges,
string title, ImmutableArray<string> tags,
CodeActionPriority priority,
ProjectId projectReferenceToAdd)
: base(contextDocument, textChanges, title, tags, priority)
{
// We only want to add a project reference if the project the import references
// is different from the project we started from.
if (projectReferenceToAdd != contextDocument.Project.Id)
{
_projectReferenceToAdd = projectReferenceToAdd;
}
}
internal override bool PerformFinalApplicabilityCheck
=> _projectReferenceToAdd != null;
internal override bool IsApplicable(Workspace workspace)
=> _projectReferenceToAdd != null && workspace.CanAddProjectReference(ContextDocument.Project.Id, _projectReferenceToAdd);
protected override Project UpdateProject(Project project)
{
return _projectReferenceToAdd == null
? project
: project.AddProjectReference(new ProjectReference(_projectReferenceToAdd));
}
}
}
}
\ 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. // 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.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{ {
...@@ -18,7 +16,7 @@ internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSynt ...@@ -18,7 +16,7 @@ internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSynt
/// we want to do things like show a glyph if this will do more than just add /// we want to do things like show a glyph if this will do more than just add
/// an import. /// an import.
/// </summary> /// </summary>
private class SymbolReferenceCodeAction : CodeAction private abstract class SymbolReferenceCodeAction : CodeAction
{ {
public override string Title { get; } public override string Title { get; }
public override ImmutableArray<string> Tags { get; } public override ImmutableArray<string> Tags { get; }
...@@ -29,104 +27,39 @@ private class SymbolReferenceCodeAction : CodeAction ...@@ -29,104 +27,39 @@ private class SymbolReferenceCodeAction : CodeAction
/// <summary> /// <summary>
/// The <see cref="Document"/> we started the add-import analysis in. /// The <see cref="Document"/> we started the add-import analysis in.
/// </summary> /// </summary>
private readonly Document _contextDocument; protected readonly Document ContextDocument;
/// <summary> /// <summary>
/// The changes to make to <see cref="_contextDocument"/> to add the import. /// The changes to make to <see cref="ContextDocument"/> to add the import.
/// </summary> /// </summary>
private readonly ImmutableArray<TextChange> _textChanges; private readonly ImmutableArray<TextChange> _textChanges;
/// <summary> protected SymbolReferenceCodeAction(
/// The optional id for a <see cref="Project"/> we'd like to add a reference to.
/// </summary>
private readonly ProjectId _projectReferenceToAdd;
/// <summary>
/// If we're adding <see cref="_portableExecutableReferenceFilePathToAdd"/> then this
/// is the id for the <see cref="Project"/> we can find that <see cref="PortableExecutableReference"/>
/// referenced from.
/// </summary>
private readonly ProjectId _portableExecutableReferenceProjectId;
/// <summary>
/// If we want to add a <see cref="PortableExecutableReference"/> metadata reference, this
/// is the <see cref="PortableExecutableReference.FilePath"/> for it.
/// </summary>
private readonly string _portableExecutableReferenceFilePathToAdd;
private SymbolReferenceCodeAction(
Document contextDocument, Document contextDocument,
ImmutableArray<TextChange> textChanges, ImmutableArray<TextChange> textChanges,
string title, ImmutableArray<string> tags, string title, ImmutableArray<string> tags,
CodeActionPriority priority) CodeActionPriority priority)
{ {
_contextDocument = contextDocument; ContextDocument = contextDocument;
_textChanges = textChanges; _textChanges = textChanges;
Title = title; Title = title;
Tags = tags; Tags = tags;
Priority = priority; Priority = priority;
} }
public SymbolReferenceCodeAction(
Document contextDocument,
ImmutableArray<TextChange> textChanges,
string title, ImmutableArray<string> tags,
CodeActionPriority priority,
ProjectId projectReferenceToAdd)
: this(contextDocument, textChanges, title, tags, priority)
{
// We only want to add a project reference if the project the import references
// is different from the project we started from.
if (projectReferenceToAdd != contextDocument.Project.Id)
{
_projectReferenceToAdd = projectReferenceToAdd;
}
}
public SymbolReferenceCodeAction(
Document contextDocument,
ImmutableArray<TextChange> textChanges,
string title, ImmutableArray<string> tags,
CodeActionPriority priority,
ProjectId portableExecutableReferenceProjectId,
string portableExecutableReferenceFilePathToAdd)
: this(contextDocument, textChanges, title, tags, priority)
{
_portableExecutableReferenceProjectId = portableExecutableReferenceProjectId;
_portableExecutableReferenceFilePathToAdd = portableExecutableReferenceFilePathToAdd;
}
protected override async Task<Solution> GetChangedSolutionAsync(CancellationToken cancellationToken) protected override async Task<Solution> GetChangedSolutionAsync(CancellationToken cancellationToken)
{ {
var oldText = await _contextDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var oldText = await ContextDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
var newText = oldText.WithChanges(_textChanges); var newText = oldText.WithChanges(_textChanges);
var updatedProject = _contextDocument.WithText(newText).Project; var updatedDocument = ContextDocument.WithText(newText);
var updatedProject = UpdateProject(updatedDocument.Project);
if (_projectReferenceToAdd != null)
{
updatedProject = updatedProject.AddProjectReference(new ProjectReference(_projectReferenceToAdd));
}
else if (_portableExecutableReferenceFilePathToAdd != null)
{
var projectWithReference = updatedProject.Solution.GetProject(_portableExecutableReferenceProjectId);
var reference = projectWithReference.MetadataReferences
.OfType<PortableExecutableReference>()
.First(pe => pe.FilePath == _portableExecutableReferenceFilePathToAdd);
updatedProject = updatedProject.AddMetadataReference(reference);
}
var updatedSolution = updatedProject.Solution; var updatedSolution = updatedProject.Solution;
return updatedSolution; return updatedSolution;
} }
internal override bool PerformFinalApplicabilityCheck protected abstract Project UpdateProject(Project project);
=> _projectReferenceToAdd != null; }
internal override bool IsApplicable(Workspace workspace)
=> _projectReferenceToAdd != null && workspace.CanAddProjectReference(_contextDocument.Project.Id, _projectReferenceToAdd);
}
} }
} }
\ No newline at end of file
...@@ -53,7 +53,7 @@ private partial class MetadataSymbolReference : SymbolReference ...@@ -53,7 +53,7 @@ private partial class MetadataSymbolReference : SymbolReference
Document document, ImmutableArray<TextChange> textChanges, string description, Document document, ImmutableArray<TextChange> textChanges, string description,
ImmutableArray<string> tags, CodeActionPriority priority) ImmutableArray<string> tags, CodeActionPriority priority)
{ {
return new SymbolReferenceCodeAction( return new MetadataSymbolReferenceCodeAction(
document, textChanges, description, tags, priority, document, textChanges, description, tags, priority,
_referenceProjectId, _reference.FilePath); _referenceProjectId, _reference.FilePath);
} }
......
...@@ -71,7 +71,7 @@ protected override CodeActionPriority GetPriority(Document document) ...@@ -71,7 +71,7 @@ protected override CodeActionPriority GetPriority(Document document)
Document document, ImmutableArray<TextChange> textChanges, string description, Document document, ImmutableArray<TextChange> textChanges, string description,
ImmutableArray<string> tags, CodeActionPriority priority) ImmutableArray<string> tags, CodeActionPriority priority)
{ {
return new SymbolReferenceCodeAction( return new ProjectSymbolReferenceCodeAction(
document, textChanges, description, tags, priority, _project.Id); document, textChanges, description, tags, priority, _project.Id);
} }
......
...@@ -100,6 +100,8 @@ ...@@ -100,6 +100,8 @@
<Link>Shared\Utilities\DesktopShim.cs</Link> <Link>Shared\Utilities\DesktopShim.cs</Link>
</Compile> </Compile>
<Compile Include="AddImport\CodeActions\AssemblyReferenceCodeAction.cs" /> <Compile Include="AddImport\CodeActions\AssemblyReferenceCodeAction.cs" />
<Compile Include="AddImport\CodeActions\MetadataSymbolReferenceCodeAction.cs" />
<Compile Include="AddImport\CodeActions\ProjectSymbolReferenceCodeAction.cs" />
<Compile Include="AddImport\SearchScopes\AllSymbolsProjectSearchScope.cs" /> <Compile Include="AddImport\SearchScopes\AllSymbolsProjectSearchScope.cs" />
<Compile Include="AddImport\SearchScopes\MetadataSymbolsSearchScope.cs" /> <Compile Include="AddImport\SearchScopes\MetadataSymbolsSearchScope.cs" />
<Compile Include="AddImport\SearchScopes\ProjectSearchScope.cs" /> <Compile Include="AddImport\SearchScopes\ProjectSearchScope.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册