diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-08-09 02:26:07 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-08-09 02:26:07 +0300 |
| commit | 92db2f2431bb58a84dc4d476b889fee1de0143e9 (patch) | |
| tree | 26e8880e86091b08064a3b20b2862d83ed726ab6 /Software/Visual_Studio | |
| parent | 255a47cf96e83e8d11befa9180dc4458f6767188 (diff) | |
| download | Tango-92db2f2431bb58a84dc4d476b889fee1de0143e9.tar.gz Tango-92db2f2431bb58a84dc4d476b889fee1de0143e9.zip | |
Procedure runtime debugging and exceptions.
Diffstat (limited to 'Software/Visual_Studio')
30 files changed, 2275 insertions, 44 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/BreakPointRequestEventArgs.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/BreakPointRequestEventArgs.cs new file mode 100644 index 000000000..768f4bb0d --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/BreakPointRequestEventArgs.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Scripting.Basic; +using Tango.Scripting.Core; + +namespace Tango.FSE.Procedures +{ + public class BreakPointRequestEventArgs : EventArgs + { + private Action _releaseAction; + + public int LineNumber { get; set; } + public Script Script { get; set; } + + public List<ScriptBreakPointSymbol> Symbols { get; set; } + + public BreakPointRequestEventArgs(Action releaseAction) + { + Symbols = new List<ScriptBreakPointSymbol>(); + _releaseAction = releaseAction; + } + + public void Release() + { + _releaseAction?.Invoke(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs index fa8a4cab6..a16345f65 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Contracts/IProcedureDesignerView.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.FSE.Common; +using Tango.Scripting.Basic; +using Tango.Scripting.Core; namespace Tango.FSE.Procedures.Contracts { @@ -24,5 +26,8 @@ namespace Tango.FSE.Procedures.Contracts void ScrollToLine(int lineNumber); void HighlightRuntimeError(int lineNumber); void CloseRunTimeError(); + List<ScriptBreakPoint> GetBreakPoints(); + void HighlightBreakPointRequest(int lineNumber, List<ScriptBreakPointSymbol> symbols); + void ResetBreakPointRequest(); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/ObjectInTreeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/ObjectInTreeView.xaml new file mode 100644 index 000000000..d331935c8 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/ObjectInTreeView.xaml @@ -0,0 +1,27 @@ +<UserControl x:Class="Tango.FSE.Procedures.Controls.ObjectInTreeView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:local="clr-namespace:Tango.FSE.Procedures.Controls" + mc:Ignorable="d" + d:DesignHeight="450" d:DesignWidth="800" x:Name="ObjectInTreeViewControl"> + <TreeView ItemsSource="{Binding TreeNodes, ElementName=ObjectInTreeViewControl}" Style="{x:Null}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" Background="Transparent" FontSize="{StaticResource FSE_SmallFontSize}" BorderThickness="0"> + <TreeView.Resources> + <Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}"> + + </Style> + <HierarchicalDataTemplate DataType="{x:Type local:TreeNode}" ItemsSource="{Binding Path=Children}"> + <TreeViewItem Style="{x:Null}"> + <TreeViewItem.Header> + <StackPanel Orientation="Horizontal"> + <TextBlock Text="{Binding Path=Name}"/> + <TextBlock Text=" : "/> + <TextBlock Text="{Binding Path=Value}"/> + </StackPanel> + </TreeViewItem.Header> + </TreeViewItem> + </HierarchicalDataTemplate> + </TreeView.Resources> + </TreeView> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/ObjectInTreeView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/ObjectInTreeView.xaml.cs new file mode 100644 index 000000000..b1d1ee14d --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/ObjectInTreeView.xaml.cs @@ -0,0 +1,50 @@ +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.FSE.Procedures.Controls +{ + /// <summary> + /// Interaction logic for ObjectInTreeView.xaml + /// </summary> + public partial class ObjectInTreeView : UserControl + { + public ObjectInTreeView() + { + InitializeComponent(); + } + + public object ObjectToVisualize + { + get { return (object)GetValue(ObjectToVisualizeProperty); } + set { SetValue(ObjectToVisualizeProperty, value); } + } + public static readonly DependencyProperty ObjectToVisualizeProperty = + DependencyProperty.Register("ObjectToVisualize", typeof(object), typeof(ObjectInTreeView), new PropertyMetadata(null, OnObjectChanged)); + + private static void OnObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TreeNode tree = TreeNode.CreateTree(e.NewValue); + (d as ObjectInTreeView).TreeNodes = new List<TreeNode>() { tree }; + } + + public List<TreeNode> TreeNodes + { + get { return (List<TreeNode>)GetValue(TreeNodesProperty); } + set { SetValue(TreeNodesProperty, value); } + } + public static readonly DependencyProperty TreeNodesProperty = + DependencyProperty.Register("TreeNodes", typeof(List<TreeNode>), typeof(ObjectInTreeView), new PropertyMetadata(null)); + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/TreeNode.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/TreeNode.cs new file mode 100644 index 000000000..47407077f --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Controls/TreeNode.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web.Script.Serialization; + +namespace Tango.FSE.Procedures.Controls +{ + public class TreeNode + { + public string Name { get; set; } + public string Value { get; set; } + public List<TreeNode> Children { get; set; } = new List<TreeNode>(); + + public static TreeNode CreateTree(object obj) + { + if (obj.GetType().IsValueTypeOrString()) + { + return new TreeNode() + { + Name = "Value", + Value = obj.ToStringSafe() + }; + } + else + { + JavaScriptSerializer jss = new JavaScriptSerializer(); + var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(obj); + Dictionary<string, object> dic = jss.Deserialize<Dictionary<string, object>>(serialized); + var root = new TreeNode(); + root.Name = "Root"; + BuildTree(dic, root); + return root; + } + } + + private static void BuildTree(object item, TreeNode node) + { + if (item is KeyValuePair<string, object>) + { + KeyValuePair<string, object> kv = (KeyValuePair<string, object>)item; + TreeNode keyValueNode = new TreeNode(); + keyValueNode.Name = kv.Key; + keyValueNode.Value = GetValueAsString(kv.Value); + node.Children.Add(keyValueNode); + BuildTree(kv.Value, keyValueNode); + } + else if (item is ArrayList) + { + ArrayList list = (ArrayList)item; + int index = 0; + foreach (object value in list) + { + TreeNode arrayItem = new TreeNode(); + arrayItem.Name = $"[{index}]"; + arrayItem.Value = ""; + node.Children.Add(arrayItem); + BuildTree(value, arrayItem); + index++; + } + } + else if (item is Dictionary<string, object>) + { + Dictionary<string, object> dictionary = (Dictionary<string, object>)item; + foreach (KeyValuePair<string, object> d in dictionary) + { + BuildTree(d, node); + } + } + } + + private static string GetValueAsString(object value) + { + if (value == null) + return "null"; + var type = value.GetType(); + if (type.IsArray) + { + return "[]"; + } + + if (value is ArrayList) + { + var arr = value as ArrayList; + return $"[{arr.Count}]"; + } + + if (type.IsGenericType) + { + return "{}"; + } + + return value.ToString(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/DebugNode.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/DebugNode.cs new file mode 100644 index 000000000..81f29c96c --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/DebugNode.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Core; +using Tango.Core.Commands; + +namespace Tango.FSE.Procedures +{ + public class DebugNode : ExtendedObject + { + private Object _originalValue; + + public String Name { get; set; } + public Object ParentObject { get; set; } + + private Object _value; + public Object Value + { + get { return _value; } + set + { + _value = value; + + if (_originalValue == null) + { + _originalValue = _value; + } + + DisplayValue = GetDisplayValue(_value); + RaisePropertyChangedAuto(); + } + } + + public bool IsSimpleValue { get; set; } + + public String Type { get; set; } + public PropertyInfo PropertyInfo { get; set; } + public FieldInfo FieldInfo { get; set; } + + public Type MemberType + { + get + { + if (PropertyInfo != null) + { + return PropertyInfo.PropertyType; + } + else if (FieldInfo != null) + { + return FieldInfo.FieldType; + } + else + { + return Value.GetType(); + } + } + } + + private bool _isEdited; + public bool IsEdited + { + get { return _isEdited; } + set { _isEdited = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand UpdateValueCommand { get; set; } + + public bool IsEditable + { + get + { + if (IsSimpleValue) + { + return false; //Sorry can't update simple script symbols as they are passed to me by value... + } + + if (MemberType != null && MemberType.IsValueTypeOrString() && ((PropertyInfo != null && PropertyInfo.SetMethod != null) || FieldInfo != null)) + { + return true; + } + + return false; + } + } + + private Object _displayValue; + public Object DisplayValue + { + get { return _displayValue; } + set { _displayValue = value; RaisePropertyChangedAuto(); } + } + + public List<DebugNode> Nodes + { + get + { + return GetChildNodes(); + } + } + + public DebugNode() + { + UpdateValueCommand = new RelayCommand(UpdateValue); + } + + private void UpdateValue() + { + try + { + if (IsSimpleValue && Value != null) + { + _value = Convert.ChangeType(DisplayValue, Value.GetType()); + IsEdited = _originalValue.ToStringSafe() != Value.ToStringSafe(); + } + else if (IsEditable && ((PropertyInfo != null && PropertyInfo.SetMethod != null) || FieldInfo != null)) + { + if (PropertyInfo != null) + { + _value = Convert.ChangeType(DisplayValue, PropertyInfo.PropertyType); + PropertyInfo.SetValue(ParentObject, Value); + IsEdited = _originalValue.ToStringSafe() != Value.ToStringSafe(); + } + else if (FieldInfo != null) + { + _value = Convert.ChangeType(DisplayValue, FieldInfo.FieldType); + FieldInfo.SetValue(ParentObject, Value); + IsEdited = _originalValue.ToStringSafe() != Value.ToStringSafe(); + } + } + } + catch { } + + DisplayValue = GetDisplayValue(Value); + } + + private List<DebugNode> GetChildNodes() + { + List<DebugNode> childNodes = new List<DebugNode>(); + + if (Value == null) return childNodes; + + var type = Value.GetType(); + + if (type.IsValueTypeOrString()) + { + return childNodes; + } + + if (typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(String)) + { + List<Object> list = (Value as IEnumerable).Cast<Object>().ToList(); + + for (int i = 0; i < list.Count; i++) + { + var item = list[i]; + + DebugNode listNode = new DebugNode(); + listNode.Name = $"[{i}]"; + listNode.Value = item; + listNode.Type = GetFriendlyName(item.GetType()); + childNodes.Add(listNode); + } + } + else + { + foreach (var prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) + { + DebugNode propNode = new DebugNode(); + propNode.Type = GetFriendlyName(prop.PropertyType); + propNode.Name = prop.Name; + propNode.Value = prop.GetValue(Value); + propNode.PropertyInfo = prop; + propNode.ParentObject = Value; + childNodes.Add(propNode); + } + + foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public)) + { + DebugNode propNode = new DebugNode(); + propNode.Type = GetFriendlyName(field.FieldType); + propNode.Name = field.Name; + propNode.Value = field.GetValue(Value); + propNode.FieldInfo = field; + propNode.ParentObject = Value; + childNodes.Add(propNode); + } + } + + return childNodes; + } + + public static DebugNode CreateNode(String name, Object obj) + { + DebugNode node = new DebugNode(); + node.Name = name; + node.Value = obj; + node.Type = GetFriendlyName(obj.GetType()); + + if (obj.GetType().IsValueTypeOrString()) + { + node.IsSimpleValue = true; + } + + return node; + } + + private static String GetFriendlyName(Type type) + { + if (type == typeof(int)) + return "int"; + else if (type == typeof(short)) + return "short"; + else if (type == typeof(byte)) + return "byte"; + else if (type == typeof(bool)) + return "bool"; + else if (type == typeof(long)) + return "long"; + else if (type == typeof(float)) + return "float"; + else if (type == typeof(double)) + return "double"; + else if (type == typeof(decimal)) + return "decimal"; + else if (type == typeof(string)) + return "string"; + else if (type.IsGenericType) + return type.Name.Split('`')[0] + "<" + string.Join(", ", type.GetGenericArguments().Select(x => GetFriendlyName(x)).ToArray()) + ">"; + else + return type.Name; + } + + private static Object GetDisplayValue(Object value) + { + if (value == null) + { + return "null"; + } + else if (value.GetType().IsValueTypeOrString()) + { + return value; + } + else if (typeof(IEnumerable).IsAssignableFrom(value.GetType())) + { + List<Object> list = (value as IEnumerable).Cast<Object>().ToList(); + return $"Count = {list.Count}"; + } + + return value.ToStringSafe(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Helpers/ProcedureExceptionHelper.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Helpers/ProcedureExceptionHelper.cs new file mode 100644 index 000000000..7a57681e7 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Helpers/ProcedureExceptionHelper.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Tango.FSE.Procedures.Helpers +{ + public static class ProcedureExceptionHelper + { + public static int? GetExceptionLineNumber(Exception ex, ProcedureProject project) + { + try + { + Regex regex = new Regex(@"OnExecute\(IProcedureContext context\) in :line (\d+)"); + var matches = regex.Matches(ex.ToString()).OfType<Match>().ToList(); + + if (matches.Count > 0) + { + var match = matches.First(); + + if (match.Groups.Count > 1) + { + var line = match.Groups[1].Value; + int lineNumber = int.Parse(line) - project.Scripts.Count + 1; + return lineNumber; + } + } + } + catch { } + + return null; + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/IProcedureContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/IProcedureContext.cs index e93311d80..8dafe2291 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/IProcedureContext.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/IProcedureContext.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -14,6 +15,7 @@ using Tango.FSE.Common.Connection; using Tango.FSE.Common.Diagnostics; using Tango.Integration.Operation; using Tango.Scripting.Basic; +using Tango.Scripting.Editors.Intellisense; namespace Tango.FSE.Procedures { @@ -22,11 +24,19 @@ namespace Tango.FSE.Procedures /// <summary> /// Occurs when the procedure is reporting about some progress. /// </summary> + [HideIntellisense] event EventHandler<TangoProgressChangedEventArgs<double>> Progress; /// <summary> + /// Occurs when a procedure object break point request occurs through the IDE break points. + /// </summary> + [HideIntellisense] + event EventHandler<BreakPointRequestEventArgs> BreakPointRequest; + + /// <summary> /// Gets the list of current results. /// </summary> + [HideIntellisense] ReadOnlyCollection<Result> Results { get; } /// <summary> @@ -469,5 +479,14 @@ namespace Tango.FSE.Procedures /// <param name="file">The file path.</param> /// <param name="items">The items to write.</param> void WriteCsv<T>(String file, List<T> items); + + /// <summary> + /// Request a breakpoint operation from the host IDE (internal use only). + /// </summary> + /// <param name="file">The file.</param> + /// <param name="lineNumber">The line number.</param> + /// <param name="symbolsMap">The symbols map.</param> + [HideIntellisense] + void BreakPoint(String file, int lineNumber, params Object[] symbolsMap); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs index 88ab8dae9..0f422c5f5 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ProcedureContext.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Reactive.Concurrency; using System.Reactive.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -25,9 +26,11 @@ using Tango.FSE.Common.Diagnostics; using Tango.FSE.Common.Notifications; using Tango.FSE.Common.Threading; using Tango.FSE.Procedures.Dialogs; +using Tango.FSE.Procedures.Helpers; using Tango.Integration.Operation; using Tango.PMR; using Tango.Scripting.Basic; +using Tango.Scripting.Core; namespace Tango.FSE.Procedures { @@ -38,6 +41,10 @@ namespace Tango.FSE.Procedures private Dictionary<String, ProcedureInput> _inputs; private DiagnosticsFrame _lastDiagnosticsFrame; + public event EventHandler<TangoProgressChangedEventArgs<double>> Progress; + + public event EventHandler<BreakPointRequestEventArgs> BreakPointRequest; + [TangoInject] private IMachineProvider MachineProvider { get; set; } @@ -561,8 +568,6 @@ namespace Tango.FSE.Procedures }); } - public event EventHandler<TangoProgressChangedEventArgs<double>> Progress; - public Result AddBitmapResult(ResultType type, String name, Bitmap bitmap) { return AddResult(new Result() @@ -799,5 +804,42 @@ namespace Tango.FSE.Procedures csvFile.Dispose(); } + + public void BreakPoint(string file, int lineNumber, params object[] symbolsMap) + { + if (BreakPointRequest != null && symbolsMap.Length > 0) + { + bool released = false; + + BreakPointRequestEventArgs args = new BreakPointRequestEventArgs(() => + { + released = true; + }); + + args.LineNumber = lineNumber; + args.Script = _project.Scripts.SingleOrDefault(x => x.Name == file); + + for (int i = 0; i < symbolsMap.Length; i += 4) + { + args.Symbols.Add(new ScriptBreakPointSymbol() + { + Name = symbolsMap[i].ToString(), + Offset = (int)symbolsMap[i + 1], + Length = (int)symbolsMap[i + 2], + SymbolObject = symbolsMap[i + 3], + }); + } + + DispatcherProvider.Invoke(() => + { + BreakPointRequest?.Invoke(this, args); + }); + + while (!released) + { + Thread.Sleep(100); + } + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj index fcd5c7603..03ae31168 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Tango.FSE.Procedures.csproj @@ -80,6 +80,7 @@ <Reference Include="System.Reactive.Windows.Threading, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL"> <HintPath>..\..\..\packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll</HintPath> </Reference> + <Reference Include="System.Web.Extensions" /> <Reference Include="System.Windows" /> <Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> @@ -100,12 +101,18 @@ </ItemGroup> <ItemGroup> <Compile Include="ArrayParsingStyle.cs" /> + <Compile Include="BreakPointRequestEventArgs.cs" /> <Compile Include="Contracts\IProcedureDesignerView.cs" /> + <Compile Include="Controls\ObjectInTreeView.xaml.cs"> + <DependentUpon>ObjectInTreeView.xaml</DependentUpon> + </Compile> + <Compile Include="Controls\TreeNode.cs" /> <Compile Include="Converters\BitmapToBitmapSourceConverter.cs" /> <Compile Include="CreateGroup.cs" /> <Compile Include="CreateItem.cs" /> <Compile Include="CSV\CsvColumn.cs" /> <Compile Include="CSV\CsvRow.cs" /> + <Compile Include="DebugNode.cs" /> <Compile Include="Designer\ProjectModel.cs" /> <Compile Include="Designer\ScriptTabModel.cs" /> <Compile Include="DialogController.cs" /> @@ -142,6 +149,7 @@ <DependentUpon>UserInputDialogView.xaml</DependentUpon> </Compile> <Compile Include="Dialogs\UserInputDialogViewVM.cs" /> + <Compile Include="Helpers\ProcedureExceptionHelper.cs" /> <Compile Include="IDialogController.cs" /> <Compile Include="IProcedureContext.cs" /> <Compile Include="IProcedureLogger.cs" /> @@ -300,6 +308,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Controls\ObjectInTreeView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Dialogs\AddReferenceAssemblyView.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml index 06e60997d..661eb5405 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Themes/Generic.xaml @@ -2,6 +2,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:realTimeGraphX="clr-namespace:RealTimeGraphX.WPF;assembly=RealTimeGraphX.WPF" xmlns:commonGraph="clr-namespace:Tango.FSE.Common.Graphs;assembly=Tango.FSE.Common" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:local="clr-namespace:Tango.FSE.Procedures.Themes"> <Style x:Key="FocusVisual"> @@ -467,4 +469,221 @@ </Style.Triggers> </Style> + <Style x:Key="FSE_Debug_TreeViewItemFocusVisualStyle"> + <Setter Property="Control.Template"> + <Setter.Value> + <ControlTemplate> + <Rectangle/> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <PathGeometry x:Key="TreeArrow" Figures="M0,0 L0,6 L6,0 z"/> + + <Style x:Key="FSE_Debug_ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}"> + <Setter Property="Focusable" Value="False"/> + <Setter Property="Width" Value="20"/> + <Setter Property="Height" Value="20"/> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type ToggleButton}"> + <Border Background="Transparent" Height="20" Padding="5,5,5,5" Width="20"> + <Path x:Name="ExpandPath" Data="{StaticResource TreeArrow}" Fill="Transparent" Stroke="{StaticResource FSE_PrimaryForegroundBrush}"> + <Path.RenderTransform> + <RotateTransform Angle="135" CenterY="3" CenterX="3"/> + </Path.RenderTransform> + </Path> + </Border> + <ControlTemplate.Triggers> + <Trigger Property="IsChecked" Value="True"> + <Setter Property="RenderTransform" TargetName="ExpandPath"> + <Setter.Value> + <RotateTransform Angle="180" CenterY="3" CenterX="3"/> + </Setter.Value> + </Setter> + <Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource FSE_PrimaryForegroundBrush}"/> + <Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource FSE_PrimaryForegroundBrush}"/> + </Trigger> + <Trigger Property="IsMouseOver" Value="True"> + <Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource FSE_PrimaryAccentBrush}"/> + <Setter Property="Fill" TargetName="ExpandPath" Value="Transparent"/> + </Trigger> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsMouseOver" Value="True"/> + <Condition Property="IsChecked" Value="True"/> + </MultiTrigger.Conditions> + <Setter Property="Stroke" TargetName="ExpandPath" Value="{StaticResource FSE_PrimaryAccentBrush}"/> + <Setter Property="Fill" TargetName="ExpandPath" Value="{StaticResource FSE_PrimaryAccentBrush}"/> + </MultiTrigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + + <Style x:Key="FSE_Debug_TreeViewItemStyle" TargetType="{x:Type TreeViewItem}"> + <Setter Property="Background" Value="Transparent"/> + <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> + <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> + <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"/> + <Setter Property="FocusVisualStyle" Value="{StaticResource FSE_Debug_TreeViewItemFocusVisualStyle}"/> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type TreeViewItem}"> + <Grid> + <Grid.ColumnDefinitions> + <ColumnDefinition MinWidth="19" Width="Auto"/> + <ColumnDefinition Width="Auto"/> + <ColumnDefinition Width="*"/> + </Grid.ColumnDefinitions> + <Grid.RowDefinitions> + <RowDefinition Height="Auto"/> + <RowDefinition/> + </Grid.RowDefinitions> + <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource FSE_Debug_ExpandCollapseToggleStyle}"/> + <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> + <ContentPresenter x:Name="PART_Header" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> + </Border> + <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/> + </Grid> + <ControlTemplate.Triggers> + <Trigger Property="IsExpanded" Value="false"> + <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/> + </Trigger> + <Trigger Property="HasItems" Value="false"> + <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/> + </Trigger> + <Trigger Property="IsSelected" Value="true"> + + </Trigger> + <MultiTrigger> + <MultiTrigger.Conditions> + <Condition Property="IsSelected" Value="true"/> + <Condition Property="IsSelectionActive" Value="false"/> + </MultiTrigger.Conditions> + + </MultiTrigger> + <Trigger Property="IsEnabled" Value="false"> + <Setter Property="Foreground" Value="{StaticResource FSE_GrayBrush}"/> + </Trigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + <Style.Triggers> + <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true"> + <Setter Property="ItemsPanel"> + <Setter.Value> + <ItemsPanelTemplate> + <VirtualizingStackPanel/> + </ItemsPanelTemplate> + </Setter.Value> + </Setter> + </Trigger> + </Style.Triggers> + </Style> + + <Style x:Key="FSE_Debug_TreeViewStyle" TargetType="{x:Type TreeView}"> + <Style.Resources> + <Style TargetType="TreeViewItem" BasedOn="{StaticResource FSE_Debug_TreeViewItemStyle}"> + + </Style> + </Style.Resources> + <Setter Property="Background" Value="Transparent"/> + <Setter Property="BorderBrush" Value="Transparent"/> + <Setter Property="BorderThickness" Value="0"/> + <Setter Property="Padding" Value="0"/> + <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"/> + <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/> + <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> + <Setter Property="ScrollViewer.PanningMode" Value="Both"/> + <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> + <Setter Property="VerticalContentAlignment" Value="Center"/> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="{x:Type TreeView}"> + <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"> + <ScrollViewer x:Name="_tv_scrollviewer_" Background="{TemplateBinding Background}" CanContentScroll="false" Focusable="false" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"> + <ItemsPresenter/> + </ScrollViewer> + </Border> + <ControlTemplate.Triggers> + <Trigger Property="IsEnabled" Value="false"> + <Setter Property="Background" TargetName="Bd" Value="Transparent"/> + </Trigger> + <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true"> + <Setter Property="CanContentScroll" TargetName="_tv_scrollviewer_" Value="true"/> + </Trigger> + </ControlTemplate.Triggers> + </ControlTemplate> + </Setter.Value> + </Setter> + <Style.Triggers> + <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true"> + <Setter Property="ItemsPanel"> + <Setter.Value> + <ItemsPanelTemplate> + <VirtualizingStackPanel/> + </ItemsPanelTemplate> + </Setter.Value> + </Setter> + </Trigger> + </Style.Triggers> + </Style> + + + <Style x:Key="FSE_Debug_TextBoxStyle" TargetType="TextBox"> + <Setter Property="Background" Value="Transparent"></Setter> + <Setter Property="BorderBrush" Value="{StaticResource FSE_BorderBrush}"></Setter> + <Setter Property="BorderThickness" Value="0"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter> + <Setter Property="CaretBrush" Value="{StaticResource FSE_PrimaryForegroundBrush}"></Setter> + </Style> + + <DataTemplate x:Key="TreeViewDataTemplate"> + <DockPanel> + <material:PackIcon Kind="Cube" VerticalAlignment="Center" Width="12" Height="12" Foreground="{StaticResource FSE_PrimaryForegroundBrush}" /> + <DockPanel Margin="2 0 0 0"> + <Border BorderThickness="0.5" BorderBrush="{StaticResource FSE_BorderBrush}" Padding="2"> + <TextBlock Margin="0 0 0 0" Width="100" Text="{Binding Name}" ToolTip="{Binding Name}"></TextBlock> + </Border> + <DockPanel> + <TextBlock DockPanel.Dock="Right" Margin="10 -1 10 0" Foreground="{StaticResource FSE_GrayBrush}" VerticalAlignment="Center"> + <Run>[</Run> + <Run Text="{Binding Type}"></Run> + <Run>]</Run> + </TextBlock> + <Border Margin="0 0 0 0" BorderThickness="0.5" BorderBrush="{StaticResource FSE_BorderBrush}" Padding="2"> + <DockPanel ToolTip="{Binding DisplayValue}"> + <material:PackIcon Kind="Search" Width="12" Height="12" VerticalAlignment="Center" /> + <TextBox IsEnabled="{Binding IsEditable}" MinWidth="100" MaxWidth="100" Margin="2 0 0 0" Text="{Binding DisplayValue,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> + <TextBox.Style> + <Style TargetType="TextBox" BasedOn="{StaticResource FSE_Debug_TextBoxStyle}"> + <Setter Property="FontWeight" Value="Normal"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding IsEdited}" Value="True"> + <Setter Property="FontWeight" Value="SemiBold"></Setter> + <Setter Property="Foreground" Value="Red"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </TextBox.Style> + <i:Interaction.Triggers> + <i:EventTrigger EventName="LostFocus"> + <i:InvokeCommandAction Command="{Binding UpdateValueCommand}" /> + </i:EventTrigger> + </i:Interaction.Triggers> + <TextBox.InputBindings> + <KeyBinding Key="Return" Command="{Binding UpdateValueCommand}" /> + </TextBox.InputBindings> + </TextBox> + </DockPanel> + </Border> + </DockPanel> + </DockPanel> + </DockPanel> + </DataTemplate> + </ResourceDictionary>
\ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs index bd36350c1..8b3912c32 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/ViewModels/ProcedureDesignerViewVM.cs @@ -59,6 +59,7 @@ namespace Tango.FSE.Procedures.ViewModels private String PROJECT_DIALOG_FILTER = $"Procedure Project Files|*.pproj"; private bool _isProjectChanged; private TaskItem _symbolsTaskItem; + private BreakPointRequestEventArgs _lastBreakPointRequestArgs; #region Properties @@ -215,6 +216,20 @@ namespace Tango.FSE.Procedures.ViewModels set { _runtimeErrorFree = value; RaisePropertyChangedAuto(); } } + private bool _isBreakPoint; + public bool IsBreakPoint + { + get { return _isBreakPoint; } + set { _isBreakPoint = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private bool _isReadOnly; + public bool IsReadOnly + { + get { return _isReadOnly; } + set { _isReadOnly = value; RaisePropertyChangedAuto(); } + } + #endregion #region Commands @@ -260,6 +275,7 @@ namespace Tango.FSE.Procedures.ViewModels public RelayCommand<ProcedureResource> OpenResourceCommand { get; set; } public RelayCommand<ProcedureResource> ExportResourceCommand { get; set; } public RelayCommand CloseRuntimeErrorCommand { get; set; } + public RelayCommand ContinueProjectCommand { get; set; } #endregion @@ -288,7 +304,7 @@ namespace Tango.FSE.Procedures.ViewModels OpenScripts = new ObservableCollection<Script>(); OpenScriptCommand = new RelayCommand<Script>(OpenScript); CloseScriptCommand = new RelayCommand<Script>(CloseScript); - RunProjectCommand = new RelayCommand(RunProject, () => ProjectRunner != null && ProjectRunner.CanRun); + RunProjectCommand = new RelayCommand(RunProject, () => ProjectRunner != null && (ProjectRunner.CanRun || IsBreakPoint)); StopProjectCommand = new RelayCommand(StopProject, () => ProjectRunner != null && ProjectRunner.IsRunning); CompileProjectCommand = new RelayCommand(async () => await CompileProject(), () => ProjectRunner != null && ProjectRunner.CanCompile); AddReferenceAssemblyCommand = new RelayCommand(AddReferenceAssembly); @@ -327,6 +343,7 @@ namespace Tango.FSE.Procedures.ViewModels OpenResourceCommand = new RelayCommand<ProcedureResource>(OpenProcedureResource); ExportResourceCommand = new RelayCommand<ProcedureResource>(ExportProcedureResource); CloseRuntimeErrorCommand = new RelayCommand(CloseRunTimeError); + ContinueProjectCommand = new RelayCommand(ContinueProject); } #endregion @@ -482,6 +499,8 @@ namespace Tango.FSE.Procedures.ViewModels private void StopProject() { ProjectRunner.Stop(); + ContinueProject(); + IsReadOnly = false; } private async Task<bool> CompileProject() @@ -541,15 +560,35 @@ namespace Tango.FSE.Procedures.ViewModels private async void RunProject() { + if (IsBreakPoint) + { + ContinueProject(); + return; + } + try { if (await CompileProject()) { + IsReadOnly = true; SelectedToolWindow = ToolWindows.Output; ResultsViewVM.Results = new List<Result>(); Logger.Clear(); Logger.WriteLine("Running project..."); + var context = new ProcedureContext(Project, this); + + context.BreakPointRequest += Context_BreakPointRequest; + + try + { + Project.BreakPoints = View.GetBreakPoints(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error initializing break points for project."); + } + await ProjectRunner.Run(context); ResultsViewVM.Results = context.Results.ToList(); @@ -564,44 +603,44 @@ namespace Tango.FSE.Procedures.ViewModels { Logger.WriteLine("Project ran to completion with zero results."); } + + IsReadOnly = false; } } catch (OperationCanceledException) { + IsReadOnly = false; Logger.WriteLine("Project terminated by user."); } catch (Exception ex) { + IsReadOnly = false; SelectedToolWindow = ToolWindows.Output; Logger.WriteLine("Project terminated with error:"); Logger.WriteLine(ex.FlattenMessage()); try { - Regex regex = new Regex(@"OnExecute\(IProcedureContext context\) in :line (\d+)"); - var matches = regex.Matches(ex.ToString()).OfType<Match>().ToList(); + int? lineNumber = Helpers.ProcedureExceptionHelper.GetExceptionLineNumber(ex, Project); - if (matches.Count > 0) + if (lineNumber != null) { - var match = matches.First(); - - if (match.Groups.Count > 1) - { - var line = match.Groups[1].Value; - int lineNumber = int.Parse(line) - Project.Scripts.Count + 1; - OpenScript(Project.Scripts.FirstOrDefault(x => x.IsEntryPoint)); - RuntimeException = ex; - View.HighlightRuntimeError(lineNumber); - RuntimeErrorFree = false; - Mouse.OverrideCursor = null; - } + OpenScript(Project.Scripts.FirstOrDefault(x => x.IsEntryPoint)); + RuntimeException = ex; + View.HighlightRuntimeError(lineNumber.Value); + RuntimeErrorFree = false; + IsReadOnly = true; } } catch (Exception exx) { - LogManager.Log(exx, "Error occurred while trying to show procedue runtime error."); + LogManager.Log(exx, "Error occurred while trying to show procedure runtime error."); } } + finally + { + Project.BreakPoints.Clear(); + } } #endregion @@ -1339,6 +1378,38 @@ namespace Tango.FSE.Procedures.ViewModels { View.CloseRunTimeError(); RuntimeErrorFree = true; + IsReadOnly = false; + } + + #endregion + + #region BreakPoint Request + + private void Context_BreakPointRequest(object sender, BreakPointRequestEventArgs e) + { + try + { + _lastBreakPointRequestArgs = e; + OpenScript(e.Script); + View.HighlightBreakPointRequest(e.LineNumber, e.Symbols); + IsBreakPoint = true; + } + catch (Exception ex) + { + e.Release(); + LogManager.Log(ex, "Error initializing runtime debug request."); + } + } + + private void ContinueProject() + { + if (_lastBreakPointRequestArgs != null) + { + View.ResetBreakPointRequest(); + IsBreakPoint = false; + _lastBreakPointRequestArgs.Release(); + _lastBreakPointRequestArgs = null; + } } #endregion diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml index dd442348f..5329c13dc 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml @@ -8,6 +8,7 @@ xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:components="clr-namespace:Tango.SharedUI.Components;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.FSE.Procedures.ViewModels" + xmlns:localControls="clr-namespace:Tango.FSE.Procedures.Controls" xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:editors="clr-namespace:Tango.Scripting.Editors;assembly=Tango.Scripting.Editors" xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" @@ -191,6 +192,12 @@ <material:PackIcon Kind="ContentPaste" /> </Button> <Separator/> + <Button Width="125" ToolTip="Continue (F5)" ToolBar.OverflowMode="AsNeeded" Command="{Binding ContinueProjectCommand}" Visibility="{Binding IsBreakPoint,Converter={StaticResource BooleanToVisibilityConverter}}"> + <DockPanel> + <material:PackIcon Kind="Play" Foreground="{StaticResource FSE_GreenBrush}" /> + <TextBlock Margin="10 2 0 0" VerticalAlignment="Center">Continue</TextBlock> + </DockPanel> + </Button> <Button Width="120" ToolTip="Run (F5)" ToolBar.OverflowMode="AsNeeded" Command="{Binding RunProjectCommand}" Visibility="{Binding ProjectRunner.IsRunning,Converter={StaticResource BooleanToVisibilityInverseConverter}}" IsEnabled="{Binding ProjectRunner.CanRun}"> <DockPanel> <material:PackIcon Kind="Play" Foreground="{StaticResource FSE_GreenBrush}" /> @@ -413,10 +420,13 @@ <ItemsControl.ItemTemplate> <DataTemplate> <editors:ScriptEditor + IsReadOnly="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.IsReadOnly}" + ScriptSource="{Binding}" ReferenceAssemblies="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.LoadedAssemblies}" AdditionalScripts="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.Project.AdditionalScripts}" FontSize="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext.FontSize}" - Code="{Binding Code,Mode=TwoWay}"> + Code="{Binding Code,Mode=TwoWay}" + BreakPointSymbolPressed="ScriptEditor_BreakPointSymbolPressed"> <editors:ScriptEditor.ContextMenu> <ContextMenu> @@ -736,7 +746,7 @@ </TabControl> </Grid> - <Canvas Grid.Column="1" Grid.RowSpan="4" Background="Transparent" Margin="75 35 0 0" x:Name="runTimeErrorCanvas" IsHitTestVisible="True" Visibility="Hidden"> + <Canvas Grid.Column="1" Grid.RowSpan="4" Background="Transparent" Margin="95 35 0 0" x:Name="runTimeErrorCanvas" IsHitTestVisible="True" Visibility="Hidden"> <DockPanel x:Name="runTimeErrorDock" Canvas.Top="200" Canvas.Left="0"> <Grid x:Name="runTimeErrorLineGrid" DockPanel.Dock="Bottom" Width="50" Height="50" HorizontalAlignment="Left"> <Line RenderTransformOrigin="0.5,0.5" x:Name="runTimeErrorLine" X1="0" Y1="50" X2="50" Y2="0" Stroke="{StaticResource FSE_ErrorBrush}"> @@ -768,7 +778,7 @@ CaretBrush="{StaticResource FSE_PrimaryForegroundBrush}" FontSize="{StaticResource FSE_SmallFontSize}" Text="{Binding RuntimeException,Mode=OneWay}" IsReadOnly="True"> - + </TextBox> </DockPanel> </Grid> @@ -776,6 +786,27 @@ </Border> </DockPanel> </Canvas> + + <Canvas Grid.Column="1" Grid.RowSpan="4" Background="Transparent" Margin="95 35 0 0" x:Name="runTimeBreakPointCanvas" IsHitTestVisible="True" Visibility="Hidden" MouseUp="RunTimeBreakPointCanvas_MouseUp"> + <DockPanel x:Name="runTimeBreakPointDock" Canvas.Top="200" Canvas.Left="0"> + <Border BorderBrush="{StaticResource FSE_BorderBrush}" MaxHeight="300" MaxWidth="700" BorderThickness="1" Background="{StaticResource FSE_PrimaryBackgroundMidBrush}" Padding="2" TextElement.FontSize="{StaticResource FSE_SmallFontSize}"> + <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> + <TreeView Style="{StaticResource FSE_Debug_TreeViewStyle}" x:Name="runTimeBreakPointTreeView"> + <TreeView.Resources> + <HierarchicalDataTemplate ItemsSource="{Binding Nodes}" DataType="{x:Type global:DebugNode}"> + <ContentControl Content="{Binding}" ContentTemplate="{StaticResource TreeViewDataTemplate}" /> + </HierarchicalDataTemplate> + </TreeView.Resources> + <TreeViewItem ItemsSource="{Binding Nodes}"> + <TreeViewItem.Header> + <ContentControl Content="{Binding}" ContentTemplate="{StaticResource TreeViewDataTemplate}" /> + </TreeViewItem.Header> + </TreeViewItem> + </TreeView> + </ScrollViewer> + </Border> + </DockPanel> + </Canvas> </Grid> <GridSplitter Grid.Column="2" Width="5" HorizontalAlignment="Center" VerticalAlignment="Stretch" Margin="0 33 0 30" /> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs index a85508b24..0ee25b64d 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Procedures/Views/ProcedureDesignerView.xaml.cs @@ -14,7 +14,9 @@ using System.Windows.Navigation; using System.Windows.Shapes; using Tango.FSE.Procedures.Contracts; using Tango.FSE.Procedures.ViewModels; +using Tango.Logging; using Tango.Scripting.Basic; +using Tango.Scripting.Core; using Tango.Scripting.Editors; using Tango.SharedUI.Helpers; @@ -182,5 +184,69 @@ namespace Tango.FSE.Procedures.Views runTimeErrorCanvas.Visibility = Visibility.Hidden; GetCurrentEditor().ResetColorizationByKeyword(); } + + public void HighlightDebugRequest(Object toDebug, int lineNumber) + { + ScrollToLine(lineNumber); + var editor = GetCurrentEditor(); + editor.HighlightDebugLine(lineNumber); + UIHelper.DoEvents(); + Point? p = editor.GetLineVisualPosition(lineNumber); + + if (p != null) + { + Point point = p.Value; + + } + } + + public List<ScriptBreakPoint> GetBreakPoints() + { + List<ScriptBreakPoint> breakPoints = new List<ScriptBreakPoint>(); + + foreach (var editor in GetAllEditors()) + { + breakPoints.AddRange(editor.GetBreakPoints()); + } + + return breakPoints; + } + + public void HighlightBreakPointRequest(int lineNumber, List<ScriptBreakPointSymbol> symbols) + { + UIHelper.DoEvents(); + ScrollToLine(lineNumber); + var editor = GetCurrentEditor(); + editor.HighlightBreakPoint(lineNumber, symbols); + UIHelper.DoEvents(); + } + + public void ResetBreakPointRequest() + { + GetCurrentEditor().ResetBreakPointLine(); + } + + private void ScriptEditor_BreakPointSymbolPressed(object sender, BreakPointSymbolPressedEventArgs e) + { + try + { + var editor = GetCurrentEditor(); + var point = new Point(e.Position.X, e.Position.Y - editor.VerticalOffset); + Canvas.SetTop(runTimeBreakPointDock, point.Y); + Canvas.SetLeft(runTimeBreakPointDock, Math.Min(point.X, editor.ActualWidth - 110 - runTimeBreakPointDock.ActualWidth)); + + runTimeBreakPointTreeView.DataContext = DebugNode.CreateNode(e.BreakPointSymbol.Name, e.BreakPointSymbol.SymbolObject); + runTimeBreakPointCanvas.Visibility = Visibility.Visible; + } + catch (Exception ex) + { + LogManager.Default.Log(ex, "Error initializing break point debug window."); + } + } + + private void RunTimeBreakPointCanvas_MouseUp(object sender, MouseButtonEventArgs e) + { + runTimeBreakPointCanvas.Visibility = Visibility.Hidden; + } } } diff --git a/Software/Visual_Studio/Installers/Sandcastle/SHFBInstaller_v2020.3.6.0.zip b/Software/Visual_Studio/Installers/Sandcastle/SHFBInstaller_v2020.3.6.0.zip Binary files differnew file mode 100644 index 000000000..c8f91b5e1 --- /dev/null +++ b/Software/Visual_Studio/Installers/Sandcastle/SHFBInstaller_v2020.3.6.0.zip diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs index 2a1a7b7fc..2bd438ff8 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs @@ -52,6 +52,8 @@ namespace Tango.Scripting.Basic } } + public List<ScriptBreakPoint> BreakPoints { get; set; } + public Project() { ID = Guid.NewGuid().ToString(); @@ -62,6 +64,8 @@ namespace Tango.Scripting.Basic Scripts = new ObservableCollection<Script>(); Scripts.CollectionChanged += (x, e) => { RaisePropertyChanged(nameof(AdditionalScripts)); }; + + BreakPoints = new List<ScriptBreakPoint>(); } public Task<CompilationResult> Compile() @@ -93,25 +97,28 @@ namespace Tango.Scripting.Basic code = loadingString + code; - if (!script.IsEntryPoint) + int debugLinesLength = 0; + + foreach (var breakPoint in BreakPoints.Where(x => x.Script == script).OrderBy(x => x.LineNumber)) { - //In case we use #load - //foreach (var match in Regex.Matches(code, "#load \".+\"").OfType<Match>()) - //{ - // String line = match.ToString(); - // var pathMatch = Regex.Match(line, "(?<=\")(.*?)(?=\")"); - // if (pathMatch.Success) - // { - // String path = pathMatch.ToString(); + var debugLine = $"context.BreakPoint(\"{script.Name}\",{breakPoint.LineNumber}"; + + foreach (var symbol in breakPoint.ContextSymbols) + { + debugLine += $",\"{symbol.Name}\",{symbol.Offset},{symbol.Length},{symbol.Name}"; + } + + debugLine += ");"; - // if (!System.IO.Path.IsPathRooted(path)) - // { - // StringBuilder builder = new StringBuilder(code); - // builder.Insert(match.Index + pathMatch.Index, System.IO.Path.GetFullPath(tempFolder + "\\")); - // code = builder.ToString(); - // } - // } - //} + StringBuilder builder = new StringBuilder(code); + builder.Insert(breakPoint.LineStartOffset + loadingString.Length + debugLinesLength, debugLine); + code = builder.ToString(); + + debugLinesLength += debugLine.Length; + } + + if (!script.IsEntryPoint) + { File.WriteAllText(codeFile, code); } else @@ -188,6 +195,7 @@ namespace Tango.Scripting.Basic } finally { + BreakPoints.Clear(); GC.Collect(); } }); diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs new file mode 100644 index 000000000..e847ea03e --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/BreakPoint.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Scripting.Core +{ + public class BreakPoint + { + public int LineNumber { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs new file mode 100644 index 000000000..626c1abc6 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPoint.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Scripting.Core; + +namespace Tango.Scripting.Core +{ + public class ScriptBreakPoint + { + public IScriptSource Script { get; set; } + public int LineNumber { get; set; } + public int LineStartOffset { get; set; } + public int LineEndOffset { get; set; } + public List<ScriptBreakPointSymbol> ContextSymbols { get; set; } + + public ScriptBreakPoint() + { + ContextSymbols = new List<ScriptBreakPointSymbol>(); + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs new file mode 100644 index 000000000..8da35fe55 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/ScriptBreakPointSymbol.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Scripting.Core +{ + public class ScriptBreakPointSymbol + { + public String Name { get; set; } + public int Offset { get; set; } + public int Length { get; set; } + public Object SymbolObject { get; set; } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj index aa4bbb240..bb623a4fe 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Core/Tango.Scripting.Core.csproj @@ -41,8 +41,11 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="BreakPoint.cs" /> <Compile Include="IScriptSource.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="ScriptBreakPoint.cs" /> + <Compile Include="ScriptBreakPointSymbol.cs" /> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs new file mode 100644 index 000000000..1728bb565 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/BreakPointSymbolPressedEventArgs.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.Scripting.Core; + +namespace Tango.Scripting.Editors +{ + public class BreakPointSymbolPressedEventArgs : EventArgs + { + public ScriptBreakPointSymbol BreakPointSymbol { get; set; } + public Point Position { get; set; } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs new file mode 100644 index 000000000..e566e6aa9 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/BreakPointMargin.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Media.TextFormatting; +using Tango.Scripting.Core; +using Tango.Scripting.Editors.Document; +using Tango.Scripting.Editors.Rendering; +using Tango.Scripting.Editors.Utils; + +namespace Tango.Scripting.Editors.Editing +{ + public class BreakPointMargin : AbstractMargin, IWeakEventListener + { + private TextArea textArea; + private int maxLineNumberLength = 1; + private BitmapSource _arrowBitmap; + private ScriptEditor _editor; + + public ObservableCollection<BreakPoint> BreakPoints { get; set; } + + public Brush Background + { + get { return (Brush)GetValue(BackgroundProperty); } + set { SetValue(BackgroundProperty, value); } + } + public static readonly DependencyProperty BackgroundProperty = + DependencyProperty.Register("Background", typeof(Brush), typeof(BreakPointMargin), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(50, 50, 50)))); + + public Brush Foreground + { + get { return (Brush)GetValue(ForegroundProperty); } + set { SetValue(ForegroundProperty, value); } + } + public static readonly DependencyProperty ForegroundProperty = + DependencyProperty.Register("Foreground", typeof(Brush), typeof(BreakPointMargin), new PropertyMetadata(Brushes.Red)); + + static BreakPointMargin() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(BreakPointMargin), + new FrameworkPropertyMetadata(typeof(BreakPointMargin))); + } + + public BreakPointMargin(ScriptEditor editor) + { + _editor = editor; + BreakPoints = new ObservableCollection<BreakPoint>(); + BreakPoints.CollectionChanged += BreakPoints_CollectionChanged; + RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified); + + _arrowBitmap = new BitmapImage(new Uri($"pack://application:,,,/Tango.Scripting.Editors;component/Images/break_point_arrow.png", UriKind.Absolute)); + } + + private void BreakPoints_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + InvalidateVisual(); + } + + protected override Size MeasureOverride(Size availableSize) + { + return new Size(20, 0); + } + + protected override void OnRender(DrawingContext drawingContext) + { + TextView textView = this.TextView; + Size renderSize = this.RenderSize; + if (textView != null && textView.VisualLinesValid) + { + drawingContext.DrawRectangle(Background, new Pen(Background, 1), new Rect(0, 0, ActualWidth, ActualHeight)); + + var foreground = Foreground; + foreach (VisualLine line in textView.VisualLines) + { + int lineNumber = line.FirstDocumentLine.LineNumber; + + BreakPoint b = BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber); + + if (b != null) + { + double y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop); + drawingContext.DrawEllipse(Foreground, new Pen(Brushes.Gainsboro, 1), new Point(10, y - textView.VerticalOffset + 8), 6, 6); + + if (b.IsActive) + { + drawingContext.DrawImage(_arrowBitmap, new Rect(6, y - textView.VerticalOffset + 2.5, 8.5, 10)); + } + } + } + } + } + + protected override void OnTextViewChanged(TextView oldTextView, TextView newTextView) + { + if (oldTextView != null) + { + oldTextView.VisualLinesChanged -= TextViewVisualLinesChanged; + } + base.OnTextViewChanged(oldTextView, newTextView); + if (newTextView != null) + { + newTextView.VisualLinesChanged += TextViewVisualLinesChanged; + + // find the text area belonging to the new text view + textArea = newTextView.Services.GetService(typeof(TextArea)) as TextArea; + } + else + { + textArea = null; + } + InvalidateVisual(); + } + + protected override void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument) + { + if (oldDocument != null) + { + PropertyChangedEventManager.RemoveListener(oldDocument, this, "LineCount"); + } + base.OnDocumentChanged(oldDocument, newDocument); + if (newDocument != null) + { + PropertyChangedEventManager.AddListener(newDocument, this, "LineCount"); + } + OnDocumentLineCountChanged(); + } + + protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) + { + if (managerType == typeof(PropertyChangedEventManager)) + { + OnDocumentLineCountChanged(); + return true; + } + return false; + } + + bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) + { + return ReceiveWeakEvent(managerType, sender, e); + } + + private void OnDocumentLineCountChanged() + { + int documentLineCount = Document != null ? Document.LineCount : 1; + int newLength = documentLineCount.ToString(CultureInfo.CurrentCulture).Length; + + foreach (var breakPoint in BreakPoints.ToList()) + { + if (breakPoint.LineNumber > documentLineCount) + { + BreakPoints.Remove(breakPoint); + } + else + { + try + { + var line = Document.GetLineByNumber(breakPoint.LineNumber); + if (line != null) + { + String lineText = Document.GetText(line.Offset, line.Length); + if (!IsBreakPointValid(lineText)) + { + BreakPoints.Remove(breakPoint); + } + } + } + catch { } + } + } + + // The margin looks too small when there is only one digit, so always reserve space for + // at least two digits + if (newLength < 2) + newLength = 2; + + if (newLength != maxLineNumberLength) + { + maxLineNumberLength = newLength; + InvalidateMeasure(); + } + } + + private void TextViewVisualLinesChanged(object sender, EventArgs e) + { + InvalidateVisual(); + } + + protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) + { + // accept clicks even when clicking on the background + return new PointHitTestResult(this, hitTestParameters.HitPoint); + } + + private VisualLine GetLineNumberByMousePosition(MouseEventArgs e) + { + Point pos = e.GetPosition(TextView); + pos.X = 0; + pos.Y += TextView.VerticalOffset; + VisualLine vl = TextView.GetVisualLineFromVisualTop(pos.Y); + return vl; + } + + private bool IsBreakPointValid(String lineText) + { + if (lineText.EndsWith(";") && !lineText.StartsWith("using")) + { + return true; + } + + return false; + } + + protected override void OnPreviewMouseMove(MouseEventArgs e) + { + base.OnPreviewMouseMove(e); + + if (_editor.DisableBreakPoints) + { + Cursor = Cursors.No; + } + else + { + Cursor = Cursors.Arrow; + } + } + + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonDown(e); + + if (_editor.DisableBreakPoints) + { + return; + } + + try + { + if (!e.Handled && TextView != null && textArea != null) + { + e.Handled = true; + textArea.Focus(); + + var visualLine = GetLineNumberByMousePosition(e); + + int? lineNumber = visualLine != null ? (int?)visualLine.FirstDocumentLine.LineNumber : null; + + if (lineNumber != null) + { + var breakPoint = BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber.Value); + if (breakPoint != null) + { + BreakPoints.Remove(breakPoint); + } + else + { + var lineText = Document.GetText(visualLine.FirstDocumentLine.Offset, visualLine.FirstDocumentLine.Length).Trim(); + + if (IsBreakPointValid(lineText)) + { + BreakPoint newBreakPoint = new BreakPoint(); + newBreakPoint.LineNumber = lineNumber.Value; + BreakPoints.Add(newBreakPoint); + } + } + } + } + } + catch (Exception ex) + { + Debug.WriteLine(ex); + } + } + } +} diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png Binary files differnew file mode 100644 index 000000000..e8d367028 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Images/break_point_arrow.png diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs new file mode 100644 index 000000000..548bd909e --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/HideIntellisenseAttribute.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Scripting.Editors.Intellisense +{ + public class HideIntellisenseAttribute : Attribute + { + } +} 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 3dc796152..c2e7ac422 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Intellisense/KnownType.cs @@ -137,6 +137,8 @@ namespace Tango.Scripting.Editors.Intellisense { var method = methods[i]; + if (method.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue; + KnownTypeMethod m = new KnownTypeMethod(this); m.Name = method.Name; m.ReturnType = method.ReturnType; @@ -183,17 +185,14 @@ namespace Tango.Scripting.Editors.Intellisense //Load Properties { - if (Type == typeof(Color)) - { - - } - var properties = Type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).ToList(); for (int i = 0; i < properties.Count; i++) { var property = properties[i]; + if (property.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue; + KnownTypeProperty p = new KnownTypeProperty(this); p.Name = property.Name; p.ReturnType = property.PropertyType; @@ -211,6 +210,8 @@ namespace Tango.Scripting.Editors.Intellisense { var ev = events[i]; + if (ev.GetCustomAttribute<HideIntellisenseAttribute>() != null) continue; + KnownTypeEvent p = new KnownTypeEvent(this); p.Name = ev.Name; diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs index c650ad425..b355ba818 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/ScriptEditor.cs @@ -47,7 +47,10 @@ namespace Tango.Scripting.Editors private char[] word_separators = { ' ', '\t', '\n', '.', '(', ',', '-', '*', '/', '+', '$', '=', '<', '>' }; private string[] _blocking_type_words = { "class", "void" }; + public event EventHandler<BreakPointSymbolPressedEventArgs> BreakPointSymbolPressed; + private DispatcherTimer _update_timer; + private BreakPointMargin breakPointMargin; private Popup _popup; private FoldingManager foldingManager; private BraceFoldingStrategy foldingStrategy; @@ -58,6 +61,11 @@ namespace Tango.Scripting.Editors private List<ScriptType> _declaredTypes; private bool _isLoadingTypes; private TextMarkerService errorMarkerService; + private List<ScriptBreakPointSymbol> _breakPointSymbols; + private int _breakPointLineNumber; + private ScriptBreakPointSymbol _currentBreakPointSymbol; + private Point _currentBreakPointSymbolPosition; + private static JsonSerializerSettings _jsonSettings; private static Dictionary<Type, KnownType> _knownTypesCache; private static String KNOWN_TYPES_CACHE_FOLDER; @@ -199,6 +207,39 @@ namespace Tango.Scripting.Editors public static readonly DependencyProperty ErrorLineBrushProperty = DependencyProperty.Register("ErrorLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Red) { Opacity = 0.5 })); + public Brush DebugLineBrush + { + get { return (Brush)GetValue(DebugLineBrushProperty); } + set { SetValue(DebugLineBrushProperty, value); } + } + public static readonly DependencyProperty DebugLineBrushProperty = + DependencyProperty.Register("DebugLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Gray) { Opacity = 0.5 })); + + public Brush BreakPointLineBrush + { + get { return (Brush)GetValue(BreakPointLineBrushProperty); } + set { SetValue(BreakPointLineBrushProperty, value); } + } + public static readonly DependencyProperty BreakPointLineBrushProperty = + DependencyProperty.Register("BreakPointLineBrush", typeof(Brush), typeof(ScriptEditor), new PropertyMetadata(new SolidColorBrush(Colors.Yellow) { Opacity = 0.5 })); + + public IScriptSource ScriptSource + { + get { return (IScriptSource)GetValue(ScriptSourceProperty); } + set { SetValue(ScriptSourceProperty, value); } + } + public static readonly DependencyProperty ScriptSourceProperty = + DependencyProperty.Register("ScriptSource", typeof(IScriptSource), typeof(ScriptEditor), new PropertyMetadata(null)); + + public bool DisableBreakPoints + { + get { return (bool)GetValue(DisableBreakPointsProperty); } + set { SetValue(DisableBreakPointsProperty, value); } + } + public static readonly DependencyProperty DisableBreakPointsProperty = + DependencyProperty.Register("DisableBreakPoints", typeof(bool), typeof(ScriptEditor), new PropertyMetadata(false)); + + #endregion #region Constructors @@ -337,6 +378,17 @@ namespace Tango.Scripting.Editors TextArea.TextView.LineTransformers.Add(errorMarkerService); Unloaded += ScriptEditor_Unloaded; + + breakPointMargin = new BreakPointMargin(this); + _breakPointSymbols = new List<ScriptBreakPointSymbol>(); + Loaded += ScriptEditor_Loaded; + + MouseMove += ScriptEditor_MouseMove; + } + + private void ScriptEditor_Loaded(object sender, RoutedEventArgs e) + { + TextArea.LeftMargins.Insert(0, breakPointMargin); } private void ScriptEditor_Unloaded(object sender, RoutedEventArgs e) @@ -500,6 +552,8 @@ namespace Tango.Scripting.Editors private void TextArea_TextEntered(object sender, TextCompositionEventArgs e) { + if (IsReadOnly) return; + try { List<Object> items = new List<object>(); @@ -2505,6 +2559,47 @@ namespace Tango.Scripting.Editors Document.EndUpdate(); } + public void HighlightDebugLine(int lineNumber) + { + Document.BeginUpdate(); + + var line = Document.GetLineByNumber(lineNumber); + OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, DebugLineBrush); + TextArea.TextView.LineTransformers.Add(errorLineColrizer); + + Document.EndUpdate(); + } + + public void HighlightBreakPoint(int lineNumber, List<ScriptBreakPointSymbol> symbols) + { + _breakPointLineNumber = lineNumber; + _breakPointSymbols = symbols.ToList(); + _currentBreakPointSymbol = null; + + Document.BeginUpdate(); + + var line = Document.GetLineByNumber(lineNumber); + OffsetColorizer errorLineColrizer = new OffsetColorizer(line, line.Offset, line.EndOffset, BreakPointLineBrush); + TextArea.TextView.LineTransformers.Add(errorLineColrizer); + + var breakPoint = breakPointMargin.BreakPoints.FirstOrDefault(x => x.LineNumber == lineNumber); + breakPoint.IsActive = true; + breakPointMargin.InvalidateVisual(); + + Document.EndUpdate(); + } + + public void ResetBreakPointLine() + { + _breakPointSymbols = new List<ScriptBreakPointSymbol>(); + _currentBreakPointSymbol = null; + ResetColorizationByKeyword(); + breakPointMargin.BreakPoints.ToList().ForEach(x => x.IsActive = false); + Mouse.OverrideCursor = null; + ClearErrors(); + breakPointMargin.InvalidateVisual(); + } + public Point? GetLineVisualPosition(int lineNumber) { double top = TextArea.TextView.GetVisualTopByDocumentLine(lineNumber); @@ -2521,6 +2616,140 @@ namespace Tango.Scripting.Editors return null; } + public List<ScriptBreakPoint> GetBreakPoints() + { + List<ScriptBreakPoint> breakPoints = new List<ScriptBreakPoint>(); + + foreach (var b in breakPointMargin.BreakPoints) + { + ScriptBreakPoint breakPoint = new ScriptBreakPoint(); + breakPoint.Script = ScriptSource; + breakPoint.LineNumber = b.LineNumber; + + var line = Document.GetLineByNumber(b.LineNumber); + breakPoint.LineStartOffset = line.Offset; + breakPoint.LineEndOffset = line.EndOffset; + + var symbols = _parser.GetContextSymbols(Document.Text, line.Offset); + + foreach (var symbol in symbols.Where(x => (x.Kind == SymbolKind.Property || x.Kind == SymbolKind.Field || x.Kind == SymbolKind.Local || x.Kind == SymbolKind.Parameter) && !x.IsUnassigned)) + { + if (symbol.Offset < line.Offset) + { + breakPoint.ContextSymbols.Add(new ScriptBreakPointSymbol() + { + Name = symbol.Name, + Offset = symbol.Offset, + Length = symbol.Length, + }); + } + } + + breakPoints.Add(breakPoint); + } + + return breakPoints; + } + + #endregion + + #region BreakPoint Symbols Search + + private void ScriptEditor_MouseMove(object sender, MouseEventArgs e) + { + if (IsReadOnly && _breakPointSymbols.Count > 0) + { + try + { + var word_separators_plus = word_separators.ToList(); + word_separators_plus.Add(')'); + word_separators_plus.Add(';'); + + var textView = TextArea.TextView; + Point position = e.GetPosition(textView); + position.Y += textView.VerticalOffset; + VisualLine visualLine = textView.GetVisualLineFromVisualTop(position.Y); + int columnIndex = visualLine.GetVisualColumnFloor(position, false); + String line = Document.GetText(visualLine.FirstDocumentLine.Offset, visualLine.FirstDocumentLine.Length); + if (columnIndex < line.Length) + { + int wordStartIndex = columnIndex; + int wordEndIndex = columnIndex; + + while (wordStartIndex > 0) + { + if (word_separators_plus.Contains(line[wordStartIndex])) break; + wordStartIndex--; + } + + while (wordEndIndex < line.Length) + { + if (word_separators_plus.Contains(line[wordEndIndex])) break; + wordEndIndex++; + } + + if (wordStartIndex > 0) + { + wordStartIndex++; + } + + String word = line.Substring(wordStartIndex, wordEndIndex - wordStartIndex); + + var breakPointSymbol = _breakPointSymbols.FirstOrDefault(x => x.Name == word); + + if (breakPointSymbol != null) + { + int wordStartOffset = visualLine.FirstDocumentLine.Offset + wordStartIndex; + + ClearErrors(); + ITextMarker marker = errorMarkerService.Create(wordStartOffset, word.Length); + marker.MarkerTypes = TextMarkerTypes.NormalUnderline; + marker.MarkerColor = Colors.Yellow; + Mouse.OverrideCursor = Cursors.Hand; + + _currentBreakPointSymbol = breakPointSymbol; + _currentBreakPointSymbolPosition = visualLine.GetVisualPosition(wordEndIndex, VisualYPosition.LineTop); + } + else + { + _currentBreakPointSymbol = null; + Mouse.OverrideCursor = null; + ClearErrors(); + } + } + else + { + _currentBreakPointSymbol = null; + Mouse.OverrideCursor = null; + ClearErrors(); + } + } + catch (Exception ex) + { + _currentBreakPointSymbol = null; + Mouse.OverrideCursor = null; + ClearErrors(); + Debug.WriteLine(ex.Message); + } + } + } + + protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnPreviewMouseLeftButtonUp(e); + + if (_currentBreakPointSymbol != null) + { + Mouse.OverrideCursor = null; + Debug.WriteLine($"Pressed on break point symbol: {_currentBreakPointSymbol.Name}"); + BreakPointSymbolPressed?.Invoke(this, new BreakPointSymbolPressedEventArgs() + { + BreakPointSymbol = _currentBreakPointSymbol, + Position = _currentBreakPointSymbolPosition + }); + } + } + #endregion } } 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 a70bbf3de..11e023f86 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 @@ -180,6 +180,7 @@ <Link>GlobalVersionInfo.cs</Link> </Compile> <Compile Include="AvalonEditCommands.cs" /> + <Compile Include="BreakPointSymbolPressedEventArgs.cs" /> <Compile Include="CachedAssembly.cs" /> <Compile Include="CachedUsing.cs" /> <Compile Include="CodeCompletion\CompletionListBox.cs" /> @@ -196,6 +197,7 @@ <Compile Include="CodeCompletion\OverloadViewer.cs" /> <Compile Include="Converters\BooleanToVisibilityConverter.cs" /> <Compile Include="Converters\BooleanToVisibilityInversedConverter.cs" /> + <Compile Include="Editing\BreakPointMargin.cs" /> <Compile Include="Errors\ITextMarker.cs" /> <Compile Include="Errors\TextMarkerService.cs" /> <Compile Include="ExtensionMethods.cs" /> @@ -207,6 +209,7 @@ <Compile Include="Intellisense\EventCompletionItem.cs" /> <Compile Include="Intellisense\FieldCompletionItem.cs" /> <Compile Include="Intellisense\FieldCompletionItemPopup.cs" /> + <Compile Include="Intellisense\HideIntellisenseAttribute.cs" /> <Compile Include="Intellisense\ICompletionItem.cs" /> <Compile Include="Intellisense\ICompletionProvider.cs" /> <Compile Include="Intellisense\InterfaceCompletionItem.cs" /> @@ -651,6 +654,9 @@ <ItemGroup> <Resource Include="Images\snippet.png" /> </ItemGroup> + <ItemGroup> + <Resource Include="Images\break_point_arrow.png" /> + </ItemGroup> <ProjectExtensions> <VisualStudio> <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UseGlobalSettings="True" /> diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj new file mode 100644 index 000000000..70a4840c4 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Tango.Scripting.Editors_di35u2uj_wpftmp.csproj @@ -0,0 +1,628 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{DA62FA39-668B-47A6-B0F2-D2C1DAF777B0}</ProjectGuid> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <OutputType>Library</OutputType> + <RootNamespace>Tango.Scripting.Editors</RootNamespace> + <AssemblyName>Tango.Scripting.Editors</AssemblyName> + <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> + <AppDesignerFolder>Properties</AppDesignerFolder> + <SourceAnalysisOverrideSettingsFile>"C:\Program Files\SharpDevelop\3.0\bin\..\AddIns\AddIns\Misc\SourceAnalysis\Settings.SourceAnalysis"</SourceAnalysisOverrideSettingsFile> + <AllowUnsafeBlocks>False</AllowUnsafeBlocks> + <NoStdLib>False</NoStdLib> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>false</TreatWarningsAsErrors> + <SignAssembly>false</SignAssembly> + <AssemblyOriginatorKeyFile>ICSharpCode.AvalonEdit.snk</AssemblyOriginatorKeyFile> + <DelaySign>False</DelaySign> + <AssemblyOriginatorKeyMode>File</AssemblyOriginatorKeyMode> + <RunCodeAnalysis>False</RunCodeAnalysis> + <CodeAnalysisRules>-Microsoft.Design#CA1020;-Microsoft.Design#CA1033;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810</CodeAnalysisRules> + <OutputPath>..\bin\$(Configuration)</OutputPath> + <DocumentationFile>..\bin\$(Configuration)\ICSharpCode.AvalonEdit.xml</DocumentationFile> + <NoWarn>1607</NoWarn> + <TargetFrameworkProfile> + </TargetFrameworkProfile> + <SccProjectName>SAK</SccProjectName> + <SccLocalPath>SAK</SccLocalPath> + <SccAuxPath>SAK</SccAuxPath> + <SccProvider>SAK</SccProvider> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>Full</DebugType> + <Optimize>False</Optimize> + <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> + <DefineConstants>DEBUG;TRACE;DOTNET4</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> + <DebugSymbols>false</DebugSymbols> + <DebugType>PdbOnly</DebugType> + <Optimize>True</Optimize> + <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> + <DefineConstants>TRACE;DOTNET4</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> + <RegisterForComInterop>False</RegisterForComInterop> + <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies> + <BaseAddress>4194304</BaseAddress> + <PlatformTarget>AnyCPU</PlatformTarget> + <FileAlignment>4096</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"> + <OutputPath>..\..\Build\Scripting\Debug\</OutputPath> + <DocumentationFile> + </DocumentationFile> + <Prefer32Bit>false</Prefer32Bit> + <DefineConstants>TRACE;DEBUG</DefineConstants> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'"> + <Prefer32Bit>false</Prefer32Bit> + <OutputPath>..\..\Build\Scripting\Release\</OutputPath> + <DocumentationFile /> + </PropertyGroup> + <PropertyGroup> + <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + </PropertyGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <Compile Include="..\..\Versioning\GlobalVersionInfo.cs"> + <Link>GlobalVersionInfo.cs</Link> + </Compile> + <Compile Include="AvalonEditCommands.cs" /> + <Compile Include="CachedAssembly.cs" /> + <Compile Include="CachedUsing.cs" /> + <Compile Include="CodeCompletion\CompletionListBox.cs" /> + <Compile Include="CodeCompletion\CompletionListBoxItem.cs" /> + <Compile Include="CodeCompletion\CompletionWindowBase.cs" /> + <Compile Include="CodeCompletion\CompletionList.cs" /> + <Compile Include="CodeCompletion\CompletionWindow.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="CodeCompletion\ICompletionData.cs" /> + <Compile Include="CodeCompletion\InsightWindow.cs" /> + <Compile Include="CodeCompletion\IOverloadProvider.cs" /> + <Compile Include="CodeCompletion\OverloadInsightWindow.cs" /> + <Compile Include="CodeCompletion\OverloadViewer.cs" /> + <Compile Include="Converters\BooleanToVisibilityConverter.cs" /> + <Compile Include="Converters\BooleanToVisibilityInversedConverter.cs" /> + <Compile Include="Editing\BreakPoint.cs" /> + <Compile Include="Editing\BreakPointMargin.cs" /> + <Compile Include="Errors\ITextMarker.cs" /> + <Compile Include="Errors\TextMarkerService.cs" /> + <Compile Include="ExtensionMethods.cs" /> + <Compile Include="Intellisense\ClassCompletionItemPopup.cs" /> + <Compile Include="Intellisense\CompletionItem.cs" /> + <Compile Include="Intellisense\CompletionItemPopupControl.cs" /> + <Compile Include="Intellisense\EnumCompletionItem.cs" /> + <Compile Include="Intellisense\EnumCompletionItemPopup.cs" /> + <Compile Include="Intellisense\EventCompletionItem.cs" /> + <Compile Include="Intellisense\FieldCompletionItem.cs" /> + <Compile Include="Intellisense\FieldCompletionItemPopup.cs" /> + <Compile Include="Intellisense\ICompletionItem.cs" /> + <Compile Include="Intellisense\ICompletionProvider.cs" /> + <Compile Include="Intellisense\InterfaceCompletionItem.cs" /> + <Compile Include="Intellisense\InterfaceCompletionItemPopup.cs" /> + <Compile Include="Intellisense\KnownType.cs" /> + <Compile Include="Document\ChangeTrackingCheckpoint.cs" /> + <Compile Include="Document\DocumentChangeOperation.cs"> + <DependentUpon>UndoStack.cs</DependentUpon> + </Compile> + <Compile Include="Document\ILineTracker.cs" /> + <Compile Include="Document\ISegment.cs" /> + <Compile Include="Document\ITextSource.cs" /> + <Compile Include="Document\IUndoableOperation.cs"> + <DependentUpon>UndoStack.cs</DependentUpon> + </Compile> + <Compile Include="Document\LineNode.cs"> + <DependentUpon>DocumentLine.cs</DependentUpon> + </Compile> + <Compile Include="Document\NewLineFinder.cs" /> + <Compile Include="Document\OffsetChangeMap.cs" /> + <Compile Include="Document\TextDocumentWeakEventManager.cs"> + <DependentUpon>TextDocument.cs</DependentUpon> + </Compile> + <Compile Include="Document\TextSegmentCollection.cs" /> + <Compile Include="Document\TextAnchor.cs" /> + <Compile Include="Document\TextAnchorNode.cs"> + <DependentUpon>TextAnchor.cs</DependentUpon> + </Compile> + <Compile Include="Document\TextAnchorTree.cs"> + <DependentUpon>TextAnchor.cs</DependentUpon> + </Compile> + <Compile Include="Document\TextLocation.cs" /> + <Compile Include="Document\TextSegment.cs" /> + <Compile Include="Document\TextUtilities.cs" /> + <Compile Include="Document\UndoOperationGroup.cs"> + <DependentUpon>UndoStack.cs</DependentUpon> + </Compile> + <Compile Include="Document\UndoStack.cs"> + </Compile> + <Compile Include="Document\WeakLineTracker.cs"> + <DependentUpon>ILineTracker.cs</DependentUpon> + </Compile> + <Compile Include="Editing\AbstractMargin.cs" /> + <Compile Include="Editing\Caret.cs" /> + <Compile Include="Editing\CaretLayer.cs"> + </Compile> + <Compile Include="Editing\CaretNavigationCommandHandler.cs"> + </Compile> + <Compile Include="Editing\CaretWeakEventHandler.cs" /> + <Compile Include="Editing\DottedLineMargin.cs" /> + <Compile Include="Editing\DragDropException.cs" /> + <Compile Include="Editing\EditingCommandHandler.cs" /> + <Compile Include="Editing\EmptySelection.cs"> + <DependentUpon>Selection.cs</DependentUpon> + </Compile> + <Compile Include="Editing\ImeNativeWrapper.cs" /> + <Compile Include="Editing\SelectionSegment.cs" /> + <Compile Include="Editing\ImeSupport.cs" /> + <Compile Include="Folding\AbstractFoldingStrategy.cs" /> + <Compile Include="Folding\BraceFoldingStrategy.cs" /> + <Compile Include="Folding\FoldingElementGenerator.cs" /> + <Compile Include="Folding\FoldingManager.cs" /> + <Compile Include="Folding\FoldingMargin.cs" /> + <Compile Include="Folding\FoldingMarginMarker.cs" /> + <Compile Include="Folding\FoldingSection.cs" /> + <Compile Include="Editing\IReadOnlySectionProvider.cs" /> + <Compile Include="Editing\LineNumberMargin.cs" /> + <Compile Include="Editing\NoReadOnlySections.cs"> + <DependentUpon>IReadOnlySectionProvider.cs</DependentUpon> + </Compile> + <Compile Include="Editing\RectangleSelection.cs"> + <DependentUpon>Selection.cs</DependentUpon> + </Compile> + <Compile Include="Editing\Selection.cs" /> + <Compile Include="Editing\SelectionColorizer.cs"> + <DependentUpon>Selection.cs</DependentUpon> + </Compile> + <Compile Include="Editing\SelectionLayer.cs"> + <DependentUpon>Selection.cs</DependentUpon> + </Compile> + <Compile Include="Editing\SelectionMouseHandler.cs"> + <DependentUpon>Selection.cs</DependentUpon> + </Compile> + <Compile Include="Editing\SimpleSelection.cs"> + <DependentUpon>Selection.cs</DependentUpon> + </Compile> + <Compile Include="Editing\TextArea.cs" /> + <Compile Include="Editing\TextAreaDefaultInputHandlers.cs" /> + <Compile Include="Editing\TextAreaInputHandler.cs" /> + <Compile Include="Editing\TextSegmentReadOnlySectionProvider.cs"> + <DependentUpon>IReadOnlySectionProvider.cs</DependentUpon> + </Compile> + <Compile Include="Folding\NewFolding.cs" /> + <Compile Include="Folding\XmlFoldingStrategy.cs" /> + <Compile Include="Highlighting\DocumentHighlighter.cs" /> + <Compile Include="Highlighting\HighlightedInlineBuilder.cs" /> + <Compile Include="Highlighting\HighlightedLine.cs" /> + <Compile Include="Highlighting\HighlightedSection.cs" /> + <Compile Include="Highlighting\HighlightingBrush.cs" /> + <Compile Include="Highlighting\HighlightingColor.cs" /> + <Compile Include="Highlighting\HighlightingColorizer.cs" /> + <Compile Include="Highlighting\HighlightingDefinitionInvalidException.cs" /> + <Compile Include="Highlighting\HighlightingDefinitionTypeConverter.cs" /> + <Compile Include="Highlighting\HighlightingManager.cs" /> + <Compile Include="Highlighting\HtmlClipboard.cs" /> + <Compile Include="Highlighting\IHighlighter.cs" /> + <Compile Include="Highlighting\IHighlightingDefinition.cs" /> + <Compile Include="Highlighting\HighlightingRule.cs" /> + <Compile Include="Highlighting\OffsetColorizer.cs" /> + <Compile Include="Highlighting\Resources\Resources.cs" /> + <Compile Include="Highlighting\HighlightingRuleSet.cs" /> + <Compile Include="Highlighting\HighlightingSpan.cs" /> + <Compile Include="Highlighting\IHighlightingDefinitionReferenceResolver.cs"> + </Compile> + <Compile Include="Highlighting\Xshd\HighlightingLoader.cs" /> + <Compile Include="Highlighting\Xshd\IXshdVisitor.cs" /> + <Compile Include="Highlighting\Xshd\SaveXshdVisitor.cs" /> + <Compile Include="Highlighting\Xshd\V1Loader.cs" /> + <Compile Include="Highlighting\Xshd\V2Loader.cs" /> + <Compile Include="Highlighting\Xshd\XmlHighlightingDefinition.cs" /> + <Compile Include="Highlighting\Xshd\XshdColor.cs" /> + <Compile Include="Highlighting\Xshd\XshdImport.cs" /> + <Compile Include="Highlighting\Xshd\XshdProperty.cs" /> + <Compile Include="Highlighting\Xshd\XshdReference.cs" /> + <Compile Include="Highlighting\Xshd\XshdElement.cs" /> + <Compile Include="Highlighting\Xshd\XshdKeywords.cs" /> + <Compile Include="Highlighting\Xshd\XshdRule.cs" /> + <Compile Include="Highlighting\Xshd\XshdRuleSet.cs" /> + <Compile Include="Highlighting\Xshd\XshdSpan.cs" /> + <Compile Include="Highlighting\Xshd\XshdSyntaxDefinition.cs" /> + <Compile Include="Indentation\CSharp\CSharpIndentationHelper.cs" /> + <Compile Include="Indentation\CSharp\IndentationReformatter.cs" /> + <Compile Include="Indentation\CSharp\CSharpIndentationStrategy.cs" /> + <Compile Include="Indentation\CSharp\DocumentAccessor.cs" /> + <Compile Include="Indentation\DefaultIndentationStrategy.cs" /> + <Compile Include="Indentation\IIndentationStrategy.cs" /> + <Compile Include="Intellisense\KnownTypeConstructor.cs" /> + <Compile Include="Intellisense\KnownTypeEvent.cs" /> + <Compile Include="Intellisense\KnownTypeField.cs" /> + <Compile Include="Intellisense\KnownTypeMember.cs" /> + <Compile Include="Intellisense\KnownTypeMethodParameter.cs" /> + <Compile Include="Intellisense\KnownTypeMethod.cs" /> + <Compile Include="Intellisense\KnownTypeProperty.cs" /> + <Compile Include="Intellisense\ClassCompletionItem.cs" /> + <Compile Include="Intellisense\MethodCompletionItem.cs" /> + <Compile Include="Intellisense\MethodCompletionItemPopup.cs" /> + <Compile Include="Intellisense\NamespaceCompletionItem.cs" /> + <Compile Include="Intellisense\NamespaceCompletionItemPopup.cs" /> + <Compile Include="Intellisense\PropertyCompletionItem.cs" /> + <Compile Include="Intellisense\PropertyCompletionItemPopup.cs" /> + <Compile Include="Intellisense\SnippetCompletionItem.cs" /> + <Compile Include="Intellisense\StructCompletionItem.cs" /> + <Compile Include="Intellisense\StructCompletionItemPopup.cs" /> + <Compile Include="Intellisense\Utils.cs" /> + <Compile Include="Popups\MethodDescription.cs" /> + <Compile Include="Popups\MethodPopup.cs" /> + <Compile Include="Popups\ParameterDescription.cs" /> + <Compile Include="Rendering\BackgroundGeometryBuilder.cs"> + <DependentUpon>IBackgroundRenderer.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\CollapsedLineSection.cs"> + <DependentUpon>HeightTree.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\ColorizingTransformer.cs"> + <DependentUpon>IVisualLineTransformer.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\ColumnRulerRenderer.cs" /> + <Compile Include="Rendering\DefaultTextRunTypographyProperties.cs" /> + <Compile Include="Rendering\DocumentColorizingTransformer.cs"> + <DependentUpon>IVisualLineTransformer.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\FormattedTextElement.cs" /> + <Compile Include="Rendering\GlobalTextRunProperties.cs"> + <DependentUpon>TextView.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\HeightTree.cs" /> + <Compile Include="Rendering\HeightTreeLineNode.cs"> + <DependentUpon>HeightTree.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\HeightTreeNode.cs"> + <DependentUpon>HeightTree.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\IBackgroundRenderer.cs" /> + <Compile Include="Rendering\InlineObjectRun.cs" /> + <Compile Include="Rendering\ITextRunConstructionContext.cs"> + <DependentUpon>VisualLineElementGenerator.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\ITextViewConnect.cs"> + <DependentUpon>TextView.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\IVisualLineTransformer.cs" /> + <Compile Include="Rendering\Layer.cs"> + <DependentUpon>TextView.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\LayerPosition.cs"> + <DependentUpon>TextView.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\LinkElementGenerator.cs" /> + <Compile Include="Rendering\MouseHoverLogic.cs" /> + <Compile Include="Rendering\SimpleTextSource.cs"> + <DependentUpon>FormattedTextElement.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\SingleCharacterElementGenerator.cs" /> + <Compile Include="Rendering\TextLayer.cs"> + <DependentUpon>TextView.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\TextView.cs" /> + <Compile Include="Rendering\TextViewCachedElements.cs" /> + <Compile Include="Rendering\TextViewWeakEventManager.cs"> + <DependentUpon>TextView.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\VisualLine.cs" /> + <Compile Include="Rendering\VisualLineConstructionStartEventArgs.cs" /> + <Compile Include="Rendering\VisualLineElement.cs" /> + <Compile Include="Rendering\VisualLineElementGenerator.cs" /> + <Compile Include="Rendering\VisualLineElementTextRunProperties.cs"> + <DependentUpon>VisualLine.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\VisualLineLinkText.cs" /> + <Compile Include="Rendering\VisualLinesInvalidException.cs" /> + <Compile Include="Rendering\VisualLineText.cs" /> + <Compile Include="Rendering\VisualLineTextParagraphProperties.cs"> + <DependentUpon>VisualLine.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\VisualLineTextSource.cs"> + <DependentUpon>VisualLineElementGenerator.cs</DependentUpon> + </Compile> + <Compile Include="Rendering\VisualYPosition.cs"> + <DependentUpon>VisualLine.cs</DependentUpon> + </Compile> + <Compile Include="ScriptEditor.cs" /> + <Compile Include="Search\Localization.cs" /> + <Compile Include="Search\RegexSearchStrategy.cs" /> + <Compile Include="Search\DropDownButton.cs" /> + <Compile Include="Search\ISearchStrategy.cs" /> + <Compile Include="Search\SearchCommands.cs" /> + <Compile Include="Search\SearchResultBackgroundRenderer.cs" /> + <Compile Include="Search\SearchPanel.cs"> + <SubType>Code</SubType> + </Compile> + <Compile Include="Search\SearchStrategyFactory.cs" /> + <Compile Include="Snippets\IActiveElement.cs" /> + <Compile Include="Snippets\SnippetAnchorElement.cs" /> + <Compile Include="Snippets\SnippetEventArgs.cs" /> + <Compile Include="Snippets\SnippetInputHandler.cs" /> + <Compile Include="Snippets\Snippet.cs" /> + <Compile Include="Snippets\SnippetBoundElement.cs" /> + <Compile Include="Snippets\SnippetCaretElement.cs" /> + <Compile Include="Snippets\SnippetContainerElement.cs" /> + <Compile Include="Snippets\SnippetElement.cs" /> + <Compile Include="Snippets\InsertionContext.cs" /> + <Compile Include="Snippets\SnippetReplaceableTextElement.cs" /> + <Compile Include="Snippets\SnippetSelectionElement.cs" /> + <Compile Include="Snippets\SnippetTextElement.cs" /> + <Compile Include="TextEditor.cs" /> + <Compile Include="TextEditorAutomationPeer.cs" /> + <Compile Include="TextEditorComponent.cs"> + </Compile> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Document\DocumentChangeEventArgs.cs" /> + <Compile Include="Document\GapTextBuffer.cs"> + <DependentUpon>TextDocument.cs</DependentUpon> + </Compile> + <Compile Include="Document\LineManager.cs"> + <DependentUpon>TextDocument.cs</DependentUpon> + </Compile> + <Compile Include="Document\DocumentLine.cs" /> + <Compile Include="Document\DocumentLineTree.cs"> + <DependentUpon>DocumentLine.cs</DependentUpon> + </Compile> + <Compile Include="Document\TextDocument.cs" /> + <Compile Include="TextEditorOptions.cs" /> + <Compile Include="TextEditorWeakEventManager.cs"> + <DependentUpon>TextEditor.cs</DependentUpon> + </Compile> + <Compile Include="TextViewPosition.cs" /> + <Compile Include="Utils\Boxes.cs" /> + <Compile Include="Utils\BusyManager.cs"> + <DependentUpon>ObserveAddRemoveCollection.cs</DependentUpon> + </Compile> + <Compile Include="Utils\CharRope.cs" /> + <Compile Include="Utils\CompressingTreeList.cs" /> + <Compile Include="Utils\Constants.cs" /> + <Compile Include="Utils\DelayedEvents.cs" /> + <Compile Include="Utils\CallbackOnDispose.cs" /> + <Compile Include="Utils\Deque.cs" /> + <Compile Include="Utils\Empty.cs" /> + <Compile Include="Utils\ExtensionMethods.cs" /> + <Compile Include="Utils\FileReader.cs" /> + <Compile Include="Utils\ImmutableStack.cs" /> + <Compile Include="Utils\NullSafeCollection.cs" /> + <Compile Include="Utils\ObserveAddRemoveCollection.cs" /> + <Compile Include="Utils\PropertyChangedWeakEventManager.cs" /> + <Compile Include="Utils\Rope.cs" /> + <Compile Include="Utils\RopeNode.cs" /> + <Compile Include="Utils\RopeTextReader.cs" /> + <Compile Include="Utils\StringSegment.cs" /> + <Compile Include="Utils\TextFormatterFactory.cs" /> + <Compile Include="Utils\WeakEventManagerBase.cs" /> + <Compile Include="Utils\PixelSnapHelpers.cs" /> + <Compile Include="Utils\ThrowUtil.cs" /> + <Compile Include="Utils\Win32.cs" /> + <CodeAnalysisDictionary Include="Properties\CodeAnalysisDictionary.xml" /> + <Compile Include="XamlEditor.cs" /> + <Compile Include="Xml\AbstractAXmlVisitor.cs" /> + <Compile Include="Xml\AXmlAttribute.cs" /> + <Compile Include="Xml\AXmlAttributeCollection.cs" /> + <Compile Include="Xml\AXmlContainer.cs" /> + <Compile Include="Xml\AXmlDocument.cs" /> + <Compile Include="Xml\AXmlElement.cs" /> + <Compile Include="Xml\AXmlObject.cs" /> + <Compile Include="Xml\AXmlObjectCollection.cs" /> + <Compile Include="Xml\AXmlObjectEventArgs.cs" /> + <Compile Include="Xml\AXmlParser.cs" /> + <Compile Include="Xml\AXmlTag.cs" /> + <Compile Include="Xml\AXmlText.cs" /> + <Compile Include="Xml\CanonicalPrintAXmlVisitor.cs" /> + <Compile Include="Xml\InternalException.cs" /> + <Compile Include="Xml\TrackedSegmentCollection.cs"> + <DependentUpon>AXmlParser.cs</DependentUpon> + </Compile> + <Compile Include="Xml\ExtensionMethods.cs" /> + <Compile Include="Xml\FilteredCollection.cs" /> + <Compile Include="Xml\IAXmlVisitor.cs" /> + <Compile Include="Xml\MergedCollection.cs" /> + <Compile Include="Xml\PrettyPrintAXmlVisitor.cs" /> + <Compile Include="Xml\SyntaxError.cs" /> + <Compile Include="Xml\TagMatchingHeuristics.cs"> + <DependentUpon>AXmlParser.cs</DependentUpon> + </Compile> + <Compile Include="Xml\TagReader.cs"> + <DependentUpon>AXmlParser.cs</DependentUpon> + </Compile> + <Compile Include="Xml\TextType.cs"> + <DependentUpon>AXmlText.cs</DependentUpon> + </Compile> + <Compile Include="Xml\TokenReader.cs"> + <DependentUpon>AXmlParser.cs</DependentUpon> + </Compile> + <EmbeddedResource Include="Highlighting\Resources\ASPX.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\Boo.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\Coco-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\CPP-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\HTML-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\Java-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\JavaScript-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\Patch-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\PHP-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\Tex-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\VBNET-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\XML-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\ModeV1.xsd" /> + <EmbeddedResource Include="Highlighting\Resources\ModeV2.xsd" /> + <EmbeddedResource Include="Highlighting\Resources\CSharp-Mode.xshd" /> + <EmbeddedResource Include="Highlighting\Resources\XmlDoc.xshd" /> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Highlighting\Resources\CSS-Mode.xshd" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\Tango.Core\Tango.Core.csproj"> + <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> + <Name>Tango.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Scripting.Core\Tango.Scripting.Core.csproj"> + <Project>{5812E1C6-ABAA-4066-94AC-971C27B4F46A}</Project> + <Name>Tango.Scripting.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Scripting.Formatting\Tango.Scripting.Formatting.csproj"> + <Project>{8d8f06ed-7f75-4933-b0c5-829b0ff654d0}</Project> + <Name>Tango.Scripting.Formatting</Name> + </ProjectReference> + <ProjectReference Include="..\Tango.Scripting\Tango.Scripting.csproj"> + <Project>{1e938fd2-c669-4738-98c9-77f96ce4d451}</Project> + <Name>Tango.Scripting</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Highlighting\Resources\PowerShell.xshd" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Highlighting\Resources\MarkDown-Mode.xshd" /> + </ItemGroup> + <ItemGroup> + <None Include="app.config" /> + <None Include="packages.config" /> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + <Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" /> + <Analyzer Include="..\..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" /> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ItemGroup> + </ItemGroup> + <ProjectExtensions> + <VisualStudio> + <UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_StartDate="2000/1/1" /> + </VisualStudio> + </ProjectExtensions> + <ItemGroup> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\FontAwesome.WPF.4.7.0.9\lib\net40\FontAwesome.WPF.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Microsoft.CodeAnalysis.CSharp.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Microsoft.CodeAnalysis.Common.2.4.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationCore.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationFramework.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ComponentModel.Composition.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Console.4.3.0\lib\net46\System.Console.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Core.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.DataSetExtensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Drawing.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Numerics.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Text.Encoding.CodePages.4.3.0\lib\net46\System.Text.Encoding.CodePages.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Windows.Forms.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xaml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Xml.Linq.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Core\Debug\Tango.Core.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Scripting\Tango.Scripting.Core\bin\Debug\Tango.Scripting.Core.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Build\Scripting\Debug\Tango.Scripting.dll" /> + <ReferencePath Include="C:\DATA\Development\Tango\Software\Visual_Studio\Scripting\Tango.Scripting.Formatting\bin\Debug\Tango.Scripting.Formatting.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\UIAutomationProvider.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\UIAutomationTypes.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\WindowsBase.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Collections.Concurrent.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Collections.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ComponentModel.Annotations.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ComponentModel.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ComponentModel.EventBasedAsync.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Contracts.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Debug.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Tools.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Diagnostics.Tracing.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Dynamic.Runtime.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Globalization.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.IO.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.Expressions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.Parallel.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Linq.Queryable.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.NetworkInformation.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.Primitives.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.Requests.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Net.WebHeaderCollection.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ObjectModel.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Emit.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Emit.ILGeneration.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Emit.Lightweight.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Extensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Reflection.Primitives.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Resources.ResourceManager.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Extensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Handles.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.InteropServices.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.InteropServices.WindowsRuntime.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Numerics.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Json.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Primitives.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Runtime.Serialization.Xml.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Security.Principal.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Duplex.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Http.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.NetTcp.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Primitives.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.ServiceModel.Security.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Text.Encoding.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Text.Encoding.Extensions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Text.RegularExpressions.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.Tasks.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.Tasks.Parallel.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Threading.Timer.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Xml.XDocument.dll" /> + <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\Facades\System.Xml.XmlSerializer.dll" /> + </ItemGroup> + <ItemGroup> + <Compile Include="C:\DATA\Development\Tango\Software\Visual_Studio\Scripting\Tango.Scripting.Editors\obj\Debug\GeneratedInternalTypeHelper.g.cs" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs index e9cb8fc4c..2e7086ce0 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs @@ -138,9 +138,32 @@ namespace Tango.Scripting.Parsing varSymbol.Type = type; varSymbol.Class = ReplaceFakeScript(symbol.ContainingType?.Name); varSymbol.Kind = symbol.Kind; + varSymbol.RealSymbol = symbol; varSymbol.Accessibility = symbol.DeclaredAccessibility; varSymbol.ContainingNamespace = ReplaceFakeScript(symbol.ContainingNamespace?.Name); varSymbol.Summary = GetSymbolDocumentation(symbol); + + try + { + if (symbol.Kind == SymbolKind.Local && symbol.DeclaringSyntaxReferences.Count() > 0) + { + var node = symbol.DeclaringSyntaxReferences.First().GetSyntax() as VariableDeclaratorSyntax; + + if (node != null) + { + varSymbol.IsUnassigned = node.Initializer == null; + } + } + } + catch { } + + try + { + varSymbol.Offset = symbol.Locations[0].SourceSpan.Start; + varSymbol.Length = symbol.Locations[0].SourceSpan.Length; + } + catch { } + vars.Add(varSymbol); if (type == "?") diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs index d6fdaeebf..4b34837af 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptSymbol.cs @@ -17,6 +17,10 @@ namespace Tango.Scripting.Parsing public String ContainingNamespace { get; set; } public List<KeyValuePair<String,String>> Parameters { get; set; } public String Summary { get; set; } + public int Offset { get; set; } + public int Length { get; set; } + public bool IsUnassigned { get; set; } + public ISymbol RealSymbol { get; set; } public ScriptSymbol() { |
