-
Notifications
You must be signed in to change notification settings - Fork 4k
/
CodeRefactoringContext.cs
137 lines (121 loc) · 6.58 KB
/
CodeRefactoringContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.ComponentModel;
using System.Threading;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeRefactorings
{
/// <summary>
/// Context for code refactorings provided by a <see cref="CodeRefactoringProvider"/>.
/// </summary>
public readonly struct CodeRefactoringContext
{
/// <summary>
/// Document corresponding to the <see cref="CodeRefactoringContext.Span"/> to refactor.
/// For code refactorings that support non-source documents by providing a non-default value for
/// <see cref="ExportCodeRefactoringProviderAttribute.DocumentKinds"/>, this property will
/// throw an <see cref="InvalidOperationException"/>. Such refactorings should use the
/// <see cref="CodeRefactoringContext.TextDocument"/> property instead.
/// </summary>
public Document Document
{
get
{
if (TextDocument is not Document document)
{
throw new InvalidOperationException(WorkspacesResources.Use_TextDocument_property_instead_of_Document_property_as_the_provider_supports_non_source_text_documents);
}
return document;
}
}
/// <summary>
/// TextDocument corresponding to the <see cref="CodeRefactoringContext.Span"/> to refactor.
/// This property should be used instead of <see cref="CodeRefactoringContext.Document"/> property by
/// code refactorings that support non-source documents by providing a non-default value for
/// <see cref="ExportCodeRefactoringProviderAttribute.DocumentKinds"/>
/// </summary>
public TextDocument TextDocument { get; }
/// <summary>
/// Text span within the <see cref="CodeRefactoringContext.Document"/> or <see cref="CodeRefactoringContext.TextDocument"/> to refactor.
/// </summary>
public TextSpan Span { get; }
/// <summary>
/// CancellationToken.
/// </summary>
public CancellationToken CancellationToken { get; }
internal readonly CodeActionOptionsProvider Options;
private readonly Action<CodeAction, TextSpan?> _registerRefactoring;
/// <summary>
/// Creates a code refactoring context to be passed into <see cref="CodeRefactoringProvider.ComputeRefactoringsAsync(CodeRefactoringContext)"/> method.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public CodeRefactoringContext(
Document document,
TextSpan span,
Action<CodeAction> registerRefactoring,
CancellationToken cancellationToken)
: this(document, span, (action, textSpan) => registerRefactoring(action), CodeActionOptions.DefaultProvider, cancellationToken)
{ }
/// <summary>
/// Creates a code refactoring context to be passed into <see cref="CodeRefactoringProvider.ComputeRefactoringsAsync(CodeRefactoringContext)"/> method.
/// </summary>
public CodeRefactoringContext(
TextDocument document,
TextSpan span,
Action<CodeAction> registerRefactoring,
CancellationToken cancellationToken)
: this(document, span, (action, textSpan) => registerRefactoring(action), CodeActionOptions.DefaultProvider, cancellationToken)
{ }
/// <summary>
/// Creates a code refactoring context to be passed into <see cref="CodeRefactoringProvider.ComputeRefactoringsAsync(CodeRefactoringContext)"/> method.
/// </summary>
internal CodeRefactoringContext(
TextDocument document,
TextSpan span,
Action<CodeAction, TextSpan?> registerRefactoring,
CodeActionOptionsProvider options,
CancellationToken cancellationToken)
{
// NOTE/TODO: Don't make this overload public & obsolete the `Action<CodeAction> registerRefactoring`
// overload to stop leaking the Lambda implementation detail.
TextDocument = document ?? throw new ArgumentNullException(nameof(document));
Span = span;
_registerRefactoring = registerRefactoring ?? throw new ArgumentNullException(nameof(registerRefactoring));
Options = options;
CancellationToken = cancellationToken;
}
/// <summary>
/// Add supplied <paramref name="action"/> to the list of refactorings that will be offered to the user.
/// </summary>
/// <param name="action">The <see cref="CodeAction"/> that will be invoked to apply the refactoring.</param>
public void RegisterRefactoring(CodeAction action) => RegisterRefactoring(action, applicableToSpan: null); // We could pass this.Span as applicableToSpan instead but that would cause these refactorings to always be closest to current selection
/// <summary>
/// Add supplied <paramref name="action"/> applicable to <paramref name="applicableToSpan"/> to the list of refactorings that will be offered to the user.
/// </summary>
/// <param name="action">The <see cref="CodeAction"/> that will be invoked to apply the refactoring.</param>
/// <param name="applicableToSpan">The <see cref="TextSpan"/> within original document the <paramref name="action"/> is applicable to.</param>
/// <remarks>
/// <paramref name="applicableToSpan"/> should represent a logical section within the original document that the <paramref name="action"/> is
/// applicable to. It doesn't have to precisely represent the exact <see cref="TextSpan"/> that will get changed.
/// </remarks>
internal void RegisterRefactoring(CodeAction action, TextSpan applicableToSpan) => RegisterRefactoring(action, new Nullable<TextSpan>(applicableToSpan));
private void RegisterRefactoring(CodeAction action, TextSpan? applicableToSpan)
{
if (action == null)
{
throw new ArgumentNullException(nameof(action));
}
_registerRefactoring(action, applicableToSpan);
}
internal void Deconstruct(out Document document, out TextSpan span, out CancellationToken cancellationToken)
{
document = Document;
span = Span;
cancellationToken = CancellationToken;
}
}
}