我正在尝试在Roslyn中创建代码分析器,我需要分析项目中的SqlCommand用法。我已经编写了分析器,当我在Visual Studio项目中测试它时工作正常,但是当我编写单元测试时,我试图从SymbolInfo
获取SemanticModel
并且总是变为空。
我缺少什么?
string test = @"public class TestClass
{
public void SomeMethod(int x)
{
var command = new SqlCommand(""Some COmmabnd"",new SqlConnection(""conn string""));
command.ExecuteReader();
}
}";
var tree = CSharpSyntaxTree.ParseText(test);
var systemDataReference = MetadataReference.CreateFromFile(typeof(System.Data.IDbCommand).Assembly.Location);
var systemConfigurationReference = MetadataReference.CreateFromFile(typeof(ConfigurationManager).Assembly.Location);
var systemTransactionReference = MetadataReference.CreateFromFile(typeof(Transaction).Assembly.Location);
var systemXmlnReference = MetadataReference.CreateFromFile(typeof(XPathDocument).Assembly.Location);
var system = MetadataReference.CreateFromFile(typeof(Uri).Assembly.Location);
var mscorRef = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var systemCore = MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location);
var systemNumerics = MetadataReference.CreateFromFile(typeof(BigInteger).Assembly.Location);
var compilation = CSharpCompilation.Create("TestCompilatin", new[] {tree},
new[]
{
mscorRef, system, systemXmlnReference, systemTransactionReference, systemDataReference,
systemConfigurationReference,systemCore,systemNumerics
});
var semanticModel = compilation.GetSemanticModel(tree);
var invocationExpressions = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach (var invocationExpressionSyntax in invocationExpressions)
{
var memeber = invocationExpressionSyntax.Expression as MemberAccessExpressionSyntax;
var symbolInfo = semanticModel.GetSymbolInfo(memeber);
}
对于我尝试的任何内容, semanticModel.GetSymbolInfo()
会返回带有空符号的SymbolInfo
。
答案 0 :(得分:0)
另一个可能的原因是,未对语法进行语法分析并将其添加到编译中。您总是可以在调用者的语法树中获得有关正在调用的方法的一些信息,但是除非被调用的方法已经添加到编译中,否则它在语义模型中将不可用。考虑了一下,这是很痛苦的。当然,语义模型将不包含有关尚未处理的方法的信息。可以使用AddSyntaxTrees()方法将多个语法树添加到单个编译中。请注意,此方法返回一个 new 编译实例。
希望这可以为某人节省一些时间,而且我也不会因为发布此答案而感到尴尬。