Sfall-ScriptEditor
199 строк · 8.5 Кб
1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Drawing;6
7using ICSharpCode.TextEditor;8using ICSharpCode.TextEditor.Document;9
10using ScriptEditor.TextEditorUI;11
12namespace ScriptEditor.TextEditorUtilities13{
14internal static class MessageStructure15{16const int Open = 0, Close = 1;17static char[] Curves = new char[] { '{', '}' };18
19public static List<Error> CheckStructure(TextAreaControl TAC, string file)20{21TAC.Document.MarkerStrategy.RemoveAll(delegate(TextMarker tm) { return true; });22
23int openCurve = 0, closeCurve = 0;24
25int[] openOffsetCurve = new int[2];26int closeOffsetCurve = 0;27
28int offsetError = -1;29int offsetOpen = -1;30int openCount = 0;31
32//bool errorOpenCurve = false, errorCloseCurve = false;33bool only_once = false, new_line = false;34
35List<int> numbersLine = new List<int>();36
37List<int> warning_comment = new List<int>();38List<Error> error_number = new List<Error>();39List<Error> warning = new List<Error>();40List<Error> report = new List<Error>();41
42char[] chars = new char[] { '.', ',', '!', '?'};43
44int len = TAC.Document.TextContent.Length;45for (int offset = 0; offset < len; offset++)46{47char ch = TAC.Document.TextContent[offset];48if (ch == '\r' || ch == '\n') {49//Check whitespace on new line50if (!new_line && openCurve == 1 && closeCurve == 0 && openCount == 3) {51int i = -1;52bool ws = false;53do {54ws = (TAC.Document.TextContent[offset + i] == ' ');55i++;56} while (!ws && i < 3);57if (!ws)58warning.Add(new Error(ErrorType.Message, "New line the whitespace character is missing.", null, offset - 1));59}60new_line = true;61only_once = false;62continue;63}64
65if (ch == Curves[Open]) {66openOffsetCurve[1] = openOffsetCurve[0];67openOffsetCurve[0] = offset;68openCurve++;69if (closeCurve > 0)70closeCurve--;71
72openCount++;73if (openCount == 1) //записываем offset кавычки в первой группе74offsetOpen = offset + 1;75
76} else if (ch == Curves[Close]) {77closeOffsetCurve = offset;78closeCurve++;79openCurve--;80
81if (openCount == 1) { //проверка корректности номера строки в первой группе кавычек82int ln = offset - offsetOpen;83string str = TAC.Document.GetText(offsetOpen, ln);84
85if (str.Trim().Length > 0) {86int number;87if (int.TryParse(str, out number) && number > 0) {88if (numbersLine.Contains(number))89error_number.Add(new Error(90ErrorType.Warning, "Duplicate message line number: " + number, null, offsetOpen, ln));91else92numbersLine.Add(number);93} else94error_number.Add(new Error(95ErrorType.Error, "Invalid line number of the message.", null, offsetOpen, ln));96} else97error_number.Add(new Error(98ErrorType.Error, "Missing line number of the message.", null, offsetOpen, ln));99
100} else if (openCount == 3)101openCount = 0;102}103
104if (closeCurve > 1) {105//errorOpenCurve = true;106offsetError = closeOffsetCurve;107break;108}109if (openCurve > 1) {110//errorCloseCurve = true;111offsetError = openOffsetCurve[1];112break;113} else if (openCurve < 0) {114//errorCloseCurve = true;115offsetError = closeOffsetCurve;116break;117}118
119//Check whitespace on punctuation120if (openCurve == 1 && closeCurve == 0 && Utilities.IsAnyChar(ch, chars)) {121char chCheck = TAC.Document.TextContent[offset + 1];122if (char.IsLetter(chCheck))123warning.Add(new Error(ErrorType.Message, "The whitespace character is missing.", null, offset));124
125if (char.IsWhiteSpace(chCheck) && TAC.Document.TextContent[offset - 1] != chars[0]126&& TAC.Document.TextContent[offset] != chars[1] && char.IsLower(TAC.Document.TextContent, offset + 2))127warning.Add(new Error(ErrorType.Message, "The sentence begins with a small letter instead of the capital letter.", null, offset + 2));128}129
130// Comment check characters131if (openCurve == 0 && closeCurve == 1) {132if (!only_once && !char.IsWhiteSpace(ch) && ch != Curves[Open] && ch != Curves[Close]) {133only_once = true;134if (ch != '#')135warning_comment.Add(offset);136}137} else138only_once = false;139
140new_line = false;141}142
143#region Build reporting error144foreach (Error error in error_number)145{146TextLocation tLoc = TAC.Document.OffsetToPosition(error.line);147if (error.column == 0) {148error.column = 2;149error.line--;150}151TextMarker tm = new TextMarker(error.line, error.column, TextMarkerType.WaveLine, Color.Red);152tm.ToolTip = error.message;153TAC.Document.MarkerStrategy.AddMarker(tm);154
155report.Add(new Error(error.type, error.message, file, tLoc.Line + 1, tLoc.Column));156if (report.Count == 1)157TAC.Caret.Position = tLoc;158}159
160if (offsetError > -1) {161TextLocation tLoc = TAC.Document.OffsetToPosition(offsetError);162TAC.Caret.Position = tLoc;163LineSegment ls = TAC.Document.GetLineSegment(tLoc.Line);164TextMarker tm = new TextMarker(ls.Offset, ls.Length, TextMarkerType.WaveLine, Color.Red);165tm.ToolTip = "Wrong structure of the paired curves brackets.";166TAC.Document.MarkerStrategy.AddMarker(tm);167
168report.Add(new Error(ErrorType.Error, tm.ToolTip, file, tLoc.Line + 1, 0));169}170
171foreach (Error error in warning)172{173TextMarker tm = new TextMarker(error.line - 1, 3, TextMarkerType.WaveLine, Color.Blue);174tm.ToolTip = error.message; //"The white space character is missing.";175TAC.Document.MarkerStrategy.AddMarker(tm);176
177TextLocation tl = TAC.Document.OffsetToPosition(error.line);178report.Add(new Error(error.type, error.message, file, tl.Line + 1, tl.Column));179}180
181foreach (int offset in warning_comment)182{183TextLocation tLoc = TAC.Document.OffsetToPosition(offset);184LineSegment ls = TAC.Document.GetLineSegment(tLoc.Line);185int length = offset - ls.Offset;186length = ls.Length - length;187TextMarker tm = new TextMarker(offset, length, TextMarkerType.Underlined, Color.ForestGreen);188tm.ToolTip = "Missing '#' character of comment?";189TAC.Document.MarkerStrategy.AddMarker(tm);190
191report.Add(new Error(ErrorType.None, tm.ToolTip, file, tLoc.Line + 1, tLoc.Column));192}193#endregion194
195TAC.Refresh();196return report;197}198}199}
200