提交 3ea6faa3 编写于 作者: C CyrusNajmabadi

Merge pull request #5237 from CyrusNajmabadi/nestedCodeActions3

Improve the GenerateType code-actions menu experience.
......@@ -2,9 +2,11 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.GenerateType;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Simplification;
using Roslyn.Test.Utilities;
......@@ -20,6 +22,11 @@ public partial class GenerateTypeTests : AbstractCSharpDiagnosticProviderBasedUs
null, new GenerateTypeCodeFixProvider());
}
protected override IList<CodeAction> MassageActions(IList<CodeAction> codeActions)
{
return FlattenActions(codeActions);
}
#region Generate Class
#region Generics
......@@ -1501,7 +1508,7 @@ public void TestDisplayStringForGlobalNamespace()
{
TestSmartTagText(
@"class C : [|Foo|]",
string.Format(FeaturesResources.GenerateForInNewFile, "class", "Foo", FeaturesResources.GlobalNamespace));
string.Format(FeaturesResources.Generate_0_1_in_new_file, "class", "Foo", FeaturesResources.GlobalNamespace));
}
[WorkItem(543853)]
......@@ -1571,8 +1578,8 @@ static void Main(string[] args)
TestExactActionSetOffered(code,
new[]
{
string.Format(FeaturesResources.GenerateForInNewFile, "class", "Foo", FeaturesResources.GlobalNamespace),
string.Format(FeaturesResources.GenerateForIn, "class", "Foo", "Program"),
string.Format(FeaturesResources.Generate_0_1_in_new_file, "class", "Foo", FeaturesResources.GlobalNamespace),
string.Format(FeaturesResources.Generate_nested_0_1, "class", "Foo", "Program"),
FeaturesResources.GenerateNewType
});
......
......@@ -24,9 +24,10 @@ internal class CodeFixSuggestedAction : SuggestedActionWithFlavors, ITelemetryDi
ITextBuffer subjectBuffer,
ICodeActionEditHandlerService editHandler,
CodeFix fix,
CodeAction action,
object provider,
SuggestedActionSet fixAllSuggestedActionSet)
: base(workspace, subjectBuffer, editHandler, fix.Action, provider)
: base(workspace, subjectBuffer, editHandler, action, provider)
{
_fix = fix;
_fixAllSuggestedActionSet = fixAllSuggestedActionSet;
......
......@@ -28,14 +28,16 @@ internal partial class SuggestedAction : ForegroundThreadAffinitizedObject, ISug
protected readonly ICodeActionEditHandlerService EditHandler;
protected readonly object Provider;
protected readonly CodeAction CodeAction;
internal readonly CodeAction CodeAction;
private readonly ImmutableArray<SuggestedActionSet> _actionSets;
protected SuggestedAction(
internal SuggestedAction(
Workspace workspace,
ITextBuffer subjectBuffer,
ICodeActionEditHandlerService editHandler,
CodeAction codeAction,
object provider)
object provider,
IEnumerable<SuggestedActionSet> actionSets = null)
{
Contract.ThrowIfTrue(provider == null);
......@@ -44,6 +46,7 @@ internal partial class SuggestedAction : ForegroundThreadAffinitizedObject, ISug
this.CodeAction = codeAction;
this.EditHandler = editHandler;
this.Provider = provider;
_actionSets = actionSets.AsImmutableOrEmpty();
}
public bool TryGetTelemetryId(out Guid telemetryId)
......@@ -210,34 +213,28 @@ protected virtual Diagnostic GetDiagnostic()
return null;
}
#region not supported
void IDisposable.Dispose()
{
// do nothing
}
public virtual bool HasActionSets => _actionSets.Length > 0;
public virtual bool HasActionSets
public virtual Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
{
get
{
return false;
}
return Task.FromResult<IEnumerable<SuggestedActionSet>>(GetActionSets());
}
public virtual Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
internal ImmutableArray<SuggestedActionSet> GetActionSets()
{
return SpecializedTasks.Default<IEnumerable<SuggestedActionSet>>();
return _actionSets;
}
string ISuggestedAction.IconAutomationText
#region not supported
void IDisposable.Dispose()
{
get
{
// same as display text
return DisplayText;
}
// do nothing
}
// same as display text
string ISuggestedAction.IconAutomationText => DisplayText;
ImageMoniker ISuggestedAction.IconMoniker
{
get
......@@ -255,9 +252,11 @@ string ISuggestedAction.InputGestureText
return null;
}
}
#endregion
#region IEquatable<ISuggestedAction>
public bool Equals(ISuggestedAction other)
{
return Equals(other as SuggestedAction);
......@@ -268,7 +267,7 @@ public override bool Equals(object obj)
return Equals(obj as SuggestedAction);
}
public bool Equals(SuggestedAction otherSuggestedAction)
internal bool Equals(SuggestedAction otherSuggestedAction)
{
if (otherSuggestedAction == null)
{
......@@ -303,6 +302,7 @@ public override int GetHashCode()
return Hash.Combine(Provider.GetHashCode(), CodeAction.EquivalenceKey.GetHashCode());
}
#endregion
}
}
......@@ -160,11 +160,69 @@ public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCateg
var fixes = GetCodeFixes(supportSuggestion, requestedActionCategories, workspace, document, range, cancellationToken);
var refactorings = GetRefactorings(supportSuggestion, requestedActionCategories, workspace, document, range, cancellationToken);
return (fixes == null) ? refactorings :
(refactorings == null) ? fixes : fixes.Concat(refactorings);
var result = fixes == null ? refactorings : refactorings == null
? fixes : fixes.Concat(refactorings);
if (result == null)
{
return null;
}
var allActionSets = result.ToList();
allActionSets = InlineActionSetsIfDesirable(allActionSets);
return allActionSets;
}
}
private List<SuggestedActionSet> InlineActionSetsIfDesirable(List<SuggestedActionSet> allActionSets)
{
// If we only have a single set of items, and that set only has three max suggestion
// offered. Then we can consider inlining any nested actions into the top level list.
// (but we only do this if the parent of the nested actions isn't invokable itself).
if (allActionSets.Sum(a => a.Actions.Count()) > 3)
{
return allActionSets;
}
return allActionSets.Select(InlineActions).ToList();
}
private bool IsInlineable(ISuggestedAction action)
{
var suggestedAction = action as SuggestedAction;
return suggestedAction != null &&
!suggestedAction.CodeAction.IsInvokable &&
suggestedAction.CodeAction.HasCodeActions;
}
private SuggestedActionSet InlineActions(SuggestedActionSet actionSet)
{
if (!actionSet.Actions.Any(IsInlineable))
{
return actionSet;
}
var newActions = new List<ISuggestedAction>();
foreach (var action in actionSet.Actions)
{
if (IsInlineable(action))
{
// Looks like something we can inline.
var childActionSets = ((SuggestedAction)action).GetActionSets();
if (childActionSets.Length != 1)
{
return actionSet;
}
newActions.AddRange(childActionSets[0].Actions);
}
newActions.Add(action);
}
return new SuggestedActionSet(newActions, actionSet.Title, actionSet.Priority, actionSet.ApplicableToSpan);
}
private IEnumerable<SuggestedActionSet> GetCodeFixes(
IDocumentSupportsSuggestionService supportSuggestion,
ISuggestedActionCategorySet requestedActionCategories,
......@@ -225,9 +283,27 @@ private void GroupFixes(Workspace workspace, IEnumerable<CodeFixCollection> fixC
// Suppression fixes are handled below.
if (!(fix.Action is SuppressionCodeAction))
{
var suggestedAction = new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler,
fix, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action));
SuggestedAction suggestedAction;
if (fix.Action.HasCodeActions)
{
var nestedActions = new List<SuggestedAction>();
foreach (var nestedAction in fix.Action.GetCodeActions())
{
nestedActions.Add(new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler,
fix, nestedAction, fixCollection.Provider, getFixAllSuggestedActionSet(nestedAction)));
}
var diag = fix.Diagnostics[0];
var set = new SuggestedActionSet(nestedActions, SuggestedActionSetPriority.Medium, GetApplicableToSpan(diag));
suggestedAction = new SuggestedAction(workspace, _subjectBuffer, _owner._editHandler,
fix.Action, fixCollection.Provider, new[] { set });
}
else
{
suggestedAction = new CodeFixSuggestedAction(workspace, _subjectBuffer, _owner._editHandler,
fix, fix.Action, fixCollection.Provider, getFixAllSuggestedActionSet(fix.Action));
}
AddFix(fix, suggestedAction, map, order);
}
......@@ -283,7 +359,7 @@ private static IEnumerable<SuggestedActionSet> PrioritizeFixGroups(IDictionary<D
var fixes = map[diag];
var priority = fixes.All(s => s is SuppressionSuggestedAction) ? SuggestedActionSetPriority.None : SuggestedActionSetPriority.Medium;
var applicableToSpan = new Span(diag.Location.SourceSpan.Start, diag.Location.SourceSpan.Length);
var applicableToSpan = GetApplicableToSpan(diag);
sets.Add(new SuggestedActionSet(fixes, priority, applicableToSpan));
}
......@@ -291,6 +367,11 @@ private static IEnumerable<SuggestedActionSet> PrioritizeFixGroups(IDictionary<D
return sets.ToImmutable();
}
private static Span GetApplicableToSpan(Diagnostic diag)
{
return new Span(diag.Location.SourceSpan.Start, diag.Location.SourceSpan.Length);
}
private IEnumerable<SuggestedActionSet> GetRefactorings(
IDocumentSupportsSuggestionService supportSuggestion,
ISuggestedActionCategorySet requestedActionCategories,
......
......@@ -43,8 +43,7 @@ public override bool HasActionSets
{
get
{
var suppressionAction = (SuppressionCodeAction)this.CodeAction;
return (suppressionAction.NestedActions != null) && suppressionAction.NestedActions.Any();
return this.CodeAction.GetCodeActions().Any();
}
}
......@@ -58,20 +57,19 @@ public override Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(Cancell
return Task.FromResult(_actionSets);
}
var suppressionAction = (SuppressionCodeAction)this.CodeAction;
if ((suppressionAction.NestedActions != null) && suppressionAction.NestedActions.Any())
if (this.CodeAction.GetCodeActions().Any())
{
var nestedSuggestedActions = ImmutableArray.CreateBuilder<SuggestedAction>();
var fixCount = suppressionAction.NestedActions.Count();
var fixCount = this.CodeAction.GetCodeActions().Length;
foreach (var c in suppressionAction.NestedActions)
foreach (var c in this.CodeAction.GetCodeActions())
{
cancellationToken.ThrowIfCancellationRequested();
var fixAllSuggestedActionSet = c.SupportsFixAllOccurrences ? _getFixAllSuggestedActionSet(c) : null;
var fixAllSuggestedActionSet = _getFixAllSuggestedActionSet(c);
nestedSuggestedActions.Add(new CodeFixSuggestedAction(
this.Workspace, this.SubjectBuffer, this.EditHandler,
new CodeFix(c, _fix.Diagnostics), this.Provider, fixAllSuggestedActionSet));
new CodeFix(c, _fix.Diagnostics), c, this.Provider, fixAllSuggestedActionSet));
}
_actionSets = ImmutableArray.Create(
......
......@@ -99,7 +99,12 @@ protected void ApplyOptionsToWorkspace(Workspace workspace, IDictionary<OptionKe
}
}
protected abstract IList<CodeAction> GetCodeActions(TestWorkspace workspace, string fixAllActionEquivalenceKey);
protected IList<CodeAction> GetCodeActions(TestWorkspace workspace, string fixAllActionEquivalenceKey)
{
return MassageActions(GetCodeActionsWorker(workspace, fixAllActionEquivalenceKey));
}
protected abstract IList<CodeAction> GetCodeActionsWorker(TestWorkspace workspace, string fixAllActionEquivalenceKey);
protected void TestSmartTagText(
string initialMarkup,
......@@ -299,7 +304,7 @@ protected static IEnumerable<CodeActionOperation> VerifyInputsAndGetOperations(i
var suppressionAction = actions.Single() as SuppressionCodeAction;
if (suppressionAction != null)
{
actions = suppressionAction.NestedActions.ToList<CodeAction>();
actions = suppressionAction.GetCodeActions().ToList();
}
}
......@@ -319,5 +324,15 @@ protected static IEnumerable<CodeActionOperation> VerifyInputsAndGetOperations(i
return Tuple.Create(oldSolution, newSolution);
}
protected virtual IList<CodeAction> MassageActions(IList<CodeAction> actions)
{
return actions;
}
protected static IList<CodeAction> FlattenActions(IEnumerable<CodeAction> codeActions)
{
return codeActions?.SelectMany(a => a.HasCodeActions ? a.GetCodeActions().ToArray() : new[] { a }).ToList();
}
}
}
......@@ -24,7 +24,7 @@ public abstract class AbstractCodeActionTest : AbstractCodeActionOrUserDiagnosti
{
protected abstract object CreateCodeRefactoringProvider(Workspace workspace);
protected override IList<CodeAction> GetCodeActions(TestWorkspace workspace, string fixAllActionEquivalenceKey)
protected override IList<CodeAction> GetCodeActionsWorker(TestWorkspace workspace, string fixAllActionEquivalenceKey)
{
return GetCodeRefactoring(workspace)?.Actions?.ToList();
}
......
......@@ -30,7 +30,7 @@ public abstract class AbstractUserDiagnosticTest : AbstractCodeActionOrUserDiagn
internal abstract IEnumerable<Tuple<Diagnostic, CodeFixCollection>> GetDiagnosticAndFixes(TestWorkspace workspace, string fixAllActionEquivalenceKey);
internal abstract IEnumerable<Diagnostic> GetDiagnostics(TestWorkspace workspace);
protected override IList<CodeAction> GetCodeActions(TestWorkspace workspace, string fixAllActionEquivalenceKey)
protected override IList<CodeAction> GetCodeActionsWorker(TestWorkspace workspace, string fixAllActionEquivalenceKey)
{
var diagnostics = GetDiagnosticAndFix(workspace, fixAllActionEquivalenceKey);
return diagnostics?.Item2?.Fixes.Select(f => f.Action).ToList();
......@@ -224,9 +224,9 @@ protected void TestEquivalenceKey(string initialMarkup, string equivalenceKey)
{
using (var workspace = isLine ? CreateWorkspaceFromFile(initialMarkup, parseOptions, compilationOptions) : TestWorkspaceFactory.CreateWorkspace(initialMarkup))
{
var diagnosticAndFix = GetDiagnosticAndFix(workspace);
var codeActions = GetCodeActions(workspace, fixAllActionEquivalenceKey: null);
TestAddDocument(workspace, expectedMarkup, index, expectedContainers, expectedDocumentName,
diagnosticAndFix.Item2.Fixes.Select(f => f.Action).ToList(), compareTokens);
codeActions, compareTokens);
}
}
......@@ -379,7 +379,7 @@ protected void TestEquivalenceKey(string initialMarkup, string equivalenceKey)
var fixes = generateTypeDiagFixes.Item2.Fixes;
Assert.NotNull(fixes);
var fixActions = fixes.Select(f => f.Action);
var fixActions = MassageActions(fixes.Select(f => f.Action).ToList());
Assert.NotNull(fixActions);
// Since the dialog option is always fed as the last CodeAction
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Option Strict Off
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions
......@@ -17,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Genera
Return New Tuple(Of DiagnosticAnalyzer, CodeFixProvider)(Nothing, New GenerateTypeCodeFixProvider())
End Function
Protected Overrides Function MassageActions(actions As IList(Of CodeAction)) As IList(Of CodeAction)
Return FlattenActions(actions)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)>
Public Sub TestGenerateTypeParameterFromArgumentInferT()
Test(
......@@ -467,7 +472,7 @@ Class Program
End Class
#End ExternalSource
</text>.NormalizedValue,
{String.Format(FeaturesResources.GenerateForInNewFile, "class", "Foo", FeaturesResources.GlobalNamespace), String.Format(FeaturesResources.GenerateForIn, "class", "Foo", "Program"), FeaturesResources.GenerateNewType})
{String.Format(FeaturesResources.Generate_0_1_in_new_file, "class", "Foo", FeaturesResources.GlobalNamespace), String.Format(FeaturesResources.Generate_nested_0_1, "class", "Foo", "Program"), FeaturesResources.GenerateNewType})
End Sub
<WorkItem(545363)>
......@@ -486,7 +491,9 @@ Class Bar
End Class
#End ExternalSource
</text>.NormalizedValue,
{String.Format(FeaturesResources.GenerateForInNewFile, "class", "Foo", FeaturesResources.GlobalNamespace), String.Format(FeaturesResources.GenerateForIn, "class", "Foo", FeaturesResources.GlobalNamespace), String.Format(FeaturesResources.GenerateForIn, "class", "Foo", "Program"), FeaturesResources.GenerateNewType})
{String.Format(FeaturesResources.Generate_0_1_in_new_file, "class", "Foo", FeaturesResources.GlobalNamespace),
String.Format(FeaturesResources.Generate_0_1, "class", "Foo", FeaturesResources.GlobalNamespace),
String.Format(FeaturesResources.Generate_nested_0_1, "class", "Foo"), FeaturesResources.GenerateNewType})
End Sub
<WorkItem(545363)>
......@@ -860,6 +867,10 @@ index:=2)
New GenerateTypeCodeFixProvider())
End Function
Protected Overrides Function MassageActions(actions As IList(Of CodeAction)) As IList(Of CodeAction)
Return FlattenActions(actions)
End Function
<WorkItem(829970)>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)>
Public Sub TestUnknownIdentifierInAttributeSyntaxWithoutTarget()
......
......@@ -525,17 +525,9 @@ private static bool NotNull(INamespaceOrTypeSymbol symbol)
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(string title, Func<CancellationToken, Task<Document>> createChangedDocument) :
base(title, createChangedDocument)
base(title, createChangedDocument, equivalenceKey: title)
{
}
public override string EquivalenceKey
{
get
{
return Title;
}
}
}
}
}
......@@ -35,7 +35,6 @@ protected sealed override async Task<IEnumerable<CodeActionOperation>> ComputeOp
}
protected abstract Task<Document> GetChangedSuppressionDocumentAsync(CancellationToken cancellationToken);
public override bool SupportsFixAllOccurrences => true;
private string GetSuppressionsFilePath(string suppressionsFileName)
{
......
......@@ -152,7 +152,6 @@ private static SyntaxToken GetNewEndToken(SyntaxToken endToken, Diagnostic diagn
}
}
public override bool SupportsFixAllOccurrences => true;
public SyntaxToken StartToken_TestOnly => _startToken;
public SyntaxToken EndToken_TestOnly => _endToken;
}
......
......@@ -109,7 +109,7 @@ public Task<IEnumerable<CodeFix>> GetSuppressionsAsync(Document document, TextSp
internal async Task<IEnumerable<PragmaWarningCodeAction>> GetPragmaSuppressionsAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
{
var codeFixes = await GetSuppressionsAsync(document, span, diagnostics, skipSuppressMessage: true, cancellationToken: cancellationToken).ConfigureAwait(false);
return codeFixes.SelectMany(fix => ((SuppressionCodeAction)fix.Action).NestedActions).Cast<PragmaWarningCodeAction>();
return codeFixes.SelectMany(fix => fix.Action.GetCodeActions()).OfType<PragmaWarningCodeAction>();
}
private async Task<IEnumerable<CodeFix>> GetSuppressionsAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, bool skipSuppressMessage, CancellationToken cancellationToken)
......
......@@ -19,7 +19,5 @@ protected NestedSuppressionCodeAction(string title)
public sealed override string EquivalenceKey => Title + DiagnosticIdForEquivalenceKey;
public static bool IsEquivalenceKeyForGlobalSuppression(string equivalenceKey) =>
equivalenceKey.StartsWith(FeaturesResources.SuppressWithGlobalSuppressMessage);
public abstract bool SupportsFixAllOccurrences { get; }
}
}
......@@ -6,22 +6,13 @@
namespace Microsoft.CodeAnalysis.CodeFixes.Suppression
{
internal sealed class SuppressionCodeAction : CodeAction
internal sealed class SuppressionCodeAction : CodeAction.SimpleCodeAction
{
private readonly string _title;
private readonly string _equivalenceKey;
public readonly IEnumerable<NestedSuppressionCodeAction> NestedActions;
public SuppressionCodeAction(Diagnostic diagnostic, IEnumerable<NestedSuppressionCodeAction> nestedActions)
public SuppressionCodeAction(Diagnostic diagnostic, IEnumerable<CodeAction> nestedActions)
: base(string.Format(FeaturesResources.SuppressionCodeActionTitle, diagnostic.Id), nestedActions.AsImmutableOrEmpty(), ComputeEquivalenceKey(nestedActions))
{
_title = string.Format(FeaturesResources.SuppressionCodeActionTitle, diagnostic.Id);
_equivalenceKey = ComputeEquivalenceKey(nestedActions);
this.NestedActions = nestedActions;
}
public override string Title => _title;
public override string EquivalenceKey => _equivalenceKey;
private static string ComputeEquivalenceKey(IEnumerable<CodeAction> nestedActions)
{
if (nestedActions == null)
......
......@@ -817,6 +817,42 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Generate {0} &apos;{1}&apos;.
/// </summary>
internal static string Generate_0_1 {
get {
return ResourceManager.GetString("Generate_0_1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate {0} &apos;{1}&apos; in new file.
/// </summary>
internal static string Generate_0_1_in_new_file {
get {
return ResourceManager.GetString("Generate_0_1_in_new_file", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate nested {0} &apos;{1}&apos;.
/// </summary>
internal static string Generate_nested_0_1 {
get {
return ResourceManager.GetString("Generate_nested_0_1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate type.
/// </summary>
internal static string Generate_type {
get {
return ResourceManager.GetString("Generate_type", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate abstract method &apos;{0}&apos; in &apos;{1}&apos;.
/// </summary>
......@@ -925,24 +961,6 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Generate {0} for &apos;{1}&apos; in &apos;{2}&apos;.
/// </summary>
internal static string GenerateForIn {
get {
return ResourceManager.GetString("GenerateForIn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate {0} for &apos;{1}&apos; in &apos;{2}&apos; (in new file).
/// </summary>
internal static string GenerateForInNewFile {
get {
return ResourceManager.GetString("GenerateForInNewFile", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate &apos;GetHashCode()&apos;.
/// </summary>
......
......@@ -234,11 +234,11 @@
<data name="GenerateLocal" xml:space="preserve">
<value>Generate local '{0}'</value>
</data>
<data name="GenerateForInNewFile" xml:space="preserve">
<value>Generate {0} for '{1}' in '{2}' (in new file)</value>
<data name="Generate_0_1_in_new_file" xml:space="preserve">
<value>Generate {0} '{1}' in new file</value>
</data>
<data name="GenerateForIn" xml:space="preserve">
<value>Generate {0} for '{1}' in '{2}'</value>
<data name="Generate_nested_0_1" xml:space="preserve">
<value>Generate nested {0} '{1}'</value>
</data>
<data name="GlobalNamespace" xml:space="preserve">
<value>Global Namespace</value>
......@@ -834,6 +834,12 @@ Do you want to continue?</value>
<data name="UseAutoProperty" xml:space="preserve">
<value>Use auto property</value>
</data>
<data name="Generate_type" xml:space="preserve">
<value>Generate type</value>
</data>
<data name="Generate_0_1" xml:space="preserve">
<value>Generate {0} '{1}'</value>
</data>
<data name="ChangeTo" xml:space="preserve">
<value>Change '{0}' to '{1}'.</value>
</data>
......
......@@ -40,21 +40,21 @@ private class GenerateTypeCodeAction : CodeAction
private static string FormatDisplayText(
State state,
bool inNewFile,
string destination)
bool isNested)
{
var finalName = GetTypeName(state);
if (inNewFile)
{
return string.Format(FeaturesResources.GenerateForInNewFile,
return string.Format(FeaturesResources.Generate_0_1_in_new_file,
state.IsStruct ? "struct" : state.IsInterface ? "interface" : "class",
state.Name, destination);
state.Name);
}
else
{
return string.Format(FeaturesResources.GenerateForIn,
return string.Format(isNested ? FeaturesResources.Generate_nested_0_1 : FeaturesResources.Generate_0_1,
state.IsStruct ? "struct" : state.IsInterface ? "interface" : "class",
state.Name, destination);
state.Name);
}
}
......@@ -74,11 +74,11 @@ public override string Title
if (_intoNamespace)
{
var namespaceToGenerateIn = string.IsNullOrEmpty(_state.NamespaceToGenerateInOpt) ? FeaturesResources.GlobalNamespace : _state.NamespaceToGenerateInOpt;
return FormatDisplayText(_state, _inNewFile, namespaceToGenerateIn);
return FormatDisplayText(_state, _inNewFile, isNested: false);
}
else
{
return FormatDisplayText(_state, inNewFile: false, destination: _state.TypeToGenerateInOpt.Name);
return FormatDisplayText(_state, inNewFile: false, isNested: true);
}
}
}
......
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
......@@ -72,7 +73,18 @@ protected AbstractGenerateTypeService()
var state = State.Generate((TService)this, semanticDocument, node, cancellationToken);
if (state != null)
{
return GetActions(semanticDocument, node, state, cancellationToken);
var actions = GetActions(semanticDocument, node, state, cancellationToken).ToList();
if (actions.Count > 1)
{
// Wrap the generate type actions into a single top level suggestion
// so as to not clutter the list.
return SpecializedCollections.SingletonEnumerable(
new MyCodeAction(FeaturesResources.Generate_type, actions.AsImmutable(), actions[0].EquivalenceKey));
}
else
{
return actions;
}
}
return SpecializedCollections.EmptyEnumerable<CodeAction>();
......@@ -280,5 +292,13 @@ protected bool GeneratedTypesMustBePublic(Project project)
return false;
}
private class MyCodeAction : CodeAction.SimpleCodeAction
{
public MyCodeAction(string title, ImmutableArray<CodeAction> nestedActions, string equivalenceKey)
: base(title, nestedActions, equivalenceKey)
{
}
}
}
}
......@@ -101,8 +101,9 @@
"sha512": "pwu80Ohe7SBzZ6i69LVdzowp6V+LaVRzd5F7A6QlD42vQkX0oT7KXKWWPlM/S00w1gnMQMRnEdbtOV12z6rXdQ==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"Microsoft.Composition.nuspec",
"License-Stable.rtf",
"lib/portable-net45+win8+wp8+wpa81/System.Composition.AttributedModel.dll",
"lib/portable-net45+win8+wp8+wpa81/System.Composition.AttributedModel.XML",
"lib/portable-net45+win8+wp8+wpa81/System.Composition.Convention.dll",
......@@ -113,255 +114,254 @@
"lib/portable-net45+win8+wp8+wpa81/System.Composition.Runtime.XML",
"lib/portable-net45+win8+wp8+wpa81/System.Composition.TypedParts.dll",
"lib/portable-net45+win8+wp8+wpa81/System.Composition.TypedParts.XML",
"License-Stable.rtf",
"Microsoft.Composition.nuspec",
"package/services/metadata/core-properties/12e2c94035674b25b911285cc26e3260.psmdcp"
"package/services/metadata/core-properties/12e2c94035674b25b911285cc26e3260.psmdcp",
"[Content_Types].xml"
]
},
"System.Collections/4.0.10": {
"sha512": "ux6ilcZZjV/Gp7JEZpe+2V1eTueq6NuoGRM3eZCFuPM25hLVVgCRuea6STW8hvqreIOE59irJk5/ovpA5xQipw==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Collections.nuspec",
"lib/netcore50/System.Collections.dll",
"lib/DNXCore50/System.Collections.dll",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net46/_._",
"lib/netcore50/System.Collections.dll",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/b4f8061406e54dbda8f11b23186be11a.psmdcp",
"ref/dotnet/System.Collections.dll",
"ref/dotnet/System.Collections.xml",
"ref/dotnet/zh-hant/System.Collections.xml",
"ref/dotnet/de/System.Collections.xml",
"ref/dotnet/es/System.Collections.xml",
"ref/dotnet/fr/System.Collections.xml",
"ref/dotnet/it/System.Collections.xml",
"ref/dotnet/ja/System.Collections.xml",
"ref/dotnet/ko/System.Collections.xml",
"ref/dotnet/ru/System.Collections.xml",
"ref/dotnet/System.Collections.dll",
"ref/dotnet/System.Collections.xml",
"ref/dotnet/zh-hans/System.Collections.xml",
"ref/dotnet/zh-hant/System.Collections.xml",
"ref/dotnet/es/System.Collections.xml",
"runtimes/win8-aot/lib/netcore50/System.Collections.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net46/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtimes/win8-aot/lib/netcore50/System.Collections.dll",
"System.Collections.nuspec"
"package/services/metadata/core-properties/b4f8061406e54dbda8f11b23186be11a.psmdcp",
"[Content_Types].xml"
]
},
"System.Collections.Immutable/1.1.36": {
"sha512": "MOlivTIeAIQPPMUPWIIoMCvZczjFRLYUWSYwqi1szu8QPyeIbsaPeI+hpXe1DzTxNwnRnmfYaoToi6kXIfSPNg==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Collections.Immutable.nuspec",
"License-Stable.rtf",
"lib/portable-net45+win8+wp8+wpa81/System.Collections.Immutable.dll",
"lib/portable-net45+win8+wp8+wpa81/System.Collections.Immutable.xml",
"License-Stable.rtf",
"package/services/metadata/core-properties/c8b7b781850445db852bd2d848380ca6.psmdcp",
"System.Collections.Immutable.nuspec"
"[Content_Types].xml"
]
},
"System.Diagnostics.Debug/4.0.10": {
"sha512": "pi2KthuvI2LWV2c2V+fwReDsDiKpNl040h6DcwFOb59SafsPT/V1fCy0z66OKwysurJkBMmp5j5CBe3Um+ub0g==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Diagnostics.Debug.nuspec",
"lib/DNXCore50/System.Diagnostics.Debug.dll",
"lib/netcore50/System.Diagnostics.Debug.dll",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net46/_._",
"lib/netcore50/System.Diagnostics.Debug.dll",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/bfb05c26051f4a5f9015321db9cb045c.psmdcp",
"ref/dotnet/System.Diagnostics.Debug.dll",
"ref/dotnet/System.Diagnostics.Debug.xml",
"ref/dotnet/zh-hant/System.Diagnostics.Debug.xml",
"ref/dotnet/de/System.Diagnostics.Debug.xml",
"ref/dotnet/es/System.Diagnostics.Debug.xml",
"ref/dotnet/fr/System.Diagnostics.Debug.xml",
"ref/dotnet/it/System.Diagnostics.Debug.xml",
"ref/dotnet/ja/System.Diagnostics.Debug.xml",
"ref/dotnet/ko/System.Diagnostics.Debug.xml",
"ref/dotnet/ru/System.Diagnostics.Debug.xml",
"ref/dotnet/System.Diagnostics.Debug.dll",
"ref/dotnet/System.Diagnostics.Debug.xml",
"ref/dotnet/zh-hans/System.Diagnostics.Debug.xml",
"ref/dotnet/zh-hant/System.Diagnostics.Debug.xml",
"ref/dotnet/es/System.Diagnostics.Debug.xml",
"runtimes/win8-aot/lib/netcore50/System.Diagnostics.Debug.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net46/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtimes/win8-aot/lib/netcore50/System.Diagnostics.Debug.dll",
"System.Diagnostics.Debug.nuspec"
"package/services/metadata/core-properties/bfb05c26051f4a5f9015321db9cb045c.psmdcp",
"[Content_Types].xml"
]
},
"System.Globalization/4.0.10": {
"sha512": "kzRtbbCNAxdafFBDogcM36ehA3th8c1PGiz8QRkZn8O5yMBorDHSK8/TGJPYOaCS5zdsGk0u9qXHnW91nqy7fw==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Globalization.nuspec",
"lib/netcore50/System.Globalization.dll",
"lib/DNXCore50/System.Globalization.dll",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net46/_._",
"lib/netcore50/System.Globalization.dll",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/93bcad242a4e4ad7afd0b53244748763.psmdcp",
"ref/dotnet/System.Globalization.dll",
"ref/dotnet/System.Globalization.xml",
"ref/dotnet/zh-hant/System.Globalization.xml",
"ref/dotnet/de/System.Globalization.xml",
"ref/dotnet/es/System.Globalization.xml",
"ref/dotnet/fr/System.Globalization.xml",
"ref/dotnet/it/System.Globalization.xml",
"ref/dotnet/ja/System.Globalization.xml",
"ref/dotnet/ko/System.Globalization.xml",
"ref/dotnet/ru/System.Globalization.xml",
"ref/dotnet/System.Globalization.dll",
"ref/dotnet/System.Globalization.xml",
"ref/dotnet/zh-hans/System.Globalization.xml",
"ref/dotnet/zh-hant/System.Globalization.xml",
"ref/dotnet/es/System.Globalization.xml",
"runtimes/win8-aot/lib/netcore50/System.Globalization.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net46/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtimes/win8-aot/lib/netcore50/System.Globalization.dll",
"System.Globalization.nuspec"
"package/services/metadata/core-properties/93bcad242a4e4ad7afd0b53244748763.psmdcp",
"[Content_Types].xml"
]
},
"System.Reflection.Metadata/1.1.0-alpha-00014": {
"sha512": "rVeIWjVoLQS0aNrGdzndZReskyfxu4EfO9BKqT5GJt0YfGtlsHB1aDPnjl4jIBDTr+WJC9YsnZg8S5sKT1X42g==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Reflection.Metadata.nuspec",
"lib/portable-net45+win8/System.Reflection.Metadata.dll",
"lib/portable-net45+win8/System.Reflection.Metadata.pdb",
"lib/portable-net45+win8/System.Reflection.Metadata.xml",
"package/services/metadata/core-properties/a48ecf967b1540bba8edfe9af3a99ea5.psmdcp",
"System.Reflection.Metadata.nuspec"
"[Content_Types].xml"
]
},
"System.Runtime/4.0.20": {
"sha512": "X7N/9Bz7jVPorqdVFO86ns1sX6MlQM+WTxELtx+Z4VG45x9+LKmWH0GRqjgKprUnVuwmfB9EJ9DQng14Z7/zwg==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Runtime.nuspec",
"lib/netcore50/System.Runtime.dll",
"lib/DNXCore50/System.Runtime.dll",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net46/_._",
"lib/netcore50/System.Runtime.dll",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/d1ded52f75da4446b1c962f9292aa3ef.psmdcp",
"ref/dotnet/System.Runtime.dll",
"ref/dotnet/System.Runtime.xml",
"ref/dotnet/zh-hant/System.Runtime.xml",
"ref/dotnet/de/System.Runtime.xml",
"ref/dotnet/es/System.Runtime.xml",
"ref/dotnet/fr/System.Runtime.xml",
"ref/dotnet/it/System.Runtime.xml",
"ref/dotnet/ja/System.Runtime.xml",
"ref/dotnet/ko/System.Runtime.xml",
"ref/dotnet/ru/System.Runtime.xml",
"ref/dotnet/System.Runtime.dll",
"ref/dotnet/System.Runtime.xml",
"ref/dotnet/zh-hans/System.Runtime.xml",
"ref/dotnet/zh-hant/System.Runtime.xml",
"ref/dotnet/es/System.Runtime.xml",
"runtimes/win8-aot/lib/netcore50/System.Runtime.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net46/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtimes/win8-aot/lib/netcore50/System.Runtime.dll",
"System.Runtime.nuspec"
"package/services/metadata/core-properties/d1ded52f75da4446b1c962f9292aa3ef.psmdcp",
"[Content_Types].xml"
]
},
"System.Runtime.Extensions/4.0.10": {
"sha512": "5dsEwf3Iml7d5OZeT20iyOjT+r+okWpN7xI2v+R4cgd3WSj4DeRPTvPFjDpacbVW4skCAZ8B9hxXJYgkCFKJ1A==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Runtime.Extensions.nuspec",
"lib/netcore50/System.Runtime.Extensions.dll",
"lib/DNXCore50/System.Runtime.Extensions.dll",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net46/_._",
"lib/netcore50/System.Runtime.Extensions.dll",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/c7fee76a13d04c7ea49fb1a24c184f37.psmdcp",
"ref/dotnet/System.Runtime.Extensions.dll",
"ref/dotnet/System.Runtime.Extensions.xml",
"ref/dotnet/zh-hant/System.Runtime.Extensions.xml",
"ref/dotnet/de/System.Runtime.Extensions.xml",
"ref/dotnet/es/System.Runtime.Extensions.xml",
"ref/dotnet/fr/System.Runtime.Extensions.xml",
"ref/dotnet/it/System.Runtime.Extensions.xml",
"ref/dotnet/ja/System.Runtime.Extensions.xml",
"ref/dotnet/ko/System.Runtime.Extensions.xml",
"ref/dotnet/ru/System.Runtime.Extensions.xml",
"ref/dotnet/System.Runtime.Extensions.dll",
"ref/dotnet/System.Runtime.Extensions.xml",
"ref/dotnet/zh-hans/System.Runtime.Extensions.xml",
"ref/dotnet/zh-hant/System.Runtime.Extensions.xml",
"ref/dotnet/es/System.Runtime.Extensions.xml",
"runtimes/win8-aot/lib/netcore50/System.Runtime.Extensions.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net46/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtimes/win8-aot/lib/netcore50/System.Runtime.Extensions.dll",
"System.Runtime.Extensions.nuspec"
"package/services/metadata/core-properties/c7fee76a13d04c7ea49fb1a24c184f37.psmdcp",
"[Content_Types].xml"
]
},
"System.Threading/4.0.10": {
"sha512": "0w6pRxIEE7wuiOJeKabkDgeIKmqf4ER1VNrs6qFwHnooEE78yHwi/bKkg5Jo8/pzGLm0xQJw0nEmPXt1QBAIUA==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"System.Threading.nuspec",
"lib/DNXCore50/System.Threading.dll",
"lib/netcore50/System.Threading.dll",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net46/_._",
"lib/netcore50/System.Threading.dll",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"package/services/metadata/core-properties/c17c3791d8fa4efbb8aded2ca8c71fbe.psmdcp",
"ref/dotnet/System.Threading.dll",
"ref/dotnet/System.Threading.xml",
"ref/dotnet/zh-hant/System.Threading.xml",
"ref/dotnet/de/System.Threading.xml",
"ref/dotnet/es/System.Threading.xml",
"ref/dotnet/fr/System.Threading.xml",
"ref/dotnet/it/System.Threading.xml",
"ref/dotnet/ja/System.Threading.xml",
"ref/dotnet/ko/System.Threading.xml",
"ref/dotnet/ru/System.Threading.xml",
"ref/dotnet/System.Threading.dll",
"ref/dotnet/System.Threading.xml",
"ref/dotnet/zh-hans/System.Threading.xml",
"ref/dotnet/zh-hant/System.Threading.xml",
"ref/dotnet/es/System.Threading.xml",
"runtimes/win8-aot/lib/netcore50/System.Threading.dll",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net46/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"runtimes/win8-aot/lib/netcore50/System.Threading.dll",
"System.Threading.nuspec"
"package/services/metadata/core-properties/c17c3791d8fa4efbb8aded2ca8c71fbe.psmdcp",
"[Content_Types].xml"
]
},
"xunit/1.9.2": {
"sha512": "c1wppJtYPUGPHVP9U1wjmfii4553MuQSXkAt8rudkXW+eUFJxOOfDvhBJ6S0YHHDMFEJwiMN770AT4Lno8EBpw==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"xunit.nuspec",
"lib/net20/xunit.dll",
"lib/net20/xunit.dll.tdnet",
"lib/net20/xunit.xml",
"lib/net20/xunit.runner.msbuild.dll",
"lib/net20/xunit.runner.tdnet.dll",
"lib/net20/xunit.runner.utility.dll",
"lib/net20/xunit.xml",
"package/services/metadata/core-properties/cb77589bcde944baab7b67d60ca583c7.psmdcp",
"xunit.nuspec"
"[Content_Types].xml"
]
}
},
......
......@@ -41,6 +41,15 @@ public abstract class CodeAction
/// </remarks>
public virtual string EquivalenceKey { get { return null; } }
internal virtual bool HasCodeActions => false;
internal virtual bool IsInvokable => true;
internal virtual ImmutableArray<CodeAction> GetCodeActions()
{
return ImmutableArray<CodeAction>.Empty;
}
/// <summary>
/// The sequence of operations that define the code action.
/// </summary>
......@@ -284,57 +293,78 @@ public static CodeAction Create(string title, Func<CancellationToken, Task<Solut
return new SolutionChangeAction(title, createChangedSolution, equivalenceKey);
}
internal class DocumentChangeAction : CodeAction
/// <summary>
/// Creates a top level code action with multiple code action choices a user can invoke.
/// </summary>
public static CodeAction Create(string title, IEnumerable<CodeAction> nestedActions, string equivalenceKey = null)
{
if (title == null)
{
throw new ArgumentNullException(nameof(title));
}
return new SimpleCodeAction(title, nestedActions.AsImmutableOrEmpty(), equivalenceKey);
}
internal class SimpleCodeAction : CodeAction
{
private readonly string _title;
private readonly Func<CancellationToken, Task<Document>> _createChangedDocument;
private readonly string _equivalenceKey;
private readonly ImmutableArray<CodeAction> _nestedActions;
public DocumentChangeAction(string title, Func<CancellationToken, Task<Document>> createChangedDocument, string equivalenceKey = null)
public SimpleCodeAction(string title, ImmutableArray<CodeAction> nestedActions, string equivalenceKey)
{
_title = title;
_createChangedDocument = createChangedDocument;
_nestedActions = nestedActions;
_equivalenceKey = equivalenceKey;
}
public override string Title
public sealed override string Title => _title;
public sealed override string EquivalenceKey => _equivalenceKey;
internal override bool IsInvokable => false;
internal override bool HasCodeActions => _nestedActions.Length > 0;
internal override ImmutableArray<CodeAction> GetCodeActions()
{
return _nestedActions;
}
protected override Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
get { return _title; }
return Task.FromResult<Document>(null);
}
}
public override string EquivalenceKey
internal class DocumentChangeAction : SimpleCodeAction
{
private readonly Func<CancellationToken, Task<Document>> _createChangedDocument;
public DocumentChangeAction(string title, Func<CancellationToken, Task<Document>> createChangedDocument, string equivalenceKey = null)
: base(title, nestedActions: ImmutableArray<CodeAction>.Empty, equivalenceKey: equivalenceKey)
{
get { return _equivalenceKey; }
_createChangedDocument = createChangedDocument;
}
internal override bool IsInvokable => true;
protected override Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
return _createChangedDocument(cancellationToken);
}
}
internal class SolutionChangeAction : CodeAction
internal class SolutionChangeAction : SimpleCodeAction
{
private readonly string _title;
private readonly Func<CancellationToken, Task<Solution>> _createChangedSolution;
private readonly string _equivalenceKey;
public SolutionChangeAction(string title, Func<CancellationToken, Task<Solution>> createChangedSolution, string equivalenceKey = null)
: base(title, nestedActions: ImmutableArray<CodeAction>.Empty, equivalenceKey: equivalenceKey)
{
_title = title;
_createChangedSolution = createChangedSolution;
_equivalenceKey = equivalenceKey;
}
public override string Title
{
get { return _title; }
}
public override string EquivalenceKey
{
get { return _equivalenceKey; }
}
internal override bool IsInvokable => true;
protected override Task<Solution> GetChangedSolutionAsync(CancellationToken cancellationToken)
{
......
Microsoft.CodeAnalysis.Editing.SyntaxEditor.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> void
Microsoft.CodeAnalysis.Project.IsSubmission.get -> bool
Microsoft.CodeAnalysis.Workspace.UpdateReferencesAfterAdd() -> void
static Microsoft.CodeAnalysis.CodeActions.CodeAction.Create(string title, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.CodeActions.CodeAction> nestedActions, string equivalenceKey = null) -> Microsoft.CodeAnalysis.CodeActions.CodeAction
static Microsoft.CodeAnalysis.Editing.SyntaxGenerator.GetGenerator(Microsoft.CodeAnalysis.Project project) -> Microsoft.CodeAnalysis.Editing.SyntaxGenerator
virtual Microsoft.CodeAnalysis.Editing.SyntaxGenerator.RemoveNode(Microsoft.CodeAnalysis.SyntaxNode root, Microsoft.CodeAnalysis.SyntaxNode node, Microsoft.CodeAnalysis.SyntaxRemoveOptions options) -> Microsoft.CodeAnalysis.SyntaxNode
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册