Ich muss Fragmente von benutzerdefinierten C# -Code analysieren und ersetzen alle Variablen, die nicht lokal mit Methodenaufrufen definiert sind. I.e.Ersetzen Sie alle Variablen in C# -Code mit Methoden
public class Foo
{
public dynamic Bar()
{
return Math.Min(x + width, maxWidth);
}
}
hat werden:
public class Foo
{
public dynamic Bar()
{
return Math.Min(Resolve("x") + Resolve("width"), Resolve("maxWidth"));
}
}
Ich Microsoft.CodeAnalysis.CSharp und die CSharpSyntaxTree mit dem String zu prüfen, aber es gibt mir nicht genug Informationen, die ersetzen auszuführen. Oder wenn es so ist, weiß ich nicht, wo ich danach suchen soll. Ich habe das SyntaxTree-Layout unten eingefügt. Alle Variablen treten als IdentifierName-Knoten auf, aber ich weiß nicht, wie ich verschiedene IdentifierNames unterscheiden kann. Wohin geht es von hier?
CompilationUnit[0..99) {
code: public class Foo\n{\n public dynamic Bar()\n {\n return Math.Min(x + width, maxWidth);\n }\n}
tokens: EndOfFileToken[]
nodes{
ClassDeclaration[0..99) {
code: public class Foo\n{\n public dynamic Bar()\n {\n return Math.Min(x + width, maxWidth);\n }\n}
tokens: PublicKeyword[public ] ClassKeyword[class ] IdentifierToken[Foo\n] OpenBraceToken[{\n] CloseBraceToken[}]
nodes{
MethodDeclaration[21..98) {
code: public dynamic Bar()\n {\n return Math.Min(x + width, maxWidth);\n }\n
tokens: PublicKeyword[ public ] IdentifierToken[Bar]
nodes{
IdentifierName[30..38) {
code: dynamic
tokens: IdentifierToken[dynamic ]
}
ParameterList[41..45) {
code: ()\n
tokens: OpenParenToken[(] CloseParenToken[)\n]
}
Block[45..98) {
code: {\n return Math.Min(x + width, maxWidth);\n }\n
tokens: OpenBraceToken[ {\n] CloseBraceToken[ }\n]
nodes{
ReturnStatement[50..93) {
code: return Math.Min(x + width, maxWidth);\n
tokens: ReturnKeyword[ return ] SemicolonToken[;\n]
nodes{
InvocationExpression[61..90) {
code: Math.Min(x + width, maxWidth)
nodes{
SimpleMemberAccessExpression[61..69) {
code: Math.Min
tokens: DotToken[.]
nodes{
IdentifierName[61..65) {
code: Math
tokens: IdentifierToken[Math]
}
IdentifierName[66..69) {
code: Min
tokens: IdentifierToken[Min]
}
}
}
ArgumentList[69..90) {
code: (x + width, maxWidth)
tokens: OpenParenToken[(] CommaToken[, ] CloseParenToken[)]
nodes{
Argument[70..79) {
code: x + width
nodes{
AddExpression[70..79) {
code: x + width
tokens: PlusToken[+ ]
nodes{
IdentifierName[70..72) {
code: x
tokens: IdentifierToken[x ]
}
IdentifierName[74..79) {
code: width
tokens: IdentifierToken[width]
}
}
}
}
}
Argument[81..89) {
code: maxWidth
nodes{
IdentifierName[81..89) {
code: maxWidth
tokens: IdentifierToken[maxWidth]
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
Der Syntaxbaum ist nicht genug, Sie müssen das semantische Modell betrachten, um zu sehen, was die Bezeichner darstellen. –
Können Sie mir einen Link geben, wo ich semantische Modelle lesen kann? –
Jetzt suchen ... Ich habe Roslyn in einer Weile nicht angeschaut, und die API hat sich seit dem letzten Mal sehr verändert –