| File: Language\Intermediate\IntermediateNodeExtensions.cs | Web Access |
| Project: src\roslyn\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Immutable; using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.AspNetCore.Razor.Language.Intermediate; public static class IntermediateNodeExtensions { public static ImmutableArray<RazorDiagnostic> GetAllDiagnostics(this IntermediateNode node) { ArgHelper.ThrowIfNull(node); var diagnostics = new PooledHashSet<RazorDiagnostic>(); try { CollectDiagnostics(node, ref diagnostics); return diagnostics.OrderByAsArray(static d => d.Span.AbsoluteIndex); } finally { diagnostics.ClearAndFree(); } static void CollectDiagnostics(IntermediateNode node, ref PooledHashSet<RazorDiagnostic> diagnostics) { if (node.HasDiagnostics) { diagnostics.UnionWith(node.Diagnostics); } foreach (var childNode in node.Children) { CollectDiagnostics(childNode, ref diagnostics); } } } public static ImmutableArray<TNode> FindDescendantNodes<TNode>(this IntermediateNode node) where TNode : IntermediateNode { using var results = new PooledArrayBuilder<TNode>(); node.CollectDescendantNodes(ref results.AsRef()); return results.ToImmutableAndClear(); } internal static void CollectDescendantNodes<TNode>(this IntermediateNode root, ref PooledArrayBuilder<TNode> results) where TNode : IntermediateNode { using var stack = new PooledArrayBuilder<IntermediateNode>(); ref var stackRef = ref stack.AsRef(); PushChildren(root, ref stackRef); while (stack.Count > 0) { var node = stack.Pop(); if (node is TNode target) { results.Add(target); } PushChildren(node, ref stackRef); } static void PushChildren(IntermediateNode node, ref PooledArrayBuilder<IntermediateNode> stack) { // Push children in reverse order so we process them in original order. var children = node.Children; for (var i = children.Count - 1; i >= 0; i--) { stack.Push(children[i]); } } } }