我目前正在尝试 Roslyn 和代码操作,以及更具体的代码重构。 感觉很简单,但是我有一个无法解决的困难。
代码操作作为“预览”选项针对虚拟工作区执行一次,以便您可以在单击该操作并针对真实工作区执行它之前看到实际的更改。
现在我正在处理一些 Roslyn 还无法真正做到的事情,因此我通过 EnvDTE
进行一些更改。我知道,这很糟糕,但我找不到其他方法。
所以这里的问题是:
当我将鼠标悬停在代码操作上时,代码将作为预览执行,并且不应执行 EnvDTE
更改。这些只有在真正执行时才应该完成。
我创建了一个gist with a small example of my code 。它确实没有意义,但应该显示我想要实现的目标。通过 roslyn 进行一些修改,然后通过 EnvDTE
进行一些操作,例如更改光标位置。但当然仅限于真正的执行。
对于那些无法点击要点的人来说,相关部分:
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(continueOnCapturedContext: false);
var node = root.FindNode(context.Span);
var dec = node as MethodDeclarationSyntax;
if (dec == null)
return;
context.RegisterRefactoring(CodeAction.Create("MyAction", c => DoMyAction(context.Document, dec, c)));
}
private static async Task<Solution> DoMyAction(Document document, MethodDeclarationSyntax method, CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken);
var root = await syntaxTree.GetRootAsync(cancellationToken);
// some - for the question irrelevant - roslyn changes, like:
document = document.WithSyntaxRoot(root.ReplaceNode(method, method.WithIdentifier(SyntaxFactory.ParseToken(method.Identifier.Text + "Suffix"))));
// now the DTE magic
var preview = false; // <--- TODO: How to check if I am in preview here?
if (!preview)
{
var requestedItem = DTE.Solution.FindProjectItem(document.FilePath);
var window = requestedItem.Open(Constants.vsViewKindCode);
window.Activate();
var position = method.Identifier.GetLocation().GetLineSpan().EndLinePosition;
var textSelection = (TextSelection) window.Document.Selection;
textSelection.MoveTo(position.Line, position.Character);
}
return document.Project.Solution;
}
最佳答案
您可以选择覆盖 ComputePreviewOperationsAsync
使预览具有与常规代码不同的行为。
关于c# - Roslyn 代码操作 : How to check if preview or real execution?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44243781/