用方法替换C#代码中的所有变量

 小牛 发布于 2023-01-02 14:40

我需要解析用户编写的C#代码片段,并用方法调用替换本地未定义的所有变量.即

public class Foo
{
  public dynamic Bar()
  {
     return Math.Min(x + width, maxWidth);
  }
}

必须成为:

public class Foo
{
  public dynamic Bar()
  {
      return Math.Min(Resolve("x") + Resolve("width"), Resolve("maxWidth"));
  }
}

我正在使用Microsoft.CodeAnalysis.CSharp和CSharpSyntaxTree来检查字符串,但它没有给我足够的信息来执行替换.或者如果确实如此,我不知道在哪里寻找它.我已粘贴下面的SyntaxTree布局.所有变量都以IdentifierName节点的形式出现,但我不知道如何区分不同的IdentifierNames.然后去哪儿?

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] 
                }
               }
              }
             }
            }
           }
          }
         }
        }
       }
      }
     }
    }
   }
  }
 }
}

Thomas Leves.. 7

我认为你需要使用语义模型.这是一个(非常基本的)示例,显示如何查找未解析的符号:

var tree = CSharpSyntaxTree.ParseFile(fileName);
var root = tree.GetRoot();
var refs = new MetadataReference[]
{
    new MetadataFileReference(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll", new MetadataReferenceProperties(MetadataImageKind.Assembly))
};
var compilation = CSharpCompilation.Create("testRoslyn", new[] { tree }, refs);
var model = compilation.GetSemanticModel(tree);

var unknownSymbols =
    from node in root.DescendantNodes()
    where node.IsKind(SyntaxKind.IdentifierName)
    let symbolInfo = model.GetSymbolInfo(node)
    where symbolInfo.Symbol == null && !symbolInfo.CandidateSymbols.Any()
    select node;

从那里你可以用Resolve(name).替换节点.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有