internal void Rehighlight(MslDocument document, int startLine, bool force) { for (int i = startLine; i < document.TextBox.LinesCount; ++i) { var oldResult = document.GetLineInfo(i); var result = MslSyntaxHighlighter.Highlight(document.TextBox, i, document.Type); if (!force && result.Matches(oldResult)) { break; } // Skip past continued lines. while (i < document.TextBox.LinesCount && document.lineInfoTable.TryGetValue(document.TextBox[i].UniqueId, out result) && result.State == (byte)MslSyntaxHighlighter.ParseStateIndex.Continuation) { ++i; } } }
internal static int Main(string[] args) { string[] files = null; int result = 0; int errors = 0, warnings = 0, notices = 0; ErrorType level = ErrorType.Note; if (args.Length == 1) { Console.WriteLine("Usage: MScripter-Verify <files>"); Console.WriteLine(); return(1); } for (int i = 0; i < args.Length; ++i) { if (args[i] == "--" || !args[i].StartsWith("-")) { ++i; files = new string[args.Length - i]; Array.Copy(args, i, files, 0, files.Length); break; } } foreach (var file in files) { try { var document = MslDocument.FromFile(file); for (int lineIndex = 0; lineIndex < document.TextBox.LinesCount; ++lineIndex) { var lineInfo = MslSyntaxHighlighter.Highlight(document.TextBox, lineIndex, document.Type); string label = "Error "; foreach (var error in lineInfo.errors) { switch (error.Type) { case ErrorType.Error: label = "Error "; ++errors; break; case ErrorType.Warning: label = "Warning"; ++warnings; break; case ErrorType.Note: label = "Notice "; ++notices; break; } if (error.Type <= level) { Console.WriteLine(label + " in file " + Path.GetFileName(document.Path) + ":" + (error.Location.FromLine + 1) + ": " + error.Text); Console.WriteLine(" " + document.TextBox[error.Location.FromLine].Text); Console.WriteLine(new string(' ', error.Location.Start.iChar + 2) + "^"); Console.WriteLine(); switch (error.Type) { case ErrorType.Error: if (result < 4) { result = 4; } break; case ErrorType.Warning: if (result < 3) { result = 3; } break; case ErrorType.Note: if (result < 2) { result = 2; } break; } } while (document.lineInfoTable.TryGetValue(document.TextBox[lineIndex].UniqueId, out lineInfo) && lineInfo.State == (byte)MslSyntaxHighlighter.ParseStateIndex.Continuation) { ++lineIndex; } } } } catch (IOException ex) { Console.WriteLine("Error opening file " + Path.GetFileName(file) + ": " + ex.Message); Console.WriteLine(); result = 5; } } Console.WriteLine($"Analysis complete: {errors} error(s), {warnings} warning(s), {notices} notice(s)."); return(result); }
private void mSLSyntaxHighlight(FastColoredTextBox sender, Range range, DocumentType syntaxType) { range.ClearStyle(MslSyntaxHighlighter.CommandStyle, MslSyntaxHighlighter.CommentStyle, MslSyntaxHighlighter.CustomCommandStyle, MslSyntaxHighlighter.ErrorStyle, MslSyntaxHighlighter.FunctionStyle, MslSyntaxHighlighter.FunctionPropertyStyle, MslSyntaxHighlighter.KeywordStyle, MslSyntaxHighlighter.AliasStyle, MslSyntaxHighlighter.VariableStyle); // Highlight the text. bool bookmarksChanged = false; bool errorsChanged = false; // If the changed line was a continuation, find the start. int i = range.FromLine; LineInfo lineInfo; while (i != 0 && this.lineInfoTable.TryGetValue(this.TextBox[i - 1].UniqueId, out lineInfo) && lineInfo.State == (byte)MslSyntaxHighlighter.ParseStateIndex.Continuation) { --i; } for (; i < range.tb.LinesCount; ++i) { LineInfo oldLineInfo; MslBookmark oldBookmark = null; string oldTitle = null; if (this.lineInfoTable.TryGetValue(range.tb[i].UniqueId, out oldLineInfo)) { oldBookmark = oldLineInfo.bookmark; oldTitle = oldBookmark?.title; } var newLineInfo = MslSyntaxHighlighter.Highlight(range.tb, i, syntaxType); if (this.Type != DocumentType.Text) { // Deal with bookmarks. if (oldBookmark != null) { if (newLineInfo.bookmark != null) { if (oldBookmark != newLineInfo.bookmark) { // A bookmark was replaced. this.bookmarks[this.bookmarks.IndexOf(oldBookmark)] = newLineInfo.bookmark; bookmarksChanged = true; } else if (oldTitle != newLineInfo.bookmark.title) { // A bookmark was renamed. this.BookmarkChanged?.Invoke(this, new BookmarkEventArgs(newLineInfo.bookmark)); } } else { // A bookmark was removed. this.bookmarks.Remove(oldLineInfo.bookmark); bookmarksChanged = true; } } else { if (newLineInfo?.bookmark != null) { // A bookmark was added. this.bookmarks.Add(newLineInfo.bookmark); bookmarksChanged = true; } } } if (this.Type != DocumentType.Text && this.Type != DocumentType.INI) { if (oldLineInfo != null && oldLineInfo.errors.Length != 0) { errorsChanged = true; foreach (var error in oldLineInfo.errors) { this.errors.Remove(error); } } // Skip past continued lines. while (i < range.tb.LinesCount && this.lineInfoTable.TryGetValue(this.TextBox[i].UniqueId, out lineInfo) && lineInfo.State == (byte)MslSyntaxHighlighter.ParseStateIndex.Continuation) { // Always reparse the next line if there is a continuation. // This avoids glitches when continuations are added or removed. oldLineInfo = null; ++i; if (lineInfo.errors.Length != 0) { errorsChanged = true; } foreach (Error error in lineInfo.errors) { this.errors.Remove(error); } } // Deal with errors. if (newLineInfo != null && newLineInfo.errors.Length != 0) { errorsChanged = true; foreach (var error in newLineInfo.errors) { this.errors.Add(error); } } // (Normally we only reparse the next line if it was changed, or the current line was changed in such // a way as to affect its meaning, such as adding braces.) if (i >= range.ToLine && oldLineInfo != null && newLineInfo.BraceLevel == oldLineInfo.BraceLevel && newLineInfo.State == oldLineInfo.State) { break; } } else { // Such cascading isn't an issue for INI files. if (i >= range.ToLine) { break; } } } if (bookmarksChanged) { //functionList.Items.Clear(); //if (currentItem == document) RebuildFunctionList(); } if (errorsChanged) { //errorList.Items.Clear(); //RebuildErrorList(); } range.SetStyle(ControlCharStyle.Instance, @"[\x01-\x03\x0F\x13\x16\x1C\x1F]"); range.ClearFoldingMarkers(); range.SetFoldingMarkers("(?<![^ :\r\n]){(?![^ \r\n])", "(?<![^ \r\n])}(?![^ \r\n])"); this.TextChanged?.Invoke(this, new TextChangedEventArgs(range)); }