public Task <CodeBlock> ParseAsync(ITextSnapshot snapshot, CancellationToken token) { CodeBlock root = new CodeBlock(null, BlockType.Root, null, new SnapshotSpan(snapshot, 0, snapshot.Length), 0, 0); CodeBlock parent = root; Stack <CodeBlock> blockOpenings = new Stack <CodeBlock>(); bool leadingWhitespace = true; int statementStart = 0; StringBuilder currentStatement = new StringBuilder(); StringBuilder filteredStatement = new StringBuilder(); SnapshotFilter filter = new SnapshotFilter(snapshot); while (filter.Next()) { int position = filter.Position; char c = filter.Character; if (leadingWhitespace) { leadingWhitespace = char.IsWhiteSpace(c); statementStart = position; } if (!filter.InQuote) { if (c == '{') { CodeBlock child = CreateCodeBlock(parent, currentStatement, filteredStatement, new SnapshotSpan(snapshot, position, 0), statementStart, blockOpenings.Count + 1); blockOpenings.Push(child); parent = child; } else if (c == '}') { if (blockOpenings.Count > 0) { CodeBlock child = blockOpenings.Pop(); child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, position + 1))); parent = child.Parent; } } } if (filter.EOS) { currentStatement.Length = 0; filteredStatement.Length = 0; leadingWhitespace = true; } else { AppendCharacter(currentStatement, c); if (!filter.InQuote) { AppendCharacter(filteredStatement, c); } } if (token.IsCancellationRequested) { return(null); } } while (blockOpenings.Count > 0) { CodeBlock child = blockOpenings.Pop(); child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, snapshot.Length))); } return(Task.FromResult <CodeBlock>(root)); }
protected abstract void ParseSyntaxNode(ITextSnapshot snapshot, SyntaxNode parentSyntaxNode, CodeBlock parentCodeBlockNode, CancellationToken token, int level);
protected abstract BlockType FindType(CodeBlock parent, string statement);
protected override void ParseSyntaxNode(ITextSnapshot snapshot, SyntaxNode parentSyntaxNode, CodeBlock parentCodeBlockNode, CancellationToken token, int level) { if (token.IsCancellationRequested) { throw new TaskCanceledException(); } else { foreach (var childnode in parentSyntaxNode.ChildNodes()) { SyntaxKind kind = SyntaxKind.None; int startPosition = 0; int endPosition = 0; int statementEndPosition = 0; if (TryAsNamespace(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsClass(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsStruct(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsInterface(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsEnum(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsModule(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsMethod(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsProperty(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsPropertyAccessor(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsIf(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsElse(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsElseIf(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsFor(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsForEach(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsSelect(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsSelectCase(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsDo(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsWhile(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsTry(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsCatch(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsFinally(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsUsing(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition) || TryAsSyncLock(childnode, ref kind, ref startPosition, ref endPosition, ref statementEndPosition)) { var statementStart = childnode.SpanStart; string statement = StatementFromSpan(snapshot, startPosition, statementEndPosition); CodeBlock child = CreateCodeBlock(parentCodeBlockNode, statement, kind, new SnapshotSpan(snapshot, Span.FromBounds(startPosition, endPosition)), statementStart, level + 1); ParseSyntaxNode(snapshot, childnode, child, token, level + 1); } } } }