From 8d3a394993673df4b9fab8bee62f4ac8b25e1a5a Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 11 Mar 2019 08:56:10 +0200 Subject: Working on scripting engine. --- .../CodeCompletion/CompletionWindowBase.cs | 14 +- .../CodeCompletion/ICompletionData.cs | 31 +- .../Tango.Scripting.Editors/ExtensionMethods.cs | 38 + .../Intellisense/ClassCompletionItem.cs | 32 + .../Intellisense/ClassCompletionItemPopup.cs | 25 + .../Intellisense/CompletionItem.cs | 48 ++ .../Intellisense/CompletionItemPopupControl.cs | 14 + .../Intellisense/EnumCompletionItem.cs | 21 + .../Intellisense/EnumCompletionItemPopup.cs | 25 + .../Intellisense/ICompletionItem.cs | 14 + .../Intellisense/ICompletionProvider.cs | 13 + .../Intellisense/InterfaceCompletionItem.cs | 21 + .../Intellisense/InterfaceCompletionItemPopup.cs | 25 + .../Intellisense/KnownType.cs | 237 +++--- .../Intellisense/KnownTypeMember.cs | 2 + .../Intellisense/KnownTypeMethod.cs | 2 - .../Intellisense/KnownTypeMethodParameter.cs | 2 +- .../Intellisense/MethodCompletionItem.cs | 36 + .../Intellisense/MethodCompletionItemPopup.cs | 25 + .../Intellisense/NamespaceCompletionItem.cs | 27 + .../Intellisense/NamespaceCompletionItemPopup.cs | 25 + .../Intellisense/PropertyCompletionItem.cs | 22 + .../Intellisense/PropertyCompletionItemPopup.cs | 25 + .../Intellisense/StructCompletionItem.cs | 21 + .../Intellisense/StructCompletionItemPopup.cs | 25 + .../Tango.Scripting.Editors/ScriptEditor.cs | 804 +++++++++------------ .../Tango.Scripting.Editors.csproj | 19 + .../Tango.Scripting.Editors/Themes/Generic.xaml | 249 +++++-- 28 files changed, 1179 insertions(+), 663 deletions(-) create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ExtensionMethods.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItemPopup.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItemPopupControl.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItemPopup.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionProvider.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItemPopup.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItemPopup.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItemPopup.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItemPopup.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItem.cs create mode 100644 Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItemPopup.cs (limited to 'Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors') diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindowBase.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindowBase.cs index e33ede203..7766d323a 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindowBase.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/CompletionWindowBase.cs @@ -290,7 +290,7 @@ namespace Tango.Scripting.Editors.CodeCompletion //sourceIsInitialized = true; } - private void SetPosition() + public void SetPosition() { if (document != null && this.StartOffset != this.TextArea.Caret.Offset) { @@ -301,6 +301,16 @@ namespace Tango.Scripting.Editors.CodeCompletion SetPosition(this.TextArea.Caret.Position); } } + + public void UpdatePositionFix() + { + SetPosition(this.TextArea.Caret.Position); + } + + //public void UpdatePosition() + //{ + // SetPosition(this.TextArea.Caret.Position); + //} /// protected override void OnClosed(EventArgs e) @@ -337,7 +347,7 @@ namespace Tango.Scripting.Editors.CodeCompletion /// Updates the position of the CompletionWindow based on the parent TextView position and the screen working area. /// It ensures that the CompletionWindow is completely visible on the screen. /// - protected void UpdatePosition() + public void UpdatePosition() { TextView textView = this.TextArea.TextView; // PointToScreen returns device dependent units (physical pixels) diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/ICompletionData.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/ICompletionData.cs index b0e9eeccb..9f16876b3 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/ICompletionData.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/CodeCompletion/ICompletionData.cs @@ -3,6 +3,7 @@ using System; using System.Windows.Media; +using System.Windows.Media.Imaging; using Tango.Scripting.Editors.Document; using Tango.Scripting.Editors.Editing; @@ -13,32 +14,26 @@ namespace Tango.Scripting.Editors.CodeCompletion /// public interface ICompletionData { - /// - /// Gets the image. - /// - ImageSource Image { get; } - - /// - /// Gets the text. This property is used to filter the list of visible elements. - /// - string Text { get; } - - /// - /// The displayed content. This can be the same as 'Text', or a WPF UIElement if - /// you want to display rich content. - /// - object Content { get; } + /// + /// Gets the image. + /// + BitmapSource Image { get; } + + /// + /// Gets the text. This property is used to filter the list of visible elements. + /// + string Text { get; } /// /// Gets the description. /// - object Description { get; } + object Description { get; set; } /// /// Gets the priority. This property is used in the selection logic. You can use it to prefer selecting those items /// which the user is accessing most frequently. /// - double Priority { get; } + double Priority { get; set; } /// /// Perform the completion. @@ -49,6 +44,6 @@ namespace Tango.Scripting.Editors.CodeCompletion /// The EventArgs used for the insertion request. /// These can be TextCompositionEventArgs, KeyEventArgs, MouseEventArgs, depending on how /// the insertion was triggered. - void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs); + void Complete(ScriptEditor editor); } } diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ExtensionMethods.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ExtensionMethods.cs new file mode 100644 index 000000000..1605ff281 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ExtensionMethods.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Tango.Scripting.Editors +{ + internal static class ExtensionMethodsNoName + { + public static String Remove(this String str, String pattern) + { + return Regex.Replace(str, pattern, ""); + } + + public static String GetFriendlyName(this Type type) + { + String name = type.Name; + + if (type.IsGenericType) + { + List args = new List(); + + foreach (var lGenericArgument in type.GetGenericTypeDefinition().GetGenericArguments()) + { + args.Add(lGenericArgument.Name); + } + + String gArgs = String.Join(",", args); + + name = $"{new String(type.Name.TakeWhile(x => x != '`').ToArray())}<{gArgs}>"; + } + + return name; + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItem.cs new file mode 100644 index 000000000..a1734ba30 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItem.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class ClassCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("class.png"); + + public override BitmapSource Image => image; + public override string Text => Name; + + public String Name { get; set; } + public String Namespace { get; set; } + public override CompletionItemPopupControl PopupControl => new ClassCompletionItemPopup(); + + public override void Complete(ScriptEditor editor) + { + base.Complete(editor); + + if (Text.Contains("")) + { + editor.CaretOffset -= 2; + editor.Select(editor.CaretOffset, 1); + } + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItemPopup.cs new file mode 100644 index 000000000..d575ba9db --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ClassCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class ClassCompletionItemPopup : CompletionItemPopupControl + { + static ClassCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ClassCompletionItemPopup), new FrameworkPropertyMetadata(typeof(ClassCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs new file mode 100644 index 000000000..83ada090f --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItem.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media.Imaging; +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Editing; + +namespace Tango.Scripting.Editors.Intellisense +{ + public abstract class CompletionItem : DependencyObject, ICompletionItem + { + public abstract string Text { get; } + public object Description { get; set; } + public double Priority { get; set; } + public abstract CompletionItemPopupControl PopupControl { get; } + + public bool IsSelected + { + get { return (bool)GetValue(IsSelectedProperty); } + set { SetValue(IsSelectedProperty, value); } + } + public static readonly DependencyProperty IsSelectedProperty = + DependencyProperty.Register("IsSelected", typeof(bool), typeof(CompletionItem), new PropertyMetadata(false)); + + public virtual void Complete(ScriptEditor editor) + { + int index = editor.GetCurrentWordStartIndex(); + int max = editor.GetCurrentLine().EndOffset; + + editor.Document.Replace(index, Math.Min(max - index, Text.Length), Text); + } + + public abstract BitmapSource Image { get; } + + protected static BitmapSource GetImage(String name) + { + return new BitmapImage(new Uri($"pack://application:,,,/Tango.Scripting.Editors;component/Images/{name}", UriKind.Absolute)); + } + + public override string ToString() + { + return Text; + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItemPopupControl.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItemPopupControl.cs new file mode 100644 index 000000000..14e5b6681 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/CompletionItemPopupControl.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace Tango.Scripting.Editors.Intellisense +{ + public abstract class CompletionItemPopupControl : Control + { + + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItem.cs new file mode 100644 index 000000000..c8f34347e --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItem.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class EnumCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("enum.png"); + + public override BitmapSource Image => image; + public override string Text => Name; + public override CompletionItemPopupControl PopupControl => new EnumCompletionItemPopup(); + + public String Name { get; set; } + public String Namespace { get; set; } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItemPopup.cs new file mode 100644 index 000000000..0ef29c338 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/EnumCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class EnumCompletionItemPopup : CompletionItemPopupControl + { + static EnumCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumCompletionItemPopup), new FrameworkPropertyMetadata(typeof(EnumCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionItem.cs new file mode 100644 index 000000000..83e304e8b --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionItem.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Scripting.Editors.CodeCompletion; + +namespace Tango.Scripting.Editors.Intellisense +{ + public interface ICompletionItem : ICompletionData + { + CompletionItemPopupControl PopupControl { get; } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionProvider.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionProvider.cs new file mode 100644 index 000000000..bc48ce401 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/ICompletionProvider.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Scripting.Editors.Intellisense +{ + public interface ICompletionProvider + { + + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItem.cs new file mode 100644 index 000000000..56f6db7af --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItem.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class InterfaceCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("interface.png"); + + public override string Text => Name; + public override CompletionItemPopupControl PopupControl => new InterfaceCompletionItemPopup(); + public override BitmapSource Image => image; + + public String Name { get; set; } + public String Namespace { get; set; } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItemPopup.cs new file mode 100644 index 000000000..126a81c4c --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/InterfaceCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class InterfaceCompletionItemPopup : CompletionItemPopupControl + { + static InterfaceCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(InterfaceCompletionItemPopup), new FrameworkPropertyMetadata(typeof(InterfaceCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs index 3cb61b991..06282e15d 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; @@ -86,39 +87,31 @@ namespace Tango.Scripting.Editors.Intellisense public KnownType(Type type) { + _summary = "Loading documentation..."; _constructors = new List(); _methods = new List(); _properties = new List(); Type = type; Name = type.Name; + Init(); } + public override string ToString() + { + return Type.ToString(); + } + private void Init() { InitTypeDefinition(); InitFriendlyName(); + InitTypeDocumentation(); } private void InitFriendlyName() { - if (Type.IsGenericType) - { - List args = new List(); - - foreach (var lGenericArgument in Type.GetGenericTypeDefinition().GetGenericArguments()) - { - args.Add(lGenericArgument.Name); - } - - String gArgs = String.Join(",", args); - - FriendlyName = $"{new String(Type.Name.TakeWhile(x => x != '`').ToArray())}<{gArgs}>"; - } - else - { - FriendlyName = Type.Name; - } + FriendlyName = Type.GetFriendlyName(); } private void InitTypeDefinition() @@ -133,6 +126,8 @@ namespace Tango.Scripting.Editors.Intellisense { if (!_initialized) { + _initialized = true; + XmlDocument xmlDoc = null; if (_assemblies_docs_cache.ContainsKey(Type.Assembly)) @@ -165,155 +160,157 @@ namespace Tango.Scripting.Editors.Intellisense if (xmlDoc != null) { - //Load Type Summary + Task.Factory.StartNew(() => { - string path = "T:" + Type.FullName; - XmlNode xmlDocuOfType = xmlDoc.SelectSingleNode("//member[starts-with(@name, '" + path + "')]"); - if (xmlDocuOfType != null) + //Load Type Summary { - XmlNode summaryNode = xmlDocuOfType.SelectSingleNode("summary"); - Summary = summaryNode.InnerText; - } - } + string path = "T:" + Type.FullName; + XmlNode xmlDocuOfType = xmlDoc.SelectSingleNode("//member[starts-with(@name, '" + path + "')]"); - //Load Constructors... - { - string path = "M:" + Type.FullName + ".#ctor"; - - var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType().ToList(); - var constructors = Type.GetConstructors().Where(x => x.IsPublic).ToList(); - - for (int i = 0; i < constructors.Count; i++) - { - var constructor = constructors[i]; - XmlNode cDoc = null; - - if (i < docNodes.Count) + if (xmlDocuOfType != null) { - cDoc = docNodes[i]; + XmlNode summaryNode = xmlDocuOfType.SelectSingleNode("summary"); + Summary = summaryNode.InnerText; } + } - KnownTypeConstructor c = new KnownTypeConstructor(this); - c.Summary = cDoc != null ? cDoc.SelectSingleNode("summary").InnerText : $"Initializes a new instance of {FriendlyName}."; + //Load Constructors... + { + string path = "M:" + Type.FullName + ".#ctor"; - var parameters = constructor.GetParameters().ToList(); - var parametersNodes = cDoc != null ? cDoc.SelectNodes("param").OfType().ToList() : new List(); + var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType().ToList(); + var constructors = Type.GetConstructors().Where(x => x.IsPublic).ToList(); - for (int j = 0; j < parameters.Count; j++) + for (int i = 0; i < constructors.Count; i++) { - var parameter = parameters[j]; - XmlNode pNode = null; + var constructor = constructors[i]; + XmlNode cDoc = null; - if (j < parametersNodes.Count) + if (i < docNodes.Count) { - pNode = parametersNodes[j]; + cDoc = docNodes[i]; } - KnownTypeMethodParameter p = new KnownTypeMethodParameter(); - p.Type = parameter.ParameterType; - p.Name = parameter.Name; - p.Description = pNode != null ? pNode.InnerText : null; + KnownTypeConstructor c = new KnownTypeConstructor(this); + c.Summary = cDoc != null ? cDoc.SelectSingleNode("summary").InnerXml : $"Initializes a new instance of {FriendlyName}."; - if (j == parameters.Count - 1) + var parameters = constructor.GetParameters().ToList(); + var parametersNodes = cDoc != null ? cDoc.SelectNodes("param").OfType().ToList() : new List(); + + for (int j = 0; j < parameters.Count; j++) { - p.IsLast = true; - } + var parameter = parameters[j]; + XmlNode pNode = null; - c.Parameters.Add(p); - } + if (j < parametersNodes.Count) + { + pNode = parametersNodes[j]; + } - _constructors.Add(c); - } - } + KnownTypeMethodParameter p = new KnownTypeMethodParameter(); + p.Type = parameter.ParameterType.GetFriendlyName(); + p.Name = parameter.Name; + p.Description = pNode != null ? pNode.InnerText : null; - //Load Methods... - { - string path = "M:" + Type.FullName; + if (j == parameters.Count - 1) + { + p.IsLast = true; + } - var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType().ToList(); - var methods = Type.GetRuntimeMethods().Where(x => x.IsPublic && !x.IsSpecialName).ToList(); + c.Parameters.Add(p); + } - //TODO: Separate extension methods! - methods.AddRange(Type.GetExtensionMethods(Type.Assembly).ToList()); + _constructors.Add(c); + } + } - for (int i = 0; i < methods.Count; i++) + //Load Methods... { - var method = methods[i]; - XmlNode mDoc = null; + string path = "M:" + Type.FullName; - mDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(method.DeclaringType.Name + "." + method.Name)); + var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType().ToList(); + var methods = Type.GetRuntimeMethods().Where(x => x.IsPublic && !x.IsSpecialName).ToList(); - KnownTypeMethod m = new KnownTypeMethod(this); - m.Summary = mDoc != null ? mDoc.SelectSingleNode("summary").InnerText : "No documentation"; - m.Name = method.Name; - m.ReturnType = method.ReturnType; - m.ReturnTypeFriendlyName = method.ReturnType.Name; + //TODO: Separate extension methods! + methods.AddRange(Type.GetExtensionMethods(Type.Assembly).ToList()); - if (method.ReturnType.IsGenericType) + if (typeof(IEnumerable).IsAssignableFrom(Type)) { - List args = new List(); + var linqMethods = typeof(System.Linq.Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).ToList(); + methods.AddRange(linqMethods); + } - foreach (var lGenericArgument in m.ReturnType.GetGenericTypeDefinition().GetGenericArguments()) - { - args.Add(lGenericArgument.Name); - } + for (int i = 0; i < methods.Count; i++) + { + var method = methods[i]; + XmlNode mDoc = null; - String gArgs = String.Join(",", args); + mDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(method.DeclaringType.Name + "." + method.Name)); - m.ReturnTypeFriendlyName = $"{new String(Type.Name.TakeWhile(x => x != '`').ToArray())}<{gArgs}>"; - } + KnownTypeMethod m = new KnownTypeMethod(this); + m.Summary = mDoc != null ? mDoc.SelectSingleNode("summary").InnerXml : "No documentation"; + m.Name = method.Name; + m.ReturnType = method.ReturnType; + m.ReturnTypeFriendlyName = method.ReturnType.GetFriendlyName(); - var parameters = method.GetParameters().ToList(); - var parametersNodes = mDoc != null ? mDoc.SelectNodes("param").OfType().ToList() : new List(); + var parameters = method.GetParameters().ToList(); + var parametersNodes = mDoc != null ? mDoc.SelectNodes("param").OfType().ToList() : new List(); - for (int j = 0; j < parameters.Count; j++) - { - var parameter = parameters[j]; - XmlNode pNode = null; + bool isLinq = method.DeclaringType == typeof(Enumerable); - if (j < parametersNodes.Count) + for (int j = 0; j < parameters.Count; j++) { - pNode = parametersNodes[j]; - } + var parameter = parameters[j]; - KnownTypeMethodParameter p = new KnownTypeMethodParameter(); - p.Type = parameter.ParameterType; - p.Name = parameter.Name; - p.Description = pNode != null ? pNode.InnerText : null; + XmlNode pNode = null; - if (j == parameters.Count - 1) - { - p.IsLast = true; + if (j < parametersNodes.Count) + { + pNode = parametersNodes[j]; + } + + KnownTypeMethodParameter p = new KnownTypeMethodParameter(); + p.Type = parameter.ParameterType.GetFriendlyName(); + p.Name = parameter.Name; + p.Description = pNode != null ? pNode.InnerText : null; + + if (j == parameters.Count - 1) + { + p.IsLast = true; + } + + if (j == 0 && isLinq) continue; + m.Parameters.Add(p); } - m.Parameters.Add(p); + _methods.Add(m); } - - _methods.Add(m); } - } - //Load Properties - { - string path = "P:" + Type.FullName; + //Load Properties + { + string path = "P:" + Type.FullName; - var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType().ToList(); - var properties = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType.IsPublic).ToList(); + var docNodes = xmlDoc.SelectNodes("//member[starts-with(@name, '" + path + "')]").OfType().ToList(); + var properties = Type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType.IsPublic).ToList(); - for (int i = 0; i < properties.Count; i++) - { - var property = properties[i]; - var pDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(property.DeclaringType.Name + "." + property.Name)); + for (int i = 0; i < properties.Count; i++) + { + var property = properties[i]; + var pDoc = docNodes.FirstOrDefault(x => x.Attributes["name"].InnerText.Contains(property.DeclaringType.Name + "." + property.Name)); - KnownTypeProperty p = new KnownTypeProperty(this); - p.Summary = pDoc != null ? pDoc.SelectSingleNode("summary").InnerText : "No documentation"; - p.Name = property.Name; - p.ReturnType = property.PropertyType; + KnownTypeProperty p = new KnownTypeProperty(this); + p.Summary = pDoc != null ? pDoc.SelectSingleNode("summary").InnerXml : "No documentation"; + p.Name = property.Name; + p.ReturnType = property.PropertyType; + p.ReturnTypeFriendlyName = property.PropertyType.GetFriendlyName(); - _properties.Add(p); + _properties.Add(p); + } } - } + + }); } _initialized = true; diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMember.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMember.cs index d3d8cb428..1405a8c34 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMember.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMember.cs @@ -10,6 +10,8 @@ namespace Tango.Scripting.Editors.Intellisense { public Type ReturnType { get; set; } + public String ReturnTypeFriendlyName { get; set; } + public KnownType Type { get; set; } public String Summary { get; set; } diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs index 27b052978..0ae4b708e 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs @@ -8,8 +8,6 @@ namespace Tango.Scripting.Editors.Intellisense { public class KnownTypeMethod : KnownTypeMember { - public String ReturnTypeFriendlyName { get; set; } - public List Parameters { get; set; } public KnownTypeMethod() diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethodParameter.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethodParameter.cs index c4f2a62c5..59f6db4fd 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethodParameter.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethodParameter.cs @@ -8,7 +8,7 @@ namespace Tango.Scripting.Editors.Intellisense { public class KnownTypeMethodParameter { - public Type Type { get; set; } + public String Type { get; set; } public String Name { get; set; } public String Description { get; set; } public bool IsLast { get; set; } diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItem.cs new file mode 100644 index 000000000..0a0883ede --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItem.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class MethodCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("method.png"); + + public override string Text => Name; + public override CompletionItemPopupControl PopupControl => new MethodCompletionItemPopup(); + public override BitmapSource Image => image; + + public String Class { get; set; } + public String Name { get; set; } + public String ReturnType { get; set; } + + public int Overloads { get; set; } + + public bool HasOverloads + { + get { return Overloads > 0; } + } + + public List Parameters { get; set; } + + public MethodCompletionItem() + { + Parameters = new List(); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItemPopup.cs new file mode 100644 index 000000000..1b9717307 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/MethodCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class MethodCompletionItemPopup : CompletionItemPopupControl + { + static MethodCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(MethodCompletionItemPopup), new FrameworkPropertyMetadata(typeof(MethodCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItem.cs new file mode 100644 index 000000000..d5c8db38a --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItem.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class NamespaceCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("namespace.png"); + + public override string Text => Name; + public override CompletionItemPopupControl PopupControl => new NamespaceCompletionItemPopup(); + public override BitmapSource Image => image; + + public String Name { get; set; } + public String Assembly { get; set; } + + public override void Complete(ScriptEditor editor) + { + var line = editor.GetCurrentLine(); + editor.Document.Replace(line, "using " + Name); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItemPopup.cs new file mode 100644 index 000000000..7adc82fd8 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/NamespaceCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class NamespaceCompletionItemPopup : CompletionItemPopupControl + { + static NamespaceCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(NamespaceCompletionItemPopup), new FrameworkPropertyMetadata(typeof(NamespaceCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItem.cs new file mode 100644 index 000000000..c301e8ede --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItem.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class PropertyCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("property.png"); + + public override string Text => Name; + public override CompletionItemPopupControl PopupControl => new PropertyCompletionItemPopup(); + public override BitmapSource Image => image; + + public String Name { get; set; } + public String Class { get; set; } + public String Type { get; set; } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItemPopup.cs new file mode 100644 index 000000000..7790d6c43 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/PropertyCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class PropertyCompletionItemPopup : CompletionItemPopupControl + { + static PropertyCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyCompletionItemPopup), new FrameworkPropertyMetadata(typeof(PropertyCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItem.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItem.cs new file mode 100644 index 000000000..b89a7cee2 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItem.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class StructCompletionItem : CompletionItem + { + private static BitmapSource image = GetImage("struct.png"); + + public override string Text => Name; + public override CompletionItemPopupControl PopupControl => new StructCompletionItemPopup(); + public override BitmapSource Image => image; + + public String Name { get; set; } + public String Namespace { get; set; } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItemPopup.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItemPopup.cs new file mode 100644 index 000000000..09512f405 --- /dev/null +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Intellisense/StructCompletionItemPopup.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class StructCompletionItemPopup : CompletionItemPopupControl + { + static StructCompletionItemPopup() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(StructCompletionItemPopup), new FrameworkPropertyMetadata(typeof(StructCompletionItemPopup))); + } + } +} diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ScriptEditor.cs index 3370ca0ee..49d745d6c 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ScriptEditor.cs +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/ScriptEditor.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -69,320 +70,7 @@ namespace Tango.Scripting.Editors private class MethodSession { public KnownType Type { get; set; } - public int ParameterIndex { get; set; } - public List TypeArguments { get; set; } - } - - #endregion - - #region Completion - - /// - /// Represents an auto complete item. - /// - /// - internal class TypeCompletionData : DependencyObject, ICompletionData - { - private String _description; - - /// - /// Gets or sets the icon source. - /// - public BitmapSource Source { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The text. - /// The description. - public TypeCompletionData(String type, string name, String ns, String description) - { - - Type = type; - this.Text = name; - Namespace = ns; - _description = description; - } - - /// - /// Gets the image. - /// - public System.Windows.Media.ImageSource Image - { - get { return Source; } - } - - /// - /// Gets the text. This property is used to filter the list of visible elements. - /// - public string Text { get; private set; } - - // Use this property if you want to show a fancy UIElement in the drop down list. - public object Content - { - get { return this.Text; } - } - - /// - /// Gets the description. - /// - public object Description - { - get { return _description; } - } - - public String Type { get; set; } - - public String Namespace { get; set; } - - /// - /// Gets the priority. This property is used in the selection logic. You can use it to prefer selecting those items - /// which the user is accessing most frequently. - /// - public double Priority { get { return 0; } } - - /// - /// Perform the completion. - /// - /// The text area on which completion is performed. - /// The text segment that was used by the completion window if - /// the user types (segment between CompletionWindow.StartOffset and CompletionWindow.EndOffset). - /// The EventArgs used for the insertion request. - /// These can be TextCompositionEventArgs, KeyEventArgs, MouseEventArgs, depending on how - /// the insertion was triggered. - public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) - { - textArea.Document.Replace(completionSegment, this.Text); - } - - public bool IsSelected - { - get { return (bool)GetValue(IsSelectedProperty); } - set { SetValue(IsSelectedProperty, value); } - } - public static readonly DependencyProperty IsSelectedProperty = - DependencyProperty.Register("IsSelected", typeof(bool), typeof(TypeCompletionData), new PropertyMetadata(false, IsSelectedChanged)); - - private static void IsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - Debug.WriteLine("Selected"); - } - - - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return Text; - } - } - - internal class MethodCompletionData : DependencyObject, ICompletionData - { - private String _description; - - /// - /// Gets or sets the icon source. - /// - public BitmapSource Source { get; set; } - - public String ReturnType { get; set; } - - public String Type { get; set; } - - public String Class { get; set; } - - public int Overloads { get; set; } - - public List Parameters { get; set; } - - public bool HasOverloads - { - get { return Overloads > 0; } - } - - public MethodCompletionData(String cls, string name, String returnType, String description, List parameters, int overloads) - { - Type = "method"; - Parameters = parameters; - Class = cls; - this.Text = name; - Overloads = overloads; - ReturnType = returnType; - _description = description; - } - - /// - /// Gets the image. - /// - public System.Windows.Media.ImageSource Image - { - get { return Source; } - } - - /// - /// Gets the text. This property is used to filter the list of visible elements. - /// - public string Text { get; private set; } - - // Use this property if you want to show a fancy UIElement in the drop down list. - public object Content - { - get { return this.Text; } - } - - /// - /// Gets the description. - /// - public object Description - { - get { return _description; } - } - - /// - /// Gets the priority. This property is used in the selection logic. You can use it to prefer selecting those items - /// which the user is accessing most frequently. - /// - public double Priority { get { return 0; } } - - /// - /// Perform the completion. - /// - /// The text area on which completion is performed. - /// The text segment that was used by the completion window if - /// the user types (segment between CompletionWindow.StartOffset and CompletionWindow.EndOffset). - /// The EventArgs used for the insertion request. - /// These can be TextCompositionEventArgs, KeyEventArgs, MouseEventArgs, depending on how - /// the insertion was triggered. - public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) - { - textArea.Document.Replace(completionSegment, this.Text); - } - - public bool IsSelected - { - get { return (bool)GetValue(IsSelectedProperty); } - set { SetValue(IsSelectedProperty, value); } - } - public static readonly DependencyProperty IsSelectedProperty = - DependencyProperty.Register("IsSelected", typeof(bool), typeof(MethodCompletionData), new PropertyMetadata(false, IsSelectedChanged)); - - private static void IsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - Debug.WriteLine("Selected"); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return Text; - } - } - - internal class PropertyCompletionData : DependencyObject, ICompletionData - { - private String _description; - - /// - /// Gets or sets the icon source. - /// - public BitmapSource Source { get; set; } - - public String ReturnType { get; set; } - - public String Type { get; set; } - - public String Class { get; set; } - - public PropertyCompletionData(String cls, string name, String returnType, String description) - { - Type = "property"; - Class = cls; - this.Text = name; - ReturnType = returnType; - _description = description; - } - - /// - /// Gets the image. - /// - public System.Windows.Media.ImageSource Image - { - get { return Source; } - } - - /// - /// Gets the text. This property is used to filter the list of visible elements. - /// - public string Text { get; private set; } - - // Use this property if you want to show a fancy UIElement in the drop down list. - public object Content - { - get { return this.Text; } - } - - /// - /// Gets the description. - /// - public object Description - { - get { return _description; } - } - - /// - /// Gets the priority. This property is used in the selection logic. You can use it to prefer selecting those items - /// which the user is accessing most frequently. - /// - public double Priority { get { return 0; } } - - /// - /// Perform the completion. - /// - /// The text area on which completion is performed. - /// The text segment that was used by the completion window if - /// the user types (segment between CompletionWindow.StartOffset and CompletionWindow.EndOffset). - /// The EventArgs used for the insertion request. - /// These can be TextCompositionEventArgs, KeyEventArgs, MouseEventArgs, depending on how - /// the insertion was triggered. - public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) - { - textArea.Document.Replace(completionSegment, this.Text); - } - - public bool IsSelected - { - get { return (bool)GetValue(IsSelectedProperty); } - set { SetValue(IsSelectedProperty, value); } - } - public static readonly DependencyProperty IsSelectedProperty = - DependencyProperty.Register("IsSelected", typeof(bool), typeof(PropertyCompletionData), new PropertyMetadata(false, IsSelectedChanged)); - - private static void IsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - Debug.WriteLine("Selected"); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return Text; - } + public String MethodName { get; set; } } #endregion @@ -700,76 +388,53 @@ namespace Tango.Scripting.Editors return null; } - //private MethodSession GetMethodSession() - //{ - // var lineText = GetCurrentLineText(); - // var expression = lineText.Split(' ').ToList().LastOrDefault(); - - // if (expression != null) - // { - - // } - - - // var expression = _parser.GetExpression(GetCurrentLineText()); - - // if (expression != null) - // { - // MethodSession session = new MethodSession(); - - // var line = GetCurrentLine(); - // int parameterIndex = 0; - // for (int i = CaretOffset; i > line.Offset; i--) - // { - // String c = Document.GetText(i, 1); - - // if (c == "(") - // { - // //var typeDeclaration = expression.Type as GenericNameSyntax; - - // //KnownType type = null; - - // //if (typeDeclaration != null) - // //{ - // // var typeName = typeDeclaration.Identifier.ToString(); - // // var argumentsCount = typeDeclaration.TypeArgumentList.Arguments.Count; - // // session.TypeArguments = typeDeclaration.TypeArgumentList.Arguments.Select(x => x.ToString()).ToList(); - - // // if (argumentsCount == 0) - // // { - // // type = _knownTypes.FirstOrDefault(x => x.Type.Name == expression.Type.ToString()); - // // } - // // else - // // { - // // type = _knownTypes.FirstOrDefault(x => x.Type.Name == typeName + "`" + argumentsCount); - // // } - // //} - // //else - // //{ - // // type = _knownTypes.FirstOrDefault(x => x.Name == expression.Type.ToString()); - // //} - - // //if (type != null) - // //{ - // // session.Type = type; - // // session.ParameterIndex = parameterIndex; - // // return session; - // //} - // //else - // //{ - // // return null; - // //} - // } - // else if (c == ",") - // { - // parameterIndex++; - // } - - // } - // } - - // return null; - //} + private MethodSession GetMethodSession() + { + var expression = GetPreviousWords().LastOrDefault(); + + if (expression != null) + { + var tree = expression.Split('.').Select(x => x.Replace("\n", "").Replace("\r", "").Replace(" ", "").Replace("\t", "").Replace("(", "").Replace(")", "").Replace("[", "").Replace("]", "")).ToList(); + var variableName = tree.FirstOrDefault(); + + if (variableName != null && tree.Count > 1) + { + tree.RemoveAt(0); + var variables = _parser.GetScriptVariables(Document.Text); + var variable = variables.FirstOrDefault(x => x.Name == variableName); + + if (variable != null) + { + var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable.Type, "<.+>", "")); + + 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(), + }; + } + } + } + } + + return null; + } public List GetPreviousWords() { @@ -782,7 +447,7 @@ namespace Tango.Scripting.Editors #region Highlighting - private async void InvalidateHighlighting() + private void InvalidateHighlighting() { _parser.GetDeclaredTypes(Text); @@ -791,26 +456,29 @@ namespace Tango.Scripting.Editors var assemblies = ReferenceAssemblies.ToList(); var usings = _current_usings.ToList(); - foreach (var asm in assemblies.Select(x => x.Assembly)) + Thread t = new Thread(() => { - Parallel.ForEach(asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive), (type) => + foreach (var asm in assemblies.Select(x => x.Assembly)) { - if (usings.Exists(x => type.Namespace == x)) + Parallel.ForEach(asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive), (type) => { - lock (_knownTypes) + if (usings.Exists(x => type.Namespace == x)) { - _knownTypes.Add(new KnownType(type)); + lock (_knownTypes) + { + if (!_knownTypes.Exists(x => x.Type.FullName == type.FullName)) + { + _knownTypes.Add(new KnownType(type)); + } + } } - } - }); - } - - if (_knownTypes.Count > 0 || _declaredTypes.Count > 0) - { - String text = String.Empty; + }); + } - await Task.Factory.StartNew(() => + 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)) @@ -864,15 +532,22 @@ namespace Tango.Scripting.Editors { text = text.Replace("@InterfaceTypes@", String.Join(Environment.NewLine, interfaceTypes.Distinct())); } - }); - using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text))) - { + MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text)); + XmlTextReader xshd_reader = new XmlTextReader(ms); - SyntaxHighlighting = HighlightingLoader.Load(xshd_reader, HighlightingManager.Instance); - xshd_reader.Close(); + + Dispatcher.BeginInvoke(new Action(() => + { + SyntaxHighlighting = HighlightingLoader.Load(xshd_reader, HighlightingManager.Instance); + xshd_reader.Close(); + ms.Dispose(); + })); + } - } + }); + t.IsBackground = true; + t.Start(); } private void InvalidateScriptTypesHighlightings() @@ -1009,74 +684,75 @@ namespace Tango.Scripting.Editors var lineText = GetCurrentLineText(); var previousWordsLast = GetPreviousWords().LastOrDefault(); String currentWord = previousWordsLast != null ? previousWordsLast.Replace("\t", "") : String.Empty; + String currentWordIncludingParenthesis = currentWord.Split('(').LastOrDefault(); + + + if (e.Text == " " && GetPreviousWord() == "new") + { + var s = _parser.GetExpression(GetCurrentLineText()); + + if (s != null) + { + String type = s.Declaration.Type.ToString(); + IList data = new List(); + + data.Add(new ClassCompletionItem() + { + Name = type, + Description = "Auto generate assignment...", + }); - if (e.Text == ";" || e.Text == " ") + ShowCompletionWindow(data, type); + } + } + else if (e.Text == ";" || e.Text == " ") { HideCompletionWindow(); } else if (e.Text == ".") { - var expression = GetPreviousWords().LastOrDefault(); + var knownType = GetCurrentKnownType(); - if (expression != null) + if (knownType != null) { - var tree = expression.Split('.').Select(x => x.Replace("\n", "").Replace("\r", "").Replace(" ", "").Replace("\t", "").Replace("(", "").Replace(")", "")).ToList(); - var variableName = tree.FirstOrDefault(); + completionWindow.HideCompletion(); + IList data = new List(); - if (variableName != null) + var typeMembers = knownType.Members.ToList(); + + foreach (var methodGroup in typeMembers.GroupBy(x => x.Name)) { - tree.RemoveAt(0); - var variables = _parser.GetScriptVariables(Document.Text); - var variable = variables.FirstOrDefault(x => x.Name == variableName); + var member = methodGroup.First(); - if (variable != null) + if (member.GetType() == typeof(KnownTypeMethod)) { - var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == variable.Type); + var method = member as KnownTypeMethod; - if (knownType != null) + data.Add(new MethodCompletionItem() { - while (tree.Count > 1) - { - var memberName = tree.First(); - tree.RemoveAt(0); - var member = knownType.Members.FirstOrDefault(x => x.Name == memberName); + Class = knownType.FriendlyName, + Name = method.Name, + ReturnType = method.ReturnTypeFriendlyName, + Description = method.Summary, + Parameters = method.Parameters, + Overloads = methodGroup.Count() - 1, + }); - if (member == null) - { - return; - } - - knownType = _knownTypes.FirstOrDefault(x => x.Type == member.ReturnType); - } - - if (knownType != null) - { - completionWindow.HideCompletion(); - IList data = new List(); - - var typeMembers = knownType.Members.ToList(); - - foreach (var methodGroup in typeMembers.GroupBy(x => x.Name)) - { - var member = methodGroup.First(); - - if (member.GetType() == typeof(KnownTypeMethod)) - { - var method = member as KnownTypeMethod; - data.Add(new MethodCompletionData(knownType.FriendlyName, method.Name, method.ReturnTypeFriendlyName, method.Summary, method.Parameters, methodGroup.Count() - 1)); - } - else - { - data.Add(new PropertyCompletionData(knownType.FriendlyName, member.Name, member.ReturnType.Name, member.Summary)); - } - } - - ShowCompletionWindow(data, GetCurrentWord()); - } - } + } + else + { + data.Add(new PropertyCompletionItem() + { + Class = knownType.FriendlyName, + Name = member.Name, + Type = member.ReturnTypeFriendlyName, + Description = member.Summary, + }); } } + + ShowCompletionWindow(data, GetCurrentWord()); } } else if (e.Text == "(" || e.Text == ",") @@ -1094,29 +770,53 @@ namespace Tango.Scripting.Editors } } - //var methodSession = GetMethodSession(); + var methodSession = GetMethodSession(); - //if (methodSession != null) - //{ + if (methodSession != null) + { + var content = CreateMethodSessionPopupContent(methodSession); + if (content.Methods.Count > 0) + { + ShowPopup(content); + } + } - //} + var a = GetMethodSession(); } else if (lineText.StartsWith("using")) { + if (completionWindow.IsVisible) + { + completionWindow.UpdatePositionFix(); + return; + } + IList data = new List(); foreach (var asm in ReferenceAssemblies) { foreach (var ns in asm.Assembly.GetTypes().Select(x => x.Namespace).Distinct().Where(x => x != null)) { - data.Add(new TypeCompletionData("namespace", ns, "", asm.Assembly.GetName().Name)); + data.Add(new NamespaceCompletionItem() + { + Name = ns, + Assembly = asm.Assembly.GetName().Name, + }); } } + data = data.DistinctBy(x => x.Text).ToList(); + ShowCompletionWindow(data, GetCurrentWord()); } - else if (!currentWord.Contains(".")) + else if (!currentWordIncludingParenthesis.Contains(".")) { + if (completionWindow.IsVisible) + { + completionWindow.UpdatePositionFix(); + return; + } + var previous_word = GetPreviousWord(); var word = GetCurrentWord(); @@ -1141,12 +841,90 @@ namespace Tango.Scripting.Editors foreach (var type in _declaredTypes.Where(x => x.Name.StartsWith(word))) { - data.Add(new TypeCompletionData(type.TypeKind.ToString().ToLower(), type.Name, type.ContainingNamespace?.Name, "Declared inside the current script...")); + if (type.TypeKind == TypeKind.Struct) + { + data.Add(new StructCompletionItem() + { + Name = type.Name, + Description = "Declared inside the current script...", + Namespace = type.ContainingNamespace?.Name, + }); + } + else if (type.TypeKind == TypeKind.Enum) + { + data.Add(new EnumCompletionItem() + { + Name = type.Name, + Description = "Declared inside the current script...", + Namespace = type.ContainingNamespace?.Name, + }); + } + else if (type.TypeKind == TypeKind.Interface) + { + data.Add(new InterfaceCompletionItem() + { + Name = type.Name, + Description = "Declared inside the current script...", + Namespace = type.ContainingNamespace?.Name, + }); + } + else if (type.TypeKind == TypeKind.Class) + { + data.Add(new ClassCompletionItem() + { + Name = type.Name, + Description = "Declared inside the current script...", + Namespace = type.ContainingNamespace?.Name, + }); + } + else + { + throw new NotImplementedException("Implement generic item here!"); + } } foreach (var type in _knownTypes.Where(x => x.Name.StartsWith(word))) { - data.Add(new TypeCompletionData(type.TypeDefinition, type.FriendlyName, type.Type.Namespace, type.Summary)); + if (type.Type.IsEnum) + { + data.Add(new EnumCompletionItem() + { + Namespace = type.Type.Namespace, + Description = type.Summary, + Name = type.FriendlyName, + }); + } + else if (type.Type.IsInterface) + { + data.Add(new InterfaceCompletionItem() + { + Name = type.FriendlyName, + Description = type.Summary, + Namespace = type.Type.Namespace, + }); + } + else if (type.Type.IsValueType) + { + data.Add(new StructCompletionItem() + { + Name = type.FriendlyName, + Description = type.Summary, + Namespace = type.Type.Namespace, + }); + } + else if (type.Type.IsClass) + { + data.Add(new ClassCompletionItem() + { + Name = type.FriendlyName, + Description = type.Summary, + Namespace = type.Type.Namespace, + }); + } + else + { + throw new NotImplementedException("Implement generic item here."); + } } ShowCompletionWindow(data, word); @@ -1157,10 +935,7 @@ namespace Tango.Scripting.Editors private void CompletionWindow_InsertionRequest(ICompletionData item) { - int index = GetCurrentWordStartIndex(); - int max = GetCurrentLine().EndOffset; - - Document.Replace(index, Math.Min(max - index, item.Text.Length), item.Text); + item.Complete(this); } private void ShowCompletionWindow(IList suggestions, String filter) @@ -1240,6 +1015,50 @@ namespace Tango.Scripting.Editors return list; } + private KnownType GetCurrentKnownType() + { + var expression = GetPreviousWords().LastOrDefault(); + + if (expression != null) + { + var tree = expression.Split('.').Select(x => x.Remove(@"\n|\t|\r|\(.*\)|\[.*\]|\s")).ToList(); + var variableName = tree.FirstOrDefault(); + + if (variableName != null) + { + tree.RemoveAt(0); + var variables = _parser.GetScriptVariables(Document.Text); + var variable = variables.FirstOrDefault(x => x.Name == variableName); + + if (variable != null) + { + var knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == Regex.Replace(variable.Type, "<.+>", "")); + + 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 knownType; + } + } + } + } + + return null; + } + #endregion #region Popup @@ -1290,7 +1109,7 @@ namespace Tango.Scripting.Editors { ParameterDescription pDescription = new ParameterDescription(method); pDescription.Name = p.Name; - pDescription.Type = p.Type.Name; + pDescription.Type = p.Type; pDescription.Description = p.Description; method.Parameters.Add(pDescription); } @@ -1320,6 +1139,57 @@ namespace Tango.Scripting.Editors return popup; } + private MethodPopup CreateMethodSessionPopupContent(MethodSession session) + { + MethodPopup popup = new MethodPopup(); + + foreach (var m in session.Type.Methods.Where(x => x.Name == session.MethodName)) + { + MethodDescription method = new MethodDescription(); + method.ReturnType = session.Type.Name; + method.Description = m.Summary; + + //if (session.Type.Type.IsGenericType && session.TypeArguments != null) + //{ + // method.ReturnType = new String(session.Type.Name.TakeWhile(x => x != '`').ToArray()) + $"<{String.Join(",", session.TypeArguments)}>"; + //} + + var parameters = m.Parameters; + + foreach (var p in parameters) + { + ParameterDescription pDescription = new ParameterDescription(method); + pDescription.Name = p.Name; + pDescription.Type = p.Type; + pDescription.Description = p.Description; + method.Parameters.Add(pDescription); + } + + popup.Methods.Add(method); + } + + //if (false) + //{ + // popup.CurrentMethod = popup.Methods.FirstOrDefault(x => x.Parameters.Count == session.ParameterIndex + 1); + + // if (popup.CurrentMethod == null) + // { + // popup.CurrentMethod = popup.Methods.FirstOrDefault(); + // } + //} + //else + //{ + popup.CurrentMethod = popup.Methods.FirstOrDefault(); + //} + + if (popup.CurrentMethod != null) + { + popup.CurrentMethodIndex = popup.Methods.IndexOf(popup.CurrentMethod) + 1; + } + + return popup; + } + #endregion } } diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj index d7c455704..5422ba805 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj @@ -191,6 +191,16 @@ + + + + + + + + + + @@ -328,6 +338,15 @@ + + + + + + + + + diff --git a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Themes/Generic.xaml b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Themes/Generic.xaml index 8b60d42a7..7a6588239 100644 --- a/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Themes/Generic.xaml +++ b/Software/Visual_Studio/TEMP/Tango.Scripting/Tango.Scripting.Editors/Themes/Generic.xaml @@ -5,6 +5,7 @@ xmlns:fa="http://schemas.fontawesome.io/icons/" xmlns:editing="clr-namespace:Tango.Scripting.Editors.Editing" xmlns:folding="clr-namespace:Tango.Scripting.Editors.Folding" + xmlns:intellisense="clr-namespace:Tango.Scripting.Editors.Intellisense" xmlns:converters="clr-namespace:Tango.Scripting.Editors.Converters" xmlns:completion="clr-namespace:Tango.Scripting.Editors.CodeCompletion"> @@ -25,6 +26,7 @@ #2B91AF #4EC9B0 #3F8FD6 + #B5CE8A @@ -35,6 +37,7 @@ + @@ -80,37 +83,17 @@ - + + + @@ -205,36 +196,8 @@ - - - - - - + + @@ -388,4 +351,184 @@ + + + + + + + + + + + + + + + + -- cgit v1.3.1