public object Clone () { var clone = new IndentStack (ie,stack.Length); clone.stack = (Node[]) stack.Clone (); clone.size = size; return clone; }
public object Clone() { var clone = new IndentStack(ie, stack.Length); clone.stack = (Node[])stack.Clone(); clone.size = size; return(clone); }
public IndentEngine(DFormattingOptions policy, bool tabsToSpaces = false, int indentWidth = 4, bool keepAlignmentSpaces = true) { if (policy == null) { throw new ArgumentNullException("policy"); } this.Policy = policy; this.tabsToSpaces = tabsToSpaces; this.indentWidth = indentWidth; this.keepAlignmentSpaces = keepAlignmentSpaces; stack = new IndentStack(this); linebuf = new StringBuilder(); Reset(); }
/// <summary> /// The engine's main logic /// </summary> public void Push(char c) { Inside inside, after; inside = stack.PeekInside(0); // Skip the first optional shebang line if (inside == Inside.Shebang && c != '\n' && c != '\r') { pc = c; prc = rc; linebuf.Append(c); cursor++; lastChar = c; return; } // pop the verbatim-string-literal if (inside == Inside.VerbatimString && popVerbatim && c != '"') { keyword = stack.PeekKeyword; popVerbatim = false; stack.Pop(); inside = stack.PeekInside(0); } needsReindent = false; if ((inside & (Inside.PreProcessor | Inside.StringOrChar | Inside.Comment)) == 0 && wordStart != -1) { if (char.IsWhiteSpace(c) || c == '(' || c == '{') { var tmp = WordIsKeyword(); if (tmp != DTokens.INVALID) { keyword = tmp; } } else if (c == ':' && WordIsDefault) { keyword = DTokens.Default; } //get the keyword for preprocessor directives } /*else if ((inside & (Inside.PreProcessor)) != 0 && stack.PeekKeyword == null) { * //replace the stack item with a keyworded one * var preProcessorKeyword = GetDirectiveKeyword (c); * int peekLine = stack.PeekLineNr (0); * stack.Pop (); * stack.Push (Inside.PreProcessor, preProcessorKeyword, peekLine, 0); * //regions need to pop back out * if (preProcessorKeyword == "region" || preProcessorKeyword == "endregion") { * curIndent = stack.PeekIndent (0); * needsReindent = true; * * } * }*/ //Console.WriteLine ("Pushing '{0}'/#{3}; wordStart = {1}; keyword = {2}", c, wordStart, keyword, (int)c); switch (c) { case '#': PushHash(inside); lastChar = '#'; break; case '/': PushSlash(inside); break; case '\\': PushBackSlash(inside); break; case '+': case '*': PushStar(inside, c); break; case '`': PushAccGrave(inside); break; case '"': PushQuote(inside); break; case '\'': PushSQuote(inside); break; case ':': PushColon(inside); break; case ';': PushSemicolon(inside); break; case '[': PushOpenSq(inside); break; case ']': PushCloseSq(inside); break; case '(': PushOpenParen(inside); break; case ')': PushCloseParen(inside); break; case '{': PushOpenBrace(inside); break; case '}': PushCloseBrace(inside); break; case '\r': CheckForParentList(); PushNewLine(inside); lastChar = c; return; case '\n': CheckForParentList(); if (lastChar == '\r') { cursor++; } else { PushNewLine(inside); } lastChar = c; return; case 'e': // If there's an 'else', look if there has been a if-else backup stack prepared //KNOWN ISSUE: Reset this backup stack if there's anything else than an 'else' following the recently closed if-stmt; // Anyway this shouldn't be noticed that often as there can't be a stand-alone 'else' dangling around somewhere. if (linebuf.Length > 2 && linebuf.ToString(linebuf.Length - 3, 3) == "els") { var backup = stack.PeekIfElseBackupStack; stack.PeekIfElseBackupStack = null; if (backup != null) { keyword = DTokens.Else; inside = Inside.FoldedStatement; stack = backup; stack.Pop(); var newIndent = stack.PeekIndent(0); if (curIndent != newIndent) { curIndent = newIndent; needsReindent = true; } } } break; default: break; } after = stack.PeekInside(0); if ((after & Inside.PreProcessor) == Inside.PreProcessor) { for (int i = 0; i < preProcessorIndents.Length; i++) { int len = preProcessorIndents[i].Length - 1; if (linebuf.Length < len) { continue; } string str = linebuf.ToString(linebuf.Length - len, len) + c; if (str == preProcessorIndents[i]) { needsReindent = true; break; } } } if ((after & (Inside.PreProcessor | Inside.StringOrChar | Inside.Comment | Inside.Shebang)) == 0) { if (!Char.IsWhiteSpace(c)) { if (firstNonLwsp == -1) { firstNonLwsp = linebuf.Length; } if (wordStart != -1 && c != ':' && Char.IsWhiteSpace(pc)) { // goto labels must be single word tokens canBeLabel = false; } else if (wordStart == -1 && Char.IsDigit(c)) { // labels cannot start with a digit canBeLabel = false; } lastNonLwsp = linebuf.Length; if (c != ':') { if (Char.IsWhiteSpace(pc) || rc == ':') { wordStart = linebuf.Length; } else if (pc == '\0') { wordStart = 0; } } } } else if (c != '\\' && (after & (Inside.StringLiteral | Inside.CharLiteral)) != 0) { // Note: PushBackSlash() will handle untoggling isEscaped if c == '\\' isEscaped = false; } pc = c; prc = rc; // Note: even though PreProcessor directive chars are insignificant, we do need to // check for rc != '\\' at the end of a line. if ((inside & Inside.Comment) == 0 && (after & Inside.Comment) == 0 && !Char.IsWhiteSpace(c)) { rc = c; } linebuf.Append(c); cursor++; lastChar = c; }
/// <summary> /// The engine's main logic /// </summary> public void Push(char c) { Inside inside, after; inside = stack.PeekInside (0); // Skip the first optional shebang line if (inside == Inside.Shebang && c != '\n' && c != '\r') { pc = c; prc = rc; linebuf.Append(c); cursor++; lastChar = c; return; } // pop the verbatim-string-literal if (inside == Inside.VerbatimString && popVerbatim && c != '"') { keyword = stack.PeekKeyword; popVerbatim = false; stack.Pop (); inside = stack.PeekInside (0); } needsReindent = false; if ((inside & (Inside.PreProcessor | Inside.StringOrChar | Inside.Comment)) == 0 && wordStart != -1) { if (char.IsWhiteSpace (c) || c == '(' || c == '{') { var tmp = WordIsKeyword (); if (tmp != DTokens.INVALID) keyword = tmp; } else if (c == ':' && WordIsDefault) { keyword = DTokens.Default; } //get the keyword for preprocessor directives } /*else if ((inside & (Inside.PreProcessor)) != 0 && stack.PeekKeyword == null) { //replace the stack item with a keyworded one var preProcessorKeyword = GetDirectiveKeyword (c); int peekLine = stack.PeekLineNr (0); stack.Pop (); stack.Push (Inside.PreProcessor, preProcessorKeyword, peekLine, 0); //regions need to pop back out if (preProcessorKeyword == "region" || preProcessorKeyword == "endregion") { curIndent = stack.PeekIndent (0); needsReindent = true; } }*/ //Console.WriteLine ("Pushing '{0}'/#{3}; wordStart = {1}; keyword = {2}", c, wordStart, keyword, (int)c); switch (c) { case '#': PushHash (inside); lastChar = '#'; break; case '/': PushSlash (inside); break; case '\\': PushBackSlash (inside); break; case '+': case '*': PushStar (inside,c); break; case '`': PushAccGrave(inside); break; case '"': PushQuote (inside); break; case '\'': PushSQuote (inside); break; case ':': PushColon (inside); break; case ';': PushSemicolon (inside); break; case '[': PushOpenSq (inside); break; case ']': PushCloseSq (inside); break; case '(': PushOpenParen (inside); break; case ')': PushCloseParen (inside); break; case '{': PushOpenBrace (inside); break; case '}': PushCloseBrace (inside); break; case '\r': CheckForParentList (); PushNewLine (inside); lastChar = c; return; case '\n': CheckForParentList (); if (lastChar == '\r') { cursor++; } else { PushNewLine (inside); } lastChar = c; return; case 'e': // If there's an 'else', look if there has been a if-else backup stack prepared //KNOWN ISSUE: Reset this backup stack if there's anything else than an 'else' following the recently closed if-stmt; // Anyway this shouldn't be noticed that often as there can't be a stand-alone 'else' dangling around somewhere. if (linebuf.Length > 2 && linebuf.ToString (linebuf.Length - 3, 3) == "els") { var backup = stack.PeekIfElseBackupStack; stack.PeekIfElseBackupStack = null; if (backup != null) { keyword = DTokens.Else; inside = Inside.FoldedStatement; stack = backup; stack.Pop (); var newIndent = stack.PeekIndent (0); if (curIndent != newIndent) { curIndent = newIndent; needsReindent = true; } } } break; default: break; } after = stack.PeekInside (0); if ((after & Inside.PreProcessor) == Inside.PreProcessor) { for (int i = 0; i < preProcessorIndents.Length; i++) { int len = preProcessorIndents[i].Length - 1; if (linebuf.Length < len) continue; string str = linebuf.ToString (linebuf.Length - len, len) + c; if (str == preProcessorIndents[i]) { needsReindent = true; break; } } } if ((after & (Inside.PreProcessor | Inside.StringOrChar | Inside.Comment | Inside.Shebang)) == 0) { if (!Char.IsWhiteSpace (c)) { if (firstNonLwsp == -1) firstNonLwsp = linebuf.Length; if (wordStart != -1 && c != ':' && Char.IsWhiteSpace (pc)) { // goto labels must be single word tokens canBeLabel = false; } else if (wordStart == -1 && Char.IsDigit (c)) { // labels cannot start with a digit canBeLabel = false; } lastNonLwsp = linebuf.Length; if (c != ':') { if (Char.IsWhiteSpace (pc) || rc == ':') wordStart = linebuf.Length; else if (pc == '\0') wordStart = 0; } } } else if (c != '\\' && (after & (Inside.StringLiteral | Inside.CharLiteral)) != 0) { // Note: PushBackSlash() will handle untoggling isEscaped if c == '\\' isEscaped = false; } pc = c; prc = rc; // Note: even though PreProcessor directive chars are insignificant, we do need to // check for rc != '\\' at the end of a line. if ((inside & Inside.Comment) == 0 && (after & Inside.Comment) == 0 && !Char.IsWhiteSpace (c)) rc = c; linebuf.Append (c); cursor++; lastChar = c; }
public IndentEngine(DFormattingOptions policy, bool tabsToSpaces = false, int indentWidth = 4, bool keepAlignmentSpaces = true) { if (policy == null) throw new ArgumentNullException ("policy"); this.Policy = policy; this.tabsToSpaces = tabsToSpaces; this.indentWidth = indentWidth; this.keepAlignmentSpaces = keepAlignmentSpaces; stack = new IndentStack (this); linebuf = new StringBuilder (); Reset (); }