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; }
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())}"); } }