From 9b7875d904456c34c3698d7fc569078f99ed5187 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sun, 19 Apr 2020 23:12:56 +0300 Subject: Scripting refactoring. --- .../Tango.Scripting.Editors/CachedAssembly.cs | 21 ++ .../Tango.Scripting.Editors/Document/UndoStack.cs | 2 +- .../Highlighting/Resources/CSharp-Mode.xshd | 1 + .../Intellisense/KnownType.cs | 12 +- .../Intellisense/KnownTypeMethod.cs | 2 + .../Tango.Scripting.Editors/ScriptEditor.cs | 348 +++++++++++++++++++-- .../Tango.Scripting.Editors.csproj | 10 +- .../Scripting/Tango.Scripting.Editors/app.config | 8 + .../Tango.Scripting.Editors/packages.config | 1 + 9 files changed, 373 insertions(+), 32 deletions(-) create mode 100644 Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors') diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs new file mode 100644 index 000000000..b0178e63e --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/CachedAssembly.cs @@ -0,0 +1,21 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Scripting.Editors.Intellisense; + +namespace Tango.Scripting.Editors +{ + public class CachedAssembly + { + public String Name { get; set; } + public List KnownTypes { get; set; } + + public CachedAssembly() + { + KnownTypes = new List(); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs index f0a759b23..86e1fa33e 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/UndoStack.cs @@ -414,7 +414,7 @@ namespace Tango.Scripting.Editors.Document /// public void ClearAll() { - ThrowIfUndoGroupOpen(); + //ThrowIfUndoGroupOpen(); actionCountInUndoGroup = 0; optionalActionCount = 0; if (undostack.Count != 0) { diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd index 409825b42..6f400c4f5 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Highlighting/Resources/CSharp-Mode.xshd @@ -194,6 +194,7 @@ enum float int + object string long sbyte diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs index 28f9ccb9a..6675eb582 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs @@ -14,8 +14,8 @@ namespace Tango.Scripting.Editors.Intellisense public class KnownType { private bool _initialized; - private bool _documentationLoaded; + public bool DocumentationLoaded { get; set; } public Type Type { get; private set; } public String Name { get; private set; } public String TypeDefinition { get; private set; } @@ -135,6 +135,7 @@ namespace Tango.Scripting.Editors.Intellisense m.Name = method.Name; m.ReturnType = method.ReturnType; m.ReturnTypeFriendlyName = method.ReturnType.GetFriendlyName(); + m.IsStatic = method.IsStatic; if (method.IsGenericMethod) { @@ -148,6 +149,11 @@ namespace Tango.Scripting.Editors.Intellisense bool isLinq = method.DeclaringType == typeof(Enumerable); + if (isLinq) + { + m.IsStatic = false; + } + for (int j = 0; j < parameters.Count; j++) { var parameter = parameters[j]; @@ -211,9 +217,9 @@ namespace Tango.Scripting.Editors.Intellisense public void LoadDocumentation() { - if (!_documentationLoaded) + if (!DocumentationLoaded) { - _documentationLoaded = true; + DocumentationLoaded = true; Utils.LoadKnownTypeDocs(this); } diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs index f84e26fe5..4cedad377 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownTypeMethod.cs @@ -8,6 +8,8 @@ namespace Tango.Scripting.Editors.Intellisense { public class KnownTypeMethod : KnownTypeMember { + public bool IsStatic { get; set; } + public List Parameters { get; set; } public List TypeArguments { get; set; } diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs index d06862cef..a4493d2c4 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs @@ -1,5 +1,6 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -23,7 +24,9 @@ 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; @@ -52,6 +55,14 @@ namespace Tango.Scripting.Editors private List _knownTypes; private List _declaredTypes; private bool _isLoadingTypes; + private static JsonSerializerSettings _jsonSettings; + private static Dictionary _knownTypesCache; + private static String KNOWN_TYPES_CACHE_FOLDER; + private static List _cachedAssemblies; + private static bool _isLoadingCachedAssemblies; + private static bool _isCacheAssembliesLoaded; + + public static event EventHandler> AssemblyCacheProgress; #region Mini Classes @@ -110,13 +121,13 @@ namespace Tango.Scripting.Editors /// /// Gets or sets the reference assemblies. /// - public ObservableCollection ReferenceAssemblies + public ObservableCollection ReferenceAssemblies { - get { return (ObservableCollection)GetValue(ReferenceAssembliesProperty); } + get { return (ObservableCollection)GetValue(ReferenceAssembliesProperty); } set { SetValue(ReferenceAssembliesProperty, value); } } public static readonly DependencyProperty ReferenceAssembliesProperty = - DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection), typeof(ScriptEditor), new PropertyMetadata(null)); + DependencyProperty.Register("ReferenceAssemblies", typeof(ObservableCollection), typeof(ScriptEditor), new PropertyMetadata(null)); public Object CurrentPopupContent { @@ -126,6 +137,21 @@ 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 AdditionalScripts + { + get { return (ObservableCollection)GetValue(AdditionalScriptsProperty); } + set { SetValue(AdditionalScriptsProperty, value); } + } + public static readonly DependencyProperty AdditionalScriptsProperty = + DependencyProperty.Register("AdditionalScripts", typeof(ObservableCollection), typeof(ScriptEditor), new PropertyMetadata(null)); #endregion @@ -137,6 +163,21 @@ namespace Tango.Scripting.Editors static ScriptEditor() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ScriptEditor), new FrameworkPropertyMetadata(typeof(ScriptEditor))); + + 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(); + _cachedAssemblies = new List(); } /// @@ -148,12 +189,11 @@ namespace Tango.Scripting.Editors _current_usings = new List(); - ReferenceAssemblies = new ObservableCollection(); + //ReferenceAssemblies = new ObservableCollection(); - //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 + ////Add basic assemblies... + //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(String))); //mscorelib + //ReferenceAssemblies.Add(new ReferenceAssembly(typeof(Enumerable))); //System.Core _knownTypes = new List(); _parser = new ScriptParser(); @@ -175,6 +215,29 @@ namespace Tango.Scripting.Editors completionWindow.AllowsTransparency = true; completionWindow.ResizeMode = ResizeMode.NoResize; completionWindow.InsertionRequest += CompletionWindow_InsertionRequest; + + TextChanged += ScriptEditor_TextChanged; + } + + 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 @@ -370,16 +433,17 @@ namespace Tango.Scripting.Editors { var knownType = GetCurrentKnownType(); + IList data = new List(); + if (knownType != null) { completionWindow.HideCompletion(); - IList data = new List(); if (!knownType.Type.IsEnum) { var typeMembers = knownType.Members.ToList(); - foreach (var methodGroup in typeMembers.OfType().GroupBy(x => x.NameWithTypeArguments)) + foreach (var methodGroup in typeMembers.OfType().Where(x => !x.IsStatic).GroupBy(x => x.NameWithTypeArguments)) { var method = methodGroup.First(); @@ -432,7 +496,6 @@ namespace Tango.Scripting.Editors if (declaredType != null) { completionWindow.HideCompletion(); - IList data = new List(); var typeMembers = declaredType.Symbols.ToList(); @@ -491,6 +554,34 @@ namespace Tango.Scripting.Editors ShowCompletionWindow(data, GetCurrentWord()); } + else + { + //Maybe static ... + var typeText = GetPreviousWord(); + knownType = _knownTypes.FirstOrDefault(x => x.FriendlyName == typeText); + + if (knownType != null) + { + var typeMembers = knownType.Members.ToList(); + + foreach (var methodGroup in typeMembers.OfType().Where(x => x.IsStatic).GroupBy(x => x.NameWithTypeArguments)) + { + var method = methodGroup.First(); + + data.Add(new MethodCompletionItem() + { + Class = knownType.FriendlyName, + Name = method.NameWithTypeArguments, + ReturnType = method.ReturnTypeFriendlyName, + Description = method.Summary, + Parameters = method.Parameters, + Overloads = methodGroup.Count() - 1, + }); + } + + ShowCompletionWindow(data.OrderBy(x => x.Text).ToList(), GetCurrentWord()); + } + } } } else if (e.Text == "(" || e.Text == ",") @@ -534,6 +625,18 @@ namespace Tango.Scripting.Editors return; } } + + var staticMethodSession = GetStaticMethodSession(); + + if (staticMethodSession != null) + { + var content = CreateMethodSessionPopupContent(staticMethodSession); + if (content.Methods.Count > 0) + { + ShowPopup(content); + return; + } + } } catch (Exception ex) { @@ -552,12 +655,12 @@ namespace Tango.Scripting.Editors 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() { Name = ns, - Assembly = asm.Assembly.GetName().Name, + Assembly = asm.GetName().Name, }); } } @@ -1147,33 +1250,114 @@ namespace Tango.Scripting.Editors return popup; } - private void InvalidateHighlighting() + public static void LoadCachedAssemblies(List assemblies) + { + if (_isLoadingCachedAssemblies) return; + + _isLoadingCachedAssemblies = true; + + if (!_isCacheAssembliesLoaded) + { + foreach (var file in System.IO.Directory.GetFiles(KNOWN_TYPES_CACHE_FOLDER)) + { + try + { + AssemblyCacheProgress?.Invoke(null, new TangoProgressChangedEventArgs() + { + Progress = new TangoProgress() + { + IsIndeterminate = true, + Maximum = 100, + Message = $"Loading metadata cache for '{System.IO.Path.GetFileName(file)}'..." + } + }); + + var cachedAssembly = JsonConvert.DeserializeObject(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 && !x.IsPrimitive).ToList(); + + int i = 0; + + foreach (var type in types) + { + AssemblyCacheProgress?.Invoke(null, new TangoProgressChangedEventArgs() + { + Progress = new TangoProgress() + { + IsIndeterminate = false, + Maximum = types.Count, + Value = i++, + Message = $"Caching metadata for '{asmFileName}'..." + } + }); + + KnownType knownType = new KnownType(type); + _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)); + } + } + + _isLoadingCachedAssemblies = false; + } + + private void InvalidateHighlighting(bool loadKnownTypes = true) { if (!_isLoadingTypes) { _isLoadingTypes = true; - _knownTypes.Clear(); var assemblies = ReferenceAssemblies.ToList(); var usings = _current_usings.ToList(); Thread t = new Thread(() => { - foreach (var asm in assemblies.Select(x => x.Assembly)) + LoadCachedAssemblies(assemblies); + + if (loadKnownTypes) { - Parallel.ForEach(asm.GetTypes().Where(x => x.IsVisible && x.IsPublic && !x.IsPrimitive), (type) => + _knownTypes.Clear(); + + foreach (var asm in assemblies) { - if (usings.Exists(x => type.Namespace == x)) + foreach (var knownType in _knownTypesCache.ToList().Select(x => x.Value).ToList()) { - lock (_knownTypes) + if (usings.Exists(x => knownType.Type.Namespace == x)) { - if (!_knownTypes.Exists(x => x.Type.FullName == type.FullName)) + lock (_knownTypes) { - _knownTypes.Add(new KnownType(type)); + _knownTypes.Add(knownType); } } } - }); + } } if (_knownTypes.Count > 0 || _declaredTypes.Count > 0) @@ -1246,10 +1430,10 @@ namespace Tango.Scripting.Editors })); - foreach (var knownType in _knownTypes) - { - knownType.LoadDocumentation(); - } + //foreach (var knownType in _knownTypes) + //{ + // knownType.LoadDocumentation(); + //} } _isLoadingTypes = false; @@ -1263,10 +1447,19 @@ 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(); + InvalidateHighlighting(false); } _declaredTypes = declaredTypes; @@ -1452,6 +1645,48 @@ 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; } @@ -1515,6 +1750,65 @@ 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, "<.+>", "")); + + 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 words = GetCurrentLineText().Split(' '); diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj index ce7c361e3..d6c89f0a4 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors.csproj @@ -77,6 +77,9 @@ ..\..\packages\Microsoft.CodeAnalysis.CSharp.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + 3.0 @@ -177,6 +180,7 @@ GlobalVersionInfo.cs + @@ -579,6 +583,10 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {5812E1C6-ABAA-4066-94AC-971C27B4F46A} + Tango.Scripting.Core + {1e938fd2-c669-4738-98c9-77f96ce4d451} Tango.Scripting @@ -628,7 +636,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config index d3a17b4de..16d75cf59 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/app.config @@ -77,6 +77,14 @@ + + + + + + + + diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config index 00eef19db..a0f62a1d4 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/packages.config @@ -4,6 +4,7 @@ + -- cgit v1.3.1 From 17abbf35ba72283c6dab9135f1e75b7057371431 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 20 Apr 2020 07:22:48 +0300 Subject: Scripting.. --- .../FSE/Modules/Tango.FSE.Stubs/App.xaml | 2 + .../Tango.FSE.Stubs/Designer/ProjectModel.cs | 20 + .../Tango.FSE.Stubs/Designer/ScriptTabModel.cs | 22 ++ .../FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs | 69 ++++ .../Modules/Tango.FSE.Stubs/ProjectRunnerState.cs | 18 + .../Properties/Resources.Designer.cs | 64 ++-- .../Tango.FSE.Stubs/Properties/Resources.resx | 20 +- .../Tango.FSE.Stubs/Resources/lib_template.csx | 14 + .../Tango.FSE.Stubs/Resources/main_template.csx | 19 + .../Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj | 26 ++ .../Modules/Tango.FSE.Stubs/Themes/Generic.xaml | 403 +++++++++++++++++++++ .../Modules/Tango.FSE.Stubs/ViewModelLocator.cs | 18 + .../Tango.FSE.Stubs/ViewModels/MainViewVM.cs | 8 +- .../ViewModels/TestDesignerViewVM.cs | 121 +++++++ .../Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs | 13 + .../Modules/Tango.FSE.Stubs/Views/MainView.xaml | 8 +- .../Tango.FSE.Stubs/Views/TestDesignerView.xaml | 324 +++++++++++++++++ .../Tango.FSE.Stubs/Views/TestDesignerView.xaml.cs | 38 ++ .../Tango.FSE.Stubs/Views/TestRunnerView.xaml | 14 + .../Tango.FSE.Stubs/Views/TestRunnerView.xaml.cs | 28 ++ .../FSE/Tango.FSE.Common/Resources/Colors.xaml | 25 ++ Software/Visual_Studio/FSE/Tango.FSE.UI/App.config | 16 +- .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 3 + .../Visual_Studio/FSE/Tango.FSE.UI/packages.config | 50 +++ .../Scripting/Tango.Scripting.Basic/Project.cs | 16 +- .../Tango.Scripting.Basic/ProjectSession.cs | 12 +- .../Tango.Scripting.Basic/ReferenceAssembly.cs | 5 + .../Scripting/Tango.Scripting.Basic/Script.cs | 21 +- .../Tango.Scripting.Editors/Intellisense/Utils.cs | 14 +- 29 files changed, 1361 insertions(+), 50 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ProjectModel.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ScriptTabModel.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunnerState.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Themes/Generic.xaml create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestRunnerViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerView.xaml create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestRunnerView.xaml.cs (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/App.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/App.xaml index 4261db47e..cf67bdbba 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/App.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/App.xaml @@ -10,6 +10,8 @@ + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ProjectModel.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ProjectModel.cs new file mode 100644 index 000000000..b5208c008 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ProjectModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; + +namespace Tango.FSE.Stubs.Designer +{ + public class ProjectModel : ExtendedObject + { + public ObservableCollection Scripts { get; set; } + + public ProjectModel() + { + Scripts = new ObservableCollection(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ScriptTabModel.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ScriptTabModel.cs new file mode 100644 index 000000000..4fba3213d --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Designer/ScriptTabModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Scripting.Basic; + +namespace Tango.FSE.Stubs.Designer +{ + public class ScriptTabModel : ExtendedObject + { + public Script Script { get; set; } + + private bool _isSelected; + public bool IsSelected + { + get { return _isSelected; } + set { _isSelected = value; RaisePropertyChangedAuto(); } + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs new file mode 100644 index 000000000..0625fa08f --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Scripting.Basic; + +namespace Tango.FSE.Stubs +{ + public class ProjectRunner : ExtendedObject + { + private ProjectSession _currentSession; + + private ProjectRunnerState _state; + public ProjectRunnerState State + { + get { return _state; } + private set { _state = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsRunning)); } + } + + public bool IsRunning + { + get { return State == ProjectRunnerState.Compiling || State == ProjectRunnerState.Running; } + } + + public Project Project { get; private set; } + + public ProjectRunner(Project project) + { + Project = project; + } + + public async Task Run() + { + if (State != ProjectRunnerState.Compiling && State != ProjectRunnerState.Running) + { + State = ProjectRunnerState.Compiling; + _currentSession = await Project.Run(null); + State = ProjectRunnerState.Running; + + try + { + var result = await _currentSession.WaitForCompletion(); + State = ProjectRunnerState.Completed; + return result; + } + catch (OperationCanceledException) + { + State = ProjectRunnerState.Aborted; + throw; + } + catch (Exception) + { + State = ProjectRunnerState.Failed; + throw; + } + } + + throw new InvalidOperationException("Project is already running."); + } + + public void Stop() + { + _currentSession.Abort(); + State = ProjectRunnerState.Aborted; + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunnerState.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunnerState.cs new file mode 100644 index 000000000..034426742 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunnerState.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.FSE.Stubs +{ + public enum ProjectRunnerState + { + None, + Compiling, + Running, + Completed, + Failed, + Aborted +} +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.Designer.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.Designer.cs index 4d805d4c8..30aff0d9b 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.Designer.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.Designer.cs @@ -8,10 +8,10 @@ // //------------------------------------------------------------------------------ -namespace Tango.FSE.Stubs.Properties -{ - - +namespace Tango.FSE.Stubs.Properties { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -19,53 +19,65 @@ namespace Tango.FSE.Stubs.Properties // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - + internal class Resources { + private static global::System.Resources.ResourceManager resourceMan; - + private static global::System.Globalization.CultureInfo resourceCulture; - + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { + internal Resources() { } - + /// /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Tango.FSE.Stubs.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } - + /// /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { + internal static global::System.Globalization.CultureInfo Culture { + get { return resourceCulture; } - set - { + set { resourceCulture = value; } } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] lib_template { + get { + object obj = ResourceManager.GetObject("lib_template", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] main_template { + get { + object obj = ResourceManager.GetObject("main_template", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.resx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.resx index af7dbebba..87094c4e4 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.resx +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Properties/Resources.resx @@ -46,7 +46,7 @@ mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with - : System.Serialization.Formatters.Binary.BinaryFormatter + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 @@ -60,6 +60,7 @@ : and then encoded with base64 encoding. --> + @@ -68,9 +69,10 @@ - + + @@ -85,9 +87,10 @@ - + + @@ -109,9 +112,16 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\lib_template.csx;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\main_template.csx;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx new file mode 100644 index 000000000..f3fd6b36a --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/lib_template.csx @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.FSE.Stubs; + +public class NewLibrary +{ + public double Calc(double a, double b) + { + return a + b; + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx new file mode 100644 index 000000000..3d6c4f3b9 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.FSE.Stubs; + +public class Program +{ + public Object OnExecute(IContext context) + { + + return new + { + Item1 = "Item 1", + Item2 = "Item 2" + }; + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj index 3222674ef..3e495564d 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj @@ -78,12 +78,24 @@ + + + + + + MainView.xaml + + TestDesignerView.xaml + + + TestRunnerView.xaml + @@ -109,6 +121,8 @@ SettingsSingleFileGenerator Settings.Designer.cs + + @@ -173,10 +187,22 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Themes/Generic.xaml new file mode 100644 index 000000000..7d8801297 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Themes/Generic.xaml @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModelLocator.cs index fe7ef42fa..6d151e5b8 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModelLocator.cs @@ -13,6 +13,8 @@ namespace Tango.FSE.Stubs static ViewModelLocator() { TangoIOC.Default.Register(); + TangoIOC.Default.Register(); + TangoIOC.Default.Register(); } public static MainViewVM MainViewVM @@ -22,5 +24,21 @@ namespace Tango.FSE.Stubs return TangoIOC.Default.GetInstance(); } } + + public static TestRunnerViewVM TestRunnerViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } + + public static TestDesignerViewVM TestDesignerViewVM + { + get + { + return TangoIOC.Default.GetInstance(); + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/MainViewVM.cs index 411335c02..02d2f8b53 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/MainViewVM.cs @@ -6,10 +6,12 @@ using System.Text; using System.Threading.Tasks; using Tango.FSE.Common; using Tango.FSE.Common.Navigation; +using Tango.FSE.Stubs.Views; using Tango.SharedUI.Helpers; namespace Tango.FSE.Stubs.ViewModels { + [NavigationContainer] public class MainViewVM : FSEViewModel { public override void OnApplicationStarted() @@ -18,7 +20,7 @@ namespace Tango.FSE.Stubs.ViewModels { NavigationManager.MenuItems.Add(new NavigationMenuItem(() => { - NavigationManager.NavigateTo(); + NavigationManager.NavigateTo(nameof(TestRunnerView)); }) { Name = "Test Runner", @@ -29,11 +31,11 @@ namespace Tango.FSE.Stubs.ViewModels NavigationManager.MenuItems.Add(new NavigationMenuItem(() => { - NavigationManager.NavigateTo(); + NavigationManager.NavigateTo(nameof(TestDesignerView)); }) { Name = "Test Designer", - Index = 6, + Index = 7, Description = "Create and test new test runner projects.", Image = ResourceHelper.GetImageFromResources("Images/test_designer.png"), }); diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs new file mode 100644 index 000000000..6544e643c --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs @@ -0,0 +1,121 @@ +using Google.Protobuf; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.Commands; +using Tango.FSE.Common; +using Tango.Integration.Operation; +using Tango.Scripting.Basic; +using Tango.Transport; + +namespace Tango.FSE.Stubs.ViewModels +{ + public class TestDesignerViewVM : FSEViewModel + { + private Project _project; + public Project Project + { + get { return _project; } + set { _project = value; RaisePropertyChangedAuto(); OnProjectChanged(); } + } + + private ProjectRunner _projectRunner; + public ProjectRunner ProjectRunner + { + get { return _projectRunner; } + set { _projectRunner = value; RaisePropertyChangedAuto(); } + } + + public ObservableCollection