public CodeBlock(CodeBlock parent, BlockType type, string statement, SnapshotSpan span, int statementStart, int level) { this.parent = parent; if (parent != null) { parent.children.Add(this); } this.statement = statement; this.type = type; this.span = span; this.statementStart = statementStart; this.level = level; }
protected override BlockType FindType(CodeBlock parent, string statement) { if (BraceParser.ContainsWord(statement, "foreach") || BraceParser.ContainsWord(statement, "for") || BraceParser.ContainsWord(statement, "while") || BraceParser.ContainsWord(statement, "do")) return BlockType.Loop; else if (BraceParser.ContainsWord(statement, "if") || BraceParser.ContainsWord(statement, "else") || BraceParser.ContainsWord(statement, "switch")) return BlockType.Conditional; else if (BraceParser.ContainsWord(statement, "class") || BraceParser.ContainsWord(statement, "struct") || BraceParser.ContainsWord(statement, "interface")) return BlockType.Class; else if (BraceParser.ContainsWord(statement, "namespace")) return BlockType.Namespace; else if (parent.Type == BlockType.Class) return BlockType.Method; else return BlockType.Unknown; }
public CodeBlock Parse(ITextSnapshot snapshot, AbortCheck abort) { CodeBlock root = new CodeBlock(null, BlockType.Root, null, new SnapshotSpan(snapshot, 0, snapshot.Length), 0, 0); CodeBlock parent = root; Stack<Tuple<int, CodeBlock>> blockOpenings = new Stack<Tuple<int, CodeBlock>>(); string previousRawText = null; string previousFilteredText = null; int previousStatementStart = -1; int previousLineIndent = 0; MacroFilter filter = new MacroFilter(snapshot); StringBuilder rawText = new StringBuilder(128); StringBuilder filteredText = new StringBuilder(128); int statementStart = -1; const int tabSize = 4; int lineIndent = 0; while (filter.Next()) { if (filter.IsAtEol) { if (rawText.Length > 0) { previousRawText = rawText.ToString().TrimEnd(); previousFilteredText = filteredText.ToString().Trim(); previousStatementStart = statementStart; previousLineIndent = lineIndent; } rawText.Clear(); filteredText.Clear(); statementStart = -1; lineIndent = 0; filter.MoveToEol(); } else { char c = filter.Character; if (!filter.InQuote) { filteredText.Append(c); if (statementStart == -1) { if (c == ' ') { ++lineIndent; } else if (c == '\t') { lineIndent = ((lineIndent / tabSize) + 1) * tabSize; } else { statementStart = filter.Position; if (previousFilteredText != null) { if (lineIndent > previousLineIndent) { //Indentation increased, treat it as a start of a block. BlockType newBlockType = BlockType.Other; if (StartsWith(previousFilteredText, "For") || StartsWith(previousFilteredText, "Do") || StartsWith(previousFilteredText, "While")) { newBlockType = BlockType.Loop; } else if (StartsWith(previousFilteredText, "If") || StartsWith(previousFilteredText, "Select") || StartsWith(previousFilteredText, "ElseIf") || StartsWith(previousFilteredText, "Else")) { newBlockType = BlockType.Conditional; } else if (Contains(previousFilteredText, "Module") || Contains(previousFilteredText, "Class") || Contains(previousFilteredText, "Interface") || Contains(previousFilteredText, "Structure")) { newBlockType = BlockType.Class; } else if (Contains(previousFilteredText, "Sub") || Contains(previousFilteredText, "Property") || Contains(previousFilteredText, "Function")) { newBlockType = BlockType.Method; } CodeBlock child = new CodeBlock(parent, newBlockType, previousRawText.ToString().TrimEnd(), new SnapshotSpan(snapshot, previousStatementStart, 0), statementStart, blockOpenings.Count); blockOpenings.Push(new Tuple<int, CodeBlock>(previousLineIndent, child)); parent = child; } else if (lineIndent < previousLineIndent) { //Indentation decreased, treat it as the end of a block. while (blockOpenings.Count > 0) { Tuple<int, CodeBlock> block = blockOpenings.Pop(); CodeBlock child = block.Item2; child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, statementStart))); parent = child.Parent; if (block.Item1 <= lineIndent) break; //Things have come back into alignment. } } } } } } //Do not append two consecutive white space characters (or leading whitespace) if ((!char.IsWhiteSpace(c)) || ((rawText.Length > 0) && (!char.IsWhiteSpace(rawText[rawText.Length - 1])))) rawText.Append(c); if (abort()) return null; } } while (blockOpenings.Count > 0) { CodeBlock child = blockOpenings.Pop().Item2; child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, snapshot.Length))); } return root; }
public CodeBlock Parse(ITextSnapshot snapshot, AbortCheck abort) { CodeBlock root = new CodeBlock(null, BlockType.Root, null, new SnapshotSpan(snapshot, 0, snapshot.Length), 0, 0); CodeBlock parent = root; Stack <Tuple <int, CodeBlock> > blockOpenings = new Stack <Tuple <int, CodeBlock> >(); string previousRawText = null; string previousFilteredText = null; int previousStatementStart = -1; int previousLineIndent = 0; MacroFilter filter = new MacroFilter(snapshot); StringBuilder rawText = new StringBuilder(128); StringBuilder filteredText = new StringBuilder(128); int statementStart = -1; const int tabSize = 4; int lineIndent = 0; while (filter.Next()) { if (filter.IsAtEol) { if (rawText.Length > 0) { previousRawText = rawText.ToString().TrimEnd(); previousFilteredText = filteredText.ToString().Trim(); previousStatementStart = statementStart; previousLineIndent = lineIndent; } rawText.Clear(); filteredText.Clear(); statementStart = -1; lineIndent = 0; filter.MoveToEol(); } else { char c = filter.Character; if (!filter.InQuote) { filteredText.Append(c); if (statementStart == -1) { if (c == ' ') { ++lineIndent; } else if (c == '\t') { lineIndent = ((lineIndent / tabSize) + 1) * tabSize; } else { statementStart = filter.Position; if (previousFilteredText != null) { if (lineIndent > previousLineIndent) { //Indentation increased, treat it as a start of a block. BlockType newBlockType = BlockType.Other; if (StartsWith(previousFilteredText, "For") || StartsWith(previousFilteredText, "Do") || StartsWith(previousFilteredText, "While")) { newBlockType = BlockType.Loop; } else if (StartsWith(previousFilteredText, "If") || StartsWith(previousFilteredText, "Select") || StartsWith(previousFilteredText, "ElseIf") || StartsWith(previousFilteredText, "Else")) { newBlockType = BlockType.Conditional; } else if (Contains(previousFilteredText, "Module") || Contains(previousFilteredText, "Class") || Contains(previousFilteredText, "Interface") || Contains(previousFilteredText, "Structure")) { newBlockType = BlockType.Class; } else if (Contains(previousFilteredText, "Sub") || Contains(previousFilteredText, "Property") || Contains(previousFilteredText, "Function")) { newBlockType = BlockType.Method; } CodeBlock child = new CodeBlock(parent, newBlockType, previousRawText.ToString().TrimEnd(), new SnapshotSpan(snapshot, previousStatementStart, 0), statementStart, blockOpenings.Count); blockOpenings.Push(new Tuple <int, CodeBlock>(previousLineIndent, child)); parent = child; } else if (lineIndent < previousLineIndent) { //Indentation decreased, treat it as the end of a block. while (blockOpenings.Count > 0) { Tuple <int, CodeBlock> block = blockOpenings.Pop(); CodeBlock child = block.Item2; child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, statementStart))); parent = child.Parent; if (block.Item1 <= lineIndent) { break; //Things have come back into alignment. } } } } } } } //Do not append two consecutive white space characters (or leading whitespace) if ((!char.IsWhiteSpace(c)) || ((rawText.Length > 0) && (!char.IsWhiteSpace(rawText[rawText.Length - 1])))) { rawText.Append(c); } if (abort()) { return(null); } } } while (blockOpenings.Count > 0) { CodeBlock child = blockOpenings.Pop().Item2; child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, snapshot.Length))); } return(root); }
public CodeBlock Parse(ITextSnapshot snapshot, AbortCheck abort) { 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 = -1; StringBuilder currentStatement = new StringBuilder(); SnapshotFilter filter = new SnapshotFilter(snapshot); while (filter.Next()) { int position = filter.Position; char c = filter.Character; if (statementStart == -1) statementStart = position; else if (leadingWhitespace) { leadingWhitespace = char.IsWhiteSpace(c); statementStart = position; } if (!filter.InQuote) { if (c == '{') { CodeBlock child = CreateCodeBlock(parent, currentStatement, 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.Remove(0, currentStatement.Length); statementStart = -1; leadingWhitespace = true; } else currentStatement.Append(c); if (abort()) return null; } while (blockOpenings.Count > 0) { CodeBlock child = blockOpenings.Pop(); child.SetSpan(new SnapshotSpan(snapshot, Span.FromBounds(child.Span.Start, snapshot.Length))); } return root; }
private CodeBlock CreateCodeBlock(CodeBlock parent, StringBuilder rawStatement, SnapshotSpan span, int statementStart, int level) { string statement = ExtractStatement(rawStatement); BlockType type = this.FindType(parent, statement); CodeBlock child = new CodeBlock(parent, type, statement, span, statementStart, level); return child; }
protected abstract BlockType FindType(CodeBlock parent, string statement);