var tree = CSharpSyntaxTree.ParseText(@"
public class MyClass{
#region MyRegion
#endregion
}");
//Try finding them as nodes.
var regionNodes = tree.GetRoot().DescendantNodes().OfType<RegionDirectiveTriviaSyntax>();
//Try finding them as trivia?
var regionTrivia = tree.GetRoot().DescendantTrivia().OfType<RegionDirectiveTriviaSyntax>();
var tree = CSharpSyntaxTree.ParseText(@"
public class MyClass{
#region MyRegion
#endregion
}");
//Descend into all node children
//Descend into all trivia children
var regionNodes = tree.GetRoot().DescendantNodes(descendIntoChildren: null, descendIntoTrivia: true).OfType<RegionDirectiveTriviaSyntax>();
var tree = CSharpSyntaxTree.ParseText(@"
class MyClass
{
int myField = 0;
public int MyProperty {get; set;}
public void MyMethod() { }
}");
var Mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);
//Get declarations
var property = tree.GetRoot().DescendantNodes().OfType<PropertyDeclarationSyntax>().Single();
var method = tree.GetRoot().DescendantNodes().OfType<PropertyDeclarationSyntax>().Single();
var field = tree.GetRoot().DescendantNodes().OfType<FieldDeclarationSyntax>().Single();
//Get symbols
var propertySymbol = model.GetDeclaredSymbol(property);
var methodSymbol = model.GetDeclaredSymbol(method);
var fieldSymbol = model.GetDeclaredSymbol(field);
var tree = CSharpSyntaxTree.ParseText(@"
class MyClass
class MyClass
{
int myField1, myField2, myField3;
}");
var Mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);
var field = tree.GetRoot().DescendantNodes().OfType<FieldDeclarationSyntax>().Single();
foreach (var variable in field.Declaration.Variables)
{
//Now we can access each of the symbols within the field
var fieldSymbol = model.GetDeclaredSymbol(variable);
}
In C#, nameof is stored in a normal InvocationExpressionSyntax node with a single argument. That is because in C# ‘nameof’ is a contextual keyword, which will only become the “nameof” operator if it doesn’t already bind to a programmatic symbol named “nameof”
var tree = CSharpSyntaxTree.ParseText(@"
class C
{
void M()
{
int variable = 0;
//Does not bind to a symbol (as there is no class called MissingClass)
//but it is not a true nameof expression
MissingClass.nameof(x);
}
}");
var Mscorlib = PortableExecutableReference.CreateFromAssembly(typeof(object).Assembly);
var compilation = CSharpCompilation.Create("MyCompilation",
syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
var model = compilation.GetSemanticModel(tree);
var nameofInvocations = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>();
var validNameOfs = nameofInvocations.Where(n => n.Ancestors().OfType<MemberAccessException>().Count() == 0);
foreach (var validNameOfSyntax in validNameOfs)
{
if (model.GetSymbolInfo(validNameOfSyntax).Symbol == null)
{
//validNameOfSyntax is the nameof operator
Console.WriteLine("We've found a nameof!");
}
}
class MyClass
{
void MyMethod()
{
int x = LogValue("x", 5);
}
public static T LogValue<T>(string name, T value)
{
//Write to file
//...
return value;
}
}
看完上面的树后,我们意识到应该创建一个SimpleMemberAccessExpressions链( a chain of ),而不是一个名称为“ CodeConnect. Instrumentation.LogValue”的调用表达式 InvocationExpression。 当绑定器将此调用绑定到符号时,它失败了,因为无法使用此名称声明任何方法。 我们创建的树无效,并且永远不会从用户的源代码中解析出来。
这是创建或重写语法树时要理解的一个关键点:
No one will stop you from creating invalid syntax trees. 没有人会阻止您创建无效的语法树。