diff options
| author | Mirta <mirta@twine-s.com> | 2020-12-30 16:39:52 +0200 |
|---|---|---|
| committer | Mirta <mirta@twine-s.com> | 2020-12-30 16:39:52 +0200 |
| commit | 00a491d93733d4625ad329b2ba8237f445364b3f (patch) | |
| tree | 4b24c6fa78d7648f4bb7cefafa464bb0b063fec4 /Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs | |
| parent | 124ad4150f80c6846fdee41dbbda9848c105f6e5 (diff) | |
| download | Tango-00a491d93733d4625ad329b2ba8237f445364b3f.tar.gz Tango-00a491d93733d4625ad329b2ba8237f445364b3f.zip | |
merge
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs')
| -rw-r--r-- | Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs | 1991 |
1 files changed, 394 insertions, 1597 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs index e65ff671d..efa1b087a 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs @@ -1,10 +1,8 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.ComponentModel.Design; using System.Diagnostics; using System.IO; using System.Linq; @@ -25,9 +23,7 @@ using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using System.Xml; -using Tango.Core; using Tango.Core.Commands; -using Tango.Scripting.Core; using Tango.Scripting.Editors.CodeCompletion; using Tango.Scripting.Editors.Document; using Tango.Scripting.Editors.Editing; @@ -37,7 +33,6 @@ using Tango.Scripting.Editors.Highlighting.Xshd; using Tango.Scripting.Editors.Intellisense; using Tango.Scripting.Editors.Popups; using Tango.Scripting.Editors.Rendering; -using Tango.Scripting.Formatting; using Tango.Scripting.Parsing; namespace Tango.Scripting.Editors @@ -47,10 +42,7 @@ namespace Tango.Scripting.Editors private char[] word_separators = { ' ', '\t', '\n', '.', '(', ',', '-', '*', '/', '+', '$', '=', '<', '>' }; private string[] _blocking_type_words = { "class", "void" }; - public event EventHandler<BreakPointSymbolPressedEventArgs> BreakPointSymbolPressed; - private DispatcherTimer _update_timer; - private BreakPointMargin breakPointMargin; private Popup _popup; private FoldingManager foldingManager; private BraceFoldingStrategy foldingStrategy; @@ -60,48 +52,9 @@ namespace Tango.Scripting.Editors private List<KnownType> _knownTypes; private List<ScriptType> _declaredTypes; private bool _isLoadingTypes; - private TextMarkerService errorMarkerService; - private List<ScriptBreakPointSymbol> _breakPointSymbols; - private int _breakPointLineNumber; - private ScriptBreakPointSymbol _currentBreakPointSymbol; - private Point _currentBreakPointSymbolPosition; - - private static JsonSerializerSettings _jsonSettings; - private static Dictionary<Type, KnownType> _knownTypesCache; - private static String KNOWN_TYPES_CACHE_FOLDER; - private static List<CachedAssembly> _cachedAssemblies; - private static List<CachedUsing> _cachedUsings; - private static bool _isLoadingCachedAssemblies; - private static bool _isCacheAssembliesLoaded; - private static bool _isUsingsLoadingStarted; - private static object _loadUsingsLock = new object(); - private static List<SnippetCompletionItem> snippets; - - public static event EventHandler<TangoProgressChangedEventArgs<int>> LoadingSymbolsProgress; - public static event EventHandler LoadingSymbolsStarted; - public static event EventHandler LoadingSymbolsCompleted; - private static event EventHandler KnownTypesAvailable; - public static event EventHandler UsingsLoadingStarted; - public static event EventHandler UsingsLoadingCompleted; #region Mini Classes - private class KnownTypeResult - { - public KnownType KnownType { get; set; } - public bool IsStatic { get; set; } - - public KnownTypeResult() - { - - } - - public KnownTypeResult(KnownType knownType) - { - KnownType = knownType; - } - } - private class ScriptClass { public String Name { get; set; } @@ -132,8 +85,6 @@ namespace Tango.Scripting.Editors #region Properties - public static List<String> BlockedUsingsCache { get; set; } - /// <summary> /// Gets or sets a value indicating whether to enable folding. /// </summary> @@ -159,13 +110,13 @@ namespace Tango.Scripting.Editors /// <summary> /// Gets or sets the reference assemblies. /// </summary> - public ObservableCollection<Assembly> ReferenceAssemblies + public ObservableCollection<ReferenceAssembly> ReferenceAssemblies { - get { return (ObservableCollection<Assembly>)GetValue(ReferenceAssembliesProperty); } + get { return (ObservableCollection<ReferenceAssembly>)GetValue(ReferenceAssembliesProperty); } set { SetValue(ReferenceAssembliesProperty, value); } } public static readonly DependencyProperty ReferenceAssembliesProperty = - DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection<Assembly>), typeof(ScriptEditor), new PropertyMetadata(null, (d, e) => (d as ScriptEditor).OnReferenceAssembliesChanged())); + DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection<ReferenceAssembly>), typeof(ScriptEditor), new PropertyMetadata(null)); public Object CurrentPopupContent { @@ -175,70 +126,6 @@ namespace Tango.Scripting.Editors public static readonly DependencyProperty CurrentPopupContentProperty = DependencyProperty.Register("CurrentPopupContent", typeof(Object), typeof(ScriptEditor), new PropertyMetadata(null)); - public String Code - { - get { return (String)GetValue(CodeProperty); } - set { SetValue(CodeProperty, value); } - } - public static readonly DependencyProperty CodeProperty = - DependencyProperty.Register("Code", typeof(String), typeof(ScriptEditor), new PropertyMetadata(null, (d, e) => (d as ScriptEditor).OnCodeChanged())); - - public ObservableCollection<IScriptSource> AdditionalScripts - { - get { return (ObservableCollection<IScriptSource>)GetValue(AdditionalScriptsProperty); } - set { SetValue(AdditionalScriptsProperty, value); } - } - public static readonly DependencyProperty AdditionalScriptsProperty = - DependencyProperty.Register("AdditionalScripts", typeof(ObservableCollection<IScriptSource>), typeof(ScriptEditor), new PropertyMetadata(null)); - - public Brush ColorizeBrush - { - get { return (Brush)GetValue(ColorizeBrushProperty); } - set { SetValue(ColorizeBrushProperty, value); } - } - public static readonly DependencyProperty ColorizeBrushProperty = - DependencyProperty.Register("ColorizeBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.YellowGreen) { Opacity = 0.5 })); - - public Brush ErrorLineBrush - { - get { return (Brush)GetValue(ErrorLineBrushProperty); } - set { SetValue(ErrorLineBrushProperty, value); } - } - public static readonly DependencyProperty ErrorLineBrushProperty = - DependencyProperty.Register("ErrorLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Red) { Opacity = 0.5 })); - - public Brush DebugLineBrush - { - get { return (Brush)GetValue(DebugLineBrushProperty); } - set { SetValue(DebugLineBrushProperty, value); } - } - public static readonly DependencyProperty DebugLineBrushProperty = - DependencyProperty.Register("DebugLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Gray) { Opacity = 0.5 })); - - public Brush BreakPointLineBrush - { - get { return (Brush)GetValue(BreakPointLineBrushProperty); } - set { SetValue(BreakPointLineBrushProperty, value); } - } - public static readonly DependencyProperty BreakPointLineBrushProperty = - DependencyProperty.Register("BreakPointLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Yellow) { Opacity = 0.5 })); - - public IScriptSource ScriptSource - { - get { return (IScriptSource)GetValue(ScriptSourceProperty); } - set { SetValue(ScriptSourceProperty, value); } - } - public static readonly DependencyProperty ScriptSourceProperty = - DependencyProperty.Register("ScriptSource", typeof(IScriptSource), typeof(ScriptEditor), new PropertyMetadata(null)); - - public bool DisableBreakPoints - { - get { return (bool)GetValue(DisableBreakPointsProperty); } - set { SetValue(DisableBreakPointsProperty, value); } - } - public static readonly DependencyProperty DisableBreakPointsProperty = - DependencyProperty.Register("DisableBreakPoints", typeof(bool), typeof(ScriptEditor), new PropertyMetadata(false)); - #endregion @@ -250,87 +137,6 @@ namespace Tango.Scripting.Editors static ScriptEditor() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ScriptEditor), new FrameworkPropertyMetadata(typeof(ScriptEditor))); - - snippets = new List<SnippetCompletionItem>(); - - BlockedUsingsCache = new List<string>(); - - if (KNOWN_TYPES_CACHE_FOLDER == null) - { - KNOWN_TYPES_CACHE_FOLDER = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Scripting", "Cache"); - Directory.CreateDirectory(KNOWN_TYPES_CACHE_FOLDER); - } - - _jsonSettings = new JsonSerializerSettings() - { - TypeNameHandling = TypeNameHandling.Auto, - PreserveReferencesHandling = PreserveReferencesHandling.All - }; - - _knownTypesCache = new Dictionary<Type, KnownType>(); - _cachedAssemblies = new List<CachedAssembly>(); - _cachedUsings = new List<CachedUsing>(); - - snippets.Add(new SnippetCompletionItem() - { - Name = "for", - Code = @"for (int i = 0; i < 10; i++) - { - - }" - }); - - snippets.Add(new SnippetCompletionItem() - { - Name = "while", - Code = @"while (true) - { - - }" - }); - - snippets.Add(new SnippetCompletionItem() - { - Name = "foreach", - Code = @"foreach (var item in items) - { - - }" - }); - - snippets.Add(new SnippetCompletionItem() - { - Name = "prop", - Code = @"public int MyProperty { get; set; }" - }); - - snippets.Add(new SnippetCompletionItem() - { - Name = "do", - Code = @"do - { - - } while (true)" - }); - - snippets.Add(new SnippetCompletionItem() - { - Name = "try", - Code = @"try - { - - } - catch (Exception ex) - { - - }" - }); - - snippets.Add(new SnippetCompletionItem() - { - Name = "cw", - Code = "context.WriteLine(\"\");" - }); } /// <summary> @@ -342,17 +148,16 @@ namespace Tango.Scripting.Editors _current_usings = new List<string>(); - //ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>(); + ReferenceAssemblies = new ObservableCollection<ReferenceAssembly>(); - ////Add basic assemblies... - //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib - //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core + //Add basic assemblies... + ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib + ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core + ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Tango.Core.CoreSettings))); //System.Core _knownTypes = new List<KnownType>(); _parser = new ScriptParser(); - KnownTypesAvailable += ScriptEditor_KnownTypesAvailable; - TextArea.IndentationStrategy = new Indentation.CSharp.CSharpIndentationStrategy(Options); foldingStrategy = new BraceFoldingStrategy(); @@ -370,59 +175,6 @@ namespace Tango.Scripting.Editors completionWindow.AllowsTransparency = true; completionWindow.ResizeMode = ResizeMode.NoResize; completionWindow.InsertionRequest += CompletionWindow_InsertionRequest; - - TextChanged += ScriptEditor_TextChanged; - - errorMarkerService = new TextMarkerService(Document); - TextArea.TextView.BackgroundRenderers.Add(errorMarkerService); - TextArea.TextView.LineTransformers.Add(errorMarkerService); - - Unloaded += ScriptEditor_Unloaded; - - breakPointMargin = new BreakPointMargin(this); - _breakPointSymbols = new List<ScriptBreakPointSymbol>(); - Loaded += ScriptEditor_Loaded; - - MouseMove += ScriptEditor_MouseMove; - } - - private void ScriptEditor_Loaded(object sender, RoutedEventArgs e) - { - TextArea.LeftMargins.Insert(0, breakPointMargin); - } - - private void ScriptEditor_Unloaded(object sender, RoutedEventArgs e) - { - _update_timer.Stop(); - } - - private void ScriptEditor_KnownTypesAvailable(object sender, EventArgs e) - { - if (sender != this) - { - InvalidateHighlightingPartial(); - } - } - - private bool preventCodeUpdate; - private void ScriptEditor_TextChanged(object sender, EventArgs e) - { - if (!preventCodeUpdate) - { - preventCodeUpdate = true; - Code = Text; - preventCodeUpdate = false; - } - } - - private void OnCodeChanged() - { - if (!preventCodeUpdate) - { - preventCodeUpdate = true; - Text = Code; - preventCodeUpdate = false; - } } #endregion @@ -527,18 +279,18 @@ namespace Tango.Scripting.Editors } else if (e.Key == Key.Oem2) { - //int offset = CaretOffset; - //var line = Document.GetLineByOffset(offset); + int offset = CaretOffset; + var line = Document.GetLineByOffset(offset); - //String text = GetCurrentLineText(); - //if (text.TrimStart('\t', ' ').StartsWith("//")) - //{ - // Document.BeginUpdate(); - // Document.Replace(line, "/// <summary>\n/// \n/// </summary>"); - // Document.EndUpdate(); - // e.Handled = true; - // CaretOffset = Document.GetLineByNumber(line.LineNumber + 1).EndOffset; - //} + String text = GetCurrentLineText(); + if (text.TrimStart('\t', ' ').StartsWith("//")) + { + Document.BeginUpdate(); + Document.Replace(line, "/// <summary>\n/// \n/// </summary>"); + Document.EndUpdate(); + e.Handled = true; + CaretOffset = Document.GetLineByNumber(line.LineNumber + 1).EndOffset; + } } else if (e.Key == Key.End || e.Key == Key.Home) { @@ -552,509 +304,474 @@ namespace Tango.Scripting.Editors private void TextArea_TextEntered(object sender, TextCompositionEventArgs e) { - if (IsReadOnly) return; + List<Object> items = new List<object>(); - try - { - List<Object> items = new List<object>(); + HidePopup(); - HidePopup(); + var lineText = GetCurrentLineText(); + var previousWords = GetPreviousWords(); + var previousWordsLast = previousWords.LastOrDefault(); + String currentWord = previousWordsLast != null ? previousWordsLast.Replace("\t", "") : String.Empty; + String currentWordIncludingParenthesis = currentWord.Split('(').LastOrDefault(); - var lineText = GetCurrentLineText(); - var previousWords = GetPreviousWords(); - var previousWordsLast = previousWords.LastOrDefault(); - String currentWord = previousWordsLast != null ? previousWordsLast.Replace("\t", "") : String.Empty; - String currentWordIncludingParenthesis = currentWord.Split('(').LastOrDefault(); + if (previousWords.Count > 0 && previousWords.First().Trim().StartsWith("//")) return; - if (previousWords.Count > 0 && previousWords.First().Trim().StartsWith("//")) return; + if (e.Text == " " && previousWords.Count > 2 && previousWords[previousWords.Count - 2] == "=") + { + var expression = previousWords.First(); + var knownType = GetKnownTypeFromExpression(expression + "."); - if (e.Text == " " && previousWords.Count > 2 && previousWords[previousWords.Count - 2] == "=") + if (knownType != null && knownType.Type.IsEnum) { - var expression = previousWords.First(); - var knownTypeResult = GetKnownTypeFromExpression(expression + "."); + completionWindow.HideCompletion(); + IList<ICompletionData> data = new List<ICompletionData>(); - if (knownTypeResult != null && knownTypeResult.KnownType.Type.IsEnum) + foreach (var field in knownType.Fields) { - completionWindow.HideCompletion(); - IList<ICompletionData> data = new List<ICompletionData>(); - - foreach (var field in knownTypeResult.KnownType.Fields) + data.Add(new FieldCompletionItem() { - data.Add(new FieldCompletionItem() - { - Class = knownTypeResult.KnownType.FriendlyName, - Name = knownTypeResult.KnownType.FriendlyName + "." + field.Name, - Type = field.ReturnTypeFriendlyName, - Description = field.Summary, - }); - } - - ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord()); + Class = knownType.FriendlyName, + Name = knownType.FriendlyName + "." + field.Name, + Type = field.ReturnTypeFriendlyName, + Description = field.Summary, + }); } + ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord()); } - else if (e.Text == " " && GetPreviousWord() == "new") - { - var s = _parser.GetExpressionFirst<FieldDeclarationSyntax>(GetCurrentLineText()); - if (s != null) - { - String type = s.Declaration.Type.ToString(); + } + else if (e.Text == " " && GetPreviousWord() == "new") + { + var s = _parser.GetExpressionFirst<FieldDeclarationSyntax>(GetCurrentLineText()); - IList<ICompletionData> data = new List<ICompletionData>(); + if (s != null) + { + String type = s.Declaration.Type.ToString(); - data.Add(new ClassCompletionItem() - { - Name = type, - Description = "Auto generate assignment...", - }); + IList<ICompletionData> data = new List<ICompletionData>(); - ShowCompletionWindow(data, type); - } - } - else if (e.Text == ";" || e.Text == " ") - { - HideCompletionWindow(); + data.Add(new ClassCompletionItem() + { + Name = type, + Description = "Auto generate assignment...", + }); + + ShowCompletionWindow(data, type); } - else if (e.Text == ".") - { - var knownTypeResult = GetCurrentKnownType(); + } + else if (e.Text == ";" || e.Text == " ") + { + HideCompletionWindow(); + } + else if (e.Text == ".") + { + var knownType = GetCurrentKnownType(); + if (knownType != null) + { + completionWindow.HideCompletion(); IList<ICompletionData> data = new List<ICompletionData>(); - if (knownTypeResult != null) + if (!knownType.Type.IsEnum) { - completionWindow.HideCompletion(); + var typeMembers = knownType.Members.ToList(); - if (!knownTypeResult.KnownType.Type.IsEnum) + foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().GroupBy(x => x.NameWithTypeArguments)) { - var typeMembers = knownTypeResult.KnownType.Members.ToList(); + var method = methodGroup.First(); - foreach (var methodGroup in typeMembers.OfType<KnownTypeMethod>().Where(x => (!knownTypeResult.IsStatic && !x.IsStatic) || (knownTypeResult.IsStatic && x.IsStatic)).GroupBy(x => x.NameWithTypeArguments)) + data.Add(new MethodCompletionItem() { - var method = methodGroup.First(); - - data.Add(new MethodCompletionItem() - { - Class = knownTypeResult.KnownType.FriendlyName, - Name = method.NameWithTypeArguments, - ReturnType = method.ReturnTypeFriendlyName, - Description = method.Summary, - Parameters = method.Parameters, - Overloads = methodGroup.Count() - 1, - }); - } + Class = knownType.FriendlyName, + Name = method.NameWithTypeArguments, + ReturnType = method.ReturnTypeFriendlyName, + Description = method.Summary, + Parameters = method.Parameters, + Overloads = methodGroup.Count() - 1, + }); + } - foreach (var ev in typeMembers.OfType<KnownTypeEvent>()) - { - data.Add(new EventCompletionItem() - { - Class = knownTypeResult.KnownType.FriendlyName, - Name = ev.Name, - Description = ev.Summary, - }); - } + foreach (var methodGroup in typeMembers.Where(x => x.GetType() != typeof(KnownTypeMethod)).GroupBy(x => x.Name)) + { + var member = methodGroup.First(); - foreach (var methodGroup in typeMembers.Where(x => x.GetType() != typeof(KnownTypeMethod) && x.GetType() != typeof(KnownTypeEvent)).GroupBy(x => x.Name)) + data.Add(new PropertyCompletionItem() { - var member = methodGroup.First(); + Class = knownType.FriendlyName, + Name = member.Name, + Type = member.ReturnTypeFriendlyName, + Description = member.Summary, + }); - data.Add(new PropertyCompletionItem() - { - Class = knownTypeResult.KnownType.FriendlyName, - Name = member.Name, - Type = member.ReturnTypeFriendlyName, - Description = member.Summary, - }); - } } - else + } + else + { + foreach (var field in knownType.Fields) { - foreach (var field in knownTypeResult.KnownType.Fields) + data.Add(new FieldCompletionItem() { - data.Add(new FieldCompletionItem() - { - Class = knownTypeResult.KnownType.FriendlyName, - Name = field.Name, - Type = field.ReturnTypeFriendlyName, - Description = field.Summary, - }); + Class = knownType.FriendlyName, + Name = field.Name, + Type = field.ReturnTypeFriendlyName, + Description = field.Summary, + }); - } } - - ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord()); } - else + + ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord()); + } + else + { + var declaredType = GetCurrentDeclaredType(); + + if (declaredType != null) { - var declaredType = GetCurrentDeclaredType(); + completionWindow.HideCompletion(); + IList<ICompletionData> data = new List<ICompletionData>(); - if (declaredType != null) - { - completionWindow.HideCompletion(); + var typeMembers = declaredType.Symbols.ToList(); - var typeMembers = declaredType.Symbols.ToList(); + foreach (var methodGroup in typeMembers.GroupBy(x => x.Name)) + { + var member = methodGroup.First(); - foreach (var methodGroup in typeMembers.GroupBy(x => x.Name)) + if (member.Kind == SymbolKind.Method) { - var member = methodGroup.First(); - - if (member.Kind == SymbolKind.Method) + var methodCompletion = new MethodCompletionItem() { - var methodCompletion = new MethodCompletionItem() - { - Class = declaredType.Name, - Name = member.Name, - ReturnType = member.Type, - Description = member.Summary, - Overloads = methodGroup.Count() - 1, - }; - - - for (int i = 0; i < member.Parameters.Count; i++) - { - var pair = member.Parameters[i]; - - methodCompletion.Parameters.Add(new KnownTypeMethodParameter() - { - Type = pair.Key, - Name = pair.Value, - IsLast = (i == member.Parameters.Count - 1) - }); - } + Class = declaredType.Name, + Name = member.Name, + ReturnType = member.Type, + Description = member.Summary, + Overloads = methodGroup.Count() - 1, + }; - data.Add(methodCompletion); - } - else if (member.Kind == SymbolKind.Property) + for (int i = 0; i < member.Parameters.Count; i++) { - data.Add(new PropertyCompletionItem() + var pair = member.Parameters[i]; + + methodCompletion.Parameters.Add(new KnownTypeMethodParameter() { - Class = declaredType.Name, - Name = member.Name, - Type = member.Type, - Description = member.Summary, + Type = pair.Key, + Name = pair.Value, + IsLast = (i == member.Parameters.Count - 1) }); } - else if (member.Kind == SymbolKind.Field) + + data.Add(methodCompletion); + + } + else if (member.Kind == SymbolKind.Property) + { + data.Add(new PropertyCompletionItem() { - data.Add(new FieldCompletionItem() - { - Class = declaredType.Name, - Name = member.Name, - Type = member.Type, - Description = member.Summary, - }); - } + Class = declaredType.Name, + Name = member.Name, + Type = member.Type, + Description = member.Summary, + }); + } + else if (member.Kind == SymbolKind.Field) + { + data.Add(new FieldCompletionItem() + { + Class = declaredType.Name, + Name = member.Name, + Type = member.Type, + Description = member.Summary, + }); } - - ShowCompletionWindow(data, GetCurrentWord()); } + + ShowCompletionWindow(data, GetCurrentWord()); } } - else if (e.Text == "(" || e.Text == ",") + } + else if (e.Text == "(" || e.Text == ",") + { + completionWindow.HideCompletion(); + + try { - completionWindow.HideCompletion(); + var session = GetConstructionSession(); - try + if (session != null) { - var session = GetConstructionSession(); - - if (session != null) - { - var content = CreateConstructionSessionPopupContent(session); - if (content.Methods.Count > 0) - { - ShowPopup(content); - return; - } - } - - var methodSession = GetMethodSession(); - - if (methodSession != null) + var content = CreateConstructionSessionPopupContent(session); + if (content.Methods.Count > 0) { - var content = CreateMethodSessionPopupContent(methodSession); - if (content.Methods.Count > 0) - { - ShowPopup(content); - return; - } + ShowPopup(content); + return; } + } - var declaredMethodSession = GetDeclaredMethodSession(); + var methodSession = GetMethodSession(); - if (declaredMethodSession != null) + if (methodSession != null) + { + var content = CreateMethodSessionPopupContent(methodSession); + if (content.Methods.Count > 0) { - var content = CreateDeclaredMethodSessionPopupContent(declaredMethodSession); - if (content.Methods.Count > 0) - { - ShowPopup(content); - return; - } + ShowPopup(content); + return; } + } - var staticMethodSession = GetStaticMethodSession(); + var declaredMethodSession = GetDeclaredMethodSession(); - if (staticMethodSession != null) + if (declaredMethodSession != null) + { + var content = CreateDeclaredMethodSessionPopupContent(declaredMethodSession); + if (content.Methods.Count > 0) { - var content = CreateMethodSessionPopupContent(staticMethodSession); - if (content.Methods.Count > 0) - { - ShowPopup(content); - return; - } + ShowPopup(content); + return; } } - catch (Exception ex) - { - Debug.WriteLine(ex); - } } - else if (lineText.StartsWith("using") && e.Text != "\n") + catch (Exception ex) { - if (completionWindow.IsVisible) - { - completionWindow.UpdatePositionFix(); - return; - } + Debug.WriteLine(ex); + } + } + else if (lineText.StartsWith("using")) + { + if (completionWindow.IsVisible) + { + completionWindow.UpdatePositionFix(); + return; + } - IList<ICompletionData> data = new List<ICompletionData>(); + IList<ICompletionData> data = new List<ICompletionData>(); - foreach (var asm in ReferenceAssemblies) + foreach (var asm in ReferenceAssemblies) + { + foreach (var ns in asm.Assembly.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null)) { - foreach (var ns in asm.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null)) + data.Add(new NamespaceCompletionItem() { - data.Add(new NamespaceCompletionItem() - { - Name = ns, - Assembly = asm.GetName().Name, - }); - } + Name = ns, + Assembly = asm.Assembly.GetName().Name, + }); } + } - data = data.DistinctBy(x => x.Text).ToList(); + data = data.DistinctBy(x => x.Text).ToList(); - ShowCompletionWindow(data, GetCurrentWord()); + ShowCompletionWindow(data, GetCurrentWord()); + } + else if (e.Text == "{") + { + int parentesisCount = lineText.TakeWhile(x => x != '{').Count(x => x == '\"'); + + if (parentesisCount % 2 == 0) + { + Document.Insert(CaretOffset, "}"); + CaretOffset--; } - else if (e.Text == "{") + } + else if (e.Text == "}") + { + if (Document.GetText(CaretOffset - 2, 1) == "{" && Document.GetText(CaretOffset, 1) == "}") { - int parentesisCount = lineText.TakeWhile(x => x != '{').Count(x => x == '\"'); - - if (parentesisCount % 2 == 0) - { - Document.Insert(CaretOffset, "}"); - CaretOffset--; - } + Document.Replace(CaretOffset, 1, ""); } - else if (e.Text == "}") + } + else if (e.Text == "\n") + { + if (Document.GetText(CaretOffset - 3, 1) == "{" && Document.GetText(CaretOffset, 1) == "}") { - if (Document.GetText(CaretOffset - 2, 1) == "{" && Document.GetText(CaretOffset, 1) == "}") - { - Document.Replace(CaretOffset, 1, ""); - } + CaretOffset--; + Document.Insert(CaretOffset, "\n\t"); + } + } + else if (!currentWordIncludingParenthesis.Contains(".") || currentWord[currentWord.Length - 2] == '<') + { + if (completionWindow.IsVisible) + { + completionWindow.UpdatePositionFix(); + return; } - else if (e.Text == "\n") + + var previous_word = GetPreviousWord(); + var word = GetCurrentWord(); + + if (word.Contains("<")) { - if (Document.GetText(CaretOffset - 3, 1) == "{" && Document.GetText(CaretOffset, 1) == "}") - { - CaretOffset--; - Document.Insert(CaretOffset, "\n\t"); - } + word = word.Last(x => x != '<').ToString(); } - else if (!currentWordIncludingParenthesis.Contains(".") || currentWord[currentWord.Length - 2] == '<') + + if (previous_word != word) { - if (completionWindow.IsVisible) + if (_knownTypes.Exists(x => x.Name == previous_word)) { - completionWindow.UpdatePositionFix(); return; } - var previous_word = GetPreviousWord(); - var word = GetCurrentWord(); - - if (word.Contains("<")) + if (_blocking_type_words.Contains(previous_word)) { - word = word.Last(x => x != '<').ToString(); + return; } + } - if (previous_word != word) + if (!String.IsNullOrWhiteSpace(word)) + { + IList<ICompletionData> data = new List<ICompletionData>(); + + foreach (var type in _declaredTypes.Where(x => x.Name.StartsWith(word))) { - if (_knownTypes.Exists(x => x.Name == previous_word)) + if (type.Kind == TypeKind.Struct) { - return; + data.Add(new StructCompletionItem() + { + Name = type.Name, + Description = type.Summary, + Namespace = type.ContainingNamespace, + Priority = 1, + }); } - - if (_blocking_type_words.Contains(previous_word)) + else if (type.Kind == TypeKind.Enum) { - return; + data.Add(new EnumCompletionItem() + { + Name = type.Name, + Description = type.Summary, + Namespace = type.ContainingNamespace, + Priority = 1, + }); + } + else if (type.Kind == TypeKind.Interface) + { + data.Add(new InterfaceCompletionItem() + { + Name = type.Name, + Description = type.Summary, + Namespace = type.ContainingNamespace, + Priority = 1, + }); + } + else if (type.Kind == TypeKind.Class) + { + data.Add(new ClassCompletionItem() + { + Name = type.Name, + Description = type.Summary, + Namespace = type.ContainingNamespace, + Priority = 1, + }); + } + else + { + throw new NotImplementedException("Implement generic item here!"); } } - if (!String.IsNullOrWhiteSpace(word)) + foreach (var type in _knownTypes.ToList().Where(x => x.Name.StartsWith(word))) { - IList<ICompletionData> data = new List<ICompletionData>(); - - foreach (var snippet in snippets) + if (type.Type.IsEnum) { - data.Add(snippet); + data.Add(new EnumCompletionItem() + { + Namespace = type.Type.Namespace, + Description = type.Summary, + Name = type.FriendlyName, + Priority = 0, + }); } - - foreach (var type in _declaredTypes.Where(x => x.Name.StartsWith(word))) + else if (type.Type.IsInterface) { - if (type.Kind == TypeKind.Struct) + data.Add(new InterfaceCompletionItem() { - data.Add(new StructCompletionItem() - { - Name = type.Name, - Description = type.Summary, - Namespace = type.ContainingNamespace, - Priority = 1, - }); - } - else if (type.Kind == TypeKind.Enum) - { - data.Add(new EnumCompletionItem() - { - Name = type.Name, - Description = type.Summary, - Namespace = type.ContainingNamespace, - Priority = 1, - }); - } - else if (type.Kind == TypeKind.Interface) - { - data.Add(new InterfaceCompletionItem() - { - Name = type.Name, - Description = type.Summary, - Namespace = type.ContainingNamespace, - Priority = 1, - }); - } - else if (type.Kind == TypeKind.Class) + Name = type.FriendlyName, + Description = type.Summary, + Namespace = type.Type.Namespace, + Priority = 0, + }); + } + else if (type.Type.IsValueType) + { + data.Add(new StructCompletionItem() { - data.Add(new ClassCompletionItem() - { - Name = type.Name, - Description = type.Summary, - Namespace = type.ContainingNamespace, - Priority = 1, - }); - } - else + Name = type.FriendlyName, + Description = type.Summary, + Namespace = type.Type.Namespace, + Priority = 0, + }); + } + else if (type.Type.IsClass) + { + data.Add(new ClassCompletionItem() { - throw new NotImplementedException("Implement generic item here!"); - } + Name = type.FriendlyName, + Description = type.Summary, + Namespace = type.Type.Namespace, + Priority = 0, + }); + } + else + { + throw new NotImplementedException("Implement generic item here."); } + } - foreach (var type in _knownTypes.ToList().Where(x => x.Name.StartsWith(word))) + foreach (var symbol in _parser.GetContextSymbols(Document.Text, CaretOffset).Where(x => x.Name.StartsWith(GetCurrentWord()))) + { + if (symbol.Kind == SymbolKind.Property) { - if (type.Type.IsEnum) - { - data.Add(new EnumCompletionItem() - { - Namespace = type.Type.Namespace, - Description = type.Summary, - Name = type.FriendlyName, - Priority = 0, - }); - } - else if (type.Type.IsInterface) + data.Add(new PropertyCompletionItem() { - data.Add(new InterfaceCompletionItem() - { - Name = type.FriendlyName, - Description = type.Summary, - Namespace = type.Type.Namespace, - Priority = 0, - }); - } - else if (type.Type.IsValueType) - { - data.Add(new StructCompletionItem() - { - Name = type.FriendlyName, - Description = type.Summary, - Namespace = type.Type.Namespace, - Priority = 0, - }); - } - else if (type.Type.IsClass) - { - data.Add(new ClassCompletionItem() - { - Name = type.FriendlyName, - Description = type.Summary, - Namespace = type.Type.Namespace, - Priority = 0, - }); - } - else + Class = symbol.Class, + Description = symbol.Summary, + Name = symbol.Name, + Type = symbol.Type, + Priority = 2, + }); + } + else if (symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter) + { + data.Add(new FieldCompletionItem() { - throw new NotImplementedException("Implement generic item here."); - } + Class = symbol.Class, + Description = symbol.Summary, + Name = symbol.Name, + Type = symbol.Type, + Priority = 2, + }); } - - foreach (var symbol in _parser.GetContextSymbols(Document.Text, CaretOffset).Where(x => x.Name.StartsWith(GetCurrentWord()))) + else if (symbol.Kind == SymbolKind.Method) { - if (symbol.Kind == SymbolKind.Property) + var methodCompletion = new MethodCompletionItem() { - data.Add(new PropertyCompletionItem() - { - Class = symbol.Class, - Description = symbol.Summary, - Name = symbol.Name, - Type = symbol.Type, - Priority = 2, - }); - } - else if (symbol.Kind == SymbolKind.Field || symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter) + Class = symbol.Class, + Description = symbol.Summary, + Name = symbol.Name, + ReturnType = symbol.Type, + Priority = 2, + }; + + for (int i = 0; i < symbol.Parameters.Count; i++) { - data.Add(new FieldCompletionItem() + var pair = symbol.Parameters[i]; + + methodCompletion.Parameters.Add(new KnownTypeMethodParameter() { - Class = symbol.Class, - Description = symbol.Summary, - Name = symbol.Name, - Type = symbol.Type, - Priority = 2, + Type = pair.Key, + Name = pair.Value, + IsLast = (i == symbol.Parameters.Count - 1) }); } - else if (symbol.Kind == SymbolKind.Method) - { - var methodCompletion = new MethodCompletionItem() - { - Class = symbol.Class, - Description = symbol.Summary, - Name = symbol.Name, - ReturnType = symbol.Type, - Priority = 2, - }; - - for (int i = 0; i < symbol.Parameters.Count; i++) - { - var pair = symbol.Parameters[i]; - methodCompletion.Parameters.Add(new KnownTypeMethodParameter() - { - Type = pair.Key, - Name = pair.Value, - IsLast = (i == symbol.Parameters.Count - 1) - }); - } - - data.Add(methodCompletion); - } + data.Add(methodCompletion); } - - ShowCompletionWindow(data, word); } + + ShowCompletionWindow(data, word); } } - catch (Exception ex) - { - Debug.WriteLine(ex.ToString()); - } } #endregion @@ -1075,7 +792,7 @@ namespace Tango.Scripting.Editors IList<ICompletionData> data = completionWindow.CompletionList.CompletionData; data.Clear(); - foreach (var item in suggestions.DistinctBy(x => x.Text)) + foreach (var item in suggestions) { data.Add(item); } @@ -1147,23 +864,16 @@ namespace Tango.Scripting.Editors return list; } - private KnownTypeResult GetCurrentKnownType() + private KnownType GetCurrentKnownType() { var expression = GetPreviousWords().LastOrDefault(); return GetKnownTypeFromExpression(expression); } - private KnownTypeResult GetKnownTypeFromExpression(String expression) + private KnownType GetKnownTypeFromExpression(String expression) { if (expression != null) { - var insideMethodExp = expression.Split('(').LastOrDefault(); - - if (insideMethodExp != null) - { - expression = insideMethodExp; - } - var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList(); var variableName = tree.FirstOrDefault(); @@ -1174,7 +884,7 @@ namespace Tango.Scripting.Editors if (enumType != null) { - return new KnownTypeResult(enumType); + return enumType; } tree.RemoveAt(0); @@ -1183,8 +893,7 @@ namespace Tango.Scripting.Editors if (variable != null) { - var name = Regex.Replace(variable.Type, "<.+>", "<T>"); - var knownType = _knownTypes.FirstOrDefault(x => name == x.FriendlyName || name == x.Alias); + var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable.Type, "<.+>", "<T>")); if (knownType != null) { @@ -1202,37 +911,9 @@ namespace Tango.Scripting.Editors knownType = _knownTypes.FirstOrDefault(x => x.Type.Namespace + "." + x.Type.Name == member.ReturnType.Namespace + "." + member.ReturnType.Name); } - return new KnownTypeResult(knownType); - } - else //Maybe a variable of a declared type... - { - if (tree.Count > 0) - { - var memberName = tree[0]; - var declaredType = _declaredTypes.SingleOrDefault(x => x.Name == name); - - if (declaredType != null) - { - var member = declaredType.Symbols.FirstOrDefault(x => x.Name == memberName); - if (member != null) - { - knownType = _knownTypes.SingleOrDefault(x => x.Name.ToLower() == member.Type.ToLower()); - - if (knownType != null) - { - return new KnownTypeResult(knownType); - } - } - } - } + return knownType; } } - else - { - //Maybe static... - var type = _knownTypes.FirstOrDefault(x => x.Name == variableName || x.Alias == variableName); - return type != null ? new KnownTypeResult(type) { IsStatic = true } : null; - } } } @@ -1245,13 +926,6 @@ namespace Tango.Scripting.Editors if (expression != null) { - var insideMethodExp = expression.Split('(').LastOrDefault(); - - if (insideMethodExp != null) - { - expression = insideMethodExp; - } - var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList(); var variableName = tree.FirstOrDefault(); @@ -1284,11 +958,6 @@ namespace Tango.Scripting.Editors return declaredType; } } - else - { - //Maybe static... - return _declaredTypes.FirstOrDefault(x => x.Name == variableName); - } } } @@ -1378,7 +1047,7 @@ namespace Tango.Scripting.Editors foreach (var m in session.Type.Methods.Where(x => x.Name == session.MethodName)) { MethodDescription method = new MethodDescription(); - method.ReturnType = m.ReturnTypeFriendlyName; + method.ReturnType = session.Type.Name; method.Description = m.Summary; method.Name = m.NameWithTypeArguments; method.Class = session.Type.FriendlyName; @@ -1471,364 +1140,33 @@ namespace Tango.Scripting.Editors return popup; } - public void LoadUsingsSymbols(List<Assembly> assemblies, List<String> usings) - { - lock (_loadUsingsLock) - { - LoadingSymbolsStarted?.Invoke(null, new EventArgs()); - - var allTypes = assemblies.SelectMany(x => x.GetTypes()); - - foreach (var use in usings) - { - if (!_cachedUsings.Exists(x => x.Namespace == use)) - { - if (!_isUsingsLoadingStarted) - { - _isUsingsLoadingStarted = true; - UsingsLoadingStarted?.Invoke(this, new EventArgs()); - } - - var useFileName = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, use + ".json"); - - if (File.Exists(useFileName)) - { - LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() - { - Progress = new TangoProgress<int>() - { - IsIndeterminate = true, - Maximum = 100, - Message = $"Loading symbols for '{use}'..." - } - }); - - CachedUsing cached = JsonConvert.DeserializeObject<CachedUsing>(File.ReadAllText(useFileName), _jsonSettings); - _cachedUsings.Add(cached); - foreach (var knownType in cached.KnownTypes) - { - _knownTypesCache.Add(knownType.Type, knownType); - } - - KnownTypesAvailable?.Invoke(this, new EventArgs()); - InvalidateHighlightingPartial(); - - continue; - } - - var useTypes = allTypes.Where(x => x.IsVisible && x.IsPublic && x.Namespace == use).ToList(); - - CachedUsing cachedUsing = new CachedUsing(); - cachedUsing.Namespace = use; - _cachedUsings.Add(cachedUsing); - - int i = 1; - - foreach (var type in useTypes) - { - LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() - { - Progress = new TangoProgress<int>() - { - IsIndeterminate = false, - Maximum = useTypes.Count, - Value = i++, - Message = $"Loading symbols for '{use}'..." - } - }); - - KnownType knownType = new KnownType(type); - - if (type.IsPrimitive) - { - if (type == typeof(Int32)) - { - knownType.Alias = "int"; - } - else if (type == typeof(float)) - { - knownType.Alias = "float"; - } - else if (type == typeof(Double)) - { - knownType.Alias = "double"; - } - else if (type == typeof(long)) - { - knownType.Alias = "long"; - } - else if (type == typeof(bool)) - { - knownType.Alias = "bool"; - } - else if (type == typeof(uint)) - { - knownType.Alias = "uint"; - } - } - else if (type == typeof(String)) - { - knownType.Alias = "string"; - } - - _knownTypesCache.Add(type, knownType); - cachedUsing.KnownTypes.Add(knownType); - knownType.LoadDocumentation(); - } - - if (!BlockedUsingsCache.Exists(x => use.StartsWith(x))) - { - Task.Factory.StartNew(() => - { - var json = JsonConvert.SerializeObject(cachedUsing, _jsonSettings); - File.WriteAllText(useFileName, json); - }); - } - } - } - - if (_isUsingsLoadingStarted) - { - UsingsLoadingCompleted?.Invoke(this, new EventArgs()); - } - - LoadingSymbolsCompleted?.Invoke(null, new EventArgs()); - } - } - - //public static void LoadCachedAssemblies(List<Assembly> assemblies, List<String> usings = null) - //{ - // if (_isLoadingCachedAssemblies) return; - - // _isLoadingCachedAssemblies = true; - - // LoadingSymbolsStarted?.Invoke(null, new EventArgs()); - - // if (!_isCacheAssembliesLoaded) - // { - // foreach (var file in System.IO.Directory.GetFiles(KNOWN_TYPES_CACHE_FOLDER)) - // { - // try - // { - // LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() - // { - // Progress = new TangoProgress<int>() - // { - // IsIndeterminate = true, - // Maximum = 100, - // Message = $"Loading metadata cache for '{System.IO.Path.GetFileName(file)}'..." - // } - // }); - - // var cachedAssembly = JsonConvert.DeserializeObject<CachedAssembly>(System.IO.File.ReadAllText(file), _jsonSettings); - - // foreach (var knownType in cachedAssembly.KnownTypes) - // { - // _knownTypesCache.Add(knownType.Type, knownType); - // } - - // _cachedAssemblies.Add(cachedAssembly); - // } - // catch { } - // } - - // _isCacheAssembliesLoaded = true; - // } - - // foreach (var asm in assemblies) - // { - // if (!_cachedAssemblies.Exists(x => x.Name == asm.FullName)) - // { - // String asmFileName = System.IO.Path.GetFileName(asm.Location); - - // CachedAssembly cachedAssembly = new CachedAssembly(); - // cachedAssembly.Name = asm.FullName; - // _cachedAssemblies.Add(cachedAssembly); - - // var types = asm.GetTypes().Where(x => x.IsVisible && x.IsPublic).ToList(); - - // int i = 0; - - // foreach (var type in types) - // { - // LoadingSymbolsProgress?.Invoke(null, new TangoProgressChangedEventArgs<int>() - // { - // Progress = new TangoProgress<int>() - // { - // IsIndeterminate = false, - // Maximum = types.Count, - // Value = i++, - // Message = $"Caching metadata for '{asmFileName}'..." - // } - // }); - - // KnownType knownType = new KnownType(type); - - // if (type.IsPrimitive) - // { - // if (type == typeof(Int32)) - // { - // knownType.Alias = "int"; - // } - // else if (type == typeof(float)) - // { - // knownType.Alias = "float"; - // } - // else if (type == typeof(Double)) - // { - // knownType.Alias = "double"; - // } - // else if (type == typeof(long)) - // { - // knownType.Alias = "long"; - // } - // else if (type == typeof(bool)) - // { - // knownType.Alias = "bool"; - // } - // else if (type == typeof(uint)) - // { - // knownType.Alias = "uint"; - // } - // } - - // _knownTypesCache.Add(type, knownType); - // cachedAssembly.KnownTypes.Add(knownType); - // //knownType.LoadDocumentation(); - // } - - // String cachedAssemblyFile = System.IO.Path.Combine(KNOWN_TYPES_CACHE_FOLDER, asmFileName); - // File.WriteAllText(cachedAssemblyFile, JsonConvert.SerializeObject(cachedAssembly, _jsonSettings)); - // } - // } - - // LoadingSymbolsCompleted?.Invoke(null, new EventArgs()); - - // _isLoadingCachedAssemblies = false; - //} - - private void InvalidateHighlightingPartial() - { - List<Assembly> assemblies = new List<Assembly>(); - Dispatcher.Invoke(() => - { - assemblies = ReferenceAssemblies.ToList(); - }); - - var usings = _current_usings.ToList(); - - _knownTypes.Clear(); - - foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList()) - { - if (usings.Exists(x => knownType.Type.Namespace == x) && assemblies.Exists(x => x == knownType.Type.Assembly)) - { - lock (_knownTypes) - { - _knownTypes.Add(knownType); - } - } - } - - if (_knownTypes.Count > 0 || _declaredTypes.Count > 0) - { - String text = String.Empty; - - Stream xshd_stream = typeof(ScriptEditor).Assembly.GetManifestResourceStream("Tango.Scripting.Editors.Highlighting.Resources.CSharp-Mode.xshd"); - - using (StreamReader reader = new StreamReader(xshd_stream)) - { - text = reader.ReadToEnd(); - } - - List<String> referenceTypes = new List<string>(); - List<String> interfaceTypes = new List<string>(); - - lock (_knownTypes) - { - foreach (var type in _knownTypes.ToList().Where(x => x != null)) - { - String name = type.Name; - - if (type.Type.ContainsGenericParameters) - { - name = new String(name.TakeWhile(x => x != '`').ToArray()); - } - - if (type.Type.IsInterface || type.Type.IsEnum) - { - interfaceTypes.Add(String.Format("<Word>{0}</Word>", name)); - } - else if (type.Type.IsClass || (type.Type.IsValueType)) - { - referenceTypes.Add(String.Format("<Word>{0}</Word>", name)); - } - } - } - - foreach (var type in _declaredTypes) - { - if (type.Kind == TypeKind.Interface || type.Kind == TypeKind.Enum) - { - interfaceTypes.Add(String.Format("<Word>{0}</Word>", type.Name)); - } - else if (type.Kind == TypeKind.Class) - { - referenceTypes.Add(String.Format("<Word>{0}</Word>", type.Name)); - } - } - - if (referenceTypes.Count > 0) - { - text = text.Replace("<Word>@ReferenceTypes@</Word>", String.Join(Environment.NewLine, referenceTypes.Distinct())); - } - - if (interfaceTypes.Count > 0) - { - text = text.Replace("<Word>@InterfaceTypes@</Word>", String.Join(Environment.NewLine, interfaceTypes.Distinct())); - } - - MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text)); - - XmlTextReader xshd_reader = new XmlTextReader(ms); - - Dispatcher.Invoke(new Action(() => - { - SyntaxHighlighting = HighlightingLoader.Load(xshd_reader, HighlightingManager.Instance); - xshd_reader.Close(); - ms.Dispose(); - })); - } - } - - public void InvalidateHighlighting(bool loadKnownTypes = true) + private void InvalidateHighlighting() { if (!_isLoadingTypes) { _isLoadingTypes = true; + _knownTypes.Clear(); var assemblies = ReferenceAssemblies.ToList(); - KnownType.ExtensionMethodsAssemblies = assemblies.ToList(); var usings = _current_usings.ToList(); Thread t = new Thread(() => { - LoadUsingsSymbols(assemblies, usings); - - if (loadKnownTypes) + foreach (var asm in assemblies.Select(x => x.Assembly)) { - _knownTypes.Clear(); - - foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList()) + Parallel.ForEach(asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive), (type) => { - if (usings.Exists(x => knownType.Type.Namespace == x) && assemblies.Exists(x => x == knownType.Type.Assembly)) + if (usings.Exists(x => type.Namespace == x)) { lock (_knownTypes) { - _knownTypes.Add(knownType); + if (!_knownTypes.Exists(x => x.Type.FullName == type.FullName)) + { + _knownTypes.Add(new KnownType(type)); + } } } - } + }); } if (_knownTypes.Count > 0 || _declaredTypes.Count > 0) @@ -1901,10 +1239,10 @@ namespace Tango.Scripting.Editors })); - //foreach (var knownType in _knownTypes) - //{ - // knownType.LoadDocumentation(); - //} + foreach (var knownType in _knownTypes) + { + knownType.LoadDocumentation(); + } } _isLoadingTypes = false; @@ -1918,19 +1256,10 @@ namespace Tango.Scripting.Editors { var declaredTypes = _parser.GetDeclaredTypes(Text); - if (AdditionalScripts != null) - { - foreach (var script in AdditionalScripts) - { - declaredTypes.AddRange(_parser.GetDeclaredTypes(script.Code)); - } - } - - if (declaredTypes.Exists(x => !_declaredTypes.Exists(y => y.Name == x.Name)) || _declaredTypes.Exists(x => !declaredTypes.Exists(y => y.Name == x.Name))) { _declaredTypes = declaredTypes; - InvalidateHighlighting(false); + InvalidateHighlighting(); } _declaredTypes = declaredTypes; @@ -1982,8 +1311,7 @@ namespace Tango.Scripting.Editors private void IndentCode() { - Text = CodeFormatter.Format(Text); - //Text = Indentation.CSharp.CSharpIndentationHelper.IndentCSharpCode(Text); + Text = Indentation.CSharp.CSharpIndentationHelper.IndentCSharpCode(Text); //Text = _parser.IndentCSharpCode(Text); } @@ -2061,11 +1389,7 @@ namespace Tango.Scripting.Editors private ConstructionSession GetConstructionSession() { - var currentLine = GetCurrentLineText(); - - //if (currentLine.Count(x => x == '(') > 1) return null; - - var expression = _parser.GetCurrentConstructionExpression(currentLine); + var expression = _parser.GetCurrentConstructionExpression(GetCurrentLineText()); if (expression != null) { @@ -2121,64 +1445,13 @@ namespace Tango.Scripting.Editors } } - else - { - var expression2 = _parser.GetCurrentConstructionExpressionAlt(GetCurrentLineText()); - - if (expression2 != null && expression2.Identifier != null) - { - ConstructionSession session = new ConstructionSession(); - - var line = GetCurrentLine(); - int parameterIndex = 0; - for (int i = CaretOffset; i > line.Offset; i--) - { - String c = Document.GetText(i, 1); - - if (c == "(") - { - KnownType type = null; - - if (expression2.Identifier != null) - { - var typeName = expression2.Identifier.ToString(); - type = _knownTypes.FirstOrDefault(x => x.Type.Name == typeName); - - if (type != null) - { - session.Type = type; - session.ParameterIndex = parameterIndex; - return session; - } - else - { - return null; - } - } - } - else if (c == ",") - { - parameterIndex++; - } - } - } - } return null; } private MethodSession GetMethodSession() { - var currentLine = GetCurrentLineText(); - - if (currentLine.Count(x => x == '(') > 1) - { - currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2]; - } - - currentLine = Regex.Replace(currentLine, "(?<=\")(.*?)(?=\")", string.Empty); - - var words = currentLine.Split(' '); + var words = GetCurrentLineText().Split(' '); if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void")) { @@ -2190,8 +1463,6 @@ namespace Tango.Scripting.Editors if (expression != null) { int parameterIndex = expression.Count(x => x == ','); - - expression = new string(expression.TakeWhile(x => x != '(').ToArray()); var tree = expression.Split('.').Select(x => x.Remove(@"\n|\r|\s|\t|\(|\)|\[|\]|<.*>")).ToList(); @@ -2237,82 +1508,16 @@ namespace Tango.Scripting.Editors return null; } - private MethodSession GetStaticMethodSession() - { - var words = GetCurrentLineText().Split(' '); - - if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void")) - { - return null; - } - - var expression = words.LastOrDefault(); - - if (expression != null) - { - int parameterIndex = expression.Count(x => x == ','); - expression = new string(expression.TakeWhile(x => x != '(').ToArray()); - - var tree = expression.Split('.').Select(x => x.Remove(@"\n|\r|\s|\t|\(|\)|\[|\]|<.*>")).ToList(); - var variableName = tree.FirstOrDefault(); - - if (variableName != null && tree.Count > 1) - { - tree.RemoveAt(0); - var variables = _parser.GetContextSymbols(Document.Text, CaretOffset); - var variable = variableName; - - if (variable != null) - { - var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable, "<.+>", "<T>")); - - if (knownType != null) - { - while (tree.Count > 1) - { - var memberName = tree.First(); - tree.RemoveAt(0); - var member = knownType.Members.FirstOrDefault(x => x.Name == memberName); - - if (member == null) - { - return null; - } - - knownType = _knownTypes.FirstOrDefault(x => x.Type.Namespace + "." + x.Type.Name == member.ReturnType.Namespace + "." + member.ReturnType.Name); - } - - return new MethodSession() - { - Type = knownType, - MethodName = tree.Last(), - ParameterIndex = parameterIndex, - }; - } - } - } - } - - return null; - } - private DeclaredMethodSession GetDeclaredMethodSession() { - var currentLine = GetCurrentLineText(); - - if (currentLine.Count(x => x == '(') > 1) - { - currentLine = currentLine.Split('(')[currentLine.Split('(').Length - 2]; - } - - var words = currentLine.Split(' '); + var words = GetCurrentLineText().Split(' '); if (words.Count() > 0 && (words.First() == "private" || words.First() == "public" || words.First() == "void")) { return null; } - var expression = currentLine; + var expression = GetPreviousWords().LastOrDefault(); if (expression != null) { @@ -2327,7 +1532,7 @@ namespace Tango.Scripting.Editors if (variable != null) { - var declaredType = _declaredTypes.FirstOrDefault(x => x.Name == Regex.Replace(variable.Type, "<.+>", "<T>")); + var declaredType = _declaredTypes.FirstOrDefault(x => x.Name == Regex.Replace(variable.Class, "<.+>", "<T>")); if (declaredType != null) { @@ -2386,413 +1591,5 @@ namespace Tango.Scripting.Editors } #endregion - - #region Reference Assemblies Changed - - private void OnReferenceAssembliesChanged() - { - if (ReferenceAssemblies != null) - { - ReferenceAssemblies.CollectionChanged -= ReferenceAssemblies_CollectionChanged; - ReferenceAssemblies.CollectionChanged += ReferenceAssemblies_CollectionChanged; - - InvalidateHighlighting(); - } - } - - private void ReferenceAssemblies_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) - { - InvalidateHighlighting(); - } - - #endregion - - #region Public Methods - - public void FormatCode() - { - try - { - int index = CaretOffset; - Document.BeginUpdate(); - IndentCode(); - Document.EndUpdate(); - CaretOffset = index; - } - catch - { - Debug.WriteLine("Error formatting code."); - } - } - - public void Highlight(int position, int length, int line) - { - Select(position, Math.Max(length, 1)); - ScrollToLine(line); - } - - public void InsertCode(String code) - { - Document.Insert(TextArea.Caret.Offset, code); - } - - public int Find(String text) - { - if (String.IsNullOrEmpty(text)) return -1; - - string txt = Document.Text; - int index = txt.IndexOf(text, TextArea.Caret.Offset); - - if (index > -1) - { - Select(index, text.Length); - ScrollToLine(TextArea.Selection.StartPosition.Line); - } - else - { - index = txt.IndexOf(text, 0); - - if (index > -1) - { - Select(index, text.Length); - ScrollToLine(TextArea.Selection.StartPosition.Line); - } - else - { - Select(0, 0); - System.Media.SystemSounds.Beep.Play(); - } - } - - return index; - } - - public int ReplaceNext(String text, String replace) - { - if (String.IsNullOrEmpty(text)) return -1; - - String selectedText = TextArea.Selection.GetText(); - - if (selectedText == text) - { - TextArea.Selection.ReplaceSelectionWithText(replace); - } - - return Find(text); - } - - public int ReplaceAll(String text, String replace) - { - int counter = 0; - - Select(0, 0); - - while (ReplaceNext(text, replace) > -1) - { - counter++; - }; - - return counter; - } - - public void ColorizeByKeyword(String text) - { - ResetColorizationByKeyword(); - - if (String.IsNullOrEmpty(text)) return; - - var txt = Document.Text; - - var indexes = txt.AllIndexesOf(text).ToList(); - - foreach (var index in indexes) - { - Document.BeginUpdate(); - - var line = Document.GetLineByOffset(index); - - OffsetColorizer colorizer = new OffsetColorizer(line, index, index + text.Length, ColorizeBrush); - TextArea.TextView.LineTransformers.Add(colorizer); - - Document.EndUpdate(); - } - } - - public void ResetColorizationByKeyword() - { - Document.BeginUpdate(); - - for (int i = 0; i < TextArea.TextView.LineTransformers.Count; i++) - { - if (TextArea.TextView.LineTransformers[i] is OffsetColorizer) - { - TextArea.TextView.LineTransformers.RemoveAt(i); - i--; - } - } - - Document.EndUpdate(); - } - - public void HighlighError(int position, int length) - { - try - { - ITextMarker marker = errorMarkerService.Create(position, length); - marker.MarkerTypes = TextMarkerTypes.SquigglyUnderline; - marker.MarkerColor = Colors.Red; - } - catch (Exception ex) - { - Debug.WriteLine($"Error highlighting script error.\n{ex.ToString()}"); - } - } - - public void ClearErrors() - { - errorMarkerService.RemoveAll(m => true); - } - - public void HighlightErrorLine(int lineNumber) - { - Document.BeginUpdate(); - - var line = Document.GetLineByNumber(lineNumber); - OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, ErrorLineBrush); - TextArea.TextView.LineTransformers.Add(errorLineColrizer); - - Document.EndUpdate(); - } - - public void HighlightDebugLine(int lineNumber) - { - Document.BeginUpdate(); - - var line = Document.GetLineByNumber(lineNumber); - OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, DebugLineBrush); - TextArea.TextView.LineTransformers.Add(errorLineColrizer); - - Document.EndUpdate(); - } - - public void HighlightBreakPoint(int lineNumber, List<ScriptBreakPointSymbol> symbols) - { - _breakPointLineNumber = lineNumber; - _breakPointSymbols = symbols.ToList(); - _currentBreakPointSymbol = null; - - Document.BeginUpdate(); - - var line = Document.GetLineByNumber(lineNumber); - OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, BreakPointLineBrush); - TextArea.TextView.LineTransformers.Add(errorLineColrizer); - - var breakPoint = breakPointMargin.BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber); - breakPoint.IsActive = true; - breakPointMargin.InvalidateVisual(); - - Document.EndUpdate(); - } - - public void ResetBreakPointLine() - { - _breakPointSymbols = new List<ScriptBreakPointSymbol>(); - _currentBreakPointSymbol = null; - ResetColorizationByKeyword(); - breakPointMargin.BreakPoints.ToList().ForEach(x => x.IsActive = false); - Mouse.OverrideCursor = null; - ClearErrors(); - breakPointMargin.InvalidateVisual(); - } - - public Point? GetLineVisualPosition(int lineNumber) - { - double top = TextArea.TextView.GetVisualTopByDocumentLine(lineNumber); - var visualLine = TextArea.TextView.GetVisualLine(lineNumber); - - if (visualLine != null) - { - var textLine = visualLine.GetTextLine(0); - var x = visualLine.GetTextLineVisualXPosition(textLine, visualLine.VisualLengthWithEndOfLineMarker); - var left = visualLine.VisualLengthWithEndOfLineMarker; - return new Point(x, top); - } - - return null; - } - - public List<ScriptBreakPoint> GetBreakPoints() - { - List<ScriptBreakPoint> breakPoints = new List<ScriptBreakPoint>(); - - foreach (var b in breakPointMargin.BreakPoints) - { - ScriptBreakPoint breakPoint = new ScriptBreakPoint(); - breakPoint.Script = ScriptSource; - breakPoint.LineNumber = b.LineNumber; - - var line = Document.GetLineByNumber(b.LineNumber); - breakPoint.LineStartOffset = line.Offset; - breakPoint.LineEndOffset = line.EndOffset; - - var symbols = _parser.GetContextSymbols(Document.Text, line.Offset); - - foreach (var symbol in symbols.Where(x => (x.Kind == SymbolKind.Property || x.Kind == SymbolKind.Field || x.Kind == SymbolKind.Local || x.Kind == SymbolKind.Parameter) && !x.IsUnassigned)) - { - if (symbol.Offset < line.Offset) - { - breakPoint.ContextSymbols.Add(new ScriptBreakPointSymbol() - { - Name = symbol.Name, - Offset = symbol.Offset, - Length = symbol.Length, - }); - } - } - - breakPoints.Add(breakPoint); - } - - return breakPoints; - } - - #endregion - - #region BreakPoint Symbols Search - - private void ScriptEditor_MouseMove(object sender, MouseEventArgs e) - { - if (IsReadOnly && _breakPointSymbols.Count > 0) - { - try - { - var word_separators_plus = word_separators.ToList(); - word_separators_plus.Add(')'); - word_separators_plus.Add(';'); - - var textView = TextArea.TextView; - Point position = e.GetPosition(textView); - position.Y += textView.VerticalOffset; - VisualLine visualLine = textView.GetVisualLineFromVisualTop(position.Y); - int columnIndex = visualLine.GetVisualColumnFloor(position, false); - String line = Document.GetText(visualLine.FirstDocumentLine.Offset, visualLine.FirstDocumentLine.Length); - if (columnIndex < line.Length) - { - int wordStartIndex = columnIndex; - int wordEndIndex = columnIndex; - - while (wordStartIndex > 0) - { - if (word_separators_plus.Contains(line[wordStartIndex])) break; - wordStartIndex--; - } - - while (wordEndIndex < line.Length) - { - if (word_separators_plus.Contains(line[wordEndIndex])) break; - wordEndIndex++; - } - - if (wordStartIndex > 0) - { - wordStartIndex++; - } - - String word = line.Substring(wordStartIndex, wordEndIndex - wordStartIndex); - - var breakPointSymbol = _breakPointSymbols.FirstOrDefault(x => x.Name == word); - - if (breakPointSymbol != null) - { - int wordStartOffset = visualLine.FirstDocumentLine.Offset + wordStartIndex; - - ClearErrors(); - ITextMarker marker = errorMarkerService.Create(wordStartOffset, word.Length); - marker.MarkerTypes = TextMarkerTypes.NormalUnderline; - marker.MarkerColor = Colors.Yellow; - Mouse.OverrideCursor = Cursors.Hand; - - _currentBreakPointSymbol = breakPointSymbol; - _currentBreakPointSymbolPosition = visualLine.GetVisualPosition(wordEndIndex, VisualYPosition.LineTop); - } - else - { - _currentBreakPointSymbol = null; - Mouse.OverrideCursor = null; - ClearErrors(); - } - } - else - { - _currentBreakPointSymbol = null; - Mouse.OverrideCursor = null; - ClearErrors(); - } - } - catch (Exception ex) - { - _currentBreakPointSymbol = null; - Mouse.OverrideCursor = null; - ClearErrors(); - Debug.WriteLine(ex.Message); - } - } - } - - protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) - { - base.OnPreviewMouseLeftButtonUp(e); - - if (_currentBreakPointSymbol != null) - { - Mouse.OverrideCursor = null; - Debug.WriteLine($"Pressed on break point symbol: {_currentBreakPointSymbol.Name}"); - BreakPointSymbolPressed?.Invoke(this, new BreakPointSymbolPressedEventArgs() - { - BreakPointSymbol = _currentBreakPointSymbol, - Position = _currentBreakPointSymbolPosition - }); - } - } - - public String GetCaretWord() - { - try - { - var word_separators_plus = word_separators.ToList(); - word_separators_plus.Add(')'); - word_separators_plus.Add(';'); - - int wordStartOffset = CaretOffset; - int wordEndOffset = CaretOffset; - - while (wordStartOffset > 0) - { - if (word_separators_plus.Contains(Document.Text[wordStartOffset])) break; - wordStartOffset--; - } - - while (wordEndOffset < Document.Text.Length) - { - if (word_separators_plus.Contains(Document.Text[wordEndOffset])) break; - wordEndOffset++; - } - - if (wordStartOffset > 0) - { - wordStartOffset++; - } - - String word = Document.Text.Substring(wordStartOffset, wordEndOffset - wordStartOffset); - - return word; - } - catch - { - return null; - } - } - - #endregion } } |
