Roslyn - 将扩展方法调用重写为完全限定格式

时间:2017-03-31 10:43:26

标签: c# roslyn

如何将扩展方法的调用重写为完全限定格式,不再需要使用?

例如。

list.OrderBy(x => x.Prop)

应该成为

System.Collections.Generic.Enumerable.OrderBy(list, x => x.Prop)

1 个答案:

答案 0 :(得分:0)

回答我自己的问题。我在CSharpSyntaxRewriter对象中使用它。 如果有人也可以看看这个会很好。

        public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
        {
            var methodInfo = _model.GetSymbolInfo(node).Symbol as IMethodSymbol;
            if (methodInfo != null)
            {
                var containingType = methodInfo.ContainingType;

                if (methodInfo.IsExtensionMethod)
                {
                    // extension method
                    var exp = node.Expression as MemberAccessExpressionSyntax;
                    if (exp != null)
                    {
                        // new arguments
                        var newArguments = SyntaxFactory.ArgumentList();
                        newArguments = newArguments.AddArguments(SyntaxFactory.Argument(exp.Expression));
                        newArguments = newArguments.AddArguments(node.ArgumentList.Arguments.ToArray());

                        // new expression
                        var stack = new Stack<SimpleNameSyntax>();
                        stack.Push(exp.Name);
                        stack.Push(SyntaxFactory.IdentifierName(containingType.Name));

                        for (var s = containingType.ContainingNamespace; s != null; s = s.ContainingNamespace)
                        {
                            if (!s.IsGlobalNamespace && s.Name != "")
                                stack.Push(SyntaxFactory.IdentifierName(s.Name));
                        }

                        // build and return
                        if (stack.Count >= 2)
                        {
                            var newExp = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, stack.Pop(), stack.Pop());

                            while (stack.Any())
                                newExp = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, newExp, stack.Pop());

                            return node.WithExpression(newExp).WithArgumentList(newArguments);
                        }
                    }
                }
            }

            return base.VisitInvocationExpression(node);
        }