// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) /* * algoritm formatirovanija sledujushij: * po sintaksicheskomu derevu stroitsja generiruetsja tekst programmy * vse chto nahoditsja mezhdu uzlami sintaksicheskogo dereva takzhe uchityvaetsja * s pomoshuj razlichnyh flagov proizvoditsja sootvetstvujushee formatirovanie * naprimer. posle procedury stavitsja pustaja stroka * dalee pod kommentariem budet ponimatsja obobshennyj kommentarii, kotorye vkluchajut v sebja * takzhe znaki operacii, drugie simvoly, kotorye ne okajamlajut tekuchij token * zdes ochen vazhny source konteksty */ using System; using System.Collections.Generic; using System.Text; using System.Globalization; using PascalABCCompiler.SyntaxTree; using System.IO; namespace CodeFormatters { class FormatterOptions { public int SpaceBetweenArguments = 1; public int AlwaysNewLineForBeginEndBlock = 1; public int SpaceBetweenIdentifiers = 1; public int AggressiveMode = 0; } public class CodeFormatter : PascalABCCompiler.SyntaxTree.AbstractVisitor/*, PascalABCCompiler.Parsers.ICodeFormatter*/ { private StringBuilder sb = new StringBuilder(); private int tab = 2;//tabulacija private int off = 0;//tekushij otstup private Stack region_offsets = new Stack(); private bool in_procedure = false;//flag, v procedure li my private bool attr_on_new_line = true; private bool in_class = false; private bool has_implementation = false; private bool init_part = false; private NumberFormatInfo nfi; private Dictionary keywords = new Dictionary(); private int[] line_lens;//massiv dlin strok, ispolzuetsja dlja podscheta pozicii v tekste (Position v sintaksicheskom dereve nepravilnye ;) ) private string Text;//tekst programmy private syntax_tree_node prev_sn = null;//predydushij obrabotannyj uzel dereva private int cur_src_off = 0; private bool add_space_before = false;//flag, stavit li probel pered kommentariem (esli nuzhno) private bool is_lambda_parameters = false; private bool add_space_after = false;//stavit li probel posle kommentarija (esli nuzhno) //private bool add_tab_after = false; private bool add_newline_before = false;//dobavlat novuju stroku pered kommentariem (esli nuzhno) private bool add_newline_after = false;//dobavit novuju stroku posle kommentarija (esli nuzhno) private bool insert_newline_after_prev = false;//stavit pustuju stroku posle konstrukcii private bool insert_newline_after_prev_semicolon = false;//vstavit pustuju stroku dlja sluchaja, kogda ot predydushej konstrukcii //ostalsja razdiletel, kotoryj ne vhodit v etu konstrukciju. primer blok var a: integer; type t = integer; pered type nado stavit pustuju stroku, no pri etom ne zabyt //dobavit tochku s zapjatoj private bool read_from_beg_pos = false; private bool dec_offset_before_comment = false; private bool add_new_line_else_specific = false; private int keyword_offset = 0; private int caret_line = 0; private int caret_col = 0; private int caret_pos = 0; private int output_caret_line = 0; private int output_caret_col = 0; private bool caret_syn_node_found = false; private Dictionary nodes_with_beg_pos = new Dictionary(); private bool use_strong_formatting = false; private bool skip_spaces_before = false; private bool skip_spaces_after = false; private bool force_tab = false; private int addit_pos_for_multiline = 0; private Stack multi_line_nodes = new Stack(); private FormatterOptions options; public CodeFormatter(int tab) { nfi = new NumberFormatInfo(); nfi.NumberGroupSeparator = "."; this.tab = tab; nodes_with_beg_pos.Add("for_node","for_node"); nodes_with_beg_pos.Add("function_header", "function_header"); ReadOptions(); } private void ReadOptions() { options = new FormatterOptions(); try { string PABCWorkIniFile = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName) + @"\pabcworknet.ini"; //System.Windows.Forms.MessageBox.Show(PABCWorkIniFile); string FormatterOptionsFile = "FormatterOptions.ini"; if (File.Exists(PABCWorkIniFile)) { string PABCWorkDir = File.ReadAllText(PABCWorkIniFile); if (File.Exists(Path.Combine(PABCWorkDir, "FormatterOptions.ini"))) FormatterOptionsFile = Path.Combine(PABCWorkDir, "FormatterOptions.ini"); } string[] lines = File.ReadAllLines(FormatterOptionsFile); for (int i = 0; i < lines.Length; i++) { int pos = lines[i].IndexOf(';'); if (pos != -1) lines[i] = lines[i].Substring(0, pos); } Type t = options.GetType(); for (int i = 0; i < lines.Length; i++) { string key = lines[i].Substring(0, lines[i].IndexOf('=')); string val = lines[i].Substring(lines[i].IndexOf('=') + 1); t.GetField(key).SetValue(options, Convert.ToInt32(val)); } } catch { } } public string FormatTree(string Text, compilation_unit cu, int cursor_line, int cursor_col) { PascalABCCompiler.Parsers.CommentBinder binder = new PascalABCCompiler.Parsers.CommentBinder(); //comments = binder.Bind(cu, Text); this.Text = Text; string[] lines = Text.Split('\n'); line_lens = new int[lines.Length]; for (int i = 0; i < lines.Length; i++) { if (i > 0) line_lens[i] = lines[i].Length + line_lens[i - 1] + 1; else line_lens[i] = lines[i].Length + 1; } caret_line = cursor_line; caret_col = cursor_col; caret_pos = GetPosition(cursor_line, cursor_col); visit_node(cu); return sb.ToString(); } public int Line { get { return output_caret_line; } } public int Column { get { return output_caret_col; } } private int GetPosition(int line, int col) { if (line >= 2) return line_lens[line - 2] + col - 1; return col - 1; } private void SetKeywordOffset(string s) { keyword_offset = s.Length; add_space_before = true; } private void multiline_stack_push(syntax_tree_node sn) { if (!in_one_row(sn)) multi_line_nodes.Push(sn); } private void multiline_stack_pop(syntax_tree_node sn) { if (!in_one_row(sn) && multi_line_nodes.Count > 0) multi_line_nodes.Pop(); } private bool in_one_row(syntax_tree_node sn) { if (options.AlwaysNewLineForBeginEndBlock == 0) return true; if (sn.source_context == null) return true; return sn.source_context.begin_position.line_num == sn.source_context.end_position.line_num; } private bool in_same_row(syntax_tree_node sn, syntax_tree_node sn2) { if (sn.source_context == null || sn2.source_context == null) return false; return sn.source_context.end_position.line_num == sn2.source_context.begin_position.line_num; } private int distance(syntax_tree_node sn1, syntax_tree_node sn2) { return GetPosition(sn2.source_context.begin_position.line_num, sn2.source_context.begin_position.column_num)-GetPosition(sn1.source_context.end_position.line_num, sn1.source_context.end_position.column_num)-1; } private bool is_forward(procedure_header ph) { if (ph.proc_attributes == null) return false; foreach (procedure_attribute pa in ph.proc_attributes.proc_attributes) if (pa.attribute_type == proc_attribute.attr_forward) return true; return false; } private void WriteAmpersandIfNeed(ident id) { if (id.source_context != null) { int pos = GetPosition(id.source_context.begin_position.line_num, id.source_context.begin_position.column_num); if (Text[pos] == '&') sb.Append("&"); } } private void WriteNodeAndReplaceOverSpaces(syntax_tree_node sn) { if (sn.source_context != null) { int start_pos = GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num); int end_pos = GetPosition(sn.source_context.end_position.line_num, sn.source_context.end_position.column_num); string s = Text.Substring(start_pos, end_pos - start_pos + 1); string[] arr = s.Split(' '); for (int i = 0; i < arr.Length; i++) { if (arr[i] != "") { sb.Append(arr[i]); if (i < arr.Length - 1) sb.Append(" "); } } } } private string RemoveOverSpaces(string s) { if (s.IndexOf("//") != -1 || s.IndexOf("{") != -1) return s; StringBuilder sb = new StringBuilder(); string[] arr = s.Split(' '); for (int i = 0; i < arr.Length; i++) { if (arr[i] != "") { sb.Append(arr[i]); if (i < arr.Length - 1) sb.Append(" "); } } return sb.ToString(); } private void WriteNode(syntax_tree_node sn, bool remove_spaces = false) { if (sn.source_context != null) { int start_pos = GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num); int end_pos = GetPosition(sn.source_context.end_position.line_num, sn.source_context.end_position.column_num); string node_text = Text.Substring(start_pos, Math.Max(end_pos - start_pos + 1, 0)); if (remove_spaces && !node_text.Contains("{")) node_text = node_text.Replace(" ", ""); sb.Append(node_text); } } private void WriteNodeWithIndent(syntax_tree_node sn) { int start_pos = GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num); int end_pos = GetPosition(sn.source_context.end_position.line_num, sn.source_context.end_position.column_num); string node_text = prepare_comment(RemoveOverSpaces(Text.Substring(start_pos, end_pos - start_pos + 1)), false); sb.Append(node_text); } private void WriteNode(syntax_tree_node sn, int offset) { int start_pos = GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num) + offset; int end_pos = GetPosition(sn.source_context.end_position.line_num, sn.source_context.end_position.column_num); bool tmp_add_space_after = add_space_after; add_space_after = false; WriteCommentWithIndent(Text.Substring(start_pos, end_pos - start_pos + 1), true); add_space_after = tmp_add_space_after; //sb.Append(new string(' ', off) + Text.Substring(start_pos, end_pos - start_pos + 1)); } private string prepare_comment(string s, bool off_first_line=true) { s = s.TrimStart(' ', '\n', '\t', '\r'); if (s.Contains("\n")) { string[] rows = s.Split('\n'); for (int i = 0; i < rows.Length; i++) { if (i != 0 || off_first_line) rows[i] = new string(' ', off) + rows[i].TrimStart(' ', '\t'); } return string.Join("\n", rows); } return s; } private string GetPossibleComment(syntax_tree_node sn, int off, syntax_tree_node next_sn) { int pos = GetPosition(sn.source_context.end_position.line_num, sn.source_context.end_position.column_num) + off; int next_pos = GetPosition(next_sn.source_context.begin_position.line_num, next_sn.source_context.begin_position.column_num); string comm = Text.Substring(pos, next_pos - pos + 1); return comm; } private bool has_comment(string s) { return s.Contains("{") || s.Contains("(*") || s.Contains("//"); } private int GetSpacesBefore(string s) { int i = 0; while (i < s.Length && s[i] == ' ') i++; return i; } private void WriteCommentWithIndent(string comm, bool before) { string[] lines = null; if (insert_newline_after_prev && !insert_newline_after_prev_semicolon && before) { if (comm.IndexOf("\n") != -1 && comm.IndexOf("\r") == -1) lines = comm.Split(new string[] { "\n" }, StringSplitOptions.None); else lines = comm.Split(new string[] { "\r\n" }, StringSplitOptions.None); if (lines.Length == 2) comm = comm + "\r\n"; else if (lines.Length < 2) comm = comm + "\r\n" + "\r\n"; insert_newline_after_prev = false; } if (add_newline_before) { if (comm.IndexOf("\r\n") == -1 && comm.IndexOf("\n") == -1) comm = comm + "\r\n"; //if (!comm.Trim(' ','\t').StartsWith("\r\n")) // comm = "\r\n" + comm; add_newline_before = false; } else if (add_newline_after) { if (!comm.Trim(' ', '\t').EndsWith("\r\n") && !comm.Trim(' ', '\t').EndsWith("\n")) comm = comm.TrimEnd()+"\r\n"; add_newline_after = false; } if (comm.IndexOf("\n") != -1 && comm.IndexOf("\r") == -1) lines = comm.Split(new string[] { "\n" }, StringSplitOptions.None); else lines = comm.Split(new string[] { "\r\n" }, StringSplitOptions.None); if (lines.Length > 1) { int min_off = 0; for (int i = 1; i < lines.Length; i++) { if (!add_new_line_else_specific && !(dec_offset_before_comment && i < lines.Length - 1)) if (multi_line_nodes.Count == 0 && lines[i].Trim() != "") { int ind = 0; string tmp = lines[i]; while (ind < tmp.Length && (tmp[ind] == ' ' || tmp[ind] == '\t')) { ind++; } if (ind < off) { min_off = Math.Max(off - ind, min_off); } } } for (int i = 1; i < lines.Length; i++) { if (add_new_line_else_specific) { if (i < lines.Length - 1 || lines[i].TrimStart(' ', '\t') != "") lines[i] = new string(' ', off - tab) + lines[i].TrimStart(' ', '\t'); else lines[i] = new string(' ', off) + lines[i].TrimStart(' ', '\t'); } else if (dec_offset_before_comment && i < lines.Length - 1) lines[i] = new string(' ', off + tab) + lines[i].TrimStart(' ', '\t'); else { if (multi_line_nodes.Count > 0) { if (multi_line_nodes.Count == 1) { if (!(multi_line_nodes.Peek() is function_lambda_definition) && !(multi_line_nodes.Peek() is simple_property)) lines[i] = new string(' ', addit_pos_for_multiline) + lines[i]; else lines[i] = new string(' ', off) + lines[i].Trim(); } else { if (!(multi_line_nodes.Peek() is function_lambda_definition) && !(multi_line_nodes.Peek() is simple_property)) { if (off > lines[i].Length) lines[i] = new string(' ', addit_pos_for_multiline + off) + lines[i]; else lines[i] = new string(' ', addit_pos_for_multiline) + lines[i]; } else { lines[i] = new string(' ', off) + lines[i].Trim(); if (lines[i].EndsWith(" else")) lines[i] += " "; } } } else { int ind = 0; string tmp = lines[i]; while (ind < tmp.Length && (tmp[ind] == ' ' || tmp[ind] == '\t')) { ind++; } if (ind < off) { addit_pos_for_multiline = off - ind; } else addit_pos_for_multiline = 0; string ln = lines[i].TrimStart(' ', '\t'); if (ln.StartsWith("{$region")) { region_offsets.Push(off); lines[i] = new string(' ', off) + ln; } else if (ln.StartsWith("{$endregion")) { int region_off = off; if (region_offsets.Count != 0) region_off = region_offsets.Pop(); lines[i] = new string(' ', region_off) + ln; } else if (i < lines.Length - 1) { if (lines[i].Trim() != "") lines[i] = new string(' ', min_off) + lines[i]; else lines[i] = new string(' ', off); } else { string str = lines[i].TrimStart(' ', '\t'); /*if (str.StartsWith("//") || str.StartsWith("{")) lines[i] = new string(' ', off) + lines[i]; else*/ lines[i] = new string(' ', off) + str; } } } } } if (lines.Length <= 2 && insert_newline_after_prev_semicolon && before) { if (lines.Length == 1) { lines = new string[3] { lines[0], new string(' ', off), new string(' ', off) }; } else { lines = new string[3] { lines[0], new string(' ', off), lines[1] }; } } string s = string.Join("\r\n", lines); if (add_space_before) { if (s.Length > 0 && !char.IsWhiteSpace(s[0]) && s[0] != '{' && !s.StartsWith("//") && !s.StartsWith("(*") && s[0] != ';' && !char.IsWhiteSpace(s[0]) && (sb.Length == 0 || !char.IsWhiteSpace(sb[sb.Length-1]))) sb.Append(' '); } else if (s.IndexOf("//") == -1) s = s.TrimStart(' ', '\t'); sb.Append(s); if (add_space_after) { if (s.Length > 0) { if (!char.IsWhiteSpace(s[s.Length - 1]) && s[s.Length - 1] != '}' && !s.EndsWith("//") && !s.EndsWith("*)")) sb.Append(' '); } else sb.Append(' '); } else s = s.TrimEnd(' ', '\t'); add_space_after = false; add_space_before = false; add_newline_after = false; dec_offset_before_comment = false; add_new_line_else_specific = false; if (before) { insert_newline_after_prev = false; insert_newline_after_prev_semicolon = false; } } private void WritePossibleCommentBefore(syntax_tree_node sn) { int pos = GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num); int prev_pos = 0; if (prev_sn != null) if (read_from_beg_pos || sn is procedure_definition && prev_sn is program_module) { prev_pos = GetPosition(prev_sn.source_context.begin_position.line_num, prev_sn.source_context.begin_position.column_num) + keyword_offset; } else prev_pos = GetPosition(prev_sn.source_context.end_position.line_num, prev_sn.source_context.end_position.column_num) + 1; if (prev_pos < pos) { string comm = Text.Substring(prev_pos, pos - prev_pos); if (options.AggressiveMode == 1) { string trimed_comm = comm.Trim(); if (comm.EndsWith(" ") && comm.IndexOf("\n") == -1) { comm = comm.TrimEnd(' '); if (comm.Length == 0 || char.IsLetterOrDigit(comm[comm.Length - 1]) || add_space_before) comm += " "; } if (comm.StartsWith(" ") && comm.IndexOf("\n") == -1) { comm = comm.TrimStart(' '); if (comm.Length == 0 || char.IsLetterOrDigit(comm[0]) || add_space_after) comm = " " + comm; } if (comm.StartsWith(" ")) { if (trimed_comm == "then" || trimed_comm == "do" || trimed_comm == "of") { comm = comm.TrimStart(' '); if (comm.Length == 0 || char.IsLetterOrDigit(comm[0]) || add_space_after) comm = " " + comm; } } if (comm.EndsWith(" ")) { string trimed_end = comm.TrimEnd(' '); if (trimed_end.EndsWith("class") || trimed_end.EndsWith("static") || trimed_end.EndsWith("else")) comm = comm.TrimEnd(' ')+" "; } if (comm.Replace(" ","") == "():")//special case: functions with no parameters { comm = "():"; } if (comm.EndsWith("->")) { if (comm.StartsWith("()")) comm = RemoveOverSpaces(comm); else if (comm.StartsWith("procedure") || comm.StartsWith("function")) { comm = RemoveOverSpaces(comm); comm = comm.Replace("( )", "()"); } if (comm == "()->") comm = "() ->"; comm += " "; } else if (comm.StartsWith(":") && comm.EndsWith(":") && comm.Replace(" ", "") == "::") comm = "::"; else if (comm.StartsWith("[") && comm.EndsWith(":")) comm = comm.Replace(" ", ""); else if (comm.StartsWith("( ") && comm.TrimEnd().EndsWith("var")) comm = comm.Replace(" ", "")+" "; else if (trimed_comm.StartsWith(", ") && comm.TrimEnd().EndsWith("var")) comm = RemoveOverSpaces(comm); else if (trimed_comm.StartsWith(",var")) comm = ", var"+ trimed_comm.Replace(",var", ""); else if (comm.StartsWith("array") || comm.StartsWith("set") || comm.StartsWith("sequence")) comm = RemoveOverSpaces(comm); else if ((comm.StartsWith("class") || comm.StartsWith("interface")) && comm.EndsWith("(")) comm = comm.Replace(" ", ""); else if ((comm.StartsWith("auto") || comm.StartsWith("sealed") || comm.StartsWith("abstract")) && comm.EndsWith("(")) comm = RemoveOverSpaces(comm); else if (comm.TrimEnd(' ').EndsWith("property")) comm = RemoveOverSpaces(comm); else if (comm.StartsWith("var") && comm.EndsWith("(")) comm = RemoveOverSpaces(comm); else if (trimed_comm.StartsWith("[") && trimed_comm.EndsWith("]")) comm = RemoveOverSpaces(comm).Replace("[ ", "[").Replace(" ]", "]"); else if ((comm.StartsWith("auto") || comm.StartsWith("sealed") || comm.StartsWith("abstract") || comm.StartsWith("static")) && (trimed_comm.EndsWith("class") || trimed_comm.EndsWith("record"))) comm = RemoveOverSpaces(comm); else if (trimed_comm.StartsWith("]") && trimed_comm.EndsWith(":")) comm = comm.Replace(" ", ""); } WriteCommentWithIndent(comm, true); read_from_beg_pos = false; keyword_offset = 0; } else if (prev_pos == pos) { keyword_offset = 0; read_from_beg_pos = false; if (insert_newline_after_prev) { sb.AppendLine(); sb.AppendLine(); insert_newline_after_prev = false; } if (force_tab && sb[sb.Length - 1] == '\n') sb.Append(new string(' ', off)); force_tab = false; } skip_spaces_after = false; skip_spaces_before = false; add_space_after = false; add_space_before = false; } private void WritePossibleCommentAfter(syntax_tree_node sn) { int prev_pos = GetPosition(prev_sn.source_context.end_position.line_num, prev_sn.source_context.end_position.column_num) + 1; int pos = GetPosition(sn.source_context.end_position.line_num, sn.source_context.end_position.column_num) + 1; if (prev_pos < pos && cur_src_off < pos) { string comm = Text.Substring(prev_pos, pos - prev_pos); string trimedstr = comm.TrimStart(); if (sn is loop_stmt || sn is case_node || sn is if_node || sn is while_node || sn is foreach_stmt || sn is for_node || sn is lock_stmt) { if (trimedstr == "do" || trimedstr == "of" || trimedstr == "then") comm = comm.TrimStart(); else if (trimedstr.StartsWith("of") && !char.IsLetterOrDigit(trimedstr[2])) comm = comm.TrimStart(); } else if (trimedstr.StartsWith(")") || trimedstr.StartsWith(";") || trimedstr.StartsWith("]") || trimedstr.StartsWith(">") || trimedstr.StartsWith(":")) comm = trimedstr; if (trimedstr.Length >= 2 && trimedstr[0] == '(' && trimedstr[trimedstr.Length - 1] == ')' && trimedstr.Replace("(", "").Replace(")", "").Trim() == "") comm = "()"; else if (trimedstr.Length >= 2 && trimedstr[0] == '(' && trimedstr[trimedstr.Length - 1] == ';') comm = trimedstr.Replace(" ", ""); else if (trimedstr.StartsWith("[") || trimedstr.EndsWith("]")) comm = trimedstr.Replace(" ", ""); if (trimedstr.StartsWith("; ")) { comm = "; " + trimedstr.Substring(1).TrimStart(' ', '\t'); } else if (trimedstr == "." || trimedstr == "^") comm = trimedstr; else if (trimedstr.StartsWith(",") && trimedstr.EndsWith(">")) comm = ",>"; //else if (sn is uses_closure || sn is formal_parameters || sn is type_declaration) // comm = comm.TrimStart(); if (sn is program_module || sn is unit_module) { comm = Text.Substring(prev_pos); trimedstr = comm.TrimStart(); if (trimedstr.StartsWith(".")) comm = trimedstr; } else if (sn is simple_property) { comm = RemoveOverSpaces(comm).Replace(" ;", ";"); } if (comm.StartsWith(" ")) add_space_before = true; if (comm != "()") WriteCommentWithIndent(comm, false); else sb.Append("()"); cur_src_off = pos; } else if (sn is program_module && (sn as program_module).program_block.program_code.right_logical_bracket.source_context == null) { string comm = Text.Substring(prev_pos).Trim(); sb.Append(comm); } } private void IncOffset() { off += tab; } private void IncOffset(int tab) { off += tab; } private void DecOffset() { off -= tab; if (off < 0) off = 0; } private void DecOffset(int tab) { off -= tab; if (off < 0) off = 0; } private bool NewLineNeeded(statement_list sl) { return true; } private string GetUnaryOperator(Operators op) { switch (op) { case Operators.Plus: return "+"; case Operators.Minus: return "-"; case Operators.LogicalNOT: return "not "; } throw new NotSupportedException(); } private string GetOperator(Operators op) { switch (op) { case Operators.Plus: return " + "; case Operators.Minus: return " - "; case Operators.Multiplication: return " * "; case Operators.Division: return " / "; case Operators.IntegerDivision: return " div "; case Operators.In: return " in "; case Operators.Equal: return " = "; case Operators.NotEqual: return " <> "; case Operators.ModulusRemainder: return " mod "; case Operators.Less: return " < "; case Operators.LessEqual: return " <= "; case Operators.Greater: return " > "; case Operators.GreaterEqual: return " >= "; case Operators.Is: return " is "; case Operators.As: return " as "; case Operators.LogicalAND: return " and "; case Operators.LogicalOR: return " or "; case Operators.BitwiseAND: return " and "; case Operators.BitwiseOR: return " or "; case Operators.BitwiseXOR: return " xor "; case Operators.BitwiseLeftShift: return " shl "; case Operators.BitwiseRightShift: return " shr "; case Operators.AssignmentAddition: return " += "; case Operators.AssignmentMultiplication: return " *= "; case Operators.AssignmentSubtraction: return " -= "; case Operators.AssignmentDivision: return " /= "; } throw new NotSupportedException(); } private string GetParamKind(parametr_kind kind) { switch (kind) { case parametr_kind.const_parametr: return "const"; case parametr_kind.out_parametr: return "out"; case parametr_kind.params_parametr: return "params"; case parametr_kind.var_parametr: return "var"; } return ""; } private string GetAccessModifier(access_modifer acc_mod) { switch (acc_mod) { case access_modifer.internal_modifer: return "internal"; case access_modifer.private_modifer: return "private"; case access_modifer.protected_modifer: return "protected"; case access_modifer.public_modifer: return "public"; case access_modifer.published_modifer: return "published"; } return ""; } private bool has_attributes(procedure_attributes_list attrs) { if (attrs.proc_attributes.Count == 0) return false; else if (attrs.proc_attributes.Count == 1) { if (attrs.proc_attributes[0].source_context == null) return false; else return true; } else return true; } private string GetClassKeyword(class_keyword key) { switch (key) { case class_keyword.Class: return "class"; case class_keyword.Interface: return "interface"; case class_keyword.Record: return "record"; case class_keyword.TemplateClass: return "template class"; case class_keyword.TemplateInterface: return "template interface"; case class_keyword.TemplateRecord: return "template record"; } throw new NotSupportedException(); } private string prepare_ident(string ident) { return ident; } private bool has_members(class_body_list body) { return body.class_def_blocks.Count != 0; } private void visit_node(syntax_tree_node sn) { if (sn != null && !(sn is empty_statement)) { if (!caret_syn_node_found && sn.source_context != null && GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num) >= caret_pos) { caret_syn_node_found = true; if (GetPosition(sn.source_context.begin_position.line_num, sn.source_context.begin_position.column_num) == caret_pos) { output_caret_line = sn.source_context.begin_position.line_num; output_caret_col = sn.source_context.begin_position.column_num; } else if (prev_sn != null && prev_sn.source_context != null) { output_caret_line = prev_sn.source_context.begin_position.line_num; output_caret_col = prev_sn.source_context.begin_position.column_num; } else if (sn.source_context != null) { output_caret_line = sn.source_context.begin_position.line_num; output_caret_col = sn.source_context.begin_position.column_num; } } if (!(sn is block) && !(sn is declarations) && !(sn is class_body_list && has_members(sn as class_body_list)) && !(sn is class_members) && !(sn is procedure_attributes_list) && !(sn is property_accessors) && !(sn is exception_block) && !(sn is exception_handler_list)) { if (sn.source_context != null) WritePossibleCommentBefore(sn); if (sn.source_context != null) prev_sn = sn; if (sn is variable_definitions || sn is array_type || sn is sequence_type || sn is set_type_definition || sn is repeat_node || sn is if_node || sn is while_node || sn is for_node || sn is foreach_stmt || sn is var_statement || sn is try_stmt || sn is goto_statement || sn is with_statement || sn is case_node || sn is function_header || sn is procedure_header || sn is constructor || sn is destructor || sn is type_declarations || sn is consts_definitions_list || sn is label_definitions || sn is class_definition || sn is uses_list || sn is uses_closure || sn is unit_name || sn is program_name || sn is new_expr || sn is raise_stmt || sn is interface_node || sn is implementation_node || sn is lock_stmt || sn is loop_stmt || sn is simple_property || sn is read_accessor_name || sn is write_accessor_name || sn is formal_parameters || sn is bracket_expr || sn is record_const || sn is array_const || sn is enum_type_definition || sn is exception_handler || sn is try_handler_finally || sn is try_handler_except || sn is external_directive || sn is where_definition || sn is var_tuple_def_statement || sn is match_with || (sn is simple_const_definition && in_class && !in_procedure) || (sn is typed_const_definition && in_class && !in_procedure) ) read_from_beg_pos = true; } sn.visit(this); if (!(sn is block) && !(sn is declarations) && !(sn is class_body_list) && !(sn is class_members)) { if (sn.source_context != null) WritePossibleCommentAfter(sn); if (sn.source_context != null /*&& !(sn is exception_handler)*/) prev_sn = sn; } } } public override void DefaultVisit(syntax_tree_node sn) { throw new NotImplementedException(); } #region IVisitor Member public override void visit(syntax_tree_node n) { } public override void visit(no_type_foreach _no_type_foreach) { } public override void visit(statement_list _statement_list) { bool tmp_init_part = false; if (_statement_list.left_logical_bracket != null) { /*if (options.AggressiveMode == 1) { add_newline_before = true; }*/ visit_node(_statement_list.left_logical_bracket); //add_space_before = true; } if (!in_one_row(_statement_list) && _statement_list.left_logical_bracket != null && _statement_list.subnodes.Count > 0 && _statement_list.subnodes[0].source_context != null && _statement_list.left_logical_bracket.source_context != null && _statement_list.left_logical_bracket.source_context.end_position.line_num == _statement_list.subnodes[0].source_context.begin_position.line_num && !_statement_list.left_logical_bracket.text.StartsWith("##")) add_newline_after = true; else add_space_after = true; bool tmp_add_newline_after = add_newline_after; if (init_part) { init_part = false; tmp_init_part = true; } foreach (statement stmt in _statement_list.subnodes) { /*if (options.AggressiveMode == 1 && !(stmt is empty_statement)) { add_newline_before = true; }*/ if (stmt is assign) { assign ass_stmt = stmt as assign; if (ass_stmt.to is ident && (ass_stmt.to as ident).source_context == null) { visit_node(ass_stmt.from); continue; } } if (!(stmt is empty_statement)) add_space_after = true; visit_node(stmt); } if (_statement_list.subnodes.Count == 2 && _statement_list.subnodes[0] is statement_list) add_newline_after = tmp_add_newline_after; DecOffset(); if (!tmp_init_part) if (_statement_list.right_logical_bracket != null) if (!(_statement_list.left_logical_bracket != null && _statement_list.left_logical_bracket is token_info && (_statement_list.left_logical_bracket as token_info).text.ToLower() == "finalization")) { dec_offset_before_comment = true; add_space_after = true; //if (options.AggressiveMode == 1) // add_newline_before = true; visit_node(_statement_list.right_logical_bracket); } } public override void visit(assign _assign) { multiline_stack_push(_assign); visit_node(_assign.to); //sb.Append(" := "); add_space_before = true; add_space_after = true; visit_node(_assign.from); multiline_stack_pop(_assign); } public override void visit(bin_expr _bin_expr) { multiline_stack_push(_bin_expr); visit_node(_bin_expr.left); add_space_before = true; add_space_after = true; visit_node(_bin_expr.right); multiline_stack_pop(_bin_expr); } public override void visit(un_expr _un_expr) { sb.Append(GetUnaryOperator(_un_expr.operation_type)); visit_node(_un_expr.subnode); } public override void visit(bool_const _bool_const) { WriteNode(_bool_const); } public override void visit(int32_const _int32_const) { WriteNode(_int32_const); } public override void visit(double_const _double_const) { WriteNode(_double_const); } public override void visit(ident _ident) { WriteAmpersandIfNeed(_ident); sb.Append(prepare_ident(_ident.name)); } public override void visit(named_type_reference _named_type_reference) { for (int i = 0; i < _named_type_reference.names.Count; i++) { visit_node(_named_type_reference.names[i]); } } public override void visit(variable_definitions _variable_definitions) { bool is_event = false; for (int i = 0; i < _variable_definitions.var_definitions.Count; i++) { if (_variable_definitions.var_definitions[i].is_event) is_event = true; } if (is_event) sb.Append("event"); else sb.Append("var"); IncOffset(); for (int i = 0; i < _variable_definitions.var_definitions.Count; i++) { if (i == 0) { add_newline_before = true; if (is_event) keyword_offset = "event".Length; else keyword_offset = "var".Length; } if (options.AggressiveMode == 1) add_newline_before = true; var_def_statement vds = _variable_definitions.var_definitions[i]; //next_sn = (i < _variable_definitions.var_definitions.Count - 1) ? _variable_definitions.var_definitions[i + 1] : null; visit_node(vds); } DecOffset(); if (!in_procedure) insert_newline_after_prev_semicolon = true; } public override void visit(ident_list _ident_list) { for (int i = 0; i < _ident_list.idents.Count; i++) { if (i > 0 && options.SpaceBetweenIdentifiers == 1) add_space_after = true; visit_node(_ident_list.idents[i]); } } public override void visit(var_def_statement _var_def_statement) { /*if (_var_def_statement.attributes != null) { visit_node(_var_def_statement.attributes); }*/ if (_var_def_statement.is_event || _var_def_statement.var_attr == definition_attribute.Static) read_from_beg_pos = true; visit_node(_var_def_statement.vars); if (_var_def_statement.vars_type != null) { //sb.Append(": "); add_space_after = true; visit_node(_var_def_statement.vars_type); } if (_var_def_statement.inital_value != null) { //sb.Append(" := "); add_space_after = true; add_space_before = true; visit_node(_var_def_statement.inital_value); } } public override void visit(declaration _declaration) { throw new NotImplementedException(); } public override void visit(declarations _declarations) { foreach (declaration decl in _declarations.defs) { if ((decl is procedure_definition || decl is short_func_definition) && in_procedure) { //insert_newline_after_prev_semicolon = true; IncOffset(); } visit_node(decl); if ((decl is procedure_definition || decl is short_func_definition) && in_procedure) DecOffset(); } } public override void visit(program_name _program_name) { //sb.Append("program "); sb.Append("program"); SetKeywordOffset("program"); visit_node(_program_name.prog_name); insert_newline_after_prev_semicolon = true; //sb.AppendLine(";"); } public override void visit(string_const _string_const) { int pos = GetPosition(_string_const.source_context.begin_position.line_num, _string_const.source_context.begin_position.column_num); if (Text[pos] == '$') sb.Append('$'); sb.Append("'"); sb.Append(_string_const.Value.Replace("'","''")); sb.Append("'"); } public override void visit(expression_list _expression_list) { for (int i = 0; i < _expression_list.expressions.Count; i++) { if (i > 0 && options.SpaceBetweenArguments == 1) add_space_after = true; visit_node(_expression_list.expressions[i]); } } public override void visit(dereference _dereference) { throw new NotImplementedException(); } public override void visit(roof_dereference _roof_dereference) { visit_node(_roof_dereference.dereferencing_value); //sb.Append('^'); } public override void visit(indexer _indexer) { visit_node(_indexer.dereferencing_value); //sb.Append("["); visit_node(_indexer.indexes); //sb.Append("]"); } public override void visit(for_node _for_node) { //WritePossibleMultilineComment(); sb.Append("for"); SetKeywordOffset("for"); visit_node(_for_node.loop_variable); if (_for_node.type_name != null) { add_space_after = true; visit_node(_for_node.type_name); } add_space_after = true; add_space_before = true; visit_node(_for_node.initial_value); add_space_before = true; add_space_after = true; visit_node(_for_node.finish_value); add_space_before = true; //WriteKeyword(" do "); bool need_off = !(_for_node.statements is statement_list); if (!in_one_row(_for_node.statements)) add_newline_after = true; if (need_off) IncOffset(); visit_node(_for_node.statements); if (need_off) DecOffset(); } public override void visit(repeat_node _repeat_node) { WriteKeyword("repeat"); SetKeywordOffset("repeat"); IncOffset(); //add_newline_after = true; visit_node(_repeat_node.statements); sb.Append("until"); //sb.Append(" "); add_space_before = true; multiline_stack_push(_repeat_node.expr); visit_node(_repeat_node.expr); multiline_stack_pop(_repeat_node.expr); } public override void visit(while_node _while_node) { sb.Append("while"); SetKeywordOffset("while"); multiline_stack_push(_while_node.expr); visit_node(_while_node.expr); multiline_stack_pop(_while_node.expr); if (!in_one_row(_while_node.statements)) add_newline_after = true; add_space_before = true; //WriteKeyword(" do"); bool need_off = !(_while_node.statements is statement_list); if (need_off) IncOffset(); visit_node(_while_node.statements); if (need_off) DecOffset(); } private void WriteKeyword(string s) { sb.Append(s); } public override void visit(if_node _if_node) { sb.Append("if"); //sb.Append(" "); SetKeywordOffset("if"); visit_node(_if_node.condition); if (!in_one_row(_if_node.condition)) add_newline_after = true; add_space_before = true; //WriteKeyword(" then"); bool need_off = true; if (_if_node.then_body is statement_list) need_off = false; if (need_off) IncOffset(); visit_node(_if_node.then_body); if (need_off) DecOffset(); if (_if_node.else_body != null) { //WriteKeyword("else"); need_off = true; add_space_before = true; if (_if_node.else_body is statement_list) need_off = false; else if (!(_if_node.else_body is if_node) && !(_if_node.else_body is empty_statement)) add_new_line_else_specific = true; else need_off = false; if (need_off) IncOffset(); visit_node(_if_node.else_body); if (need_off) DecOffset(); } } public override void visit(ref_type _ref_type) { sb.Append("^"); visit_node(_ref_type.pointed_to); } public override void visit(diapason _diapason) { visit_node(_diapason.left); visit_node(_diapason.right); } private bool is_multi_dyn_arr(indexers_types _indexers_types) { for (int i = 0; i < _indexers_types.indexers.Count; i++) { if (_indexers_types.indexers[i] != null) return false; } return true; } public override void visit(indexers_types _indexers_types) { if (is_multi_dyn_arr(_indexers_types)) { WriteNode(_indexers_types); } else { //sb.Append("["); for (int i = 0; i < _indexers_types.indexers.Count; i++) { if (i > 0) add_space_after = true; if (_indexers_types.indexers[i] != null) visit_node(_indexers_types.indexers[i]); } } } public override void visit(array_type _array_type) { if (_array_type.indexers != null) { skip_spaces_after = true; visit_node(_array_type.indexers); add_space_after = false; add_space_before = false; } visit_node(_array_type.elements_type); } public override void visit(label_definitions _label_definitions) { sb.Append("label"); SetKeywordOffset("label"); visit_node(_label_definitions.labels); } public override void visit(procedure_attribute _procedure_attribute) { if (_procedure_attribute.source_context != null) switch (_procedure_attribute.attribute_type) { case proc_attribute.attr_abstract: sb.Append("abstract"); return; case proc_attribute.attr_forward: sb.Append("forward"); return; case proc_attribute.attr_overload: sb.Append("overload"); return; case proc_attribute.attr_override: sb.Append("override"); return; case proc_attribute.attr_reintroduce: sb.Append("reintroduce"); return; case proc_attribute.attr_virtual: sb.Append("virtual"); return; case proc_attribute.attr_static: sb.Append("static"); return; case proc_attribute.attr_extension: sb.Append("extensionmethod"); return; } return; } public override void visit(typed_parameters _typed_parametres) { /*if (_typed_parametres.attributes != null) { attr_on_new_line = false; visit_node(_typed_parametres.attributes); attr_on_new_line = true; }*/ if (_typed_parametres.param_kind != parametr_kind.none) { string s = GetParamKind(_typed_parametres.param_kind); sb.Append(s); SetKeywordOffset(s); read_from_beg_pos = true; } //sb.Append(GetParamKind(_typed_parametres.param_kind)); visit_node(_typed_parametres.idents); add_space_after = true; //sb.Append(": "); if (!(_typed_parametres.vars_type is lambda_inferred_type)) visit_node(_typed_parametres.vars_type); if (_typed_parametres.inital_value != null) { //sb.Append(" := "); add_space_before = true; add_space_after = true; visit_node(_typed_parametres.inital_value); } } public override void visit(formal_parameters _formal_parametres) { if (!is_lambda_parameters) { sb.Append("("); keyword_offset = 1; } else is_lambda_parameters = true; for (int i = 0; i < _formal_parametres.params_list.Count; i++) { if (i > 0) add_space_after = true; if (_formal_parametres.params_list[i].attributes != null) { add_space_after = true; } visit_node(_formal_parametres.params_list[i]); } } public override void visit(procedure_attributes_list _procedure_attributes_list) { for (int i=0; i<_procedure_attributes_list.proc_attributes.Count; i++) { if (_procedure_attributes_list.proc_attributes[i].source_context == null) continue; add_space_after = true; visit_node(_procedure_attributes_list.proc_attributes[i]); } } public override void visit(procedure_header _procedure_header) { multiline_stack_push(_procedure_header); sb.Append("procedure"); SetKeywordOffset("procedure"); if (_procedure_header.name != null) visit_node(_procedure_header.name); else add_space_before = false; if (_procedure_header.template_args != null && !(_procedure_header.name.meth_name is operator_name_ident)) { sb.Append("<"); visit_node(_procedure_header.template_args); //sb.Append(">"); } if (_procedure_header.parameters != null) { visit_node(_procedure_header.parameters); } if (_procedure_header.proc_attributes != null && has_attributes(_procedure_header.proc_attributes)) { if (is_forward(_procedure_header)) _procedure_header.source_context = new SourceContext(_procedure_header.source_context.begin_position.line_num, _procedure_header.source_context.begin_position.column_num, _procedure_header.proc_attributes.source_context.end_position.line_num, _procedure_header.proc_attributes.source_context.end_position.column_num); visit_node(_procedure_header.proc_attributes); } if (_procedure_header.where_defs != null) visit_node(_procedure_header.where_defs); keyword_offset = 0; read_from_beg_pos = false; multiline_stack_pop(_procedure_header); //add_newline_before = true; } public override void visit(function_header _function_header) { //if (_function_header.attributes != null) // visit_node(_function_header.attributes); multiline_stack_push(_function_header); sb.Append("function"); SetKeywordOffset("function"); if (_function_header.name != null) visit_node(_function_header.name); else add_space_before = false; if (_function_header.template_args != null && !(_function_header.name.meth_name is operator_name_ident)) { sb.Append("<"); visit_node(_function_header.template_args); } if (_function_header.parameters != null) { visit_node(_function_header.parameters); } //sb.Append(": "); add_space_after = true; visit_node(_function_header.return_type); if (_function_header.proc_attributes != null && has_attributes(_function_header.proc_attributes)) { if (is_forward(_function_header)) _function_header.source_context = new SourceContext(_function_header.source_context.begin_position.line_num, _function_header.source_context.begin_position.column_num, _function_header.proc_attributes.source_context.end_position.line_num, _function_header.proc_attributes.source_context.end_position.column_num); visit_node(_function_header.proc_attributes); } if (_function_header.where_defs != null) { visit_node(_function_header.where_defs); } keyword_offset = 0; read_from_beg_pos = false; multiline_stack_pop(_function_header); //add_newline_before = true; } public override void visit(procedure_definition _procedure_definition) { if (_procedure_definition.proc_body is external_directive) multiline_stack_push(_procedure_definition); visit_node(_procedure_definition.proc_header); bool tmp_in_proc = in_procedure; in_procedure = true; if (_procedure_definition.proc_body is external_directive) add_space_after = true; if (/*options.AggressiveMode == 1 && _procedure_definition.proc_body != null ||*/ (!in_one_row(_procedure_definition) && in_same_row(_procedure_definition.proc_header, _procedure_definition.proc_body))) { if (distance(_procedure_definition.proc_header, _procedure_definition.proc_body) > 0) add_newline_after = true; else sb.AppendLine(); } if (_procedure_definition.proc_body is block && (_procedure_definition.proc_body as block).program_code.left_logical_bracket == null) { add_space_before = true; add_space_after = true; } visit_node(_procedure_definition.proc_body); in_procedure = tmp_in_proc; //if (in_procedure) // DecOffset(); if (_procedure_definition.proc_body is external_directive || is_forward(_procedure_definition.proc_header)) insert_newline_after_prev_semicolon = true; else insert_newline_after_prev_semicolon = true; if (_procedure_definition.proc_body is external_directive) multiline_stack_pop(_procedure_definition); } public override void visit(type_declaration _type_declaration) { visit_node(_type_declaration.type_name); //sb.Append(" = "); add_space_after = true; add_space_before = true; visit_node(_type_declaration.type_def); } public override void visit(type_declarations _type_declarations) { sb.Append("type"); IncOffset(); for (int i = 0; i < _type_declarations.types_decl.Count; i++) { if (i == 0) { add_newline_before = true; keyword_offset = "type".Length; } type_declaration td = _type_declarations.types_decl[i]; //next_sn = (i < _variable_definitions.var_definitions.Count - 1) ? _variable_definitions.var_definitions[i + 1] : null; visit_node(td); } DecOffset(); if (!in_procedure) insert_newline_after_prev_semicolon = true; } public override void visit(simple_const_definition _simple_const_definition) { if (in_class && !in_procedure) { sb.Append("const"); SetKeywordOffset("const"); add_space_before = true; } visit_node(_simple_const_definition.const_name); //sb.Append(" = "); add_space_before = true; add_space_after = true; visit_node(_simple_const_definition.const_value); //sb.AppendLine(";"); } public override void visit(typed_const_definition _typed_const_definition) { if (in_class && !in_procedure) { sb.Append("const"); SetKeywordOffset("const"); add_space_before = true; } visit_node(_typed_const_definition.const_name); //sb.Append(" : "); add_space_after = true; visit_node(_typed_const_definition.const_type); //sb.Append(" = "); add_space_before = true; add_space_after = true; visit_node(_typed_const_definition.const_value); //sb.AppendLine(";"); } public override void visit(consts_definitions_list _consts_definitions_list) { sb.Append("const"); IncOffset(); for (int i = 0; i < _consts_definitions_list.const_defs.Count; i++) { if (i == 0) { add_newline_before = true; keyword_offset = "const".Length; } if (options.AggressiveMode == 1) add_newline_before = true; const_definition cnst = _consts_definitions_list.const_defs[i]; //next_sn = (i < _variable_definitions.var_definitions.Count - 1) ? _variable_definitions.var_definitions[i + 1] : null; visit_node(cnst); } DecOffset(); if (!in_procedure) insert_newline_after_prev_semicolon = true; } public override void visit(unit_name _unit_name) { if (_unit_name.HeaderKeyword == UnitHeaderKeyword.Unit) { sb.Append("unit"); SetKeywordOffset("unit"); } else if (_unit_name.HeaderKeyword == UnitHeaderKeyword.Library) { sb.Append("library"); SetKeywordOffset("library"); } else if (_unit_name.HeaderKeyword == UnitHeaderKeyword.Namespace) { sb.Append("namespace"); SetKeywordOffset("namespace"); } visit_node(_unit_name.idunit_name); //sb.AppendLine(";"); } public override void visit(unit_or_namespace _unit_or_namespace) { for (int i = 0; i < _unit_or_namespace.name.idents.Count; i++) { visit_node(_unit_or_namespace.name.idents[i]); } } public override void visit(uses_unit_in _uses_unit_in) { for (int i = 0; i < _uses_unit_in.name.idents.Count; i++) { visit_node(_uses_unit_in.name.idents[i]); } add_space_before = true; visit_node(_uses_unit_in.in_file); } public override void visit(uses_list _uses_list) { //sb.Append("uses"); IncOffset(tab); //if (!in_one_row(_uses_list)) force_tab = true; for (int i = 0; i < _uses_list.units.Count; i++) { if (i > 0) add_space_after = true; if (_uses_list.units[i].source_context != null) visit_node(_uses_list.units[i]); } insert_newline_after_prev = true; DecOffset(tab); } public override void visit(unit_module _unit_module) { has_implementation = _unit_module.implementation_part != null; if (_unit_module.attributes != null) visit_node(_unit_module.attributes); visit_node(_unit_module.unit_name); insert_newline_after_prev = true; if (_unit_module.interface_part != null) visit_node(_unit_module.interface_part); if (_unit_module.implementation_part != null) visit_node(_unit_module.implementation_part); init_part = true; if (_unit_module.initialization_part != null) { if (_unit_module.initialization_part.source_context != null) _unit_module.initialization_part.source_context = new SourceContext(_unit_module.initialization_part.left_logical_bracket.source_context.begin_position.line_num, _unit_module.initialization_part.left_logical_bracket.source_context.begin_position.column_num,_unit_module.initialization_part.source_context.end_position.line_num, _unit_module.initialization_part.source_context.end_position.column_num); visit_node(_unit_module.initialization_part); } init_part = true; if (_unit_module.finalization_part != null) { if (_unit_module.finalization_part.source_context != null) _unit_module.finalization_part.source_context = new SourceContext(_unit_module.finalization_part.left_logical_bracket.source_context.begin_position.line_num, _unit_module.finalization_part.left_logical_bracket.source_context.begin_position.column_num, _unit_module.finalization_part.source_context.end_position.line_num, _unit_module.finalization_part.source_context.end_position.column_num); visit_node(_unit_module.finalization_part); } //sb.Append("."); } public override void visit(program_module _program_module) { // Где-то хранить и добавить ## if (_program_module.program_name != null) visit_node(_program_module.program_name); if (_program_module.used_units != null && _program_module.used_units.source_context != null) { /*if (_program_module.program_block != null && _program_module.program_block.program_code.left_logical_bracket.text.StartsWith("##")) ; else*/ visit_node(_program_module.used_units); } if (_program_module.program_block != null) visit_node(_program_module.program_block); //sb.Append("."); } public override void visit(hex_constant _hex_constant) { sb.Append("$"); sb.Append(_hex_constant.val.ToString()); } public override void visit(get_address _get_address) { sb.Append("@"); visit_node(_get_address.address_of); } public override void visit(case_variant _case_variant) { List variants = (_case_variant.Parent as case_variants).variants; visit_node(_case_variant.conditions); //sb.Append(": "); if (!(_case_variant.exec_if_true is empty_statement && variants.IndexOf(_case_variant) == variants.Count - 1)) add_space_after = true; bool one_row = in_one_row(_case_variant.exec_if_true); if (!one_row) { add_newline_after = true; IncOffset(); } visit_node(_case_variant.exec_if_true); if (!one_row) { DecOffset(); } //sb.AppendLine(";"); } public override void visit(case_node _case_node) { sb.Append("case"); SetKeywordOffset("case"); visit_node(_case_node.param); //sb.AppendLine(" of"); add_space_before = true; IncOffset(); if (_case_node.conditions != null) visit_node(_case_node.conditions); DecOffset(); if (_case_node.else_statement != null) { //IncOffset(); add_new_line_else_specific = true; IncOffset(); //if (!(_case_node.else_statement is statement_list sl && sl.list.Count == 1 && sl.list[0] is empty_statement)) statement_list stmt_list = _case_node.else_statement as statement_list; visit_node(_case_node.else_statement); if (stmt_list != null && stmt_list.subnodes.Count > 0 && contains_only_empty_statements(stmt_list.subnodes)) { WriteNode(stmt_list); add_space_after = false; } //DecOffset(); } } public override void visit(method_name _method_name) { if (_method_name.ln != null) { foreach (ident id in _method_name.ln) visit_node(id); } else { if (_method_name.class_name != null) visit_node(_method_name.class_name); if (_method_name.explicit_interface_name != null) visit_node(_method_name.explicit_interface_name); if (_method_name.meth_name != null) visit_node(_method_name.meth_name); } } public override void visit(dot_node _dot_node) { visit_node(_dot_node.left); visit_node(_dot_node.right); } public override void visit(empty_statement _empty_statement) { //sb.Append(""); } public override void visit(goto_statement _goto_statement) { sb.Append("goto"); SetKeywordOffset("goto"); visit_node(_goto_statement.label); } public override void visit(labeled_statement _labeled_statement) { visit_node(_labeled_statement.label_name); add_space_after = true; visit_node(_labeled_statement.to_statement); } public override void visit(with_statement _with_statement) { sb.Append("with"); SetKeywordOffset("with"); multiline_stack_push(_with_statement.do_with); visit_node(_with_statement.do_with); multiline_stack_pop(_with_statement.do_with); //sb.Append(" do"); add_space_before = true; bool need_off = !(_with_statement.what_do is statement_list); if (need_off) IncOffset(); if (!in_one_row(_with_statement.what_do)) add_newline_after = true; visit_node(_with_statement.what_do); if (need_off) DecOffset(); } public override void visit(method_call _method_call) { multiline_stack_push(_method_call); visit_node(_method_call.dereferencing_value); if (_method_call.parameters != null) { //sb.Append("("); visit_node(_method_call.parameters); //sb.Append(")"); } multiline_stack_pop(_method_call); } public override void visit(pascal_set_constant _pascal_set_constant) { if (_pascal_set_constant.values != null) { sb.Append("["); visit_node(_pascal_set_constant.values); } else WriteNode(_pascal_set_constant, true); //sb.Append("]"); } public override void visit(array_const _array_const) { if (_array_const.elements != null) { multiline_stack_push(_array_const); sb.Append("("); keyword_offset = 1; visit_node(_array_const.elements); multiline_stack_pop(_array_const); } else { WriteNode(_array_const); read_from_beg_pos = false; } } public override void visit(write_accessor_name _write_accessor_name) { sb.Append("write"); SetKeywordOffset("write"); if (_write_accessor_name.statment_for_formatting != null) { if (_write_accessor_name.statment_for_formatting is statement_list) IncOffset(); visit_node(_write_accessor_name.statment_for_formatting); if (_write_accessor_name.statment_for_formatting is statement_list) DecOffset(); } else if (_write_accessor_name.accessor_name != null) visit_node(_write_accessor_name.accessor_name); else read_from_beg_pos = false; } public override void visit(read_accessor_name _read_accessor_name) { sb.Append("read"); SetKeywordOffset("read"); if (_read_accessor_name.expression_for_formatting != null) visit_node(_read_accessor_name.expression_for_formatting); else if (_read_accessor_name.accessor_name != null) visit_node(_read_accessor_name.accessor_name); else read_from_beg_pos = false; } public override void visit(property_accessors _property_accessors) { //MikhailoMMX - теперь исходный порядок Accessor'ов учитывается syntax_tree_node FirstAccessor = _property_accessors.read_accessor; syntax_tree_node SecondAccessor = _property_accessors.write_accessor; if (FirstAccessor != null && SecondAccessor != null) if ((FirstAccessor.source_context.begin_position.line_num>SecondAccessor.source_context.begin_position.line_num) || ((FirstAccessor.source_context.begin_position.line_num == SecondAccessor.source_context.begin_position.line_num) && (FirstAccessor.source_context.begin_position.column_num > SecondAccessor.source_context.begin_position.column_num))) { syntax_tree_node t = FirstAccessor; FirstAccessor = SecondAccessor; SecondAccessor = t; } //\MikhailoMMX if (FirstAccessor != null) { visit_node(FirstAccessor); } if (SecondAccessor != null) { add_space_after = true; visit_node(SecondAccessor); } } public override void visit(simple_property _simple_property) { multiline_stack_push(_simple_property); var property_keyword = "property"; if (_simple_property.attr != definition_attribute.Static && !_simple_property.is_auto) { sb.Append(property_keyword); SetKeywordOffset(property_keyword); } visit_node(_simple_property.property_name); if (_simple_property.parameter_list != null) { visit_node(_simple_property.parameter_list); } add_space_after = true; visit_node(_simple_property.property_type); add_space_after = true; if (_simple_property.accessors != null) visit_node(_simple_property.accessors); if (_simple_property.initial_value != null) { add_space_before = true; visit_node(_simple_property.initial_value); } if (_simple_property.array_default != null) visit_node(_simple_property.array_default); add_space_before = false; add_space_after = false; multiline_stack_pop(_simple_property); } public override void visit(class_members _class_members) { if (_class_members.access_mod != null && _class_members.access_mod.source_context != null) { bool already_off = true; declaration first_decl = null; if (_class_members.members.Count > 0) first_decl = _class_members.members[0]; if (first_decl is short_func_definition) first_decl = (first_decl as short_func_definition).procdef; if (first_decl != null && first_decl.source_context != null && _class_members.access_mod.source_context.end_position.line_num == first_decl.source_context.begin_position.line_num) IncOffset(); else already_off = false; visit_node(_class_members.access_mod); if (first_decl != null && !(_class_members.members[0] is short_func_definition) && _class_members.access_mod.source_context.end_position.line_num == _class_members.source_context.begin_position.line_num) sb.Append(" "); if (!already_off) IncOffset(); } else IncOffset(); foreach (declaration decl in _class_members.members) { visit_node(decl); } DecOffset(); } public override void visit(access_modifer_node _access_modifer_node) { sb.Append(GetAccessModifier(_access_modifer_node.access_level)); } public override void visit(class_body_list _class_body) { in_class = true; if (_class_body.class_def_blocks.Count == 0) sb.Append("end"); else foreach (class_members cmem in _class_body.class_def_blocks) visit_node(cmem); in_class = false; } public override void visit(class_definition _class_definition) { bool class_pred = true; if (_class_definition.class_parents != null) { class_pred = false; visit_node(_class_definition.class_parents); } if (_class_definition.where_section != null) { class_pred = false; add_space_after = true; visit_node(_class_definition.where_section); } if (_class_definition.body != null) { if (!((_class_definition.body.class_def_blocks.Count == 0 || _class_definition.body.class_def_blocks[0].members != null && _class_definition.body.class_def_blocks[0].members.Count == 0) && _class_definition.class_parents == null && _class_definition.where_section == null)) { class_pred = false; visit_node(_class_definition.body); } else { read_from_beg_pos = false; class_pred = false; WriteNodeWithIndent(_class_definition); } } if (class_pred) { read_from_beg_pos = false; WriteNode(_class_definition); } insert_newline_after_prev = false; insert_newline_after_prev_semicolon = false; } public override void visit(set_type_definition _set_type_definition) { visit_node(_set_type_definition.of_type); } public override void visit(record_const_definition _record_const_definition) { visit_node(_record_const_definition.name); //sb.Append(": "); add_space_before = false; add_space_after = true; visit_node(_record_const_definition.val); } public override void visit(record_const _record_const) { multiline_stack_push(_record_const); sb.Append("("); keyword_offset = 1; for (int i = 0; i < _record_const.rec_consts.Count; i++) { if (i > 0) add_space_after = true; visit_node(_record_const.rec_consts[i]); } multiline_stack_pop(_record_const); } public override void visit(record_type _record_type) { throw new NotImplementedException(); } public override void visit(enum_type_definition _enum_type_definition) { sb.Append("("); keyword_offset = 1; multiline_stack_push(_enum_type_definition); visit_node(_enum_type_definition.enumerators); multiline_stack_pop(_enum_type_definition); //sb.Append(")"); } public override void visit(char_const _char_const) { sb.Append("'"); sb.Append(_char_const.cconst.ToString()); sb.Append("'"); } public override void visit(raise_statement _raise_statement) { sb.Append("raise"); sb.Append(" "); visit_node(_raise_statement.excep); } public override void visit(sharp_char_const _sharp_char_const) { sb.Append("#"); sb.Append(_sharp_char_const.char_num.ToString()); } public override void visit(literal_const_line _literal_const_line) { foreach (literal l in _literal_const_line.literals) visit_node(l); } public override void visit(string_num_definition _string_num_definition) { visit_node(_string_num_definition.name); visit_node(_string_num_definition.num_of_symbols); } public override void visit(variant _variant) { throw new NotImplementedException(); } public override void visit(variant_list _variant_list) { throw new NotImplementedException(); } public override void visit(variant_type _variant_type) { throw new NotImplementedException(); } public override void visit(variant_types _variant_types) { throw new NotImplementedException(); } public override void visit(variant_record_type _variant_record_type) { throw new NotImplementedException(); } public override void visit(procedure_call _procedure_call) { visit_node(_procedure_call.func_name); } public override void visit(class_predefinition _class_predefinition) { throw new NotImplementedException(); } public override void visit(nil_const _nil_const) { sb.Append("nil"); } public override void visit(file_type_definition _file_type_definition) { if (_file_type_definition.elem_type != null) { //sb.Append("file of "); visit_node(_file_type_definition.elem_type); } else { sb.Append("file"); } } public override void visit(constructor _constructor) { if (_constructor.name == null && _constructor.template_args == null && _constructor.parameters == null && _constructor.where_defs == null && (_constructor.proc_attributes == null || !has_attributes(_constructor.proc_attributes))) { WriteNode(_constructor); read_from_beg_pos = false; keyword_offset = 0; return; } multiline_stack_push(_constructor); if (!_constructor.class_keyword) { sb.Append("constructor"); SetKeywordOffset("constructor"); } if (_constructor.name != null) { //add_space_before = true; visit_node(_constructor.name); } else add_space_before = false; if (_constructor.template_args != null) { sb.Append("<"); visit_node(_constructor.template_args); } if (_constructor.parameters != null) { visit_node(_constructor.parameters); } if (_constructor.where_defs != null) visit_node(_constructor.where_defs); if (_constructor.proc_attributes != null && has_attributes(_constructor.proc_attributes)) visit_node(_constructor.proc_attributes); read_from_beg_pos = false; keyword_offset = 0; multiline_stack_pop(_constructor); } public override void visit(destructor _destructor) { multiline_stack_push(_destructor); sb.Append("destructor"); SetKeywordOffset("destructor"); if (_destructor.name != null) { add_space_before = true; visit_node(_destructor.name); } if (_destructor.template_args != null) { sb.Append("<"); visit_node(_destructor.template_args); } if (_destructor.parameters != null) { visit_node(_destructor.parameters); } if (_destructor.where_defs != null) visit_node(_destructor.where_defs); if (_destructor.proc_attributes != null && has_attributes(_destructor.proc_attributes)) visit_node(_destructor.proc_attributes); read_from_beg_pos = false; keyword_offset = 0; multiline_stack_pop(_destructor); } public override void visit(inherited_method_call _inherited_method_call) { visit_node(_inherited_method_call.method_name); if (_inherited_method_call.exprs != null) { sb.Append("("); visit_node(_inherited_method_call.exprs); sb.Append(")"); } } public override void visit(typecast_node _typecast_node) { visit_node(_typecast_node.expr); if (_typecast_node.cast_op == op_typecast.is_op || _typecast_node.cast_op == op_typecast.as_op) { add_space_before = true; add_space_after = true; } visit_node(_typecast_node.type_def); } public override void visit(interface_node _interface_node) { if (_interface_node.source_context != null && has_implementation) { sb.Append("interface"); SetKeywordOffset("interface"); insert_newline_after_prev_semicolon = true; } else if (_interface_node.source_context == null) { read_from_beg_pos = false; //return; } visit_node(_interface_node.uses_modules); if (_interface_node.interface_definitions != null) visit_node(_interface_node.interface_definitions); } public override void visit(implementation_node _implementation_node) { if (_implementation_node.source_context != null) { sb.Append("implementation"); SetKeywordOffset("implementation"); insert_newline_after_prev_semicolon = true; } visit_node(_implementation_node.uses_modules); if (_implementation_node.implementation_definitions != null) visit_node(_implementation_node.implementation_definitions); } public override void visit(diap_expr _diap_expr) { throw new NotImplementedException(); } public override void visit(block _block) { if (_block.defs != null) visit_node(_block.defs); visit_node(_block.program_code); } public override void visit(proc_block _proc_block) { throw new NotImplementedException(); } public override void visit(array_of_named_type_definition _array_of_named_type_definition) { throw new NotImplementedException(); } public override void visit(array_of_const_type_definition _array_of_const_type_definition) { throw new NotImplementedException(); } public override void visit(literal _literal) { throw new NotImplementedException(); } public override void visit(case_variants _case_variants) { foreach (case_variant cv in _case_variants.variants) visit_node(cv); } public override void visit(diapason_expr _diapason_expr) { visit_node(_diapason_expr.left); visit_node(_diapason_expr.right); } public override void visit(var_def_list_for_record _var_def_list) { throw new NotImplementedException(); } public override void visit(record_type_parts _record_type_parts) { throw new NotImplementedException(); } public override void visit(property_array_default _property_array_default) { WriteNode(_property_array_default); } public override void visit(property_interface _property_interface) { throw new NotImplementedException(); } public override void visit(property_parameter _property_parameter) { visit_node(_property_parameter.names); add_space_after = true; visit_node(_property_parameter.type); } public override void visit(property_parameter_list _property_parameter_list) { for (int i=0; i<_property_parameter_list.parameters.Count; i++) { if (i > 0) add_space_after = true; visit_node(_property_parameter_list.parameters[i]); } } public override void visit(inherited_ident _inherited_ident) { sb.Append("inherited "); sb.Append(_inherited_ident.name); } public override void visit(format_expr _format_expr) { visit_node(_format_expr.expr); visit_node(_format_expr.format1); if (_format_expr.format2 != null) { visit_node(_format_expr.format2); } } public override void visit(initfinal_part _initfinal_part) { throw new NotImplementedException(); } public override void visit(token_info _token_info) { if (string.Compare(_token_info.text, "begin", true) == 0) { WriteKeyword("begin"); IncOffset(); } else if (string.Compare(_token_info.text, "##", true) == 0) { WriteKeyword("##\n"); } else if (string.Compare(_token_info.text, "###", true) == 0) { WriteKeyword("###\n"); } else if (string.Compare(_token_info.text, "initialization", true) == 0) { WriteKeyword("initialization"); IncOffset(); } else if (string.Compare(_token_info.text, "finalization", true) == 0) { WriteKeyword("finalization"); IncOffset(); } else if (string.Compare(_token_info.text, "finally", true) == 0) { WriteKeyword("finally"); IncOffset(); } else if (string.Compare(_token_info.text, "end", true) == 0) { sb.Append("end"); } } public override void visit(raise_stmt _raise_stmt) { sb.Append("raise"); SetKeywordOffset("raise"); if (_raise_stmt.expr != null) visit_node(_raise_stmt.expr); else add_space_before = false; } public override void visit(op_type_node _op_type_node) { throw new NotImplementedException(); } public override void visit(file_type _file_type) { sb.Append("file"); if (_file_type.file_of_type != null) { sb.Append(" of "); visit_node(_file_type.file_of_type); } else { } } public override void visit(known_type_ident _known_type_ident) { throw new NotImplementedException(); } public override void visit(exception_handler ex) { sb.Append("on"); SetKeywordOffset("on"); if (ex.variable != null) { visit_node(ex.variable); add_space_after = true; } visit_node(ex.type_name); add_space_before = true; if (!(ex.statements is statement_list)) IncOffset(); visit_node(ex.statements); if (!(ex.statements is statement_list)) DecOffset(); } public override void visit(exception_ident _exception_ident) { throw new NotImplementedException(); } public override void visit(exception_handler_list _exception_handler_list) { foreach (exception_handler ex in _exception_handler_list.handlers) { visit_node(ex); } } public override void visit(exception_block _exception_block) { if (_exception_block.handlers != null) { IncOffset(); visit_node(_exception_block.handlers); DecOffset(); } if (_exception_block.stmt_list != null) { IncOffset(); visit_node(_exception_block.stmt_list); } if (_exception_block.else_stmt_list != null) { add_space_before = true; if (!(_exception_block.else_stmt_list.Count == 1 && _exception_block.else_stmt_list.list[0] is empty_statement)) { add_new_line_else_specific = true; IncOffset(); visit_node(_exception_block.else_stmt_list); } else { add_newline_after = false; } //DecOffset(); } } public override void visit(try_handler _try_handler) { throw new NotImplementedException(); } public override void visit(try_handler_finally _try_handler_finally) { _try_handler_finally.stmt_list.source_context = new SourceContext(_try_handler_finally.source_context.LeftSourceContext, _try_handler_finally.source_context.RightSourceContext); visit_node(_try_handler_finally.stmt_list); } public override void visit(try_handler_except _try_handler_except) { sb.Append("except"); SetKeywordOffset("except"); add_newline_after = true; visit_node(_try_handler_except.except_block); add_newline_after = false; } public override void visit(try_stmt _try_stmt) { WriteKeyword("try"); SetKeywordOffset("try"); add_newline_after = true; if (!contains_only_empty_statements(_try_stmt.stmt_list.subnodes)) { IncOffset(); visit_node(_try_stmt.stmt_list); } if (_try_stmt.handler is try_handler_except) { try_handler_except hndlr = _try_stmt.handler as try_handler_except; visit_node(_try_stmt.handler); if (hndlr.except_block.stmt_list != null && hndlr.except_block.stmt_list.subnodes.Count > 0 && contains_only_empty_statements(hndlr.except_block.stmt_list.subnodes)) { add_space_before = true; WriteNode(_try_stmt.handler, "except".Length); read_from_beg_pos = false; add_space_before = false; add_space_after = false; } } else if (_try_stmt.handler is try_handler_finally) { try_handler_finally hndlr = _try_stmt.handler as try_handler_finally; visit_node(_try_stmt.handler); } read_from_beg_pos = false; } private bool contains_only_empty_statements(List statements) { foreach (statement stmt in statements) if (!(stmt is empty_statement)) return false; return true; } public override void visit(inherited_message _inherited_message) { sb.Append("inherited"); } public override void visit(external_directive _external_directive) { sb.Append("external"); SetKeywordOffset("external"); if (_external_directive.modulename != null) { visit_node(_external_directive.modulename); } if (_external_directive.name != null) { add_space_before = true; add_space_after = true; visit_node(_external_directive.name); } add_space_before = false; add_space_after = false; read_from_beg_pos = false; } public override void visit(using_list _using_list) { throw new NotImplementedException(); } public override void visit(jump_stmt _jump_stmt) { throw new NotImplementedException(); } public override void visit(loop_stmt loop) { sb.Append("loop"); SetKeywordOffset("loop"); multiline_stack_push(loop.count); visit_node(loop.count); multiline_stack_pop(loop.count); if (!in_one_row(loop.stmt)) add_newline_after = true; add_space_before = true; //WriteKeyword(" do"); bool need_off = !(loop.stmt is statement_list); if (need_off) IncOffset(); visit_node(loop.stmt); if (need_off) DecOffset(); } public override void visit(foreach_stmt _foreach_stmt) { WriteKeyword("foreach"); SetKeywordOffset("foreach"); visit_node(_foreach_stmt.identifier); if (_foreach_stmt.type_name != null) { add_space_after = true; visit_node(_foreach_stmt.type_name); } add_space_after = true; add_space_before = true; visit_node(_foreach_stmt.in_what); if (!in_one_row(_foreach_stmt.stmt)) add_newline_after = true; add_space_before = true; bool need_off = !(_foreach_stmt.stmt is statement_list); if (need_off) IncOffset(); visit_node(_foreach_stmt.stmt); if (need_off) DecOffset(); } public override void visit(addressed_value_funcname _addressed_value_funcname) { throw new NotImplementedException(); } public override void visit(named_type_reference_list _named_type_reference_list) { for (int i = 0; i < _named_type_reference_list.types.Count; i++) { if (i > 0) add_space_after = true; visit_node(_named_type_reference_list.types[i]); } } public override void visit(template_param_list _template_param_list) { sb.Append("<"); for (int i = 0; i < _template_param_list.params_list.Count; i++) { if (i > 0 && !(_template_param_list.params_list[i] is named_type_reference && (_template_param_list.params_list[i] as named_type_reference).names.Count > 0 && (_template_param_list.params_list[i] as named_type_reference).names[0].name == "")) add_space_after = true; visit_node(_template_param_list.params_list[i]); } } public override void visit(template_type_reference _template_type_reference) { visit_node(_template_type_reference.name); visit_node(_template_type_reference.params_list); } public override void visit(int64_const _int64_const) { WriteNode(_int64_const); } public override void visit(uint64_const _uint64_const) { WriteNode(_uint64_const); } public override void visit(new_expr _new_expr) { sb.Append("new"); SetKeywordOffset("new"); visit_node(_new_expr.type); if (_new_expr.params_list != null && _new_expr.params_list.expressions[0].source_context != null) { skip_spaces_after = true; visit_node(_new_expr.params_list); } if (_new_expr.array_init_expr != null) visit_node(_new_expr.array_init_expr); } public override void visit(where_type_specificator_list _type_definition_list) { for (int i = 0; i < _type_definition_list.defs.Count; i++) { if (i > 0) add_space_after = true; visit_node(_type_definition_list.defs[i]); } } public override void visit(where_definition _where_definition) { sb.Append("where"); SetKeywordOffset("where"); visit_node(_where_definition.names); add_space_after = true; visit_node(_where_definition.types); } public override void visit(where_definition_list _where_definition_list) { foreach (where_definition wd in _where_definition_list.defs) { visit_node(wd); } } public override void visit(sizeof_operator _sizeof_operator) { sb.Append("sizeof"); SetKeywordOffset("sizeof"); add_space_before = false; read_from_beg_pos = true; if (_sizeof_operator.expr != null) visit_node(_sizeof_operator.expr); else if (_sizeof_operator.type_def != null) visit_node(_sizeof_operator.type_def); } public override void visit(typeof_operator _typeof_operator) { sb.Append("typeof"); SetKeywordOffset("typeof"); add_space_before = false; read_from_beg_pos = true; visit_node(_typeof_operator.type_name); } public override void visit(compiler_directive _compiler_directive) { throw new NotImplementedException(); } public override void visit(operator_name_ident _operator_name_ident) { WriteNodeAndReplaceOverSpaces(_operator_name_ident); } public override void visit(var_statement _var_statement) { sb.Append("var"); SetKeywordOffset("var"); visit_node(_var_statement.var_def); } public override void visit(question_colon_expression _question_colon_expression) { visit_node(_question_colon_expression.condition); add_space_before = true; add_space_after = true; visit_node(_question_colon_expression.ret_if_true); add_space_before = true; add_space_after = true; visit_node(_question_colon_expression.ret_if_false); } public override void visit(expression_as_statement _expression_as_statement) { visit_node(_expression_as_statement.expr); } public override void visit(c_scalar_type _c_scalar_type) { throw new NotImplementedException(); } public override void visit(c_module _c_module) { throw new NotImplementedException(); } public override void visit(declarations_as_statement _declarations_as_statement) { throw new NotImplementedException(); } public override void visit(array_size _array_size) { throw new NotImplementedException(); } public override void visit(enumerator _enumerator) { visit_node(_enumerator.name); if (_enumerator.value != null) { add_space_before = true; add_space_after = true; visit_node(_enumerator.value); } } public override void visit(enumerator_list _enumerator_list) { for (int i = 0; i < _enumerator_list.enumerators.Count; i++) { if (i > 0) add_space_after = true; visit_node(_enumerator_list.enumerators[i]); } } public override void visit(c_for_cycle _c_for_cycle) { throw new NotImplementedException(); } public override void visit(switch_stmt _switch_stmt) { throw new NotImplementedException(); } public override void visit(type_definition_attr_list _type_definition_attr_list) { throw new NotImplementedException(); } public override void visit(type_definition_attr _type_definition_attr) { throw new NotImplementedException(); } public override void visit(lock_stmt _lock_stmt) { sb.Append("lock"); SetKeywordOffset("lock"); multiline_stack_push(_lock_stmt.lock_object); visit_node(_lock_stmt.lock_object); multiline_stack_pop(_lock_stmt.lock_object); add_space_before = true; bool need_off = !(_lock_stmt.stmt is statement_list); if (!in_one_row(_lock_stmt.stmt)) add_newline_after = true; if (need_off) IncOffset(); visit_node(_lock_stmt.stmt); if (need_off) DecOffset(); } public override void visit(compiler_directive_list _compiler_directive_list) { throw new NotImplementedException(); } public override void visit(compiler_directive_if _compiler_directive_if) { throw new NotImplementedException(); } public override void visit(documentation_comment_list _documentation_comment_list) { throw new NotImplementedException(); } public override void visit(documentation_comment_tag _documentation_comment_tag) { throw new NotImplementedException(); } public override void visit(documentation_comment_tag_param _documentation_comment_tag_param) { throw new NotImplementedException(); } public override void visit(documentation_comment_section _documentation_comment_section) { throw new NotImplementedException(); } public override void visit(token_taginfo _token_taginfo) { throw new NotImplementedException(); } public override void visit(declaration_specificator _declaration_specificator) { sb.Append(_declaration_specificator.name); } public override void visit(ident_with_templateparams _ident_with_templateparams) { visit_node(_ident_with_templateparams.name); visit_node(_ident_with_templateparams.template_params); } public override void visit(template_type_name _template_type_name) { sb.Append(prepare_ident(_template_type_name.name)); sb.Append("<"); visit_node(_template_type_name.template_args); } public override void visit(default_operator _default_operator) { sb.Append("default"); SetKeywordOffset("default"); add_space_before = false; read_from_beg_pos = true; //sb.Append("("); visit_node(_default_operator.type_name); } public override void visit(bracket_expr _bracket_expr) { sb.Append("("); keyword_offset = 1; visit_node(_bracket_expr.expr); } public override void visit(attribute _attribute) { if (_attribute.qualifier != null) visit_node(_attribute.qualifier); visit_node(_attribute.type); if (_attribute.arguments != null) { //sb.Append("("); visit_node(_attribute.arguments); //sb.Append(")"); } } public override void visit(simple_attribute_list _simple_attribute_list) { sb.Append("["); for (int i = 0; i < _simple_attribute_list.attributes.Count; i++) { visit_node(_simple_attribute_list.attributes[i]); if (i < _simple_attribute_list.attributes.Count - 1) sb.Append(","); } } public override void visit(attribute_list _attribute_list) { foreach (simple_attribute_list sal in _attribute_list.attributes) visit_node(sal); } public override void visit(function_lambda_definition _function_lambda_definition) { multiline_stack_push(_function_lambda_definition); read_from_beg_pos = true; if (_function_lambda_definition.formal_parameters != null) WritePossibleCommentBefore(_function_lambda_definition.formal_parameters); add_space_before = false; if (_function_lambda_definition.formal_parameters != null) { is_lambda_parameters = true; visit_node(_function_lambda_definition.formal_parameters); keyword_offset = 0; read_from_beg_pos = false; } if (_function_lambda_definition.formal_parameters != null && Text[GetPosition(_function_lambda_definition.formal_parameters.source_context.end_position.line_num, _function_lambda_definition.formal_parameters.source_context.end_position.column_num)+1] != ')') add_space_before = true; int tmp_off = off; visit_node(_function_lambda_definition.proc_body); multiline_stack_pop(_function_lambda_definition); off = tmp_off; } public override void visit(function_lambda_call _function_lambda_call) { // } public override void visit(semantic_check _semantic_check) { } public override void visit(lambda_inferred_type lit) //lroman// { } public override void visit(same_type_node stn) //SS 22/06/13// { } public override void visit(name_assign_expr _name_assign_expr) // SSM 27.06.13 { multiline_stack_push(_name_assign_expr); if (_name_assign_expr.name.source_context.Eq(_name_assign_expr.expr.source_context)) { visit_node(_name_assign_expr.expr); } else { visit_node(_name_assign_expr.name); //sb.Append(" := "); add_space_before = true; add_space_after = true; visit_node(_name_assign_expr.expr); } multiline_stack_pop(_name_assign_expr); } public override void visit(name_assign_expr_list _name_assign_expr_list) // SSM 27.06.13 { if (_name_assign_expr_list.name_expr != null) for (int i = 0; i < _name_assign_expr_list.name_expr.Count; i++) { if (i > 0 && options.SpaceBetweenIdentifiers == 1) add_space_after = true; visit_node(_name_assign_expr_list.name_expr[i]); } } public override void visit(unnamed_type_object _unnamed_type_object) // SSM 27.06.13 { //sb.Append("new"); //SetKeywordOffset("new"); read_from_beg_pos = true; visit_node(_unnamed_type_object.ne_list); } public override void visit(semantic_type_node stn) // SSM { } public override void visit(matching_expression _matching_expression) { visit_node(_matching_expression.left); visit_node(_matching_expression.right); } public override void visit(short_func_definition _short_func_definition) { multiline_stack_push(_short_func_definition); add_space_after = true; if (_short_func_definition.Parent is class_members && (_short_func_definition.Parent as class_members).access_mod != null && (_short_func_definition.Parent as class_members).access_mod.source_context != null) add_space_before = true; add_newline_after = false; int cur_off = tab; visit_node(_short_func_definition.procdef.proc_header); bool tmp_in_procedure = in_procedure; in_procedure = true; //sb.Append(":="); add_space_before = true; add_space_after = true; visit_node(_short_func_definition.procdef.proc_body); //if (!(_short_func_definition.procdef.proc_header is constructor)) IncOffset(); in_procedure = tmp_in_procedure; multiline_stack_pop(_short_func_definition); } public override void visit(sequence_type _sequence_type) { visit_node(_sequence_type.elements_type); } public override void visit(modern_proc_type _modern_proc_type) { if (_modern_proc_type.aloneparam != null) { visit_node(_modern_proc_type.aloneparam); add_space_before = false; add_space_after = false; visit_node(_modern_proc_type.res); } else { if (_modern_proc_type.el == null && _modern_proc_type.res == null) { int beg_pos = GetPosition(_modern_proc_type.source_context.begin_position.line_num, _modern_proc_type.source_context.begin_position.column_num); int end_pos = GetPosition(_modern_proc_type.source_context.end_position.line_num, _modern_proc_type.source_context.end_position.column_num); sb.Append(Text.Substring(beg_pos, end_pos - beg_pos + 1)); } else { if (_modern_proc_type.el != null && _modern_proc_type.el.enumerators != null) { sb.Append("("); for (int i = 0; i < _modern_proc_type.el.enumerators.Count; i++) { visit_node(_modern_proc_type.el.enumerators[i]); } } else read_from_beg_pos = true; add_space_before = false; add_space_after = false; visit_node(_modern_proc_type.res); } } } public override void visit(tuple_node _tuple_node) { sb.Append("("); visit_node(_tuple_node.el); } public override void visit(uses_closure uc) { foreach (var ul in uc.listunitsections) { visit_node(ul); } } public override void visit(assign_tuple at) { //multiline_stack_push(at); visit_node(at.vars); add_space_after = true; visit_node(at.expr); //multiline_stack_pop(at); } public override void visit(addressed_value_list al) { sb.Append("("); var i = 0; foreach (var av in al.variables) { visit_node(av); add_space_after = true; i++; } } public override void visit(yield_node yn) { sb.Append("yield "); visit_node(yn.ex); } public override void visit(yield_sequence_node yn) { sb.Append("yield sequence "); visit_node(yn.ex); } public override void visit(assign_var_tuple _assign_var_tuple) { read_from_beg_pos = true; for (int i = 0; i < _assign_var_tuple.idents.idents.Count; i++) { if (options.SpaceBetweenArguments == 1 && i > 0) { add_space_after = true; } visit_node(_assign_var_tuple.idents.idents[i]); } sb.Append(")"); add_space_after = true; add_space_before = true; prev_sn = _assign_var_tuple.idents; visit_node(_assign_var_tuple.expr); } public override void visit(slice_expr _slice_expr) { visit_node(_slice_expr.v); if (_slice_expr.from != null) visit_node(_slice_expr.from); if (_slice_expr.to != null) visit_node(_slice_expr.to); if (_slice_expr.step != null) visit_node(_slice_expr.step); } public override void visit(slice_expr_question _slice_expr_question) { visit_node(_slice_expr_question.v); if (_slice_expr_question.from != null) visit_node(_slice_expr_question.from); if (_slice_expr_question.to != null) visit_node(_slice_expr_question.to); if (_slice_expr_question.step != null) visit_node(_slice_expr_question.step); } public override void visit(index _index) { if (_index.inverted) sb.Append("^"); visit_node(_index.index_expr); } public override void visit(is_pattern_expr _is_pattern_expr) { if (_is_pattern_expr.left != null) visit_node(_is_pattern_expr.left); if (_is_pattern_expr.right == null || !(_is_pattern_expr.right is collection_pattern) && !(_is_pattern_expr.right is tuple_pattern)) sb.Append(" is "); else add_space_before = true; if (_is_pattern_expr.right != null) visit_node(_is_pattern_expr.right); } public override void visit(type_pattern _type_pattern) { if (_type_pattern.type != null) visit_node(_type_pattern.type); } public override void visit(match_with _match_with) { sb.Append("match"); SetKeywordOffset("match"); visit_node(_match_with.expr); IncOffset(); add_space_before = true; visit_node(_match_with.case_list); DecOffset(); } public override void visit(pattern_cases _pattern_cases) { foreach (var patternCase in _pattern_cases.elements) visit_node(patternCase); } public override void visit(pattern_case _pattern_case) { visit_node(_pattern_case.pattern); if (_pattern_case.condition != null) { add_space_before = true; visit_node(_pattern_case.condition); } add_space_after = true; IncOffset(); visit_node(_pattern_case.case_action); DecOffset(); } public override void visit(const_pattern _const_pattern) { visit_node(_const_pattern.pattern_expressions); add_space_after = false; } public override void visit(const_pattern_parameter _const_parameter) { visit_node(_const_parameter.const_param); add_space_after = false; } public override void visit(wild_card_deconstructor_parameter _wild_card_deconstructor_parameter) { sb.Append("_"); add_space_after = true; } public override void visit(tuple_pattern_var_parameter _tuple_pattern_var_parameter) { sb.Append("var"); SetKeywordOffset("var"); read_from_beg_pos = true; visit_node(_tuple_pattern_var_parameter.identifier); } public override void visit(tuple_pattern_wild_card _tuple_pattern_wild_card) { sb.Append("_"); add_space_after = true; } public override void visit(tuple_pattern _tuple_pattern) { sb.Append("("); foreach (var parameter in _tuple_pattern.parameters) { visit_node(parameter); add_space_after = true; } add_space_after = false; } public override void visit(collection_pattern _collection_pattern) { sb.Append("["); foreach (var parameter in _collection_pattern.parameters) { visit_node(parameter); add_space_after = true; } add_space_after = false; } public override void visit(collection_pattern_gap_parameter _collection_pattern_gap_parameter) { sb.Append(".."); add_space_after = true; } public override void visit(collection_pattern_var_parameter _collection_pattern_var_parameter) { sb.Append("var"); SetKeywordOffset("var"); read_from_beg_pos = true; visit_node(_collection_pattern_var_parameter.identifier); } public override void visit(collection_pattern_wild_card _collection_pattern_wild_card) { sb.Append("_"); add_space_after = true; } public override void visit(deconstructor_pattern _deconstructor_pattern) { visit_node(_deconstructor_pattern.type); foreach (var parameter in _deconstructor_pattern.parameters) { visit_node(parameter); add_space_after = true; } add_space_after = false; } public override void visit(var_deconstructor_parameter _var_deconstructor_parameter) { if (_var_deconstructor_parameter.var_keyword_used) { sb.Append("var"); SetKeywordOffset("var"); read_from_beg_pos = true; } visit_node(_var_deconstructor_parameter.identifier); if (_var_deconstructor_parameter.type != null) visit_node(_var_deconstructor_parameter.type); } public override void visit(recursive_pattern_parameter _recursive_pattern_parameter) { visit_node(_recursive_pattern_parameter.pattern); } public override void visit(recursive_deconstructor_parameter _recursive_deconstructor_parameter) { visit_node(_recursive_deconstructor_parameter.pattern); } public override void visit(recursive_tuple_parameter _recursive_tuple_parameter) { visit_node(_recursive_tuple_parameter.pattern); } public override void visit(recursive_collection_parameter _recursive_collection_parameter) { visit_node(_recursive_collection_parameter.pattern); } public override void visit(var_tuple_def_statement _var_tuple_def_statement) { sb.Append("("); SetKeywordOffset("("); read_from_beg_pos = true; visit_node(_var_tuple_def_statement.vars); if (_var_tuple_def_statement.vars_type != null) { add_space_after = true; visit_node(_var_tuple_def_statement.vars_type); } if (_var_tuple_def_statement.inital_value != null) { add_space_after = true; add_space_before = true; visit_node(_var_tuple_def_statement.inital_value); } } public override void visit(dot_question_node _dot_question_node) { visit_node(_dot_question_node.left); visit_node(_dot_question_node.right); } public override void visit(diapason_expr_new diap) { visit_node(diap.left); visit_node(diap.right); } public override void visit(if_expr_new _if_expr_new) { sb.Append("if"); //sb.Append(" "); SetKeywordOffset("if"); read_from_beg_pos = true; visit_node(_if_expr_new.condition); if (!in_one_row(_if_expr_new.condition)) add_newline_after = true; add_space_before = true; visit_node(_if_expr_new.if_true); if (_if_expr_new.if_false != null) { add_space_before = true; visit_node(_if_expr_new.if_false); } } public override void visit(array_const_new acn) { sb.Append("|"); visit_node(acn.elements); //sb.Append("|"); } public override void visit(double_question_node dn) { visit_node(dn.left); visit_node(dn.right); } public override void visit(bigint_const bi) { visit(new uint64_const(bi.val, bi.source_context)); //sb.Append("bi"); } public override void visit(foreach_stmt_formatting fe) { WriteKeyword("foreach"); SetKeywordOffset("foreach"); sb.Append(" var ("); visit_node(fe.il); add_space_after = true; add_space_before = true; visit_node(fe.in_what); if (!in_one_row(fe.stmt)) add_newline_after = true; add_space_before = true; bool need_off = !(fe.stmt is statement_list); if (need_off) IncOffset(); visit_node(fe.stmt); if (need_off) DecOffset(); } #endregion } }