【发布时间】:2021-05-07 15:39:50
【问题描述】:
我有一个应用程序,它允许用户编写 c-sharp 代码,这些代码被保存为类库以供以后调用。
已经建立了一项新要求,即不再允许某些命名空间(以及它们包含的方法以及任何具有返回类型的变量或方法)。所以我需要分析代码并提醒用户注意他们代码中的任何被禁止的命名空间,以便他们可以删除它们。
使用 Roslyn,我可以访问 InvocationExpressionSyntax 节点以进行方法调用。然后我通过调用var mySymbol = mySemanticModel.GetSymbolInfo(myInvocationExpressionSyntaxNode).Symbol 获取符号信息。
然后调用mySymbol.ContainingType.ToDisplayString()返回调用的命名空间类型。
但是,似乎并非所有被调用的方法在 Roslyn 中都有符号信息。比如System.Math.Sqrt()有符号信息,所以我可以从中得到System.Math的包含命名空间。另一方面,System.Net.WebRequest.Create() 或 System.Diagnostics.Process.Start() 不这样做。如何从这些节点获取System.Net.WebRequest 或System.Dignostics.Process?我可以使用 QuickWatch 清楚地看到它们。
例如,System.Diagnostics.Process.Start() 节点本身在 QuickWatch 中显示以下值:
InvocationExpressionSyntax InvocationExpression System.Diagnostics.Process.Start("CMD.exe","")
并且节点的表达式有这个值:
MemberAccessExpressionSyntax SimpleMemberAccessExpression System.Diagnostics.Process.Start
很明显,命名空间存在于值本身中。但是 SymbolInfo 中的 Symbol 和 TypeInfo 中的 Type 都是空的。
编辑
关于我的编译,C# Roslyn 工具设置如下(我们应该也支持 VB,因此属性是接口的):
private class CSharpRoslynTools : IRoslynTools
{
public CompilationUnitSyntax SyntaxTreeRoot { get; }
public SemanticModel SemanticModel { get; }
public CSharpRoslynTools(string code)
{
var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var syntaxTree = CSharpSyntaxTree.ParseText(code);
var compilation = CSharpCompilation.Create(
"MyCompilation",
syntaxTrees: new[] { syntaxTree },
references: new[]
{
mscorlib
});
this.SemanticModel = compilation.GetSemanticModel(syntaxTree);
this.SyntaxTreeRoot = (CompilationUnitSyntax)syntaxTree.GetRoot();
}
}
我确实意识到系统诊断不是 mscorlib 的一部分。这可能是符号信息丢失的原因吗?
老实说,我觉得这有点浪费我的时间,因为这些脚本被设计为在一个可能已经有 15 年历史的 WinForms 桌面应用程序中运行。但后来他们决定将此桌面应用程序迁移到某些客户需要的 Citrix Cloud。因此,如果不是管理员登录到应用程序,我们必须锁定任何可以访问文件系统的东西。因此,这些脚本存在巨大的潜在安全漏洞。不过,有人访问该应用程序并利用其中任何一个的机会很小。
我推动了一个黑名单,这很容易通过简单的代码字符串搜索来完成。他们想要一个需要完整解析符号的白名单。
【问题讨论】:
标签: c# roslyn roslyn-code-analysis