Ejemplo n.º 1
0
        /// <summary>
        /// Allows to get parts of code surrounded by #region directives
        /// </summary>
        /// <param name="root">Root of the document syntax tree</param>
        /// <returns>List of processed nodes</returns>
        public List <DirectiveSyntaxNode> GetRegionNodes(SyntaxNode root)
        {
            var regionDirectives    = new List <SyntaxTrivia>();
            var endRegionDirectives = new List <SyntaxTrivia>();

            var directiveNodes = new List <DirectiveSyntaxNode>();

            // find all #region directives
            foreach (var regionDirective in root.DescendantTrivia().Where(i => i.Kind() == SyntaxKind.RegionDirectiveTrivia))
            {
                regionDirectives.Add(regionDirective);
            }

            // find all #endregion directives
            foreach (var endRegionDirective in root.DescendantTrivia().Where(j => j.Kind() == SyntaxKind.EndRegionDirectiveTrivia))
            {
                endRegionDirectives.Add(endRegionDirective);
            }

            // just in case: order by position in the document to allow further processing
            regionDirectives = regionDirectives
                               .OrderBy(d => d.SpanStart)
                               .ToList();

            endRegionDirectives = endRegionDirectives
                                  .OrderBy(d => d.SpanStart)
                                  .ToList();

            foreach (var regionDirective in regionDirectives)
            {
                var directiveNode = new DirectiveSyntaxNode {
                    RegionDirective = regionDirective
                };

                // find #endregion directive for the corresponding #region
                foreach (var endRegionDirective in endRegionDirectives)
                {
                    // skip #endregion if it is earlier than #region
                    if (endRegionDirective.SpanStart < regionDirective.SpanStart)
                    {
                        continue;
                    }

                    // check for inner pairs of #region/#endregion directives
                    if (regionDirectives.Exists(d => d.SpanStart > regionDirective.SpanStart && d.SpanStart < endRegionDirective.SpanStart) &&
                        !endRegionDirectives.Exists(d => d.SpanStart > regionDirective.SpanStart && d.SpanStart < endRegionDirective.SpanStart))
                    {
                        continue;
                    }

                    directiveNode.EndRegionDirective = endRegionDirective;

                    // add nodes that are placed between #region and #endregion directives
                    var descendantNodes = root.DescendantNodes()
                                          .Where(t => (t is MemberDeclarationSyntax || t is StatementSyntax) &&
                                                 t.SpanStart > regionDirective.SpanStart &&
                                                 t.SpanStart < endRegionDirective.SpanStart)
                                          .ToList();

                    directiveNode.AddNodes(descendantNodes);
                    directiveNodes.Add(directiveNode);
                    break;
                }
            }

            return(directiveNodes);
        }