From 617d68f7e99d1b5abc3b1b723d4905128619a792 Mon Sep 17 00:00:00 2001 From: Sinai Date: Tue, 11 May 2021 01:43:08 +1000 Subject: [PATCH] rename Lexer folder to match namespace, some cleanups and color adjustments --- src/UI/CSConsole/Lexer/KeywordLexer.cs | 48 ----------- src/UI/CSConsole/Lexer/StringLexer.cs | 59 -------------- .../{Lexer => Lexers}/CommentLexer.cs | 1 + src/UI/CSConsole/Lexers/KeywordLexer.cs | 59 ++++++++++++++ src/UI/CSConsole/{Lexer => Lexers}/Lexer.cs | 0 .../{Lexer => Lexers}/NumberLexer.cs | 1 + src/UI/CSConsole/Lexers/StringLexer.cs | 80 +++++++++++++++++++ .../{Lexer => Lexers}/SymbolLexer.cs | 21 ++--- src/UI/Panels/CSConsolePanel.cs | 2 +- src/UI/Widgets/AutoComplete/TypeCompleter.cs | 14 ++-- src/UnityExplorer.csproj | 12 +-- 11 files changed, 166 insertions(+), 131 deletions(-) delete mode 100644 src/UI/CSConsole/Lexer/KeywordLexer.cs delete mode 100644 src/UI/CSConsole/Lexer/StringLexer.cs rename src/UI/CSConsole/{Lexer => Lexers}/CommentLexer.cs (98%) create mode 100644 src/UI/CSConsole/Lexers/KeywordLexer.cs rename src/UI/CSConsole/{Lexer => Lexers}/Lexer.cs (100%) rename src/UI/CSConsole/{Lexer => Lexers}/NumberLexer.cs (97%) create mode 100644 src/UI/CSConsole/Lexers/StringLexer.cs rename src/UI/CSConsole/{Lexer => Lexers}/SymbolLexer.cs (55%) diff --git a/src/UI/CSConsole/Lexer/KeywordLexer.cs b/src/UI/CSConsole/Lexer/KeywordLexer.cs deleted file mode 100644 index eeca41f..0000000 --- a/src/UI/CSConsole/Lexer/KeywordLexer.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; - -namespace UnityExplorer.UI.CSharpConsole.Lexers -{ - public class KeywordLexer : Lexer - { - private readonly HashSet keywords = new HashSet - { "add", "as", "ascending", "await", "bool", "break", "by", "byte", -"case", "catch", "char", "checked", "const", "continue", "decimal", "default", "descending", "do", "dynamic", -"else", "equals", "false", "finally", "float", "for", "foreach", "from", "global", "goto", "group", "if", "in", -"int", "into", "is", "join", "let", "lock", "long", "new", "null", "object", "on", "orderby", "out", "ref", -"remove", "return", "sbyte", "select", "short", "sizeof", "stackalloc", "string", "switch", "throw", "true", -"try", "typeof", "uint", "ulong", "ushort", "var", "where", "while", "yield", "abstract", "async", "base", -"class", "delegate", "enum", "explicit", "extern", "fixed", "get", "implicit", "interface", "internal", -"namespace", "operator", "override", "params", "private", "protected", "public", "using", "partial", "readonly", -"sealed", "set", "static", "struct", "this", "unchecked", "unsafe", "value", "virtual", "volatile", "void" }; - - protected override Color HighlightColor => new Color(0.33f, 0.61f, 0.83f, 1.0f); - - public override bool TryMatchCurrent(LexerBuilder lexer) - { - if (!lexer.IsDelimiter(lexer.Previous, true)) - return false; - - var sb = new StringBuilder(); - while (!lexer.EndOfInput) - { - sb.Append(lexer.Current); - var next = lexer.PeekNext(); - if (lexer.IsDelimiter(next, true)) - { - lexer.RollbackBy(1); - break; - } - } - - if (keywords.Contains(sb.ToString())) - { - lexer.Commit(); - return true; - } - - return false; - } - } -} diff --git a/src/UI/CSConsole/Lexer/StringLexer.cs b/src/UI/CSConsole/Lexer/StringLexer.cs deleted file mode 100644 index 079a981..0000000 --- a/src/UI/CSConsole/Lexer/StringLexer.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace UnityExplorer.UI.CSharpConsole.Lexers -{ - public class StringLexer : Lexer - { - protected override Color HighlightColor => new Color(0.79f, 0.52f, 0.32f, 1.0f); - - public override IEnumerable Delimiters => new[] { '"' }; - - public override bool TryMatchCurrent(LexerBuilder lexer) - { - if (lexer.Current != '"') - return false; - - if (lexer.Previous == '@') - { - // verbatim string, continue until un-escaped quote. - while (!lexer.EndOfInput) - { - lexer.Commit(); - if (lexer.PeekNext() == '"') - { - lexer.Commit(); - // possibly the end, check for escaped quotes. - // commit the character and flip the escape bool for each quote. - bool escaped = false; - while (lexer.PeekNext() == '"') - { - lexer.Commit(); - escaped = !escaped; - } - // if the last quote wasnt escaped, that was the end of the string. - if (!escaped) - break; - } - } - } - else - { - // normal string - // continue until a quote which is not escaped, or end of input - - while (!lexer.EndOfInput) - { - lexer.Commit(); - if (lexer.PeekNext() == '"' && lexer.Previous != '\\') - { - lexer.Commit(); - break; - } - } - } - - return true; - } - } -} diff --git a/src/UI/CSConsole/Lexer/CommentLexer.cs b/src/UI/CSConsole/Lexers/CommentLexer.cs similarity index 98% rename from src/UI/CSConsole/Lexer/CommentLexer.cs rename to src/UI/CSConsole/Lexers/CommentLexer.cs index 24dfbe9..bd903e7 100644 --- a/src/UI/CSConsole/Lexer/CommentLexer.cs +++ b/src/UI/CSConsole/Lexers/CommentLexer.cs @@ -12,6 +12,7 @@ namespace UnityExplorer.UI.CSharpConsole.Lexers Block } + // forest green protected override Color HighlightColor => new Color(0.34f, 0.65f, 0.29f, 1.0f); public override bool TryMatchCurrent(LexerBuilder lexer) diff --git a/src/UI/CSConsole/Lexers/KeywordLexer.cs b/src/UI/CSConsole/Lexers/KeywordLexer.cs new file mode 100644 index 0000000..1de9fd8 --- /dev/null +++ b/src/UI/CSConsole/Lexers/KeywordLexer.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Text; +using UnityEngine; + +namespace UnityExplorer.UI.CSharpConsole.Lexers +{ + public class KeywordLexer : Lexer + { + // system blue + protected override Color HighlightColor => new Color(0.33f, 0.61f, 0.83f, 1.0f); + + private readonly HashSet keywords = new HashSet + { +// reserved keywords +"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", +"decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", +"fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", +"long", "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public", +"readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", +"this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", +"volatile", "while", +// contextual keywords +"add", "and", "alias", "ascending", "async", "await", "by", "descending", "dynamic", "equals", "from", "get", +"global", "group", "init", "into", "join", "let", "managed", "nameof", "not", "notnull", "on", +"or", "orderby", "partial", "record", "remove", "select", "set", "unmanaged", "value", "var", "when", "where", +"where", "with", "yield", "nint", "nuint" + }; + + public override bool TryMatchCurrent(LexerBuilder lexer) + { + var prev = lexer.Previous; + var first = lexer.Current; + + // check for keywords + if (lexer.IsDelimiter(prev, true) && char.IsLetter(first)) + { + // can be a keyword... + + var sb = new StringBuilder(); + sb.Append(lexer.Current); + while (!lexer.EndOfInput && char.IsLetter(lexer.PeekNext())) + sb.Append(lexer.Current); + + if (keywords.Contains(sb.ToString())) + { + if (!lexer.EndOfInput) + lexer.RollbackBy(1); + lexer.Commit(); + return true; + } + + return false; + + } + else + return false; + } + } +} diff --git a/src/UI/CSConsole/Lexer/Lexer.cs b/src/UI/CSConsole/Lexers/Lexer.cs similarity index 100% rename from src/UI/CSConsole/Lexer/Lexer.cs rename to src/UI/CSConsole/Lexers/Lexer.cs diff --git a/src/UI/CSConsole/Lexer/NumberLexer.cs b/src/UI/CSConsole/Lexers/NumberLexer.cs similarity index 97% rename from src/UI/CSConsole/Lexer/NumberLexer.cs rename to src/UI/CSConsole/Lexers/NumberLexer.cs index 8cc9ccb..542ff30 100644 --- a/src/UI/CSConsole/Lexer/NumberLexer.cs +++ b/src/UI/CSConsole/Lexers/NumberLexer.cs @@ -4,6 +4,7 @@ namespace UnityExplorer.UI.CSharpConsole.Lexers { public class NumberLexer : Lexer { + // Maroon protected override Color HighlightColor => new Color(0.58f, 0.33f, 0.33f, 1.0f); private bool IsNumeric(char c) => char.IsNumber(c) || c == '.'; diff --git a/src/UI/CSConsole/Lexers/StringLexer.cs b/src/UI/CSConsole/Lexers/StringLexer.cs new file mode 100644 index 0000000..403f1af --- /dev/null +++ b/src/UI/CSConsole/Lexers/StringLexer.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UnityExplorer.UI.CSharpConsole.Lexers +{ + public class StringLexer : Lexer + { + public override IEnumerable Delimiters => new[] { '"', '\'', }; + + // orange + protected override Color HighlightColor => new Color(0.79f, 0.52f, 0.32f, 1.0f); + + public override bool TryMatchCurrent(LexerBuilder lexer) + { + if (lexer.Current == '"') + { + if (lexer.Previous == '@') + { + // verbatim string, continue until un-escaped quote. + while (!lexer.EndOfInput) + { + lexer.Commit(); + if (lexer.PeekNext() == '"') + { + lexer.Commit(); + // possibly the end, check for escaped quotes. + // commit the character and flip the escape bool for each quote. + bool escaped = false; + while (lexer.PeekNext() == '"') + { + lexer.Commit(); + escaped = !escaped; + } + // if the last quote wasnt escaped, that was the end of the string. + if (!escaped) + break; + } + } + } + else + { + // normal string + // continue until a quote which is not escaped, or end of input + + while (!lexer.EndOfInput) + { + lexer.Commit(); + lexer.PeekNext(); + if ((lexer.Current == '"') && lexer.Previous != '\\') + { + lexer.Commit(); + break; + } + } + } + + return true; + } + else if (lexer.Current == '\'') + { + // char + + while (!lexer.EndOfInput) + { + lexer.Commit(); + lexer.PeekNext(); + if ((lexer.Current == '\'') && lexer.Previous != '\\') + { + lexer.Commit(); + break; + } + } + + return true; + } + else + return false; + } + } +} diff --git a/src/UI/CSConsole/Lexer/SymbolLexer.cs b/src/UI/CSConsole/Lexers/SymbolLexer.cs similarity index 55% rename from src/UI/CSConsole/Lexer/SymbolLexer.cs rename to src/UI/CSConsole/Lexers/SymbolLexer.cs index c939e35..58c4bc3 100644 --- a/src/UI/CSConsole/Lexer/SymbolLexer.cs +++ b/src/UI/CSConsole/Lexers/SymbolLexer.cs @@ -7,17 +7,20 @@ namespace UnityExplorer.UI.CSharpConsole.Lexers { public class SymbolLexer : Lexer { - protected override Color HighlightColor => Color.white; + // silver + protected override Color HighlightColor => new Color(0.6f, 0.6f, 0.6f); // all symbols are delimiters - public override IEnumerable Delimiters => uniqueSymbols; + public override IEnumerable Delimiters => symbols; - // all symbol combinations are made of valid individual symbols. - private readonly HashSet uniqueSymbols = new HashSet + private readonly HashSet symbols = new HashSet { - '[', ']', '{', '}', '(', ')', ',', '.', ';', ':', - '+', '-', '*', '/', '%', '&', '|', '^', '~', '=', - '<', '>', '?', '!', '@' + '[', '{', '(', // open + ']', '}', ')', // close + '.', ',', ';', ':', '?', '@', // special + + // operators + '+', '-', '*', '/', '%', '&', '|', '^', '~', '=', '<', '>', '!', }; public override bool TryMatchCurrent(LexerBuilder lexer) @@ -26,14 +29,14 @@ namespace UnityExplorer.UI.CSharpConsole.Lexers if (!lexer.IsDelimiter(lexer.Previous, true, true)) return false; - if (uniqueSymbols.Contains(lexer.Current)) + if (symbols.Contains(lexer.Current)) { do { lexer.Commit(); lexer.PeekNext(); } - while (uniqueSymbols.Contains(lexer.Current)); + while (symbols.Contains(lexer.Current)); return true; } diff --git a/src/UI/Panels/CSConsolePanel.cs b/src/UI/Panels/CSConsolePanel.cs index 263f37b..05a8715 100644 --- a/src/UI/Panels/CSConsolePanel.cs +++ b/src/UI/Panels/CSConsolePanel.cs @@ -118,7 +118,7 @@ namespace UnityExplorer.UI.Panels InputText = Input.InputField.textComponent; InputText.supportRichText = false; - InputText.color = new Color(1, 1, 1, 0.65f); + InputText.color = Color.white; Input.PlaceholderText.fontSize = fontSize; // Lexer highlight text overlay diff --git a/src/UI/Widgets/AutoComplete/TypeCompleter.cs b/src/UI/Widgets/AutoComplete/TypeCompleter.cs index 0668624..c54c18a 100644 --- a/src/UI/Widgets/AutoComplete/TypeCompleter.cs +++ b/src/UI/Widgets/AutoComplete/TypeCompleter.cs @@ -25,7 +25,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete public bool AnchorToCaretPosition => false; private readonly List suggestions = new List(); - //private float timeOfLastCheck; + private readonly HashSet suggestedNames = new HashSet(); private HashSet allowedTypes; @@ -47,8 +47,6 @@ namespace UnityExplorer.UI.Widgets.AutoComplete public void OnSuggestionClicked(Suggestion suggestion) { - //timeOfLastCheck = Time.realtimeSinceStartup; - InputField.Text = suggestion.UnderlyingValue; SuggestionClicked?.Invoke(suggestion); @@ -58,11 +56,6 @@ namespace UnityExplorer.UI.Widgets.AutoComplete private void OnInputFieldChanged(string value) { - //if (!timeOfLastCheck.OccuredEarlierThanDefault()) - // return; - // - //timeOfLastCheck = Time.realtimeSinceStartup; - value = value ?? ""; if (string.IsNullOrEmpty(value)) @@ -81,6 +74,7 @@ namespace UnityExplorer.UI.Widgets.AutoComplete private void GetSuggestions(string value) { suggestions.Clear(); + suggestedNames.Clear(); if (BaseType == null) { @@ -101,6 +95,10 @@ namespace UnityExplorer.UI.Widgets.AutoComplete void AddSuggestion(Type type) { + if (suggestedNames.Contains(type.FullName)) + return; + suggestedNames.Add(type.FullName); + if (!sharedTypeToLabel.ContainsKey(type.FullName)) sharedTypeToLabel.Add(type.FullName, SignatureHighlighter.Parse(type, true)); diff --git a/src/UnityExplorer.csproj b/src/UnityExplorer.csproj index fc27caf..73f90ea 100644 --- a/src/UnityExplorer.csproj +++ b/src/UnityExplorer.csproj @@ -220,12 +220,12 @@ - - - - - - + + + + + +