У меня есть приложение, которое позволяет пользователям писать код 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 и Type из TypeInfo равны нулю.
Изменить
Что касается моей компиляции, инструменты 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();
}
}
Одна вещь, которую я действительно понял, это то, что System Diagnostics не является частью mscorlib. Может быть, поэтому отсутствует символьная информация?
Честно говоря, я считаю это пустой тратой времени, потому что сценарии были разработаны для запуска в настольном приложении WinForms, которому на данный момент уже 15 лет. Но затем они решили, что это настольное приложение необходимо перенести в Citrix Cloud для определенных клиентов. И в результате мы должны заблокировать все, что может получить доступ к файловой системе, если это не администратор, вошедший в приложение. Таким образом, у нас есть гигантская потенциальная дыра в безопасности с этими скриптами. Однако шанс того, что кто-то получит доступ к приложению и воспользуется любым из этого, невелик.
Я настаивал на создании черного списка, что было бы достаточно легко сделать с помощью простого строкового поиска кода. Им нужен белый список, который требует полного анализа символов.