提交 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.
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
......@@ -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
/// an import.
/// </summary>
private class SymbolReferenceCodeAction : CodeAction
private abstract class SymbolReferenceCodeAction : CodeAction
{
public override string Title { get; }
public override ImmutableArray<string> Tags { get; }
......@@ -29,104 +27,39 @@ private class SymbolReferenceCodeAction : CodeAction
/// <summary>
/// The <see cref="Document"/> we started the add-import analysis in.
/// </summary>
private readonly Document _contextDocument;
protected readonly Document ContextDocument;
/// <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>
private readonly ImmutableArray<TextChange> _textChanges;
/// <summary>
/// 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(
protected SymbolReferenceCodeAction(
Document contextDocument,
ImmutableArray<TextChange> textChanges,
string title, ImmutableArray<string> tags,
CodeActionPriority priority)
{
_contextDocument = contextDocument;
ContextDocument = contextDocument;
_textChanges = textChanges;
Title = title;
Tags = tags;
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)
{
var oldText = await _contextDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
var oldText = await ContextDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);
var newText = oldText.WithChanges(_textChanges);
var updatedProject = _contextDocument.WithText(newText).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 updatedDocument = ContextDocument.WithText(newText);
var updatedProject = UpdateProject(updatedDocument.Project);
var updatedSolution = updatedProject.Solution;
return updatedSolution;
}
internal override bool PerformFinalApplicabilityCheck
=> _projectReferenceToAdd != null;
internal override bool IsApplicable(Workspace workspace)
=> _projectReferenceToAdd != null && workspace.CanAddProjectReference(_contextDocument.Project.Id, _projectReferenceToAdd);
}
protected abstract Project UpdateProject(Project project);
}
}
}
\ No newline at end of file
......@@ -53,7 +53,7 @@ private partial class MetadataSymbolReference : SymbolReference
Document document, ImmutableArray<TextChange> textChanges, string description,
ImmutableArray<string> tags, CodeActionPriority priority)
{
return new SymbolReferenceCodeAction(
return new MetadataSymbolReferenceCodeAction(
document, textChanges, description, tags, priority,
_referenceProjectId, _reference.FilePath);
}
......
......@@ -71,7 +71,7 @@ protected override CodeActionPriority GetPriority(Document document)
Document document, ImmutableArray<TextChange> textChanges, string description,
ImmutableArray<string> tags, CodeActionPriority priority)
{
return new SymbolReferenceCodeAction(
return new ProjectSymbolReferenceCodeAction(
document, textChanges, description, tags, priority, _project.Id);
}
......
......@@ -100,6 +100,8 @@
<Link>Shared\Utilities\DesktopShim.cs</Link>
</Compile>
<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\MetadataSymbolsSearchScope.cs" />
<Compile Include="AddImport\SearchScopes\ProjectSearchScope.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册