是否期望Rosyln的ToFullString()输出包含前一个“#endregion”?

时间:2015-08-27 13:35:21

标签: c# visual-studio-2015 roslyn

我正在使用Roslyn开发一个搜索代码库的小工具。一个功能是我可以搜索方法是否存在,如果存在,我会返回完整的方法文本以显示在UI上。

我正在使用与其集成的Roslyn的Visual Studio 2015。我观察到的一个奇怪的情况是特定方法是#region中的第一个方法。

每当我得到该特定方法的全文时,我都会从前一个区域末尾获得一个额外的#endregion,以及当前的区域开始部分。

我为一个区域内第一个方法获取的示例输出。

#endregion      -- why is this coming?

#region Public Methods and Operators

/// <summary>
/// My Method's summary.
/// </summary>
/// <param name="param1">
/// The param1.
/// </param>
/// <returns>
/// returns something
/// </returns>
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SampleMethod(Parameter param1)
{
    ....
....
sample code
    return this.RedirectToAction("sample_action");
}

我写的代码是为了获得完整的方法文本,如下所示。

var MethodText = ((MethodDeclarationSyntax)method).ToFullString()

这是预期的工作方式吗?

2 个答案:

答案 0 :(得分:2)

从查看语法可视化工具来看,它看起来并不适合。我不完全确定这是否是预期的行为,但它并不像你说的那样感觉正确。

但是,如果您不需要任何文档,可以使用ToString(),这将只返回方法及其中的所有内容。

ToFullString()包括领先和尾随琐事。它似乎一直持续到下一个领先的SyntaxNode。

在使用ToFullString()

之前,你现在可以使用类似的东西删除琐事
var trivia = method.DescendantTrivia()
                   .Where(t => t.IsKind(SyntaxKind.EndRegionDirectiveTrivia));

foreach (var t in trivia)
{
    method = method.ReplaceTrivia(t, trivia.ToSyntaxTriviaList()
                   .Except(st => st.IsKind(SyntaxKind.EndRegionDirectiveTrivia)));
}

method.ToFullString();

Snippet to use in Linqpad

我似乎无法在Roslyn Github问题上找到任何问题。

编辑:您也没有获得该方法的#endregion。我建议删除任何区域语法类型,然后调用.ToFullString()

答案 1 :(得分:2)

解析器有一个一般规则,即“一行上的琐事本身会附加到未来某行的下一个真实令牌”。所以在这种情况下,方法之前的所有琐事都会附加到下一个方法。 #endregion没有特殊情况逻辑来做其他事情。也许它应该但它今天不存在。

您可能需要编写一些自定义代码来调整显示。例如,您可能希望排除非文档评论琐事的所有琐事。考虑一下这个更人为的案例:

#region Comment

// some long comment about the method below me

#endregion

void AbandonAllHopeYeWhoEntersHere() { ...}

你想要显示吗?说实话,不太确定。

琐事不是微不足道的。它涉及在很多情况下确定用户意图,因此我们采用简单的规则与大量的启发式方法。 (我们经常考虑将琐事重命名为“复杂”或警告远方接近的人,但决定不这样做。)