private IEnumerable <AnonymousFunctionData> GetSelfAndDescendantsAnonymousFunctionDataRecursively(
            AnonymousFunctionData functionData, Func <AnonymousFunctionData, bool> predicate = null)
        {
            if (predicate?.Invoke(functionData) == false)
            {
                yield break;
            }
            yield return(functionData);

            foreach (var subTypeData in functionData.NestedAnonymousFunctions.Values)
            {
                if (predicate?.Invoke(subTypeData) == false)
                {
                    yield break;
                }
                foreach (var td in GetSelfAndDescendantsAnonymousFunctionDataRecursively(subTypeData, predicate))
                {
                    if (predicate?.Invoke(td) == false)
                    {
                        yield break;
                    }
                    yield return(td);
                }
            }
        }
 public AnonymousFunctionData(MethodData methodData, IMethodSymbol symbol, AnonymousFunctionExpressionSyntax node,
                              AnonymousFunctionData parent = null) : base(symbol)
 {
     MethodData = methodData;
     Node       = node;
     ParentAnonymousFunctionData = parent;
 }
Exemplo n.º 3
0
        public AbstractData GetNodeData(SyntaxNode node,
                                        bool create = false,
                                        NamespaceData namespaceData = null,
                                        TypeData typeData           = null,
                                        MethodData methodData       = null)
        {
            AnonymousFunctionData functionData = null;
            SyntaxNode            endNode;

            if (methodData != null)
            {
                endNode = methodData.Node;
            }
            else if (typeData != null)
            {
                endNode = typeData.Node;
            }
            else if (namespaceData != null)
            {
                endNode = namespaceData.Node;
            }
            else
            {
                endNode = Node;
            }

            foreach (var n in node.AncestorsAndSelf()
                     .TakeWhile(o => !ReferenceEquals(o, endNode))
                     .Where(
                         o => _validDataKinds.Contains(o.Kind()))
                     .Reverse())
            {
                switch (n.Kind())
                {
                case SyntaxKind.ParenthesizedLambdaExpression:
                case SyntaxKind.AnonymousMethodExpression:
                case SyntaxKind.SimpleLambdaExpression:
                    if (methodData == null)
                    {
                        throw new InvalidOperationException($"Anonymous function {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    var symbol = SemanticModel.GetSymbolInfo(n).Symbol as IMethodSymbol;
                    functionData = functionData != null
                                                        ? functionData.GetNestedAnonymousFunctionData((AnonymousFunctionExpressionSyntax)n, symbol, create)
                                                        : methodData.GetAnonymousFunctionData((AnonymousFunctionExpressionSyntax)n, symbol, create);

                    if (functionData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.MethodDeclaration:
                    if (typeData == null)
                    {
                        throw new InvalidOperationException($"Method {n} is declared outside a {nameof(TypeDeclarationSyntax)}");
                    }
                    var methodNode   = (MethodDeclarationSyntax)n;
                    var methodSymbol = SemanticModel.GetDeclaredSymbol(methodNode);
                    methodData = typeData.GetMethodData(methodNode, methodSymbol, create);
                    if (methodData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.ClassDeclaration:
                case SyntaxKind.InterfaceDeclaration:
                case SyntaxKind.StructDeclaration:
                    if (namespaceData == null)
                    {
                        namespaceData = GlobalNamespaceData;
                    }
                    var typeNode   = (TypeDeclarationSyntax)n;
                    var typeSymbol = SemanticModel.GetDeclaredSymbol(typeNode);
                    typeData = typeData != null
                                                        ? typeData.GetNestedTypeData(typeNode, typeSymbol, create)
                                                        : namespaceData.GetTypeData(typeNode, typeSymbol, create);

                    if (typeData == null)
                    {
                        return(null);
                    }
                    break;

                case SyntaxKind.NamespaceDeclaration:
                    var namespaceNode   = (NamespaceDeclarationSyntax)n;
                    var namespaceSymbol = SemanticModel.GetDeclaredSymbol(namespaceNode);
                    namespaceData = namespaceData != null
                                                        ? namespaceData.GetNestedNamespaceData(namespaceNode, namespaceSymbol, create)
                                                        : GetNamespaceData(namespaceNode, namespaceSymbol, create);

                    if (namespaceData == null)
                    {
                        return(null);
                    }
                    break;
                }
            }

            switch (node.Kind())
            {
            case SyntaxKind.ParenthesizedLambdaExpression:
            case SyntaxKind.AnonymousMethodExpression:
            case SyntaxKind.SimpleLambdaExpression:
                return(functionData);

            case SyntaxKind.MethodDeclaration:
                return(methodData);

            case SyntaxKind.ClassDeclaration:
            case SyntaxKind.InterfaceDeclaration:
            case SyntaxKind.StructDeclaration:
                return(typeData);

            case SyntaxKind.NamespaceDeclaration:
                return(namespaceData);

            default:
                throw new InvalidOperationException($"Invalid node kind {Enum.GetName(typeof(SyntaxKind), node.Kind())}");
            }
        }